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/02/19 03:42:24 UTC

svn commit: r628968 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/annotations/ main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/services/ test/app1/ test/java/org/apache/tapestry/integrati...

Author: hlship
Date: Mon Feb 18 18:42:21 2008
New Revision: 628968

URL: http://svn.apache.org/viewvc?rev=628968&view=rev
Log:
TAPESTRY-2170: Add annotation to inject a component defined in the template

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/InjectComponent.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/InjectComponentDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectComponentWorkerTest.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/InjectComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/InjectComponent.java?rev=628968&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/InjectComponent.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/annotations/InjectComponent.java Mon Feb 18 18:42:21 2008
@@ -0,0 +1,35 @@
+// Copyright 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.tapestry.annotations;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Allows components defined in the template to be injected as read-only properties.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface InjectComponent
+{
+    /**
+     * The name of the component to inject. Defaults to the name of the annotated field.
+     */
+    String value() default "";
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java?rev=628968&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java Mon Feb 18 18:42:21 2008
@@ -0,0 +1,58 @@
+// Copyright  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.tapestry.internal.services;
+
+import org.apache.tapestry.annotations.InjectComponent;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Performs transformations that allow components defined in the template to be injected.
+ */
+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);
+
+            String type = transformation.getFieldType(fieldName);
+
+            String resourcesFieldName = transformation.getResourcesFieldName();
+
+            String componentId = annotation.value();
+            if (InternalUtils.isBlank(componentId))
+                componentId = fieldName;
+
+            transformation.makeReadOnly(fieldName);
+
+            String body = String.format(
+                    "%s = (%s) %s.getEmbeddedComponent(\"%s\");",
+                    fieldName,
+                    type,
+                    resourcesFieldName,
+                    componentId);
+
+            transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
+        }
+
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=628968&r1=628967&r2=628968&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Mon Feb 18 18:42:21 2008
@@ -248,7 +248,8 @@
         configuration.add("OnEvent", new OnEventWorker());
         configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
         configuration.add("InjectPage", new InjectPageWorker(requestPageCache, resolver));
-        configuration.add("InjectComponent", new InjectContainerWorker());
+        configuration.add("InjectContainer", new InjectContainerWorker());
+        configuration.add("InjectComponent", new InjectComponentWorker());
         configuration.add("RenderCommand", new RenderCommandWorker());
 
         // Default values for parameters are often some form of injection, so make sure

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/InjectComponentDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/InjectComponentDemo.tml?rev=628968&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/InjectComponentDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/InjectComponentDemo.tml Mon Feb 18 18:42:21 2008
@@ -0,0 +1,9 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <h1>Inject Component Demo</h1>
+
+    <t:form t:id="form"/>
+
+    ${injectComponentId}
+
+</t:border>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=628968&r1=628967&r2=628968&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Mon Feb 18 18:42:21 2008
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.integration;
 
+import org.apache.tapestry.corelib.components.Form;
 import org.apache.tapestry.corelib.mixins.RenderDisabled;
 import org.apache.tapestry.integration.app1.pages.RenderErrorDemo;
 import org.apache.tapestry.internal.services.InjectContainerWorker;
@@ -1667,4 +1668,13 @@
         assertText("name", "Barney");
         assertText("email", "rubble@bedrock.gov");
     }
+
+    @Test
+    public void zone_inject_component_from_template()
+    {
+        start("Inject Component Demo");
+
+        assertTextPresent(Form.class.getName() + "[form--form]");
+    }
+
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java?rev=628968&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentDemo.java Mon Feb 18 18:42:21 2008
@@ -0,0 +1,33 @@
+// Copyright 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.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.InjectComponent;
+import org.apache.tapestry.corelib.components.Form;
+
+public class InjectComponentDemo
+{
+
+    @InjectComponent
+    private Form form;
+
+    @InjectComponent("form")
+    private Form form2;
+
+    public String getInjectComponentId()
+    {
+        return Form.class.getName() + "[" + form.getClientId() + "--" + form2.getClientId() + "]";
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?rev=628968&r1=628967&r2=628968&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java Mon Feb 18 18:42:21 2008
@@ -229,7 +229,10 @@
                      "render phase methods may throw checked exceptions"),
 
             new Item("TrackEditor", "Generic Page Class Demo",
-                     "demo use of generics with component classes and, particularily, with property types"));
+                     "demo use of generics with component classes and, particularily, with property types"),
+
+            new Item("injectcomponentdemo", "Inject Component Demo",
+                     "inject component defined in template"));
 
     static
     {

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectComponentWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectComponentWorkerTest.java?rev=628968&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectComponentWorkerTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InjectComponentWorkerTest.java Mon Feb 18 18:42:21 2008
@@ -0,0 +1,81 @@
+// Copyright 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.tapestry.internal.services;
+
+import org.apache.tapestry.annotations.InjectComponent;
+import org.apache.tapestry.corelib.components.Grid;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class InjectComponentWorkerTest extends TapestryTestCase
+{
+
+    private static final String CLASS_NAME = Grid.class.getName();
+
+    @Test
+    public void default_id_from_field_name()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        InjectComponent annotation = newMock(InjectComponent.class);
+        ComponentClassTransformWorker worker = new InjectComponentWorker();
+
+        train_findFieldsWithAnnotation(ct, InjectComponent.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", InjectComponent.class, annotation);
+        train_getFieldType(ct, "myfield", CLASS_NAME);
+        train_getResourcesFieldName(ct, "resources");
+        expect(annotation.value()).andReturn("");
+        ct.makeReadOnly("myfield");
+
+        train_extendMethod(ct, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                           "myfield = (" + CLASS_NAME + ") resources.getEmbeddedComponent(\"myfield\");");
+
+
+        replay();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+    @Test
+    public void explicit_component_id_provided_as_annotation()
+    {
+        ClassTransformation ct = mockClassTransformation();
+        MutableComponentModel model = mockMutableComponentModel();
+        InjectComponent annotation = newMock(InjectComponent.class);
+        ComponentClassTransformWorker worker = new InjectComponentWorker();
+
+        train_findFieldsWithAnnotation(ct, InjectComponent.class, "myfield");
+        train_getFieldAnnotation(ct, "myfield", InjectComponent.class, annotation);
+        train_getFieldType(ct, "myfield", CLASS_NAME);
+        train_getResourcesFieldName(ct, "resources");
+        expect(annotation.value()).andReturn("id_provided_as_annotation").atLeastOnce();
+        ct.makeReadOnly("myfield");
+        train_extendMethod(ct, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+                           "myfield = (" + CLASS_NAME + ") resources.getEmbeddedComponent(\"id_provided_as_annotation\");");
+
+        replay();
+
+        worker.transform(ct, model);
+
+        verify();
+    }
+
+}