All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ar.com.zauber.commons.web.utils.HttpHeadersUtils Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2005-2015 Zauber S.A. 
 *
 * 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 ar.com.zauber.commons.web.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Clases de utilidad para trabajar con headers http.
 * 
 * 
 * @author Pablo Grigolatto
 * @since May 14, 2009
 */
public final class HttpHeadersUtils {

    /** Creates the HttpAcceptUtils. */
    private HttpHeadersUtils() {
        // utility class
    }


    /**
     * Dado el contenido del Header Accept, y una lista de mime-types que 
     * se manejan, el metodo decide la mejor opcion entre los tipos de 
     * contenido aceptados.
     * 
     * Ver: 
     * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
     * @see http://httpd.apache.org/docs/1.3/content-negotiation.html
     * 
     * @param acceptedContentTypes
     * @return la mejor opcion entre los tipos de contenido aceptados por el
     *         cliente o null si no acepta ninguno
     */
    public static String getContentType(final String acceptHeader,
            final Collection acceptedContentTypes) {
        for (ContentTypeContainer container : getPrioritizedList(acceptHeader)) {
            for (String string : acceptedContentTypes) {
                if(container.matches(string)) {
                    return string;
                }
            }
        }
        return null;
    }

    /**
     * Parsea el Header Accept y retorna una lista ordenada segun los parametros
     * de calidad del protocolo
     * 
     * Por ejemplo para el contenido de Accept: 
     *     
text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c
* Retorna: *
     * [{text/html  1.0 1}, 
     *  {text/x-c   1.0 3}, 
     *  {text/x-dvi 0.8 2}, 
     *  {text/plain 0.5 0}]
     *  
*/ static List getPrioritizedList( final String acceptHeader) { final List priorizedList = new ArrayList(); final String[] array = acceptHeader.split(","); for (int i = 0; i < array.length; i++) { priorizedList.add(new ContentTypeContainer(array[i].trim(), i)); } Collections.sort(priorizedList); return priorizedList; } } /** * Representaria al header Accept segun... * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 * * Usado internamente. */ class ContentTypeContainer implements Comparable { // Accept = "Accept" ":" // #( media-range [ accept-params ] ) // // media-range = ( "*/*" // | ( type "/" "*" ) // | ( type "/" subtype ) // ) *( ";" parameter ) // accept-params = ";" "q" "=" qvalue *( accept-extension ) // accept-extension = ";" token [ "=" ( token | quoted-string ) ] private final double q; private final String mediaRange; private final long position; private final Pattern pattern; /** * Creates the ContentTypeContainer. * */ public ContentTypeContainer(final String type, final int position) { if (type.contains(";")) { mediaRange = type.substring(0, type.indexOf(";")).trim(); if (type.contains("q=")) { q = Double.parseDouble(type.substring( type.indexOf("q=") + 2, type.indexOf("q=") + 5)); } else { q = 1.0; } } else { mediaRange = type.trim(); q = 1.0; } pattern = Pattern.compile(mediaRange.replace("*", ".+")); this.position = position; } /** @see Comparable#compareTo(Object) */ public int compareTo(final ContentTypeContainer o) { final int ret; if (this.q > o.q) { ret = -1; } else if (this.q < o.q) { ret = 1; } else { if (this.position < o.position) { ret = -1; } else if (this.position > o.position) { ret = 1; } else { ret = mediaRange.compareTo(o.mediaRange); } } return ret; } /** @see Object#equals(Object) */ @Override public final boolean equals(final Object obj) { boolean ret = false; if(obj == this) { ret = true; } else if(obj instanceof ContentTypeContainer) { final ContentTypeContainer c = (ContentTypeContainer) obj; ret = mediaRange.equals(c.mediaRange) && position == c.position && q == c.q; } return ret; } /** @see Object#hashCode() */ @Override public final int hashCode() { int ret = 17; ret = 37 * ret + mediaRange.hashCode(); ret = 37 * ret + ((int)(position ^ (position >>> 32))); final long ql = Double.doubleToLongBits(q); ret = 37 * ret + ((int)(ql ^ (ql >>> 32))); return ret; } /** * @return true el mediaRange que se pasa como argumento * es "compatible" con el que representa este objeto. */ public boolean matches(final String acceptedMediaRange) { return pattern.matcher(acceptedMediaRange).lookingAt(); } public final String getMediaRange() { return mediaRange; } /** @see java.lang.Object#toString() */ @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append(mediaRange); sb.append("\t"); sb.append(q); sb.append("\t"); sb.append(position); sb.append("}"); return sb.toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy