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

com.noelios.restlet.application.Encoder Maven / Gradle / Ivy

Go to download

This OSGi bundle wraps org.restlet, and com.noelios.restlet ${pkgVersion} jar files.

The newest version!
/**
 * Copyright 2005-2008 Noelios Technologies.
 * 
 * The contents of this file are subject to the terms of the following open
 * source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 (the "Licenses"). You can
 * select the license that you prefer but you may not use this file except in
 * compliance with one of these Licenses.
 * 
 * You can obtain a copy of the LGPL 3.0 license at
 * http://www.gnu.org/licenses/lgpl-3.0.html
 * 
 * You can obtain a copy of the LGPL 2.1 license at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 * 
 * You can obtain a copy of the CDDL 1.0 license at
 * http://www.sun.com/cddl/cddl.html
 * 
 * See the Licenses for the specific language governing permissions and
 * limitations under the Licenses.
 * 
 * Alternatively, you can obtain a royaltee free commercial license with less
 * limitations, transferable or non-transferable, directly at
 * http://www.noelios.com/products/restlet-engine
 * 
 * Restlet is a registered trademark of Noelios Technologies.
 */

package com.noelios.restlet.application;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.restlet.Context;
import org.restlet.Filter;
import org.restlet.data.ClientInfo;
import org.restlet.data.Encoding;
import org.restlet.data.MediaType;
import org.restlet.data.Preference;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.Representation;

