001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2014 ForgeRock AS. 016 */ 017 018package org.forgerock.openig.header; 019 020import java.nio.charset.Charset; 021import java.util.List; 022 023import org.forgerock.openig.http.Message; 024 025/** 026 * Processes the <strong>{@code Content-Type}</strong> message header. For more information, 027 * see <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a> §14.17. 028 */ 029public class ContentTypeHeader implements Header { 030 031 /** The name of the header that this object represents. */ 032 public static final String NAME = "Content-Type"; 033 034 /** The type/sub-type of the message. */ 035 private String type = null; 036 037 /** The character set used in encoding the message. */ 038 private String charset = null; 039 040 /** The boundary value provided in multipart messages. */ 041 private String boundary = null; 042 043 /** 044 * Constructs a new empty header. 045 */ 046 public ContentTypeHeader() { 047 } 048 049 /** 050 * Constructs a new header, initialized from the specified message. 051 * 052 * @param message the message to initialize the header from. 053 */ 054 public ContentTypeHeader(Message<?> message) { 055 fromMessage(message); 056 } 057 058 /** 059 * Constructs a new header, initialized from the specified string value. 060 * 061 * @param string the value to initialize the header from. 062 */ 063 public ContentTypeHeader(String string) { 064 fromString(string); 065 } 066 067 /** 068 * Returns the media type of the underlying data or {@code null} if none specified. 069 * 070 * @return The media type of the underlying data or {@code null} if none specified. 071 */ 072 public String getType() { 073 return type != null ? type : null; 074 } 075 076 /** 077 * Returns the character set encoding used to encode the message, or {@code null} if no character set was specified. 078 * 079 * @throws java.nio.charset.IllegalCharsetNameException 080 * if the given charset name is illegal. 081 * @throws java.nio.charset.UnsupportedCharsetException 082 * if no support for the named charset is available. 083 * @return The character set encoding used to encode the message or {@code null} if empty. 084 */ 085 public Charset getCharset() { 086 return charset != null ? Charset.forName(charset) : null; 087 } 088 089 /** 090 * Returns the encapsulation boundary or {@code null} if none specified. 091 * 092 * @return The encapsulation boundary or {@code null} if none specified. 093 */ 094 public String getBoundary() { 095 return boundary != null ? boundary : null; 096 } 097 098 private void clear() { 099 type = null; 100 charset = null; 101 boundary = null; 102 } 103 104 @Override 105 public String getKey() { 106 return NAME; 107 } 108 109 @Override 110 public void fromMessage(Message<?> message) { 111 if (message != null && message.getHeaders() != null) { 112 fromString(message.getHeaders().getFirst(NAME)); 113 } 114 } 115 116 @Override 117 public void fromString(String string) { 118 clear(); 119 List<String> parts = HeaderUtil.split(string, ';'); 120 if (parts.size() > 0) { 121 type = parts.get(0); 122 charset = HeaderUtil.parseParameters(parts).get("charset"); 123 boundary = HeaderUtil.parseParameters(parts).get("boundary"); 124 } 125 } 126 127 @Override 128 public void toMessage(Message<?> message) { 129 String value = toString(); 130 if (value != null) { 131 message.getHeaders().putSingle(NAME, value); 132 } 133 } 134 135 @Override 136 public String toString() { 137 StringBuilder sb = new StringBuilder(); 138 if (type != null) { 139 sb.append(type); 140 if (charset != null) { 141 sb.append("; charset=").append(charset); 142 } 143 if (boundary != null) { 144 sb.append("; boundary=").append(boundary); 145 } 146 } 147 return sb.length() > 0 ? sb.toString() : null; 148 } 149 150 @Override 151 public boolean equals(Object o) { 152 if (this == o) { 153 return true; 154 } 155 if (o == null || !(o instanceof ContentTypeHeader)) { 156 return false; 157 } 158 ContentTypeHeader ct = (ContentTypeHeader) o; 159 return ((type == null && ct.type == null) 160 || (type != null && type.equals(ct.type))) 161 && ((charset == null && ct.charset == null) 162 || (charset != null && charset.equals(ct.charset))) 163 && ((boundary == null && ct.boundary == null) 164 || (boundary != null && boundary.equals(ct.boundary))); 165 } 166 167 @Override 168 public int hashCode() { 169 return (type == null ? 0 : type.hashCode()) 170 ^ (charset == null ? 0 : charset.hashCode()) 171 ^ (boundary == null ? 0 : boundary.hashCode()); 172 } 173}