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 2008/12/22 20:50:28 UTC

svn commit: r728754 [3/3] - in /tapestry/tapestry5/trunk: ./ src/site/apt/ src/site/apt/guide/ tapestry-core/ tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/ tapestry-core/src/main/java/org/apache/tapestry5/dom/ tapestry-core/src/m...

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java Mon Dec 22 11:50:26 2008
@@ -23,7 +23,6 @@
 import org.apache.tapestry5.internal.test.InternalBaseTestCase;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
 import org.apache.tapestry5.model.ComponentModel;
 import org.apache.tapestry5.model.ParameterModel;
 import org.apache.tapestry5.runtime.Component;
@@ -50,8 +49,8 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        TypeCoercer coercer = mockTypeCoercer();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -60,7 +59,7 @@
         replay();
 
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         ComponentResources resources = cpe.getComponentResources();
 
@@ -83,9 +82,9 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        TypeCoercer coercer = mockTypeCoercer();
         Block block = mockBlock();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         Instantiator ins = newInstantiator(component, model);
 
@@ -93,7 +92,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         ComponentResources resources = cpe.getComponentResources();
 
@@ -106,6 +105,18 @@
         verify();
     }
 
+    protected final ComponentPageElementResources mockResources(Logger logger)
+    {
+        Logger eventLogger = mockLogger();
+        ComponentPageElementResources resources = mockComponentPageElementResources();
+
+        train_isDebugEnabled(eventLogger, false);
+
+        expect(resources.getEventLogger(logger)).andReturn(eventLogger);
+
+        return resources;
+    }
+
     @Test
     public void parameter_is_bound()
     {
@@ -113,8 +124,8 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         Binding binding = mockBinding();
-        TypeCoercer coercer = mockTypeCoercer();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         Instantiator ins = newInstantiator(component, model);
 
@@ -126,7 +137,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         ComponentResources resources = cpe.getComponentResources();
         assertFalse(resources.isBound("fred"));
@@ -145,10 +156,10 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        TypeCoercer coercer = mockTypeCoercer();
         Block block1 = mockBlock();
         Block block2 = mockBlock();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -156,7 +167,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addBlock("myblock", block1);
 
@@ -181,9 +192,9 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         Binding binding = mockBinding();
-        TypeCoercer coercer = mockTypeCoercer();
         ParameterModel pmodel = mockParameterModel();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -196,7 +207,7 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.bindParameter("barney", binding);
 
@@ -212,8 +223,8 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         ParameterModel pmodel = mockParameterModel();
-        TypeCoercer coercer = mockTypeCoercer();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -227,7 +238,7 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.containingPageDidLoad();
 
@@ -244,8 +255,8 @@
         ComponentModel model = mockComponentModel();
         ParameterModel pmodel = mockParameterModel();
         Location l = mockLocation();
-        TypeCoercer coercer = mockTypeCoercer();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -274,7 +285,8 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, container, "myid", null, ins, l, null);
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, container, "myid", null, ins, l,
+                                                                    elementResources);
 
         try
         {
@@ -297,28 +309,29 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         Binding binding = mockBinding();
-        TypeCoercer coercer = mockTypeCoercer();
         ParameterModel pmodel = mockParameterModel();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
         Instantiator ins = newInstantiator(component, model);
 
         train_getParameterModel(model, "barney", pmodel);
+        train_getParameterModel(model, "fred", null);
 
         train_isInvariant(binding, true);
+        train_isAllowNull(pmodel, false);
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
-        assertFalse(cpe.getComponentResources().isInvariant("fred"));
+        assertFalse(cpe.getComponentResources().getParameterAccess("fred").isInvariant());
 
         cpe.bindParameter("barney", binding);
 
-        assertFalse(cpe.getComponentResources().isInvariant("fred"));
-        assertTrue(cpe.getComponentResources().isInvariant("barney"));
+        assertTrue(cpe.getComponentResources().getParameterAccess("barney").isInvariant());
 
         verify();
     }
