/**
* Copyright 2005-2014 Restlet
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: Apache 2.0 or or EPL 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 Apache 2.0 license at
* http://www.opensource.org/licenses/apache-2.0
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://restlet.com/products/restlet-framework
*
* Restlet is a registered trademark of Restlet S.A.S.
*/
package org.restlet.ext.jaxrs.internal.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Variant;
import javax.ws.rs.core.Variant.VariantListBuilder;
import org.restlet.ext.jaxrs.internal.util.OneElementIterator;
import org.restlet.ext.jaxrs.internal.util.Util;
/**
* Concrete implementation of abstract class {@link VariantListBuilder}
*
* @author Stephan Koops
*/
public class VariantListBuilderImpl extends VariantListBuilder {
/**
* Creates an Iterator over the elements of the list. If the list is null or
* empty, an Iterator with exact one element is returned: null.
*
* @param <T>
* @param list
* @return an {@link Iterator} with at least one element (perhaps null).
* never null.
*/
private static <T> Iterator<T> createIterator(List<T> list) {
if ((list == null) || list.isEmpty()) {
return new OneElementIterator<T>(null);
}
return list.iterator();
}
private List<String> encodings;
private List<Locale> languages;
private List<MediaType> mediaTypes;
private List<Variant> variants;
/**
* Creates a new VariantListBuilder
*/
public VariantListBuilderImpl() {
}
/**
* Add the current combination of metadata to the list of supported
* variants, after this method is called the current combination of metadata
* is emptied. If more than one value is supplied for one or more of the
* variant properties then a variant will be generated for each possible
* combination. E.g. in the following <code>list</code> would have four
* members:
* <p>
*
* <pre>
* List<Variant> list = VariantListBuilder.newInstance().languages("en","fr")
* .encodings("zip", "identity").add().build()
* </pre>
*
*
* @return the updated builder
* @see javax.ws.rs.core.Variant.VariantListBuilder#add()
*/
@Override
public VariantListBuilder add() {
buildVariants();
return this;
}
/**
* Build a list of representation variants from the current state of the
* builder. After this method is called the builder is reset to an empty
* state.
*
* @return a list of representation variants
* @see javax.ws.rs.core.Variant.VariantListBuilder#build()
*/
@Override
public List<Variant> build() {
if (Util.isNotEmpty(this.encodings) || Util.isNotEmpty(this.languages)
|| Util.isNotEmpty(this.mediaTypes)) {
buildVariants();
}
List<Variant> variants = this.variants;
this.variants = null;
return variants;
}
private void buildVariants() {
Iterator<MediaType> mediaTypeIter = createIterator(this.mediaTypes);
if (this.variants == null) {
this.variants = new ArrayList<Variant>();
}
while (mediaTypeIter.hasNext()) {
MediaType mediaType = mediaTypeIter.next();
Iterator<Locale> languageIter = createIterator(this.languages);
while (languageIter.hasNext()) {
Locale language = languageIter.next();
Iterator<String> encodingIter = createIterator(this.encodings);
while (encodingIter.hasNext()) {
String encoding = encodingIter.next();
Variant variant = new Variant(mediaType, language, encoding);
this.variants.add(variant);
}
}
}
this.encodings.clear();
this.languages.clear();
this.mediaTypes.clear();
}
/**
* Set the encoding[s] for this variant.
*
* @param encodings
* the available encodings
* @return the updated builder
* @see javax.ws.rs.core.Variant.VariantListBuilder#encodings(java.lang.String[])
*/
@Override
public VariantListBuilder encodings(String... encodings) {
if (this.encodings == null) {
this.encodings = new ArrayList<String>();
}
for (String encoding : encodings) {
this.encodings.add(encoding);
}
return this;
}
/**
* Set the language[s] for this variant.
*
* @param languages
* the available languages
* @return the updated builder
* @see javax.ws.rs.core.Variant.VariantListBuilder#languages(java.lang.String[])
*/
@Override
public VariantListBuilder languages(Locale... languages) {
if (this.languages == null) {
this.languages = new ArrayList<Locale>();
}
for (Locale language : languages) {
this.languages.add(language);
}
return this;
}
/**
* Set the media type[s] for this variant.
*
* @param mediaTypes
* the available mediaTypes. If specific charsets are supported
* they should be included as parameters of the respective media
* type.
* @return the updated builder
* @see javax.ws.rs.core.Variant.VariantListBuilder#mediaTypes(javax.ws.rs.core.MediaType[])
*/
@Override
public VariantListBuilder mediaTypes(MediaType... mediaTypes) {
if (this.mediaTypes == null) {
this.mediaTypes = new ArrayList<MediaType>();
}
for (MediaType mediaType : mediaTypes) {
this.mediaTypes.add(mediaType);
}
return this;
}
}