Author: hlship Date: Sat Sep 23 10:07:42 2006 New Revision: 449272 URL: http://svn.apache.org/viewvc?view=rev&rev=449272 Log: Make use of the TypeCoercer when reading parameter bindings.
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryException.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Output.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/MerryChristmas.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryException.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryException.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryException.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryException.java Sat Sep 23 10:07:42 2006 @@ -48,6 +48,17 @@ /** * @param message * a message (may be null) + * @param cause + * if not null, the root cause of the exception, also used to set the location + */ + public TapestryException(String message, Throwable cause) + { + this(message, cause, cause); + } + + /** + * @param message + * a message (may be null) * @param locatable * location to associated with the exception, or null if not known * @param cause Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalModule.java Sat Sep 23 10:07:42 2006 @@ -51,6 +51,7 @@ import org.apache.tapestry.services.ComponentClassResolver; import org.apache.tapestry.services.ComponentClassTransformWorker; import org.apache.tapestry.services.MarkupWriterFactory; +import org.apache.tapestry.services.TypeCoercer; import org.apache.tapestry.services.WebContext; import org.apache.tapestry.services.WebRequestFilter; @@ -132,9 +133,11 @@ return new TemplateParserImpl(log); } - public PageElementFactory buildPageElementFactory() + public PageElementFactory buildPageElementFactory(@InjectService("tapestry.TypeCoercer") + TypeCoercer typeCoercer) { - return new PageElementFactoryImpl(_componentInstantiatorSource, _componentClassResolver); + return new PageElementFactoryImpl(_componentInstantiatorSource, _componentClassResolver, + typeCoercer); } public PageLoader buildPageLoader(@InjectService("PageElementFactory") @@ -386,7 +389,7 @@ BindingFactory stringFactory = new BindingFactory() { // This will match embedded single quotes as-is, no escaping necessary. - + private final Pattern _pattern = Pattern.compile("^\\s*'(.*)'\\s*$"); @SuppressNullCheck @@ -407,7 +410,7 @@ }; // Do be honest, order probably doesn't matter. - + configuration.add("Keyword", keywordFactory); configuration.add("This", thisFactory); configuration.add("Long", longFactory); Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageElementFactoryImpl.java Sat Sep 23 10:07:42 2006 @@ -16,6 +16,7 @@ import org.apache.tapestry.Location; import org.apache.tapestry.MarkupWriter; +import org.apache.tapestry.internal.annotations.SuppressNullCheck; import org.apache.tapestry.internal.parser.AttributeToken; import org.apache.tapestry.internal.parser.StartElementToken; import org.apache.tapestry.internal.parser.TextToken; @@ -29,21 +30,29 @@ import org.apache.tapestry.model.ComponentModel; import org.apache.tapestry.runtime.RenderQueue; import org.apache.tapestry.services.ComponentClassResolver; +import org.apache.tapestry.services.TypeCoercer; /** + * Null check suppressed as much as to simplify testing (yea! I can pass a null TypeCoercer) as it + * is for efficiency. + * * @author Howard M. Lewis Ship */ [EMAIL PROTECTED] public class PageElementFactoryImpl implements PageElementFactory { private final ComponentInstantiatorSource _componentInstantiatorSource; private final ComponentClassResolver _componentClassResolver; + private final TypeCoercer _typeCoercer; + public PageElementFactoryImpl(ComponentInstantiatorSource componentInstantiatorSource, - ComponentClassResolver resolver) + ComponentClassResolver resolver, TypeCoercer typeCoercer) { _componentInstantiatorSource = componentInstantiatorSource; _componentClassResolver = resolver; + _typeCoercer = typeCoercer; } /** Singleton instance that represents any close tag of any element in any template. */ @@ -99,7 +108,7 @@ // template. ComponentPageElementImpl result = new ComponentPageElementImpl(page, container, id, - instantiator, model, location); + instantiator, model, _typeCoercer, location); page.addLifecycleListener(result); @@ -111,7 +120,8 @@ Instantiator instantiator = _componentInstantiatorSource.findInstantiator(componentType); ComponentModel model = _componentInstantiatorSource.findComponentModel(componentType); - ComponentPageElementImpl result = new ComponentPageElementImpl(page, instantiator, model); + ComponentPageElementImpl result = new ComponentPageElementImpl(page, instantiator, model, + _typeCoercer); page.addLifecycleListener(result); Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/TypeCoercerImpl.java Sat Sep 23 10:07:42 2006 @@ -121,9 +121,17 @@ Class effectiveTargetType = TransformUtils.getWrapperType(targetType); + // Is a coercion even necessary? Not if the target type is assignable from the + // input value. + + if (effectiveTargetType.isAssignableFrom(sourceType)) + return input; + Coercion coercer = findCoercer(sourceType, effectiveTargetType); Object result = coercer.coerce(input); + + // Double check that the coercer provided a result of the correct type return effectiveTargetType.cast(result); } Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sat Sep 23 10:07:42 2006 @@ -36,6 +36,7 @@ import org.apache.tapestry.runtime.PageLifecycleListener; import org.apache.tapestry.runtime.RenderCommand; import org.apache.tapestry.runtime.RenderQueue; +import org.apache.tapestry.services.TypeCoercer; /** * Implements [EMAIL PROTECTED] org.apache.tapestry.internal.structure.PageElement} and @@ -85,34 +86,19 @@ private boolean _loaded; - private static final Map<Class, Class> PRIMITIVE_TO_WRAPPER = newMap(); + private final TypeCoercer _typeCoercer; - static + /** + * Constructor for the root component of a page. + * + * @param typeCoercer + * TODO + */ + @SuppressNullCheck + public ComponentPageElementImpl(Page page, Instantiator instantiator, ComponentModel model, + TypeCoercer typeCoercer) { - PRIMITIVE_TO_WRAPPER.put(boolean.class, Boolean.class); - PRIMITIVE_TO_WRAPPER.put(byte.class, Byte.class); - PRIMITIVE_TO_WRAPPER.put(short.class, Short.class); - PRIMITIVE_TO_WRAPPER.put(int.class, Integer.class); - PRIMITIVE_TO_WRAPPER.put(long.class, Long.class); - PRIMITIVE_TO_WRAPPER.put(char.class, Character.class); - PRIMITIVE_TO_WRAPPER.put(float.class, Float.class); - PRIMITIVE_TO_WRAPPER.put(double.class, Double.class); - } - - /** Constructor for the root component of a page. */ - public ComponentPageElementImpl(Page page, Instantiator instantiator, ComponentModel model) - { - super(null); - - _container = null; - _id = null; - - // A little bit of duplication that's unavoiable if we want - // to keep the fields final. - - _page = page; - _componentModel = model; - _component = instantiator.newInstance(this); + this(page, null, null, instantiator, model, typeCoercer, null); } /** @@ -129,22 +115,24 @@ * used to create the new component instance * @param model * defines the component + * @param typeCoercer + * TODO * @param location * location of the element (within a template), used as part of exception reporting */ + @SuppressNullCheck public ComponentPageElementImpl(Page page, ComponentPageElement container, String id, - Instantiator instantiator, ComponentModel model, Location location) + Instantiator instantiator, ComponentModel model, TypeCoercer typeCoercer, + Location location) { super(location); _container = container; _id = id; - - // A little bit of duplication that's unavoiable if we want - // to keep the fields final. - _page = page; _componentModel = model; + _typeCoercer = typeCoercer; + _component = instantiator.newInstance(this); } @@ -466,15 +454,19 @@ // TODO: If binding is null ... - // TODO: Type coercion to expected type - - // Easier to do primitive-to-wrapper conversions in this code than in - // the generated component code. - - if (expectedType.isPrimitive()) - expectedType = PRIMITIVE_TO_WRAPPER.get(expectedType); + try + { + Object boundValue = b.get(); - return expectedType.cast(b.get()); + return _typeCoercer.coerce(boundValue, expectedType); + } + catch (Exception ex) + { + throw new TapestryException(StructureMessages.getParameterFailure( + parameterName, + getCompleteId(), + ex), ex); + } } public <T> void writeParameter(String parameterName, T parameterValue) Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/StructureMessages.java Sat Sep 23 10:07:42 2006 @@ -39,4 +39,9 @@ { return MESSAGES.format("no-such-component", parent.getCompleteId(), embeddedId); } + + static String getParameterFailure(String parameterName, String componentId, Throwable cause) + { + return MESSAGES.format("get-parameter-failure", parameterName, componentId, cause); + } } Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Sat Sep 23 10:07:42 2006 @@ -489,12 +489,18 @@ } /** - * Contributes a set of standard coercions: + * Contributes a set of standard type coercions: * <ul> * <li>Object to String</li> - * <li>String to Integer</li> + * <li>String to Double</li> + * <li>Number to Byte</li> + * <li>Number to Short</li> * <li>Number to Integer</li> - * <li>String to Boolean</li> + * <li>Number to Long</li> + * <li>Number to Float</li> + * <li>Number to Double</li> + * <li>String to Boolean ("false" is always false, other non-blank strings are true)</li> + * <li>Number to Boolean (true if long value is non zero)</li> * <li>Null to Boolean (always false)</li> * </ul> * @@ -510,11 +516,27 @@ } }); - add(configuration, String.class, Integer.class, new Coercion<String, Integer>() + add(configuration, String.class, Double.class, new Coercion<String, Double>() { - public Integer coerce(String input) + public Double coerce(String input) { - return new Integer(input); + return new Double(input); + } + }); + + add(configuration, Number.class, Byte.class, new Coercion<Number, Byte>() + { + public Byte coerce(Number input) + { + return input.byteValue(); + } + }); + + add(configuration, Number.class, Short.class, new Coercion<Number, Short>() + { + public Short coerce(Number input) + { + return input.shortValue(); } }); @@ -526,6 +548,30 @@ } }); + add(configuration, Number.class, Long.class, new Coercion<Number, Long>() + { + public Long coerce(Number input) + { + return input.longValue(); + } + }); + + add(configuration, Number.class, Float.class, new Coercion<Number, Float>() + { + public Float coerce(Number input) + { + return input.floatValue(); + } + }); + + add(configuration, Number.class, Double.class, new Coercion<Number, Double>() + { + public Double coerce(Number input) + { + return input.doubleValue(); + } + }); + add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>() { public Boolean coerce(String input) @@ -538,6 +584,14 @@ // Any non-blank string but "false" return true; + } + }); + + add(configuration, Number.class, Boolean.class, new Coercion<Number, Boolean>() + { + public Boolean coerce(Number input) + { + return input.longValue() != 0; } }); Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java Sat Sep 23 10:07:42 2006 @@ -59,6 +59,7 @@ import org.apache.tapestry.services.ClassTransformation; import org.apache.tapestry.services.ComponentClassResolver; import org.apache.tapestry.services.MethodSignature; +import org.apache.tapestry.services.TypeCoercer; import org.apache.tapestry.services.WebRequest; /** @@ -494,5 +495,16 @@ { model.getParameterNames(); setReturnValue(Arrays.asList(names)); + } + + protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType, T coercedValue) + { + coercer.coerce(input, expectedType); + setReturnValue(coercedValue); + } + + protected final TypeCoercer newTypeCoercer() + { + return newMock(TypeCoercer.class); } } Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/structure/StructureStrings.properties Sat Sep 23 10:07:42 2006 @@ -13,4 +13,5 @@ # limitations under the License. missing-parameters=Parameter(s) %s are required for %s, but have not been bound. -no-such-component=Component %s does not contain an embedded component with id '%s'. \ No newline at end of file +no-such-component=Component %s does not contain an embedded component with id '%s'. +get-parameter-failure=Failure reading parameter %s of component %s: %s \ No newline at end of file Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sat Sep 23 10:07:42 2006 @@ -36,7 +36,7 @@ private static final String BASE_URL = "http://localhost/"; /** 5 seconds */ - public static final String PAGE_LOAD_TIMEOUT = "5000"; + public static final String PAGE_LOAD_TIMEOUT = "50000"; private Selenium _selenium; Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Output.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Output.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Output.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Output.java Sat Sep 23 10:07:42 2006 @@ -23,11 +23,11 @@ public class Output { @Parameter(required = true) - private Object _value; + private String _value; @BeginRender void render(MarkupWriter writer) { - writer.write(_value.toString()); + writer.write(_value); } } Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Countdown.java Sat Sep 23 10:07:42 2006 @@ -26,7 +26,7 @@ public class Countdown { @Component(parameters = - { "start=max", "end=min", "value=count" }) + { "start=5", "end=1", "value=count" }) private Loop _loop; @SuppressWarnings("unused") @@ -43,18 +43,6 @@ public void setCount(int count) { _count = count; - } - - // These are just necessary until we get parameter type coercions working. - - public int getMax() - { - return 5; - } - - public int getMin() - { - return 1; } // Just needed until component: binding prefix is added. Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/MerryChristmas.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/MerryChristmas.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/MerryChristmas.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/MerryChristmas.java Sat Sep 23 10:07:42 2006 @@ -19,8 +19,4 @@ @ComponentClass public class MerryChristmas { - public int getMax() - { - return 3; - } } Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java Sat Sep 23 10:07:42 2006 @@ -42,7 +42,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); StartElementToken token = new StartElementToken("fred", l); PageElement element = factory.newStartElement(token); @@ -66,7 +66,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); AttributeToken token = new AttributeToken("name", "value", l); PageElement element = factory.newAttributeElement(token); @@ -91,7 +91,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); PageElement element = factory.newEndElement(); @@ -117,7 +117,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); PageElement element1 = factory.newEndElement(); PageElement element2 = factory.newEndElement(); @@ -138,7 +138,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); TextToken token = new TextToken("some text", l); PageElement element = factory.newTextElement(token); @@ -165,7 +165,7 @@ replay(); - PageElementFactory factory = new PageElementFactoryImpl(source, resolver); + PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null); PageElement element = factory.newRenderBodyElement(component); Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TypeCoercerImplTest.java Sat Sep 23 10:07:42 2006 @@ -33,13 +33,13 @@ @Test public void builtin_coercion() { - // String to Integer + // String to Double - assertEquals(_coercer.coerce("-15", Integer.class), new Integer(-15)); + assertEquals(_coercer.coerce("-15", Double.class), new Double(-15)); // Now a second pass through, to exercise the internal cache - assertEquals(_coercer.coerce("227", Integer.class), new Integer(227)); + assertEquals(_coercer.coerce("2.27", Double.class), new Double(2.27)); } @Test @@ -49,6 +49,14 @@ } @Test + public void no_coercion_necessary() + { + Object input = new Integer(-37); + + assertSame(_coercer.coerce(input, Number.class), input); + } + + @Test public void combined_coercion() { StringBuilder builder = new StringBuilder("12345"); @@ -56,6 +64,10 @@ // This should trigger Object -> String, String -> Integer assertEquals(_coercer.coerce(builder, int.class), new Integer(12345)); + + // This should trigger String -> Double, Number -> Integer + + assertEquals(_coercer.coerce("52", Integer.class), new Integer(52)); } @Test @@ -96,6 +108,15 @@ { "false", Boolean.class, false }, { " False ", Boolean.class, false }, { null, Boolean.class, false }, // void --> Boolean + { new Double(256), Integer.class, new Integer(256) }, // Number --> Integer + { new Double(22.7), Integer.class, new Integer(22) }, + { new Integer(0), Boolean.class, false }, // Number --> Boolean + { new Long(32838), Boolean.class, true }, + { new Integer(127), Byte.class, new Byte("127") }, // Number --> Byte + { new Double(58), Short.class, new Short("58") }, // Number --> Short + { new Integer(33), Long.class, new Long(33) }, // Number --> Long + { new Integer(22), Float.class, new Float(22) }, // Number --> Float + { new Integer(1234), Double.class, new Double(1234) }, // Number --> Float }; } Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java Sat Sep 23 10:07:42 2006 @@ -23,6 +23,7 @@ import org.apache.tapestry.model.ComponentModel; import org.apache.tapestry.model.ParameterModel; import org.apache.tapestry.runtime.ComponentLifecycle; +import org.apache.tapestry.services.TypeCoercer; import org.easymock.EasyMock; import org.testng.annotations.Test; @@ -43,7 +44,7 @@ replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, null); assertFalse(cpe.isBound("fred")); @@ -70,7 +71,7 @@ replay(); - ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, model, null); cpe.addParameter("barney", binding); @@ -96,7 +97,7 @@ replay(); - ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, model, null); cpe.containingPageDidLoad(); @@ -129,7 +130,7 @@ replay(); ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, container, "myid", ins, - model, l); + model, null, l); try { @@ -161,7 +162,7 @@ replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, null); assertFalse(cpe.isInvariant("fred")); @@ -180,19 +181,23 @@ ComponentLifecycle component = newComponentLifecycle(); Instantiator ins = newInstantiator(component); ComponentModel model = newComponentModel(); - + TypeCoercer coercer = newTypeCoercer(); Binding binding = newBinding(); + Long boundValue = new Long(23); + binding.get(); - setReturnValue(new Long(23)); + setReturnValue(boundValue); + + train_coerce(coercer, boundValue, Long.class, boundValue); replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, coercer); cpe.addParameter("barney", binding); - assertEquals(cpe.readParameter("barney", Long.class), new Long(23)); + assertSame(cpe.readParameter("barney", Long.class), boundValue); verify(); } @@ -211,7 +216,7 @@ replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, null); cpe.addParameter("barney", binding); @@ -232,7 +237,7 @@ replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, null); try { @@ -262,7 +267,7 @@ replay(); - ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model); + ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, model, null); cpe.addEmbeddedElement(childElement); Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties Sat Sep 23 10:07:42 2006 @@ -19,7 +19,7 @@ # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%c{1} [%p] %m%n +log4j.appender.A1.layout.ConversionPattern=[%p] %c{1} %m%n log4j.category.org.apache.tapestry=debug log4j.category.tapestry=debug Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html?view=diff&rev=449272&r1=449271&r2=449272 ============================================================================== --- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html (original) +++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/MerryChristmas.html Sat Sep 23 10:07:42 2006 @@ -1,5 +1,5 @@ <t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <p> The Loop component demonstrates reading and writing of properties with the prop: binding prefix.</p> - <p> Merry Christmas: <t:comp type="Loop" end="prop:max"> Ho! </t:comp> + <p> Merry Christmas: <t:comp type="Loop" end="3"> Ho! </t:comp> </p> </t:comp>