@@ -330,8 +343,8 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         Binding binding = mockBinding();
-        ComponentPageElementResources resources = mockComponentPageElementResources();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -345,15 +358,15 @@
 
         train_get(binding, boundValue);
 
-        train_coerce(resources, boundValue, Long.class, boundValue);
+        train_coerce(elementResources, boundValue, Long.class, boundValue);
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, resources);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.bindParameter("barney", binding);
 
-        assertSame(cpe.getComponentResources().readParameter("barney", Long.class), boundValue);
+        assertSame(cpe.getComponentResources().getParameterAccess("barney").read(Long.class), boundValue);
 
         verify();
     }
@@ -365,9 +378,9 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        ComponentPageElementResources resources = mockComponentPageElementResources();
         Binding binding = mockBinding();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -379,17 +392,17 @@
 
         expect(binding.getBindingType()).andReturn(Integer.class);
 
-        train_coerce(resources, 23, Integer.class, 23);
+        train_coerce(elementResources, 23, Integer.class, 23);
 
         binding.set(23);
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, resources);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.bindParameter("barney", binding);
 
-        cpe.getComponentResources().writeParameter("barney", 23);
+        cpe.getComponentResources().getParameterAccess("barney").write(23);
 
         verify();
     }
@@ -401,6 +414,8 @@
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources1 = mockResources(logger);
+        ComponentPageElementResources elementResources2 = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -409,8 +424,8 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
-        cpe.addEmbeddedElement(new ComponentPageElementImpl(page, cpe, "nested", null, ins2, null, null));
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, elementResources1);
+        cpe.addEmbeddedElement(new ComponentPageElementImpl(page, cpe, "nested", null, ins2, null, elementResources2));
 
         try
         {
@@ -435,6 +450,7 @@
         ComponentPageElement childElement = mockComponentPageElement();
         Component childComponent = mockComponent();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -445,7 +461,7 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addEmbeddedElement(childElement);
 
@@ -468,6 +484,7 @@
         ComponentPageElement child2 = mockComponentPageElement();
         Location l = mockLocation();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -480,7 +497,7 @@
 
         replay();
 
-        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElementImpl cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addEmbeddedElement(child1);
 
@@ -504,11 +521,11 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        TypeCoercer coercer = mockTypeCoercer();
         final String mixinClassName = "foo.Bar";
         Component mixin = mockComponent();
         ComponentModel mixinModel = mockComponentModel();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -519,7 +536,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addMixin(mixinIns);
 
@@ -534,10 +551,10 @@
         Page page = newPage(PAGE_NAME);
         Component component = mockComponent();
         ComponentModel model = mockComponentModel();
-        TypeCoercer coercer = mockTypeCoercer();
         Component mixin = mockComponent();
         ComponentModel mixinModel = mockComponentModel();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -548,7 +565,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addMixin(mixinIns);
 
@@ -573,9 +590,9 @@
         ComponentModel model = mockComponentModel();
         ComponentModel mixinModel = mockComponentModel();
         Component mixin = mockComponent();
-        TypeCoercer coercer = mockTypeCoercer();
         Binding binding = mockBinding();
         Logger logger = mockLogger();
+        ComponentPageElementResources elementResources = mockResources(logger);
 
         train_getLogger(model, logger);
 
@@ -586,7 +603,7 @@
 
         replay();
 
-        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, null);
+        ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, elementResources);
 
         cpe.addMixin(mixinInstantiator);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ExpansionPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ExpansionPageElementImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ExpansionPageElementImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ExpansionPageElementImplTest.java Mon Dec 22 11:50:26 2008
@@ -1,25 +1,26 @@
-// Copyright 2006, 2007 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
-//
-// 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.
-
+// Copyright 2006, 2007, 2008 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
+//
+// 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.apache.tapestry5.internal.structure;
 
