Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright 2013 SAP AG Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
 
 package com.sap.core.odata.core.commons;
 
 import java.util.List;
 import java.util.Map;
Internally used ContentType for OData library. For more details on format and content of a ContentType see Media Type format as defined in RFC 2616 chapter 3.7. Once created a ContentType is IMMUTABLE.

Author(s):
SAP AG
 
 public class ContentType {
 
   public enum ODataFormat {
     ATOM, XML, JSON, CUSTOM
   }
 
   private static final char WHITESPACE_CHAR = ' ';
   private static final String PARAMETER_SEPARATOR = ";";
   private static final String TYPE_SUBTYPE_SEPARATOR = "/";
   private static final String MEDIA_TYPE_WILDCARD = "*";
   private static final String VERBOSE = "verbose";
 
   public static final String PARAMETER_CHARSET = "charset";
   public static final String PARAMETER_ODATA = "odata";
   public static final String PARAMETER_Q = "q";
   public static final String CHARSET_UTF_8 = "utf-8";
 
   public static final ContentType WILDCARD = new ContentType();
 
   public static final ContentType APPLICATION_XML = new ContentType("application""xml".);
   public static final ContentType APPLICATION_ATOM_XML = new ContentType("application""atom+xml".);
   public static final ContentType APPLICATION_ATOM_XML_ENTRY = new ContentType("application""atom+xml".parameterMap("type""entry"));
   public static final ContentType APPLICATION_ATOM_XML_FEED = new ContentType("application""atom+xml".parameterMap("type""feed"));
   public static final ContentType APPLICATION_ATOM_SVC = new ContentType("application""atomsvc+xml".);
   public static final ContentType APPLICATION_JSON = new ContentType("application""json".);
   public static final ContentType APPLICATION_OCTET_STREAM = new ContentType("application""octet-stream");
   public static final ContentType TEXT_PLAIN = new ContentType("text""plain");
   public static final ContentType TEXT_PLAIN_CS_UTF_8 = ContentType.create();
   public static final ContentType MULTIPART_MIXED = new ContentType("multipart""mixed");
 
   private String type;
   private String subtype;
   private Map<StringStringparameters;
   private ODataFormat odataFormat;
 
   private ContentType(final String typefinal String subtype) {
     this(typesubtype.null);
   }
 
   private ContentType(final String typefinal String subtypefinal Map<StringStringparameters) {
     this(typesubtypemapToODataFormat(subtype), parameters);
   }
 
   private ContentType(final String typefinal String subtypefinal ODataFormat odataFormat) {
     this(typesubtypeodataFormatnull);
   }
 
   private ContentType(final String typefinal String subtypefinal ODataFormat odataFormatfinal Map<StringStringparameters) {
     if ((type == null || .equals(type)) && !.equals(subtype)) {
       throw new IllegalArgumentException("Illegal combination of WILDCARD type with NONE WILDCARD subtype.");
     }
     this. = odataFormat;
     this. = validateType(type);
     this. = validateType(subtype);
    if (parameters == null) {
      this. = Collections.emptyMap();
    } else {
      this. = new TreeMap<StringString>(new Comparator<String>() {
        @Override
        public int compare(final String o1final String o2) {
          return o1.compareToIgnoreCase(o2);
        }
      });
      this..putAll(parameters);
      this..remove();
    }
  }
  private String validateType(final String type) {
    if (type == null) {
      return ;
    }
    if (type.charAt(0) ==  || type.charAt(type.length() - 1) == ) {
      throw new IllegalArgumentException("Illegal leading/trailing whitespace found for type '" + type + "'.");
    }
    return type;
  }

  
Validates if given format is parseable and can be used as input for create(java.lang.String) method.

Parameters:
format to be validated string
Returns:
true if format is parseable otherwise false
  public static boolean isParseable(final String format) {
    try {
      return ContentType.create(format) != null;
    } catch (IllegalArgumentException e) {
      return false;
    }
  }

  
Creates a content type from type and subtype

Parameters:
type
subtype
Returns:
a new ContentType object
  public static ContentType create(final String typefinal String subtype) {
    return new ContentType(typesubtypemapToODataFormat(subtype), null);
  }

  

Parameters:
type
subtype
parameters
Returns:
a new ContentType object
  public static ContentType create(final String typefinal String subtypefinal Map<StringStringparameters) {
    return new ContentType(typesubtypemapToODataFormat(subtype), parameters);
  }

  

Parameters:
contentType
parameterKey
parameterValue
Returns:
a new ContentType object
  public static ContentType create(final ContentType contentTypefinal String parameterKeyfinal String parameterValue) {
    ContentType ct = new ContentType(contentType.typecontentType.subtypecontentType.odataFormatcontentType.parameters);
    ct.parameters.put(parameterKeyparameterValue);
    return ct;
  }

  
Create a ContentType based on given input string (format). Supported format is Media Type format as defined in RFC 2616 chapter 3.7. This format is used as HTTP Accept HEADER format as defined in RFC 2616 chapter 14.1 and HTTP Content-Type HEADER format as defined in RFC 2616 chapter 14.17

Parameters:
format a string in format as defined in RFC 2616 section 3.7
Returns:
a new ContentType object
Throws:
java.lang.IllegalArgumentException if input string is not parseable
  public static ContentType create(final String format) {
    if (format == null) {
      throw new IllegalArgumentException("Parameter format MUST NOT be NULL.");
    }
    // split 'types' and 'parameters'
    String[] typesAndParameters = format.split(, 2);
    String types = typesAndParameters[0];
    String parameters = (typesAndParameters.length > 1 ? typesAndParameters[1] : null);
    //
    Map<StringStringparametersMap = parseParameters(parameters);
    //
    if (types.contains()) {
      String[] tokens = types.split();
      if (tokens.length == 2) {
        return create(tokens[0], tokens[1], parametersMap);
      } else {
        throw new IllegalArgumentException("Too many '" +  + "' in format '" + format + "'.");
      }
    } else {
      return create(typesparametersMap);
    }
  }

  
Create a list of ContentType based on given input strings (contentTypes). Supported format is Media Type format as defined in RFC 2616 chapter 3.7. This format is used as HTTP Accept HEADER format as defined in RFC 2616 chapter 14.1 and HTTP Content-Type HEADER format as defined in RFC 2616 chapter 14.17.

If one of the given strings can not be parsed an exception is thrown (hence no list is returned with the parseable strings).

Parameters:
contentTypeStrings a list of strings in format as defined in RFC 2616 section 3.7
Returns:
a list of new ContentType object
Throws:
java.lang.IllegalArgumentException if one of the given input string is not parseable this exceptions is thrown
  public static List<ContentTypecreate(final List<StringcontentTypeStrings) {
    List<ContentTypecontentTypes = new ArrayList<ContentType>(contentTypeStrings.size());
    for (String contentTypeString : contentTypeStrings) {
      contentTypes.add(create(contentTypeString));
    }
    return contentTypes;
  }

  
Parses the given input string (format) and returns created ContentType if input was valid or return NULL if input was not parseable. For the definition of the supported format see create(java.lang.String).

Parameters:
format a string in format as defined in RFC 2616 section 3.7
Returns:
a new ContentType object
  public static ContentType parse(final String format) {
    try {
      return ContentType.create(format);
    } catch (IllegalArgumentException e) {
      return null;
    }
  }

  

Parameters:
subtype
Returns:
  private static ODataFormat mapToODataFormat(final String subtype) {
    ODataFormat odataFormat = null;
    if (subtype.contains("atom")) {
      odataFormat = .;
    } else if (subtype.contains("xml")) {
      odataFormat = .;
    } else if (subtype.contains("json")) {
      odataFormat = .;
    } else {
      odataFormat = .;
    }
    return odataFormat;
  }

  

Parameters:
content
Returns:
a new ContentType object
  private static Map<StringStringparameterMap(final String... content) {
    Map<StringStringmap = new HashMap<StringString>();
    for (int i = 0; i < content.length - 1; i += 2) {
      String key = content[i];
      String value = content[i + 1];
      map.put(keyvalue);
    }
    return map;
  }

  
Valid input are ; separated key = value pairs.

Parameters:
parameters
Returns:
Map with keys mapped to values
  private static Map<StringStringparseParameters(final String parameters) {
    Map<StringStringparameterMap = new HashMap<StringString>();
    if (parameters != null) {
      String[] splittedParameters = parameters.split();
      for (String parameter : splittedParameters) {
        String[] keyValue = parameter.split("=");
        String key = keyValue[0].trim().toLowerCase(.);
        if (isParameterAllowed(key)) {
          String value = keyValue.length > 1 ? keyValue[1].trim() : null;
          parameterMap.put(keyvalue);
        }
      }
    }
    return parameterMap;
  }
  private static boolean isParameterAllowed(final String key) {
    return key != null && !.equals(key.toLowerCase(.));
  }

  
Ensure that charset parameter (PARAMETER_CHARSET) is set on returned content type if this ContentType is a odata text related content type (@see isContentTypeODataTextRelated()). If this ContentType has no charset parameter set a new ContentType with given defaultCharset is created. Otherwise if charset parameter is already set nothing is done.

Parameters:
defaultCharset
Returns:
ContentType
  public ContentType receiveWithCharsetParameter(final String defaultCharset) {
        return ContentType.create(this.defaultCharset);
      }
    }
    return this;
  }

  

