/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.content; /** * ContentNegotation implements the content negotiation algorithm. * From a list of content-types acceptable by the client (accepted types) * and for a list of content-types producible by the server * (produced types), it returns the best fitting content-type. * Both client and server types can contain wildcards and specify a * quality parameter indicating their preference to accept or produce the type. * <p> * For all pairs (accepted type, produced type) the {@link CombinedContentType} * is built, and given a score. * The best combined content type determines the resulting content type, * (which may be null, if accepted and produced types are incompatible). */ public class ContentNegotiation { /** * Creates a ContentNegotation object. * @param acceptedTypes the list of content types * accepted by the client */ public ContentNegotiation(ContentTypeList acceptedTypes) { acceptedTypes_ = acceptedTypes; } /** * Creates a ContentNegotation object. * @param acceptedTypes the list of content types * accepted by the client */ public ContentNegotiation(ContentType... acceptedTypes) { this(new ContentTypeList(acceptedTypes)); } /** * Evaluates if the ContentType is a suitable content type. * @param produced a ContentType which can be produced by the server. * @return true if the ContentType is suitable for the client and is * better than the previous best content type. * If true is returned, then {@link #bestType} contains the * CombinedContentType which should be used by the server * to produce the response. */ public boolean evaluate(ContentType produced) { int n = acceptedTypes_.size(); for (int i=0; i<n; i++) { ContentType accepted = acceptedTypes_.get(i); if (test(accepted, produced)) return true; } return false; } /** * Evaluates if one of the content types in the given list * is a suitable content type and finds the best matching type. * @param produced a list of ContentTypes which can be produced by the server. * @return true if one ContentType is suitable for the client and is * better than the previous best content type. * If true is returned, then {@link #bestType} contains the * CombinedContentType which should be used by the server * to produce the response. */ public boolean evaluate(ContentTypeList produced) { boolean result = false; int n = produced.size(); for (int i=0; i<n; i++) { if (evaluate(produced.get(i))) result = true; } return result; } private boolean test(ContentType accepted, ContentType produced) { CombinedContentType candidate = CombinedContentType.negotiate(accepted, produced, bestType); if (candidate != null) { bestType = candidate; return true; } else return false; } private ContentTypeList acceptedTypes_; public CombinedContentType bestType; }