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