-import org.apache.tapestry5.Binding;
-import org.apache.tapestry5.MarkupWriter;
-import org.apache.tapestry5.internal.test.InternalBaseTestCase;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
-import org.apache.tapestry5.runtime.RenderQueue;
-import org.testng.annotations.Test;
+import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
+import org.testng.annotations.Test;
 
 public class ExpansionPageElementImplTest extends InternalBaseTestCase
 {
@@ -37,7 +38,7 @@
 
         replay();
 
-        PageElement element = new ExpansionPageElement(binding, coercer);
+        RenderCommand element = new ExpansionPageElement(binding, coercer);
 
         verify();
 
@@ -76,7 +77,7 @@
 
         replay();
 
-        PageElement element = new ExpansionPageElement(binding, coercer);
+        RenderCommand element = new ExpansionPageElement(binding, coercer);
 
         verify();
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/InternalBaseTestCase.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/InternalBaseTestCase.java Mon Dec 22 11:50:26 2008
@@ -22,7 +22,6 @@
 import org.apache.tapestry5.internal.structure.ComponentPageElement;
 import org.apache.tapestry5.internal.structure.ComponentPageElementResources;
 import org.apache.tapestry5.internal.structure.Page;
-import org.apache.tapestry5.internal.structure.PageElement;
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.def.ContributionDef;
 import org.apache.tapestry5.ioc.def.ModuleDef;
@@ -36,6 +35,7 @@
 import org.apache.tapestry5.model.EmbeddedComponentModel;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.RenderCommand;
 import org.apache.tapestry5.runtime.RenderQueue;
 import org.apache.tapestry5.services.*;
 import org.apache.tapestry5.test.TapestryTestCase;
@@ -236,9 +236,9 @@
         expect(model.getComponentClassName()).andReturn(className).atLeastOnce();
     }
 
-    protected final PageElement mockPageElement()
+    protected final RenderCommand mockRenderCommand()
     {
-        return newMock(PageElement.class);
+        return newMock(RenderCommand.class);
     }
 
     protected final void train_getParameterNames(EmbeddedComponentModel model, String... names)

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java Mon Dec 22 11:50:26 2008
@@ -23,10 +23,6 @@
 import org.apache.tapestry5.test.TapestryTestCase;
 import org.testng.annotations.Test;
 
