package org.etk.core.rest.impl.header; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; public final class MediaTypeHelper { /** * Constructor. */ private MediaTypeHelper() { } /** * Compare two mimetypes. The main rule for sorting media types is : * <p> * <li>n / m</li> * <li>n / *</li> * <li>* / *</li> * <p> * Method that explicitly list of media types is sorted before a method that * list * / *. */ public static final Comparator<MediaType> MEDIA_TYPE_COMPARATOR = new Comparator<MediaType>() { /** * {@inheritDoc} */ public int compare(MediaType o1, MediaType o2) { if (o1.getType().equals(MediaType.MEDIA_TYPE_WILDCARD) && !o2.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) { return 1; } if (!o1.getType().equals(MediaType.MEDIA_TYPE_WILDCARD) && o2.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) { return -1; } if (o1.getSubtype().equals(MediaType.MEDIA_TYPE_WILDCARD) && !o2.getSubtype().equals(MediaType.MEDIA_TYPE_WILDCARD)) { return 1; } if (!o1.getSubtype().equals(MediaType.MEDIA_TYPE_WILDCARD) && o2.getSubtype().equals(MediaType.MEDIA_TYPE_WILDCARD)) { return -1; } return 0; } }; /** * Default media type. It minds any content type. */ public static final String DEFAULT = "*/*"; /** * Default media type. It minds any content type. */ public static final MediaType DEFAULT_TYPE = new MediaType("*", "*"); /** * List which contains default media type. */ public static final List<MediaType> DEFAULT_TYPE_LIST = Collections.singletonList(DEFAULT_TYPE); /** * WADL media type. */ public static final String WADL = "application/vnd.sun.wadl+xml"; /** * WADL media type. */ public static final MediaType WADL_TYPE = new MediaType("application", "vnd.sun.wadl+xml"); /** * Create a list of media type for given Consumes annotation. If parameter * mime is null then list with single element * {@link MediaTypeHelper#DEFAULT_TYPE} will be returned. * * @param mime the Consumes annotation. * @return ordered list of media types. */ public static List<MediaType> createConsumesList(Consumes mime) { if (mime == null) { return DEFAULT_TYPE_LIST; } return createMediaTypesList(mime.value()); } /** * Create a list of media type for given Produces annotation. If parameter * mime is null then list with single element * {@link MediaTypeHelper#DEFAULT_TYPE} will be returned. * * @param mime the Produces annotation. * @return ordered list of media types. */ public static List<MediaType> createProducesList(Produces mime) { if (mime == null) { return DEFAULT_TYPE_LIST; } return createMediaTypesList(mime.value()); } /** * Useful for checking does method able to consume certain media type. * * @param consumes list of consumed media types * @param contentType should be checked * @return true contentType is compatible to one of consumes, false otherwise */ public static boolean isConsume(List<MediaType> consumes, MediaType contentType) { for (MediaType c : consumes) { if (contentType.isCompatible(c)) return true; } return false; } /** * Create a list of media type from string array. * * @param mimes source string array * @return ordered list of media types */ private static List<MediaType> createMediaTypesList(String[] mimes) { List<MediaType> l = new ArrayList<MediaType>(mimes.length); for (String m : mimes) l.add(MediaType.valueOf(m)); Collections.sort(l, MEDIA_TYPE_COMPARATOR); return l; } /** * Looking for accept media type with the best quality. Accept list of media * type must be sorted by quality value. * * @param accept See {@link AcceptMediaType}, {@link QualityValue} * @param produces list of produces media type, See {@link Produces} * @return quality value of best found compatible accept media type or 0.0 if * media types are not compatible */ @SuppressWarnings("unchecked") public static float processQuality(List<MediaType> accept, List<MediaType> produces) { // NOTE accept contains list of AcceptMediaType instead // MediaType, see ContainerRequest#getAcceptableMediaTypes Iterator i = accept.iterator(); while (i.hasNext()) { AcceptMediaType a = (AcceptMediaType) i.next(); if ("*".equals(a.getType())) // accept everything, not need continue return a.getQvalue(); for (MediaType p : produces) { if (p.isCompatible(a)) return a.getQvalue(); } } return 0.0F; // 0 quality not acceptable } }