/** * Copyright 2014 Opower, Inc. * 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.opower.rest.client.generator.util; import java.io.Serializable; import java.util.Comparator; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Method; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * */ public class MediaTypeHelper { public static MediaType getConsumes(Class<?> declaring, AccessibleObject method) { Consumes consume = method.getAnnotation(Consumes.class); if (consume == null) { consume = declaring.getAnnotation(Consumes.class); if (consume == null) return null; } return MediaType.valueOf(consume.value()[0]); } public static MediaType getProduces(Class<?> declaring, Method method) { return getProduces(declaring, method, MediaType.APPLICATION_JSON_TYPE); } public static MediaType getProduces(Class<?> declaring, Method method, MediaType defaultProduces) { Produces consume = method.getAnnotation(Produces.class); if (consume == null) { consume = declaring.getAnnotation(Produces.class); } if (consume == null) return defaultProduces; return MediaType.valueOf(consume.value()[0]); } public static float getQWithParamInfo(MediaType type) { if (type.getParameters() != null) { String val = type.getParameters().get("q"); try { if (val != null) { float rtn = Float.valueOf(val); if (rtn > 1.0F) throw new IllegalArgumentException("MediaType q value cannot be greater than 1.0: " + type.toString()); return rtn; } } catch (NumberFormatException e) { throw new RuntimeException("MediaType q parameter must be a float: " + type, e); } } return 2.0f; } public static int compareWeight(MediaType one, MediaType two) { return new MediaTypeComparator().compare(one, two); } /** * subtypes like application/*+xml * * @param subtype * @return */ public static boolean isCompositeWildcardSubtype(String subtype) { return subtype.startsWith("*+"); } /** * subtypes like application/*+xml * * @param subtype * @return */ public static boolean isWildcardCompositeSubtype(String subtype) { return subtype.endsWith("+*"); } public static boolean isComposite(String subtype) { return (isCompositeWildcardSubtype(subtype) || isWildcardCompositeSubtype(subtype)); } private static class MediaTypeComparator implements Comparator<MediaType>, Serializable { private static final long serialVersionUID = -5828700121582498092L; public int compare(MediaType mediaType2, MediaType mediaType) { float q = getQWithParamInfo(mediaType); boolean wasQ = q != 2.0f; if (q == 2.0f) q = 1.0f; float q2 = getQWithParamInfo(mediaType2); boolean wasQ2 = q2 != 2.0f; if (q2 == 2.0f) q2 = 1.0f; if (q < q2) return -1; if (q > q2) return 1; if (mediaType.isWildcardType() && !mediaType2.isWildcardType()) return -1; if (!mediaType.isWildcardType() && mediaType2.isWildcardType()) return 1; if (mediaType.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) return -1; if (!mediaType.isWildcardSubtype() && mediaType2.isWildcardSubtype()) return 1; if (isComposite(mediaType.getSubtype()) && !isComposite(mediaType2.getSubtype())) return -1; if (!isComposite(mediaType.getSubtype()) && isComposite(mediaType2.getSubtype())) return 1; if (isCompositeWildcardSubtype(mediaType.getSubtype()) && !isCompositeWildcardSubtype(mediaType2.getSubtype())) return -1; if (!isCompositeWildcardSubtype(mediaType.getSubtype()) && isCompositeWildcardSubtype(mediaType2.getSubtype())) return 1; if (isWildcardCompositeSubtype(mediaType.getSubtype()) && !isWildcardCompositeSubtype(mediaType2.getSubtype())) return -1; if (!isWildcardCompositeSubtype(mediaType.getSubtype()) && isWildcardCompositeSubtype(mediaType2.getSubtype())) return 1; int numNonQ = 0; if (mediaType.getParameters() != null) { numNonQ = mediaType.getParameters().size(); if (wasQ) numNonQ--; } int numNonQ2 = 0; if (mediaType2.getParameters() != null) { numNonQ2 = mediaType2.getParameters().size(); if (wasQ2) numNonQ2--; } if (numNonQ < numNonQ2) return -1; if (numNonQ > numNonQ2) return 1; return 0; } } }