-/**
- * Of course, we're committing the cardinal sin of testing the code that's generated, rather than the *behavior* of the
- * generated code. Fortunately, we back all this up with lots and lots of integration testing.
- */
 public class RenderPhaseMethodWorkerTest extends TapestryTestCase
 {
     @Test

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/log4j.properties Mon Dec 22 11:50:26 2008
@@ -23,5 +23,8 @@
 
 log4j.category.org.apache.tapestry5.integration.app2=debug
 
+log4j.category.tapestry.render=debug
+log4j.category.org.apache.tapestry5.internal.services.InternalModule.PageResponseRenderer=debug
+
 # log4j.category.org.apache.tapestry5.corelib.components=debug
 

Modified: tapestry/tapestry5/trunk/tapestry-core/tapestry-core.iml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/tapestry-core.iml?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/tapestry-core.iml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/tapestry-core.iml Mon Dec 22 11:50:26 2008
@@ -9,7 +9,9 @@
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/antlr" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target/Tapestry Core" />
       <excludeFolder url="file://$MODULE_DIR$/target/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/target/maven-archiver" />
       <excludeFolder url="file://$MODULE_DIR$/target/surefire-reports" />
       <excludeFolder url="file://$MODULE_DIR$/target/test-classes" />
       <excludeFolder url="file://$MODULE_DIR$/test-output" />

Modified: tapestry/tapestry5/trunk/tapestry-hibernate-core/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate-core/pom.xml?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate-core/pom.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate-core/pom.xml Mon Dec 22 11:50:26 2008
@@ -3,7 +3,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.apache.tapestry</groupId>
     <artifactId>tapestry-hibernate-core</artifactId>
-    <name>Core Hibernate Support</name>
+    <name>Tapestry Hibernate Support</name>
     <description>
         Basic Hibernate services for Tapestry, useable outside of a Tapestry web application
     </description>

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=728754&r1=728753&r2=728754&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 Mon Dec 22 11:50:26 2008
@@ -15,8 +15,8 @@
 package org.apache.tapestry5.ioc.internal.services;
 
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.*;
-import static org.apache.tapestry5.ioc.internal.util.Defense.notNull;
+import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry5.ioc.internal.util.Defense;
 import org.apache.tapestry5.ioc.internal.util.InheritanceSearch;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.ClassFabUtils;
@@ -28,53 +28,75 @@
 
 public class TypeCoercerImpl implements TypeCoercer
 {
-    // Read only after constructor
+    // Constructed from the service's configuration.
 
     private final Map<Class, List<CoercionTuple>> sourceTypeToTuple = CollectionFactory.newMap();
 
-    // Access to the cache must be thread safe
-
-    private final Map<CacheKey, Coercion> cache = CollectionFactory.newConcurrentMap();
-
-    static class CacheKey
+    /**
+     * A coercion to a specific target type.  Manages a cache of coercions to specific types.
+     */
+    private class TargetCoercion
     {
-        private final Class sourceClass;
+        private final Class type;
 
-        private final Class targetClass;
+        private final Map<Class, Coercion> cache = CollectionFactory.newConcurrentMap();
 
-        CacheKey(final Class sourceClass, final Class targetClass)
+        TargetCoercion(Class type)
         {
-            this.sourceClass = sourceClass;
-            this.targetClass = targetClass;
+            this.type = type;
         }
 
-        @Override
-        public boolean equals(Object obj)
+        void clearCache()
         {
-            if (obj == null) return false;
+            cache.clear();
+        }
 
-            if (!(obj instanceof CacheKey)) return false;
+        Object coerce(Object input)
+        {
+
+            Class sourceType = input != null ? input.getClass() : void.class;
+
+            if (type.isAssignableFrom(sourceType)) return input;
 
-            CacheKey other = (CacheKey) obj;
+            Coercion c = getCoercion(sourceType);
 
-            return sourceClass.equals(other.sourceClass)
-                    && targetClass.equals(other.targetClass);
+            try
+            {
+                return type.cast(c.coerce(input));
+            }
+            catch (Exception ex)
+            {
+                throw new RuntimeException(ServiceMessages.failedCoercion(
+                        input,
+                        type,
+                        c,
+                        ex), ex);
+            }
         }
 
-        @Override
-        public int hashCode()
+        String explain(Class sourceType)
         {
-            return sourceClass.hashCode() * 27 % targetClass.hashCode();
+            return getCoercion(sourceType).toString();
         }
 
-        @Override
-        public String toString()
+        private Coercion getCoercion(Class sourceType)
         {
-            return String.format("CacheKey[%s --> %s]", sourceClass.getName(), targetClass
-                    .getName());
+            Coercion c = cache.get(sourceType);
+
+            if (c == null)
+            {
+                c = findOrCreateCoercion(sourceType, type);
+                cache.put(sourceType, c);
+            }
+            return c;
         }
     }
 
+    /**
+     * Map from a target type to a TargetCoercion for that type.
+     */
+    private final Map<Class, TargetCoercion> typeToTargetCoercion = new WeakHashMap<Class, TargetCoercion>();
+
     private static final Coercion COERCION_NULL_TO_OBJECT = new Coercion<Void, Object>()
     {
         public Object coerce(Void input)
@@ -102,49 +124,20 @@
     @SuppressWarnings("unchecked")
     public Object coerce(Object input, Class targetType)
     {
-        notNull(targetType, "targetType");
-
-        // Treat null as void in terms of locating a coercion.
-
-        Class sourceType = input != null ? input.getClass() : void.class;
-
-        // The caller may ask for the value in a primitive type, but the best we can do is the
-        // equivalent wrapper type.
+        Defense.notNull(targetType, "targetType");
 
         Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
 
-        // Is a coercion even necessary? Not if the target type is assignable from the
-        // input value.
-
-        if (effectiveTargetType.isAssignableFrom(sourceType)) return input;
+        if (effectiveTargetType.isInstance(input)) return input;
 
-        Coercion coercion = findCoercion(sourceType, effectiveTargetType);
-
-        Object result;
-
-        try
-        {
-            result = coercion.coerce(input);
-        }
-        catch (Exception ex)
-        {
-            throw new RuntimeException(ServiceMessages.failedCoercion(
-                    input,
-                    targetType,
-                    coercion,
-                    ex), ex);
-        }
-
-        // Double check that the coercer provided a result of the correct type
-
-        return effectiveTargetType.cast(result);
+        return getTargetCoercion(effectiveTargetType).coerce(input);
     }
 
     @SuppressWarnings("unchecked")
     public <S, T> String explain(Class<S> inputType, Class<T> targetType)
     {
-        notNull(inputType, "inputType");
-        notNull(targetType, "targetType");
+        Defense.notNull(inputType, "inputType");
+        Defense.notNull(targetType, "targetType");
 
         Class effectiveTargetType = ClassFabUtils.getWrapperType(targetType);
 
@@ -153,29 +146,35 @@
 
         if (effectiveTargetType.isAssignableFrom(inputType)) return "";
 
-        Coercion coercion = findCoercion(inputType, effectiveTargetType);
-
-        return coercion.toString();
+        return getTargetCoercion(targetType).explain(inputType);
     }
 
-    private Coercion findCoercion(Class sourceType, Class targetType)
+    private synchronized TargetCoercion getTargetCoercion(Class targetType)
     {
-        CacheKey key = new CacheKey(sourceType, targetType);
-
-        Coercion result = cache.get(key);
+        TargetCoercion tc = typeToTargetCoercion.get(targetType);
 
-        if (result == null)
+        if (tc == null)
         {
-            result = findOrCreateCoercion(sourceType, targetType);
-            cache.put(key, result);
+            tc = new TargetCoercion(targetType);
+            typeToTargetCoercion.put(targetType, tc);
         }
 
-        return result;
+        return tc;
     }
 
-    public void clearCache()
+    public synchronized void clearCache()
     {
-        cache.clear();
+        // There's no need to clear the typeToTargetCoercion map, as it is a WeakHashMap and
+        // will release the keys for classes that are no longer in existence.  On the other hand,
+        // there's likely all sorts of references to unloaded classes inside each TargetCoercion's
+        // individual cache, so clear all those.
+
+        for (TargetCoercion tc : typeToTargetCoercion.values())
+        {
+            // Can tc ever be null?
+
+            tc.clearCache();
+        }
     }
 
     /**
@@ -211,8 +210,8 @@
         // a tuple twice, but it's more likely that different threads are looking
         // for different source/target coercions.
 
-        Set<CoercionTuple> consideredTuples = newSet();
-        LinkedList<CoercionTuple> queue = newLinkedList();
+        Set<CoercionTuple> consideredTuples = CollectionFactory.newSet();
+        LinkedList<CoercionTuple> queue = CollectionFactory.newLinkedList();
 
         seedQueue(sourceType, consideredTuples, queue);
 
@@ -378,5 +377,4 @@
             }
         }
     }
-
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java Mon Dec 22 11:50:26 2008
@@ -39,14 +39,12 @@
  */
 public final class CollectionFactory
 {
-    private static final int INITIAL_HASHMAP_CAPACITY = 31;
-
     /**
      * Constructs and returns a generic {@link HashMap} instance.
      */
     public static <K, V> Map<K, V> newMap()
     {
-        return new HashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+        return new HashMap<K, V>();
     }
 
     /**
@@ -84,7 +82,7 @@
      */
     public static <K, V> ConcurrentMap<K, V> newConcurrentMap()
     {
-        return new ConcurrentHashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+        return new ConcurrentHashMap<K, V>();
     }
 
     /**