You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/05/15 01:19:42 UTC
svn commit: r944513 - in /tapestry/tapestry5/trunk/tapestry-ioc/src:
main/java/org/apache/tapestry5/ioc/internal/services/
main/java/org/apache/tapestry5/ioc/services/
test/java/org/apache/tapestry5/ioc/internal/services/
Author: hlship
Date: Fri May 14 23:19:42 2010
New Revision: 944513
URL: http://svn.apache.org/viewvc?rev=944513&view=rev
Log:
TAP5-1152: TypeCoercer should include a method exposing the coercion it would use for a given source and target type
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java?rev=944513&r1=944512&r2=944513&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java Fri May 14 23:19:42 2010
@@ -100,6 +100,14 @@ public class TypeCoercerImpl implements
*/
private final Map<Class, TargetCoercion> typeToTargetCoercion = new WeakHashMap<Class, TargetCoercion>();
+ private static final Coercion NO_COERCION = new Coercion<Object, Object>()
+ {
+ public Object coerce(Object input)
+ {
+ return input;
+ }
+ };
+
private static final Coercion COERCION_NULL_TO_OBJECT = new Coercion<Void, Object>()
{
public Object coerce(Void input)
@@ -138,21 +146,36 @@ public class TypeCoercerImpl implements
}
@SuppressWarnings("unchecked")
- public <S, T> String explain(Class<S> inputType, Class<T> targetType)
+ public <S, T> Coercion<S, T> getCoercion(Class<S> sourceType, Class<T> targetType)
+ {
+ Defense.notNull(sourceType, "sourceType");
+ Defense.notNull(targetType, "targetType");
+
+ Class effectiveSourceType = ClassFabUtils.getWrapperType(sourceType);
+ Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
+
+ if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
+ return NO_COERCION;
+
+ return getTargetCoercion(effectiveTargetType).getCoercion(effectiveSourceType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <S, T> String explain(Class<S> sourceType, Class<T> targetType)
{
- Defense.notNull(inputType, "inputType");
+ Defense.notNull(sourceType, "effectiveInputType");
Defense.notNull(targetType, "targetType");
Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
- Class effctiveInputType = ClassFabUtils.getWrapperType(inputType);
+ Class effectiveSourceType = ClassFabUtils.getWrapperType(sourceType);
// Is a coercion even necessary? Not if the target type is assignable from the
// input value.
- if (effectiveTargetType.isAssignableFrom(effctiveInputType))
+ if (effectiveTargetType.isAssignableFrom(effectiveSourceType))
return "";
- return getTargetCoercion(targetType).explain(inputType);
+ return getTargetCoercion(targetType).explain(sourceType);
}
private synchronized TargetCoercion getTargetCoercion(Class targetType)
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java?rev=944513&r1=944512&r2=944513&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TypeCoercer.java Fri May 14 23:19:42 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010 The Apache Software Foundation
//
// 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
+// 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,
@@ -17,7 +17,7 @@ package org.apache.tapestry5.ioc.service
import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
/**
- * Makes use of {@link org.apache.tapestry5.ioc.services.Coercion}s to convert between an input value (of some specific
+ * Makes use of {@link org.apache.tapestry5.ioc.services.Coercion}s to convert between an input value (of some specific
* type) and a desired output type. Smart about coercing, even if it requires multiple coercion steps (i.e., via an
* intermediate type, such as String).
*/
@@ -32,26 +32,53 @@ public interface TypeCoercer
* <p/>
* <p/>
* The TypeCoercer also caches the results of a coercion search.
- *
- * @param <S> source type (input)
- * @param <T> target type (output)
+ *
+ * @param <S>
+ * source type (input)
+ * @param <T>
+ * target type (output)
* @param input
- * @param targetType defines the target type
+ * @param targetType
+ * defines the target type
* @return the coerced value
*/
<S, T> T coerce(S input, Class<T> targetType);
/**
+ * Given a source and target type, computes the coercion that will be used.
+ * <p>
+ * Note: holding the returned coercion past the time when {@linkplain #clearCache() the cache is cleared} can cause
+ * a memory leak, especially in the context of live reloading (wherein holding a reference to a single class make
+ * keep an entire ClassLoader from being reclaimed).
+ *
+ * @since 5.2.0
+ * @param <S>
+ * source type (input)
+ * @param <T>
+ * target type (output)
+ * @param sourceType
+ * type to coerce from
+ * @param targetType
+ * defines the target type
+ * @return the coercion that will ultimately be used
+ */
+ <S, T> Coercion<S, T> getCoercion(Class<S> sourceType, Class<T> targetType);
+
+ /**
* Used primarily inside test suites, this method performs the same steps as {@link #coerce(Object, Class)}, but
* returns a string describing the series of coercision, such as "Object --> String --> Long --> Integer".
- *
- * @param <S> source type (input)
- * @param <T> target type (output)
- * @param inputType the source coercion type (use void.class for coercions from null)
- * @param targetType defines the target type
+ *
+ * @param <S>
+ * source type (input)
+ * @param <T>
+ * target type (output)
+ * @param sourceType
+ * the source coercion type (use void.class for coercions from null)
+ * @param targetType
+ * defines the target type
* @return a string identifying the series of coercions, or the empty string if no coercion is necessary
*/
- <S, T> String explain(Class<S> inputType, Class<T> targetType);
+ <S, T> String explain(Class<S> sourceType, Class<T> targetType);
/**
* Clears cached information stored by the TypeCoercer.
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java?rev=944513&r1=944512&r2=944513&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java Fri May 14 23:19:42 2010
@@ -16,6 +16,7 @@ package org.apache.tapestry5.ioc.interna
import org.apache.tapestry5.ioc.internal.IOCInternalTestCase;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.services.Coercion;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.ioc.util.TimeInterval;
import org.testng.annotations.AfterClass;
@@ -63,12 +64,17 @@ public class TypeCoercerImplTest extends
assertEquals(coercer.coerce(227l, int.class), new Integer(227));
}
+ @SuppressWarnings("unchecked")
@Test
public void no_coercion_necessary()
{
Object input = new Integer(-37);
assertSame(coercer.coerce(input, Number.class), input);
+
+ Coercion coercion = coercer.getCoercion(int.class, Number.class);
+
+ assertSame(coercion.coerce(input), input);
}
@Test
@@ -145,6 +151,10 @@ public class TypeCoercerImplTest extends
Object actual = coercer.coerce(input, targetType);
assertEquals(actual, expected);
+
+ Coercion c = coercer.getCoercion(input == null ? void.class : input.getClass(), targetType);
+
+ assertEquals(c.coerce(input), expected);
}
@SuppressWarnings("unchecked")