/** * 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.engine.converter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.restlet.data.ClientInfo; import org.restlet.data.MediaType; import org.restlet.data.Preference; import org.restlet.engine.Helper; import org.restlet.engine.resource.VariantInfo; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.Resource; /** * Converter between Representations and regular Java objects. * * @author Jerome Louvel */ public abstract class ConverterHelper extends Helper { /** * Adds an object class to the given list. Creates a new list if necessary. * * @param objectClasses * The object classes list to update or null. * @param objectClass * The object class to add. * @return The input object classes list or a new one. */ protected List<Class<?>> addObjectClass(List<Class<?>> objectClasses, Class<?> objectClass) { if (objectClasses == null) { objectClasses = new ArrayList<Class<?>>(); } objectClasses.add(objectClass); return objectClasses; } /** * Adds a variant to the given list. Creates a new list if necessary. * * @param variants * The variants list to update or null. * @param userVariant * The variant to add if not null. * @return The input variants list or a new one. */ protected List<VariantInfo> addVariant(List<VariantInfo> variants, VariantInfo userVariant) { if (userVariant != null) { if (variants == null) { variants = new ArrayList<VariantInfo>(); } variants.add(userVariant); } return variants; } /** * Returns the list of variants that can be converted from a given object * class. * * @param sourceClass * The source class. * @param targetVariant * The expected representation metadata. * @param variants * The variants list to update. * @throws IOException */ public List<VariantInfo> addVariants(Class<?> sourceClass, Variant targetVariant, List<VariantInfo> variants) throws IOException { // List of variants that can be converted from the source class List<VariantInfo> helperVariants = getVariants(sourceClass); if (helperVariants != null) { // Loop over the variants list for (VariantInfo helperVariant : helperVariants) { if (targetVariant == null) { variants = addVariant(variants, helperVariant); } else if (helperVariant.includes(targetVariant)) { // Detected a more generic variant, but still // consider // the conversion is possible to the target variant. variants = addVariant(variants, new VariantInfo( targetVariant.getMediaType())); } else if (targetVariant.includes(helperVariant)) { // Detected a more specific variant, but still // consider // the conversion is possible to the target variant. variants = addVariant(variants, helperVariant); } } } return variants; } /** * Returns the list of object classes that can be converted from a given * variant. * * @param source * The source variant. * @return The list of object class that can be converted. */ public abstract List<Class<?>> getObjectClasses(Variant source); /** * Returns the list of variants that can be converted from a given object * class. The preferred variant should be set in first position. * * @param source * The source object class. * @return The list of variants that can be converted. */ public abstract List<VariantInfo> getVariants(Class<?> source) throws IOException; /** * Returns the list of variants that can be converted from a given object * class by a specific converter helper. * * @param sourceClass * The source class. * @param targetVariant * The expected representation metadata. * @return The list of variants that can be converted. * @throws IOException */ public List<VariantInfo> getVariants(Class<?> sourceClass, Variant targetVariant) throws IOException { return addVariants(sourceClass, targetVariant, null); } /** * Scores the affinity of this helper with the source class. * * @param source * The source object to convert. * @param target * The expected representation metadata. * @param resource * The calling resource. * @return The affinity score of this helper. */ public abstract float score(Object source, Variant target, Resource resource); /** * Scores the affinity of this helper with the source class. * * @param source * The source representation to convert. * @param target * The expected class of the Java object. * @param resource * The calling resource. * @return The affinity score of this helper. */ public abstract <T> float score(Representation source, Class<T> target, Resource resource); /** * Converts a Representation into a regular Java object. * * @param <T> * The expected class of the Java object. * @param source * The source representation to convert. * @param target * The expected class of the Java object. * @param resource * The calling resource. * @return The converted Java object. */ public abstract <T> T toObject(Representation source, Class<T> target, Resource resource) throws IOException; /** * Converts a regular Java object into a Representation. * * @param source * The source object to convert. * @param target * The expected representation metadata. * @param resource * The calling resource. * @return The converted representation. */ public abstract Representation toRepresentation(Object source, Variant target, Resource resource) throws IOException; /** * Updates the preferences of the given {@link ClientInfo} object with * conversion capabilities for the given entity class. * * @param preferences * The media type preferences. * @param entity * The entity class to convert. */ public <T> void updatePreferences(List<Preference<MediaType>> preferences, Class<T> entity) { // Does nothing by default } /** * Updates the preferences of the given {@link ClientInfo} object with * conversion capabilities for the given entity class. * * @param preferences * The media type preferences. * @param mediaType * The media type to update to add to the preferences. * @param score * The media type score to use as a quality score. */ public void updatePreferences(List<Preference<MediaType>> preferences, MediaType mediaType, float score) { boolean found = false; Preference<MediaType> preference; for (int i = 0; !found && (i < preferences.size()); i++) { preference = preferences.get(i); if (preference.getMetadata().equals(mediaType) && (preference.getQuality() < score)) { preference.setQuality(score); found = true; } } if (!found) { preferences.add(new Preference<MediaType>(mediaType, score)); } } }