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>();
}
/**