Returns:
true if this ContentType is text related (in the view of OData)
  public boolean isContentTypeODataTextRelated() {
    return (..equals(this)
        || (getODataFormat() == .)
        || (getODataFormat() == .)
        || (getODataFormat() == .));
  }
  public String getType() {
    return ;
  }
  public String getSubtype() {
    return ;
  }

  

Returns:
parameters of this ContentType as unmodifiable map.
  public Map<StringStringgetParameters() {
    return Collections.unmodifiableMap();
  }
  public int hashCode() {
    return 1;
  }

  
ContentTypes are equal
  • if type, subtype and all parameters have the same value.
  • if type and/or subtype is set to "*" (in such a case the parameters are ignored).

Returns:
true if both instances are equal (see definition above), otherwise false.
  public boolean equals(final Object obj) {
    Boolean compatible = isEqualWithoutParameters(obj);
    if (compatible == null) {
      ContentType other = (ContentTypeobj;
      // parameter checks
      if ( == null) {
        if (other.parameters != null) {
          return false;
        }
      } else if (.size() == other.parameters.size()) {
        Iterator<Entry<StringString>> entries = .entrySet().iterator();
        Iterator<Entry<StringString>> otherEntries = other.parameters.entrySet().iterator();
        while (entries.hasNext()) {
          Entry<StringStringe = entries.next();
          Entry<StringStringoe = otherEntries.next();
          if (!areEqual(e.getKey(), oe.getKey())) {
            return false;
          }
          if (!areEqual(e.getValue(), oe.getValue())) {
            return false;
          }
        }
      } else {
        return false;
      }
      return true;
    } else {
      // all tests run
      return compatible.booleanValue();
    }
  }

  
ContentTypes are compatible
  • if type, subtype have the same value.
  • if type and/or subtype is set to "*"
The set parameters are always ignored (for compare with parameters see equals(java.lang.Object)).

Returns:
true if both instances are equal (see definition above), otherwise false.
  public boolean isCompatible(final ContentType obj) {
    Boolean compatible = isEqualWithoutParameters(obj);
    if (compatible == null) {
      return true;
    }
    return compatible.booleanValue();
  }

  
Check equal without parameters. It is possible that no decision about equal/none equal can be determined a NULL is returned.

Parameters:
obj to checked object
Returns:
true if both instances are equal (see definition above), otherwise false or NULL if no decision about equal/none equal could be determined.
  private Boolean isEqualWithoutParameters(final Object obj) {
    // basic checks
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    ContentType other = (ContentTypeobj;
    // subtype checks
    if ( == null) {
      if (other.subtype != null) {
        return false;
      }
    } else if (!.equals(other.subtype)) {
      if (!.equals() && !other.subtype.equals()) {
        return false;
      }
    }
    // type checks
    if ( == null) {
      if (other.type != null) {
        return false;
      }
    } else if (!.equals(other.type)) {
      if (!.equals() && !other.type.equals()) {
        return false;
      }
    }
    // if wildcards are set, content types are defined as 'equal'
    if (countWildcards() > 0 || other.countWildcards() > 0) {
      return true;
    }
    return null;
  }

  
Check whether both string are equal ignoring the case of the strings.

Parameters:
first
second
Returns:
  private static boolean areEqual(final String firstfinal String second) {
    if (first == null) {
      if (second != null) {
        return false;
      }
    } else if (!first.equalsIgnoreCase(second)) {
      return false;
    }
    return true;
  }

  
Get ContentType as string as defined in RFC 2616 (http://www.ietf.org/rfc/rfc2616.txt - chapter 14.17: Content-Type)

Returns:
string representation of ContentType object
  public String toContentTypeString() {
    StringBuilder sb = new StringBuilder();
    for (String key : .keySet()) {
      if (isParameterAllowed(key)) {
        String value = .get(key);
        sb.append("; ").append(key).append("=").append(value);
      }
    }
    return sb.toString();
  }
  public String toString() {
    return toContentTypeString();
  }
  public ODataFormat getODataFormat() {
    return ;
  }

  
Find best match between this ContentType and the ContentType in the list. If a match (this ContentType is equal to a ContentType in list) is found either this or the ContentType from the list is returned based on which ContentType has less "**" characters set (checked with compareWildcardCounts(com.sap.core.odata.core.commons.ContentType). If no match (none ContentType in list is equal to this ContentType) is found NULL is returned.

Parameters:
toMatchContentTypes list of ContentTypes which are matches against this ContentType
Returns:
best matched content type in list or NULL if none content type match to this content type instance
  public ContentType match(final List<ContentTypetoMatchContentTypes) {
    for (ContentType supportedContentType : toMatchContentTypes) {
      if (equals(supportedContentType)) {
        if (compareWildcardCounts(supportedContentType) < 0) {
          return this;
        } else {
          return supportedContentType;
        }
      }
    }
    return null;
  }

  
Find best match between this ContentType and the ContentType in the list ignoring all set parameters. If a match (this ContentType is equal to a ContentType in list) is found either this or the ContentType from the list is returned based on which ContentType has less "**" characters set (checked with compareWildcardCounts(com.sap.core.odata.core.commons.ContentType). If no match (none ContentType in list is equal to this ContentType) is found NULL is returned.

Parameters:
toMatchContentTypes list of ContentTypes which are matches against this ContentType
Returns:
best matched content type in list or NULL if none content type match to this content type instance
  public ContentType matchCompatible(final List<ContentTypetoMatchContentTypes) {
    for (ContentType supportedContentType : toMatchContentTypes) {
      if (isCompatible(supportedContentType)) {
        if (compareWildcardCounts(supportedContentType) < 0) {
          return this;
        } else {
          return supportedContentType;
        }
      }
    }
    return null;
  }

  
Check if a valid match for this ContentType exists in given list. For more detail what a valid match is see match(java.util.List).

Parameters:
toMatchContentTypes list of ContentTypes which are matches against this ContentType
Returns:
true if a matching content type was found in given list or false if none matching content type match was found
  public boolean hasMatch(final List<ContentTypetoMatchContentTypes) {
    return match(toMatchContentTypes) != null;
  }

  
Compare wildcards counts/weights of both ContentType. The smaller ContentType has lesser weighted wildcards then the bigger ContentType. As result this method returns this object weighted wildcards minus the given parameter object weighted wildcards. A type wildcard is weighted with 2 and a subtype wildcard is weighted with 1.

Parameters:
otherContentType ContentType to be compared to
Returns:
this object weighted wildcards minus the given parameter object weighted wildcards.
  public int compareWildcardCounts(final ContentType otherContentType) {
    return countWildcards() - otherContentType.countWildcards();
  }
  private int countWildcards() {
    int count = 0;
      count += 2;
    }
      count++;
    }
    return count;
  }

  

Returns:
true if type or subtype of this instance is a "*".
  public boolean hasWildcard() {
  }

  

Returns:
true if both type and subtype of this instance are a "*".
  public boolean isWildcard() {
  }
  public static List<ContentTypeconvert(final List<Stringtypes) {
    List<ContentTyperesults = new ArrayList<ContentType>();
    for (String contentType : types) {
      results.add(ContentType.create(contentType));
    }
    return results;
  }

  
Check if a valid match for given content type formated string (toMatch) exists in given list. Therefore the given content type formated string (toMatch) is converted into a ContentType with a simple create(java.lang.String) call (during which an exception can occur). For more detail in general see hasMatch(java.util.List) and for what a valid match is see match(java.util.List).

Parameters:
toMatch content type formated string (toMatch) for which is checked if a match exists in given list
matchExamples list of ContentTypes which are matches against content type formated string (toMatch)
Returns:
true if a matching content type was found in given list or false if none matching content type match was found
  public static boolean match(final String toMatchfinal ContentType... matchExamples) {
    ContentType toMatchContentType = ContentType.create(toMatch);
    return toMatchContentType.hasMatch(Arrays.asList(matchExamples));
  }
New to GrepCode? Check out our FAQ X