/* * Copyright (c) 2001-2007, Inversoft Inc., All Rights Reserved * * 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 org.primeframework.mvc.parameter.convert; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Map; /** * Converters are used to convert objects from one type to another, convert strings to objects and to convert from * objects and strings to arrays of objects. The way that this is setup is that a Converter implementation is * registered with the ConverterRegistry. The registry can then be queried for a particular Converter (see {@link * org.primeframework.mvc.parameter.convert.ConverterProvider} for more information about retrieval). Next, the * Converter can be used for conversions using one of the methods described below. Any given Converter may be used to * convert to many different types because of the way that the ConverterRegistry searches for Converters. Because of * this flexibility when converting the Converter must be told what type to convert to. This is the reason for the * second Class parameter on all of the convert methods. * <p/> * The type that appears on all of the methods in this interface can be any type that is support by the Converter, but * generally is a type that is the type or a sub-type of the type the converter is registered for. For example, let's * say the converter is registered to java.lang.Number, then this converter should be able to convert Integer, Long, * Double, etc. unless a converter is registered for each one of these. So, we could call the converter with ("0.5", * Double.class) in order to convert the String to a Double object. * <p/> * <h3>Arrays</h3> * <p/> * Arrays pose a significant issue when considering null values and multi-dimensional arrays as well as communicative * conversion (i.e. a -> b -> a). Because of this, implementations are free to NOT support multi-dimensional arrays, * null values or communicative conversions. When supporting these concepts however implementations must take care to * use array delimiters and null indicators. The recommended versions of these are: * <p/> * <table> * <tr><th>Name</th><th>Recommendation</th></tr> * <tr><td>Array open</td><td>{</td></tr> * <tr><td>Array close</td><td>}</td></tr> * <tr><td>Array separator</td><td>,</td></tr> * <tr><td>Null indicator</td><td>__#null#__</td></tr> * </table> * <p/> * We highly recommend against crazy array handling and just focus on simple String/Object conversions. However, single * dimensional arrays should almost always be handled correctly. You only need to support String to array conversions. * Array to String conversions are rarely necessary. * <p/> * <h3>Null values</h3> * <p/> * When performing any conversion of a single value that is null, it is recommended that implementations return null. * <p/> * <h3>Primitives</h3> * <p/> * There are already pre-written conversion for primitives, but when overriding these, implementations must ensure that * during conversions of nulls, that the default value of the primitive is returned. * <p/> * <h3>Custom converters</h3> * <p/> * In order to write a custom annotation type converter, you need to implement this interface, create an annotation and * annotate your annotation with the {@link org.primeframework.mvc.parameter.convert.annotation.ConverterAnnotation} * annotation and specify your implementation in the type parameter. * * @author Brian Pontarelli */ public interface AnnotationConverter<T extends Annotation> { /** * Converts the given object to the given type. * <p/> * This method should handle all variations of String[] conversion. The values incoming are pulled directly from the * HTTP request parameters so there might be one or many. Here are some of the possible variations that should be * handled. * <p/> * <ul> * <li>Single String to Object</li> * <li>String array to Object (very uncommon)</li> * <li>Single String to array</li> * <li>Single String to multi-dimensional array</li> * <li>String array to array</li> * <li>String array to multi-dimensional array</li> * </ul> * * @param annotation The annotation from the field. * @param values The value(s) to convert. This might be a single value or multiple values. * @param convertTo The type to convert the value to. This might be a Class or it might be a parametrized type such * as List<String>. * @param attributes Any attributes associated with the parameter being converted. Parameter attributes are described * in the {@link org.primeframework.mvc.parameter.ParameterWorkflow} class comment. * @param expression The full path to the expression that is causing the conversion. * @return The converted value. * @throws ConversionException If there was a problem converting the given value to the given type. * @throws ConverterStateException If the state of the request, response, locale or attributes was such that * conversion could not occur. This is normally a fatal exception that is fixable * during development but not in production. */ Object convertFromStrings(T annotation, String[] values, Type convertTo, Map<String, String> attributes, String expression) throws ConversionException, ConverterStateException; /** * Converts the given Object to a String for display purposes. * <p/> * This method should handle all variations of Object to String conversion. The value is always pulled from the * object in the action and is converted to a single String to display. * <p/> * <ul> * <li>Object to String</li> * <li>Array to String</li> * <li>Multi-dimensional array to String</li> * </ul> * * @param annotation The annotation from the field. * @param value The Object value to convert. * @param convertFrom The type to convert the value from. This might be a Class or it might be a parametrized type * such as List<String>. * @param attributes Any attributes associated with the parameter being converted. Parameter attributes are described * in the {@link org.primeframework.mvc.parameter.ParameterWorkflow} class comment. * @return The converted value. * @throws ConversionException If there was a problem converting the given value to the given type. * @throws ConverterStateException If the state of the request, response, locale or attributes was such that * conversion could not occur. This is normally a fatal exception that is fixable * during development but not in production. */ String convertToString(T annotation, Object value, Type convertFrom, Map<String, String> attributes) throws ConversionException; }