/**
 * Filter compressing entities. The best encoding is automatically selected
 * based on the preferences of the client and on the encoding supported by NRE:
 * GZip, Zip and Deflate.
* If the {@link org.restlet.resource.Representation} has an unknown size, it * will always be a candidate for encoding. Candidate representations need to * respect media type criteria by the lists of accepted and ignored media types. * * Concurrency note: instances of this class or its subclasses can be invoked by * several threads at the same time and therefore must be thread-safe. You * should be especially careful when storing state in member variables. * * @author Lars Heuer (heuer[at]semagia.com) Semagia * @author Jerome Louvel */ public class Encoder extends Filter { /** * Indicates if the encoding should always occur, regardless of the size. */ public static final int ENCODE_ALL_SIZES = -1; /** * Returns the list of default encoded media types. This can be overriden by * subclasses. By default, all media types are encoded (except those * explicitely ignored). * * @return The list of default encoded media types. */ public static List getDefaultAcceptedMediaTypes() { final List result = new ArrayList(); result.add(MediaType.ALL); return result; } /** * Returns the list of default ignored media types. This can be overriden by * subclasses. By default, all archive, audio, image and video media types * are ignored. * * @return The list of default ignored media types. */ public static List getDefaultIgnoredMediaTypes() { final List result = Arrays. asList( MediaType.APPLICATION_CAB, MediaType.APPLICATION_GNU_ZIP, MediaType.APPLICATION_ZIP, MediaType.APPLICATION_GNU_TAR, MediaType.APPLICATION_JAVA_ARCHIVE, MediaType.APPLICATION_STUFFIT, MediaType.APPLICATION_TAR, MediaType.AUDIO_ALL, MediaType.IMAGE_ALL, MediaType.VIDEO_ALL); return result; } /** * The media types that should be encoded. */ private volatile List acceptedMediaTypes; /** * Indicates if the request entity should be encoded. */ private volatile boolean encodeRequest; /** * Indicates if the response entity should be encoded. */ private volatile boolean encodeResponse; /** * The media types that should be ignored. */ private volatile List ignoredMediaTypes; /** * The minimal size necessary for encoding. */ private volatile long mininumSize; /** * Constructor using the default media types and with * {@link #ENCODE_ALL_SIZES} setting. This constructor will only encode * response entities after call handling. * * @param context * The context. */ public Encoder(Context context) { this(context, false, true, ENCODE_ALL_SIZES, getDefaultAcceptedMediaTypes(), getDefaultIgnoredMediaTypes()); } /** * Constructor. * * @param context * The context. * @param encodeInput * Indicates if the request entities should be encoded. * @param encodeOutput * Indicates if the response entities should be encoded. * @param minimumSize * The minimal size of the representation where compression * should be used. * @param acceptedMediaTypes * The media types that should be encoded. * @param ignoredMediaTypes * The media types that should be ignored. */ public Encoder(Context context, boolean encodeInput, boolean encodeOutput, long minimumSize, List acceptedMediaTypes, List ignoredMediaTypes) { super(context); this.encodeRequest = encodeInput; this.encodeResponse = encodeOutput; this.mininumSize = minimumSize; this.acceptedMediaTypes = acceptedMediaTypes; this.ignoredMediaTypes = ignoredMediaTypes; } /** * Allows filtering after its handling by the target Restlet. Does nothing * by default. * * @param request * The request to filter. * @param response * The response to filter. */ @Override public void afterHandle(Request request, Response response) { // Check if encoding of the response entity is needed if (isEncodeResponse() && canEncode(response.getEntity())) { response.setEntity(encode(request.getClientInfo(), response .getEntity())); } } /** * Allows filtering before its handling by the target Restlet. Does nothing * by default. * * @param request * The request to filter. * @param response * The response to filter. * @return The continuation status. */ @Override public int beforeHandle(Request request, Response response) { // Check if encoding of the request entity is needed if (isEncodeRequest() && canEncode(request.getEntity())) { request.setEntity(encode(request.getClientInfo(), request .getEntity())); } return CONTINUE; } /** * Indicates if a representation can be encoded. * * @param representation * The representation to test. * @return True if the call can be encoded. */ public boolean canEncode(Representation representation) { // Test the existence of the representation and that no existing // encoding applies boolean result = false; if (representation != null) { boolean identity = true; for (final Iterator iter = representation.getEncodings() .iterator(); identity && iter.hasNext();) { identity = (iter.next().equals(Encoding.IDENTITY)); } result = identity; } if (result) { // Test the size of the representation result = (getMinimumSize() == ENCODE_ALL_SIZES) || (representation.getSize() == Representation.UNKNOWN_SIZE) || (representation.getSize() >= getMinimumSize()); } if (result) { // Test the acceptance of the media type final MediaType mediaType = representation.getMediaType(); boolean accepted = false; for (final Iterator iter = getAcceptedMediaTypes() .iterator(); !accepted && iter.hasNext();) { accepted = iter.next().includes(mediaType); } result = accepted; } if (result) { // Test the rejection of the media type final MediaType mediaType = representation.getMediaType(); boolean rejected = false; for (final Iterator iter = getIgnoredMediaTypes() .iterator(); !rejected && iter.hasNext();) { rejected = iter.next().includes(mediaType); } result = !rejected; } return result; } /** * Encodes a given representation if an encoding is supported by the client. * * @param client * The client preferences to use. * @param representation * The representation to encode. * @return The encoded representation or the original one if no encoding * supported by the client. */ public Representation encode(ClientInfo client, Representation representation) { Representation result = representation; final Encoding bestEncoding = getBestEncoding(client); if (bestEncoding != null) { result = new EncodeRepresentation(bestEncoding, representation); } return result; } /** * Returns the media types that should be encoded. * * @return The media types that should be encoded. */ public List getAcceptedMediaTypes() { return this.acceptedMediaTypes; } /** * Returns the best supported encoding for a given client. * * @param client * The client preferences to use. * @return The best supported encoding for the given call. */ public Encoding getBestEncoding(ClientInfo client) { Encoding bestEncoding = null; Encoding currentEncoding = null; Preference currentPref = null; float bestScore = 0F; for (final Iterator iter = EncodeRepresentation .getSupportedEncodings().iterator(); iter.hasNext();) { currentEncoding = iter.next(); for (final Iterator> iter2 = client .getAcceptedEncodings().iterator(); iter2.hasNext();) { currentPref = iter2.next(); if (currentPref.getMetadata().equals(Encoding.ALL) || currentPref.getMetadata().equals(currentEncoding)) { // A match was found, compute its score if (currentPref.getQuality() > bestScore) { bestScore = currentPref.getQuality(); bestEncoding = currentEncoding; } } } } return bestEncoding; } /** * Returns the media types that should be ignored. * * @return The media types that should be ignored. */ public List getIgnoredMediaTypes() { return this.ignoredMediaTypes; } /** * Returns the minimum size a representation must have before compression is * done. * * @return The minimum size a representation must have before compression is * done. */ public long getMinimumSize() { return this.mininumSize; } /** * Indicates if the request entity should be encoded. * * @return True if the request entity should be encoded. */ public boolean isEncodeRequest() { return this.encodeRequest; } /** * Indicates if the response entity should be encoded. * * @return True if the response entity should be encoded. */ public boolean isEncodeResponse() { return this.encodeResponse; } /** * Indicates if the request entity should be encoded. * * @param encodeRequest * True if the request entity should be encoded. */ public void setEncodeRequest(boolean encodeRequest) { this.encodeRequest = encodeRequest; } /** * Indicates if the response entity should be encoded. * * @param encodeResponse * True if the response entity should be encoded. */ public void setEncodeResponse(boolean encodeResponse) { this.encodeResponse = encodeResponse; } /** * Sets the minimum size a representation must have before compression is * done. * * @param mininumSize * The minimum size a representation must have before compression * is done. */ public void setMinimumSize(long mininumSize) { this.mininumSize = mininumSize; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy