/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.wink.common.internal.utils; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.Set; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import org.apache.wink.common.RuntimeContext; import org.apache.wink.common.internal.contexts.MediaTypeCharsetAdjuster; import org.apache.wink.common.internal.runtime.RuntimeContextTLS; import org.apache.wink.common.internal.uri.UriEncoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MediaTypeUtils { private static final Logger logger = LoggerFactory.getLogger(MediaTypeUtils.class); public static final String ATOM_SERVICE_DOCUMENT = "application/atomsvc+xml"; //$NON-NLS-1$ public static final MediaType ATOM_SERVICE_DOCUMENT_TYPE = new MediaType("application", //$NON-NLS-1$ "atomsvc+xml"); //$NON-NLS-1$ public static final String ATOM_CATEGORIES_DOCUMENT = "application/atomcat+xml"; //$NON-NLS-1$ public static final MediaType ATOM_CATEGORIES_DOCUMENT_TYPE = new MediaType("application", //$NON-NLS-1$ "atomcat+xml"); //$NON-NLS-1$ public static final String ATOM_ENTRY = "application/atom+xml;type=entry"; //$NON-NLS-1$ public static final MediaType ATOM_ENTRY_TYPE = new MediaType("application", //$NON-NLS-1$ "atom+xml", //$NON-NLS-1$ Collections.singletonMap("type", //$NON-NLS-1$ "entry")); //$NON-NLS-1$ public static final String ATOM_FEED = "application/atom+xml;type=feed"; //$NON-NLS-1$ public static final MediaType ATOM_FEED_TYPE = new MediaType( "application", //$NON-NLS-1$ "atom+xml", //$NON-NLS-1$ Collections .singletonMap("type", //$NON-NLS-1$ "feed")); //$NON-NLS-1$ public static final String IMAGE_X_ICON = "image/x-icon"; //$NON-NLS-1$ public static final MediaType IMAGE_X_ICON_TYPE = new MediaType("image", "x-icon"); //$NON-NLS-1$ //$NON-NLS-2$ public static final String IMAGE_PNG = "image/png"; //$NON-NLS-1$ public static final MediaType IMAGE_PNG_TYPE = new MediaType("image", //$NON-NLS-1$ "png"); //$NON-NLS-1$ public static final String IMAGE_VND = "image/vnd.microsoft.icon"; public static final MediaType IMAGE_VND_TYPE = new MediaType("image", //$NON-NLS-1$ "vnd.microsoft.icon"); //$NON-NLS-1$ public static final String IMAGE_JPEG = "image/jpeg"; //$NON-NLS-1$ public static final MediaType IMAGE_JPEG_TYPE = new MediaType("image", //$NON-NLS-1$ "jpeg"); //$NON-NLS-1$ public static final String UNKNOWN = "x-internal/unknown"; //$NON-NLS-1$ public static final MediaType UNKNOWN_TYPE = new MediaType("x-internal", //$NON-NLS-1$ "unknown"); //$NON-NLS-1$ public static final String OPENSEARCH = "application/opensearchdescription+xml"; //$NON-NLS-1$ public static final MediaType OPENSEARCH_TYPE = new MediaType( "application", //$NON-NLS-1$ "opensearchdescription+xml"); //$NON-NLS-1$ public static final String JAVASCRIPT = "application/javascript"; //$NON-NLS-1$ public static final MediaType JAVASCRIPT_TYPE = new MediaType("application", //$NON-NLS-1$ "javascript"); //$NON-NLS-1$ public static final String ECMASCRIPT = "application/ecmascript"; //$NON-NLS-1$ public static final MediaType ECMASCRIPT_TYPE = new MediaType("application", //$NON-NLS-1$ "ecmascript"); //$NON-NLS-1$ public static final String TEXT_ECMASCRIPT = "text/ecmascript"; //$NON-NLS-1$ public static final MediaType TEXT_ECMASCRIPT_TYPE = new MediaType("text", //$NON-NLS-1$ "ecmascript"); //$NON-NLS-1$ public static final String TEXT_JAVASCRIPT = "text/javascript"; //$NON-NLS-1$ public static final MediaType TEXT_JAVASCRIPT_TYPE = new MediaType("text", //$NON-NLS-1$ "javascript"); //$NON-NLS-1$ public static final String CSV = "text/csv"; //$NON-NLS-1$ public static final MediaType CSV_TYPE = new MediaType("text", "csv"); //$NON-NLS-1$ //$NON-NLS-2$ public static final String PDF = "application/pdf"; //$NON-NLS-1$ public static final MediaType PDF_TYPE = new MediaType("application", //$NON-NLS-1$ "pdf"); //$NON-NLS-1$ public static final String ZIP = "application/zip"; //$NON-NLS-1$ public static final MediaType ZIP_TYPE = new MediaType("application", //$NON-NLS-1$ "zip"); //$NON-NLS-1$ public static final String MS_WORD = "application/msword"; //$NON-NLS-1$ public static final MediaType MS_WORD_TYPE = new MediaType("application", //$NON-NLS-1$ "msword"); //$NON-NLS-1$ public static final String MS_EXCEL = "application/vnd.ms-excel"; //$NON-NLS-1$ public static final MediaType MS_EXCEL_TYPE = new MediaType( "application", //$NON-NLS-1$ "vnd.ms-excel"); //$NON-NLS-1$ public static final String MS_PPt = "application/vnd.ms-powerpoint"; //$NON-NLS-1$ public static final MediaType MS_PPT_TYPE = new MediaType( "application", //$NON-NLS-1$ "vnd.ms-powerpoint"); //$NON-NLS-1$ public static final String MULTIPART_MIXED = "multipart/mixed"; //$NON-NLS-1$ public static final MediaType MULTIPART_MIXED_TYPE = new MediaType("multipart", //$NON-NLS-1$ "mixed"); //$NON-NLS-1$ public static final String MULTIPART_FORM_DATA = "multipart/form-data"; //$NON-NLS-1$ public static final MediaType MULTIPART_FORM_DATA_TYPE = new MediaType("multipart", //$NON-NLS-1$ "form-data"); //$NON-NLS-1$ public static final Set<MediaType> JSON_TYPES = createJsonTypes(); private static Set<MediaType> createJsonTypes() { Set<MediaType> result = new LinkedHashSet<MediaType>(); result.add(MediaType.APPLICATION_JSON_TYPE); result.add(JAVASCRIPT_TYPE); result.add(ECMASCRIPT_TYPE); result.add(TEXT_JAVASCRIPT_TYPE); result.add(TEXT_ECMASCRIPT_TYPE); return Collections.unmodifiableSet(result); } public static boolean isXmlType(MediaType mediaType) { return (MediaTypeUtils.equalsIgnoreParameters(mediaType, MediaType.TEXT_XML_TYPE) || MediaTypeUtils .equalsIgnoreParameters(mediaType, MediaType.APPLICATION_XML_TYPE) || (mediaType .getType().equals("application") && mediaType.getSubtype().endsWith("+xml"))); //$NON-NLS-1$ //$NON-NLS-2$ } public static MediaType clone(MediaType mt) { return new MediaType(mt.getType(), mt.getSubtype(), mt.getParameters()); } public static String toEncodedString(MediaType mediaType) { // TODO: optimize with cache? return UriEncoder.encodeString(mediaType.toString()); } /** * The method returns true if m1 is compatible to m2. However, the method * doesn't check that m2 is compatible to m1. For example: * isCompatibleNonCommutative("text/*", "text/plain") returns true, but * isCompatibleNonCommutative("text/plain", "text/*") returns false * * @param m1 * @param m2 * @return */ public static boolean isCompatibleNonCommutative(MediaType m1, MediaType m2) { if (m1 == m2) { return true; } if (m1 == null || m2 == null) { return false; } if (m1.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) return true; else if (m1.getType().equalsIgnoreCase(m2.getType()) && (m1.getSubtype() .equals(MediaType.MEDIA_TYPE_WILDCARD))) return true; else return m1.getType().equalsIgnoreCase(m2.getType()) && m1.getSubtype() .equalsIgnoreCase(m2.getSubtype()); } public static boolean equalsIgnoreParameters(MediaType m1, MediaType m2) { if (m1 == m2) { return true; } if (m1 == null || m2 == null) { return false; } return (m1.getType().equalsIgnoreCase(m2.getType()) && m1.getSubtype().equalsIgnoreCase(m2 .getSubtype())); } /** * compares according to the rule: n/m > n/* > /* */ public static int compareTo(MediaType m1, MediaType m2) { if (m1 == m2) { return 0; } return compareTypeAndSubType(m1, m2); } private static int compareTypeAndSubType(MediaType m1, MediaType m2) { int ret = compareSubType(m1, m2); if (ret != 0) { return ret; } return compareType(m1, m2); } private static int compareType(MediaType m1, MediaType m2) { return compareMediaPart(m1.getType(), m2.getType()); } private static int compareSubType(MediaType m1, MediaType m2) { return compareMediaPart(m1.getSubtype(), m2.getSubtype()); } private static int compareMediaPart(String part1, String part2) { if (part1.equals(MediaType.MEDIA_TYPE_WILDCARD)) { if (part2.equals(MediaType.MEDIA_TYPE_WILDCARD)) { return 0; } return -1; } else if (part2.equals(MediaType.MEDIA_TYPE_WILDCARD)) { return 1; } return 0; } public static class MediaTypeComparator implements Comparator<MediaType> { public int compare(MediaType m1, MediaType m2) { return compareTo(m1, m2); } } /** * Given a set of response HTTP headers and a chosen media type, the method * determines the best acceptable charset encoding to use. * * @param httpHeaders the response HTTP headers, a Content-Type will be set * if one does not exist and if the media type does not have a * charset. * @param mediaType the current media type * @return the chosen media type */ public static MediaType setDefaultCharsetOnMediaTypeHeader(MultivaluedMap<String, Object> httpHeaders, MediaType mediaType) { RuntimeContext context = RuntimeContextTLS.getRuntimeContext(); MediaTypeCharsetAdjuster adjuster = null; if (context != null) { adjuster = context.getAttribute(MediaTypeCharsetAdjuster.class); if (adjuster != null) { return adjuster.setDefaultCharsetOnMediaTypeHeader(httpHeaders, mediaType); } } return mediaType; } }