001    // Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.ioc.services;
016    
017    import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
018    
019    /**
020     * Makes use of {@link org.apache.tapestry5.ioc.services.Coercion}s to convert between an input value (of some specific
021     * type) and a desired output type. Smart about coercing, even if it requires multiple coercion steps (i.e., via an
022     * intermediate type, such as String).
023     */
024    @UsesConfiguration(CoercionTuple.class)
025    public interface TypeCoercer
026    {
027        /**
028         * Performs a coercion from an input type to a desired output type. When the target type is a primitive, the actual
029         * conversion will be to the equivalent wrapper type. In some cases, the TypeCoercer will need to search for an
030         * appropriate coercion, and may even combine existing coercions to form new ones; in those cases, the results of
031         * the search are cached.
032         * <p/>
033         * The TypeCoercer also caches the results of a coercion search.
034         * 
035         * @param <S>
036         *            source type (input)
037         * @param <T>
038         *            target type (output)
039         * @param input
040         * @param targetType
041         *            defines the target type
042         * @return the coerced value
043         * @throws RuntimeException
044         *             if the input can not be coerced
045         */
046        <S, T> T coerce(S input, Class<T> targetType);
047    
048        /**
049         * Given a source and target type, computes the coercion that will be used.
050         * <p>
051         * Note: holding the returned coercion past the time when {@linkplain #clearCache() the cache is cleared} can cause
052         * a memory leak, especially in the context of live reloading (wherein holding a reference to a single class make
053         * keep an entire ClassLoader from being reclaimed).
054         * 
055         * @since 5.2.0
056         * @param <S>
057         *            source type (input)
058         * @param <T>
059         *            target type (output)
060         * @param sourceType
061         *            type to coerce from
062         * @param targetType
063         *            defines the target type
064         * @return the coercion that will ultimately be used
065         */
066        <S, T> Coercion<S, T> getCoercion(Class<S> sourceType, Class<T> targetType);
067    
068        /**
069         * Used primarily inside test suites, this method performs the same steps as {@link #coerce(Object, Class)}, but
070         * returns a string describing the series of coercions, such as "Object --&gt; String --&gt; Long --&gt; Integer".
071         * 
072         * @param <S>
073         *            source type (input)
074         * @param <T>
075         *            target type (output)
076         * @param sourceType
077         *            the source coercion type (use void.class for coercions from null)
078         * @param targetType
079         *            defines the target type
080         * @return a string identifying the series of coercions, or the empty string if no coercion is necessary
081         */
082        <S, T> String explain(Class<S> sourceType, Class<T> targetType);
083    
084        /**
085         * Clears cached information stored by the TypeCoercer.
086         */
087        void clearCache();
088    }