You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/02/04 01:45:52 UTC
svn commit: r906306 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/transform/
main/java/org/apache/tapestry5/services/
test/java/org/apache/tapestry5/integration/app1/
Author: hlship
Date: Thu Feb 4 00:45:51 2010
New Revision: 906306
URL: http://svn.apache.org/viewvc?rev=906306&view=rev
Log:
Rework InjectComponentWorker around the new ClassTransformation APIs
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java?rev=906306&r1=906305&r2=906306&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectComponentWorker.java Thu Feb 4 00:45:51 2010
@@ -1,10 +1,10 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,61 +16,93 @@
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.internal.services.ComponentClassCache;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.util.BodyBuilder;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.runtime.PageLifecycleAdapter;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.ComponentValueProvider;
+import org.apache.tapestry5.services.TransformField;
/**
* Recognizes the {@link org.apache.tapestry5.annotations.InjectComponent} annotation, and converts the field into a
- * read-only field containing the component. The id of the component may be explicitly stated or will be determined
+ * read-only field containing the component. The id of the component may be explicitly stated or will be determined
* from the field name.
*/
public class InjectComponentWorker implements ComponentClassTransformWorker
{
- public void transform(ClassTransformation transformation,
- MutableComponentModel model)
- {
- for (String fieldName : transformation.findFieldsWithAnnotation(InjectComponent.class))
- {
- InjectComponent annotation = transformation.getFieldAnnotation(fieldName, InjectComponent.class);
+ private final ComponentClassCache classCache;
- String type = transformation.getFieldType(fieldName);
+ public InjectComponentWorker(ComponentClassCache classCache)
+ {
+ this.classCache = classCache;
+ }
- String resourcesFieldName = transformation.getResourcesFieldName();
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ for (TransformField field : transformation.matchFieldsWithAnnotation(InjectComponent.class))
+ {
+ InjectComponent annotation = field.getAnnotation(InjectComponent.class);
- String componentId = annotation.value();
- if (InternalUtils.isBlank(componentId))
- componentId = InternalUtils.stripMemberName(fieldName);
+ field.claim(annotation);
- transformation.makeReadOnly(fieldName);
+ final String type = field.getType();
- BodyBuilder builder = new BodyBuilder().addln("try").begin();
+ final String componentId = getComponentId(field, annotation);
- builder.addln(
- "%s = (%s) %s.getEmbeddedComponent(\"%s\");",
- fieldName,
- type,
- resourcesFieldName,
- componentId);
- builder.end();
- builder.addln("catch (ClassCastException ex)").begin();
- builder.addln("throw new RuntimeException(%s.formatMessage(%s, \"%s\", \"%s\", \"%s\"), ex);",
- getClass().getName(), resourcesFieldName, fieldName, type, componentId);
- builder.end();
+ final String fieldName = field.getName();
+
+ ComponentValueProvider<FieldValueConduit> provider = new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(final ComponentResources resources)
+ {
+ return new ReadOnlyFieldValueConduit(resources, fieldName)
+ {
+ private Component embedded;
+
+ {
+ resources.addPageLifecycleListener(new PageLifecycleAdapter()
+ {
+ public void containingPageDidLoad()
+ {
+ embedded = resources.getEmbeddedComponent(componentId);
+
+ Class fieldType = classCache.forName(type);
+
+ if (!fieldType.isInstance(embedded))
+ throw new RuntimeException(
+ String
+ .format(
+ "Unable to inject component '%s' into field %s of component %s. Class %s is not assignable to a field of type %s.",
+ componentId, fieldName, resources.getCompleteId(),
+ embedded.getClass().getName(), fieldType.getName()));
+ };
+ });
+ }
+
+ public Object get()
+ {
+ return embedded;
+ }
+ };
+ }
+ };
- transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder.toString());
+ field.replaceAccess(provider);
}
+
}
- public static String formatMessage(ComponentResources resources, String fieldName, String fieldType,
- String componentId)
+ private String getComponentId(TransformField field, InjectComponent annotation)
{
- return String.format(
- "Unable to inject component '%s' into field %s of component %s. Class %s is not assignable to a field of type %s.",
- componentId, fieldName, resources.getCompleteId(),
- resources.getEmbeddedComponent(componentId).getClass().getName(), fieldType);
+ String id = annotation.value();
+
+ if (InternalUtils.isNonBlank(id))
+ return id;
+
+ return InternalUtils.stripMemberName(field.getName());
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=906306&r1=906305&r2=906306&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Thu Feb 4 00:45:51 2010
@@ -539,7 +539,7 @@
configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
configuration.addInstance("InjectPage", InjectPageWorker.class);
configuration.addInstance("InjectContainer", InjectContainerWorker.class);
- configuration.add("InjectComponent", new InjectComponentWorker());
+ configuration.addInstance("InjectComponent", InjectComponentWorker.class);
configuration.add("RenderCommand", new RenderCommandWorker());
// Default values for parameters are often some form of injection, so
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java?rev=906306&r1=906305&r2=906306&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java Thu Feb 4 00:45:51 2010
@@ -111,8 +111,7 @@
// mismatched tag.
clickThru("BadTemplate Page");
- assertTextPresent(
- "org.apache.tapestry5.ioc.internal.util.TapestryException",
+ assertTextPresent("org.apache.tapestry5.ioc.internal.util.TapestryException",
"Failure parsing template classpath:org/apache/tapestry5/integration/app1/pages/BadTemplate.tml",
"The element type \"t:foobar\" must be terminated by the matching end-tag \"</t:foobar>\"",
"classpath:org/apache/tapestry5/integration/app1/pages/BadTemplate.tml, line 6",
@@ -149,9 +148,7 @@
{
clickThru("InjectComponentMismatch");
- assertTextPresent(
- "Unable to inject component 'form' into field form of component InjectComponentMismatch. Class org.apache.tapestry5.corelib.components.BeanEditForm is not assignable to a field of type org.apache.tapestry5.corelib.components.Form.",
- "ClassCastException");
+ assertTextPresent("Unable to inject component 'form' into field form of component InjectComponentMismatch. Class org.apache.tapestry5.corelib.components.BeanEditForm is not assignable to a field of type org.apache.tapestry5.corelib.components.Form.");
}
@Test
@@ -343,8 +340,7 @@
clickAndWait("link=go");
assertTextSeries("//li[%d]", 1, "betty", "wilma", "betty/wilma", "\u82B1\u5B50");
- assertTextSeries("//ul[2]/li[%d]", 1, "fred", "barney", "clark kent", "fred/barney",
- "\u592A\u90CE");
+ assertTextSeries("//ul[2]/li[%d]", 1, "fred", "barney", "clark kent", "fred/barney", "\u592A\u90CE");
}
@Test
@@ -430,8 +426,7 @@
clickAndWait(clear);
clickAndWait("link=No Context");
- assertText("methodNames",
- "[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild()]");
+ assertText("methodNames", "[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild()]");
clickAndWait(clear);
clickAndWait("link=Single context value");
@@ -460,8 +455,7 @@
{
clickThru("Inherited Bindings Demo");
- assertTextPresent("Bound: [ value: the-bound-value, bound: true ]",
- "Unbound: [ value: null, bound: false ]");
+ assertTextPresent("Bound: [ value: the-bound-value, bound: true ]", "Unbound: [ value: null, bound: false ]");
}
@Test
@@ -490,8 +484,7 @@
assertAttribute("//div[@id='single']/@class", "red");
assertAttribute("//div[@id='consecutive']/@class", "goober-red");
assertAttribute("//div[@id='trailer']/@class", "goober-green");
- assertText("//div[@id='formal']",
- "ALERT-expansions work inside formal component parameters as well");
+ assertText("//div[@id='formal']", "ALERT-expansions work inside formal component parameters as well");
// An unrelated test, but fills in a bunch of minor gaps.
@@ -641,8 +634,7 @@
clickAndWait("link=force invalid event context");
assertTextPresent("An unexpected application exception has occurred.",
- "org.apache.tapestry5.runtime.ComponentEventException",
- "java.lang.NumberFormatException");
+ "org.apache.tapestry5.runtime.ComponentEventException", "java.lang.NumberFormatException");
}
/**
@@ -672,8 +664,8 @@
// Just sample a smattering of the vast amount of data in the exception
// report.
- assertTextPresent("RenderErrorDemo", "class " + RenderErrorDemo.class.getName(),
- "RenderErrorDemo:border", "RenderErrorDemo:echo");
+ assertTextPresent("RenderErrorDemo", "class " + RenderErrorDemo.class.getName(), "RenderErrorDemo:border",
+ "RenderErrorDemo:echo");
}
/**
@@ -863,8 +855,7 @@
assertText("version", "5");
// @ReverseStrings filtered the checked exception to a string result
- assertText(
- "cranky",
+ assertText("cranky",
"Invocation of method getCranky() failed with org.apache.tapestry5.integration.app1.services.DearGodWhyMeException.");
// Now to check advice on a setter that manipulates parameters
@@ -903,8 +894,7 @@
clickThru("Informal Parameters Demo");
assertTextSeries("//dl[@id='informals']/dt[%d]", 1, "barney", "fred", "pageName");
- assertTextSeries("//dl[@id='informals']/dd[%d]", 1, "rubble", "flintstone",
- "InformalParametersDemo");
+ assertTextSeries("//dl[@id='informals']/dd[%d]", 1, "rubble", "flintstone", "InformalParametersDemo");
}
/**
@@ -1170,8 +1160,8 @@
* "from" is < 0, checking the corresponding mixin values is disabled.
*/
- private void assertEchoMixins(String fieldName, String originalValue, int echo1From,
- int echo2From, int echo3From, int fieldFrom, boolean isField)
+ private void assertEchoMixins(String fieldName, String originalValue, int echo1From, int echo2From, int echo3From,
+ int fieldFrom, boolean isField)
{
String[] vals =
{ originalValue, "temporaryvaluefromechovaluemixin", "3", "world" };