You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/09/26 18:37:10 UTC

svn commit: r450108 - in /tapestry/tapestry5/tapestry-core/trunk/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: Tue Sep 26 09:37:06 2006
New Revision: 450108

URL: http://svn.apache.org/viewvc?view=rev&rev=450108
Log:
Add Environmental annotation and corresponding EnvironmentalWorker.
Add an integration test for Environmental behavior.
Tweak the names of transformed fields and methods, slightly.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Environmental.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EnvironmentalWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.html
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UnclaimedFieldWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/UnclaimedFieldWorkerTest.java

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Environmental.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Environmental.java?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Environmental.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Environmental.java Tue Sep 26 09:37:06 2006
@@ -0,0 +1,23 @@
+package org.apache.tapestry.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.tapestry.services.Environment;
+
+/**
+ * Defines a field that is replaced at runtime with a read-only value obtained from the
+ * {@link Environment} service.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Environmental {
+
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EnvironmentalWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EnvironmentalWorker.java?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EnvironmentalWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EnvironmentalWorker.java Tue Sep 26 09:37:06 2006
@@ -0,0 +1,74 @@
+package org.apache.tapestry.internal.services;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.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.Environment;
+import org.apache.tapestry.services.MethodSignature;
+
+/**
+ * Obtains a value from the {@link Environment} service based on the field type. This is triggered
+ * by the presense of the {@link Environmental} annotation.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class EnvironmentalWorker implements ComponentClassTransformWorker
+{
+    private final Environment _environment;
+
+    public EnvironmentalWorker(Environment environment)
+    {
+        _environment = environment;
+    }
+
+    public void transform(ClassTransformation transformation, MutableComponentModel model)
+    {
+        List<String> names = transformation.findFieldsWithAnnotation(Environmental.class);
+
+        if (names.isEmpty())
+            return;
+
+        // TODO: addInjectField should be smart about if the field has already been injected (with
+        // the same type)
+        // for this transformation, or the parent transformation.
+
+        String envField = transformation.addInjectedField(
+                Environment.class,
+                "environment",
+                _environment);
+
+        for (String name : names)
+        {
+            Environmental annotation = transformation.getFieldAnnotation(name, Environmental.class);
+
+            String type = transformation.getFieldType(name);
+
+            // TODO: Check for primitives
+
+            // Caching might be good for efficiency at some point.
+
+            String methodName = transformation.newMemberName("_environment_read_"
+                    + InternalUtils.stripMemberPrefix(name));
+
+            MethodSignature sig = new MethodSignature(Modifier.PRIVATE, type, methodName, null,
+                    null);
+
+            // TODO: Check for null
+
+            String body = String.format("return ($r) %s.peek($type);", envField);
+
+            transformation.addMethod(sig, body);
+
+            transformation.replaceReadAccess(name, methodName);
+            transformation.makeReadOnly(name);
+
+            transformation.claimField(name, annotation);
+        }
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java Tue Sep 26 09:37:06 2006
@@ -1144,7 +1144,7 @@
 
     public void makeReadOnly(String fieldName)
     {
-        String methodName = "_write_" + fieldName;
+        String methodName = "_write_" + InternalUtils.stripMemberPrefix(fieldName);
 
         String fieldType = getFieldType(fieldName);
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UnclaimedFieldWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UnclaimedFieldWorker.java?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UnclaimedFieldWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/UnclaimedFieldWorker.java Tue Sep 26 09:37:06 2006
@@ -47,7 +47,7 @@
         String type = transformation.getFieldType(fieldName);
 
         String defaultFieldName = transformation.addField(Modifier.PRIVATE, type, fieldName
-                + "Default");
+                + "_default");
 
         transformation.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, defaultFieldName + " = "
                 + fieldName + ";");

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Tue Sep 26 09:37:06 2006
@@ -44,6 +44,7 @@
 import org.apache.tapestry.internal.services.ComponentWorker;
 import org.apache.tapestry.internal.services.DefaultInjectionProvider;
 import org.apache.tapestry.internal.services.EnvironmentImpl;
+import org.apache.tapestry.internal.services.EnvironmentalWorker;
 import org.apache.tapestry.internal.services.HTMLDispatcher;
 import org.apache.tapestry.internal.services.InfrastructureImpl;
 import org.apache.tapestry.internal.services.InfrastructureManagerImpl;
@@ -428,12 +429,14 @@
      * Adds a number of standard component class transform workers:
      * <ul>
      * <li>Retain -- allows fields to retain their values between requests</li>
-     * <li>Parameter</li> -- identifies parameters based on the
+     * <li>Parameter -- identifies parameters based on the
      * {@link org.apache.tapestry.annotations.Parameter} annotation</li>
-     * <li>Component</li> -- identifies embedded components based on the
+     * <li>Component -- identifies embedded components based on the
      * {@link org.apache.tapestry.annotations.Component} annotation</li>
-     * <li>UnclaimedField</li> -- identifies unclaimed fields and resets them to null/0/false at
-     * the end of the request</li>
+     * <li>Environment -- allows fields to contain values extracted from the {@link Environment}
+     * service</li>
+     * <li>UnclaimedField -- identifies unclaimed fields and resets them to null/0/false at the end
+     * of the request</li>
      * <li>SetupRender, BeginRender, etc. -- correspond to component render phases and annotations</li>
      * </ul>
      * 
@@ -443,13 +446,15 @@
             OrderedConfiguration<ComponentClassTransformWorker> configuration,
             ServiceLocator locator, @InjectService("tapestry.ioc.MasterObjectProvider")
             ObjectProvider objectProvider, @InjectService("InjectionProvider")
-            InjectionProvider injectionProvider)
+            InjectionProvider injectionProvider, @InjectService("Environment")
+            Environment environment)
     {
         // TODO: Proper scheduling of all of this.
 
         configuration.add("Inject", new InjectWorker(objectProvider, locator, injectionProvider));
         configuration.add("Parameter", new ParameterWorker());
         configuration.add("Component", new ComponentWorker());
+        configuration.add("Environment", new EnvironmentalWorker(environment));
 
         // Workers for the component rendering state machine methods; this is in typical
         // execution order.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Tue Sep 26 09:37:06 2006
@@ -19,8 +19,11 @@
                 <li>
                     <a href="Countdown.html">Countdown Page</a>
                 </li>
+                <li>
+                    <a href="ParameterConflict.html">Template Overriden by Class Page</a>
+                </li>
             <li>
-                <a href="ParameterConflict.html">Template Overriden by Class Page</a>
+                <a href="EnvironmentalDemo.html">Environmental Annotation Useage</a>
             </li>
             </ul>
         </p>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Tue Sep 26 09:37:06 2006
@@ -29,7 +29,7 @@
  * 
  * @author Howard M. Lewis Ship
  */
-@Test(sequential = true, groups =
+@Test(timeOut = 50000, sequential = true, groups =
 { "integration" })
 public class IntegrationTests extends Assert
 {
@@ -74,13 +74,12 @@
         _jettyRunner = null;
     }
 
-    @Test(timeOut = 50000)
+    @Test
     public void app1_basic_output() throws Exception
     {
         _selenium.open(BASE_URL);
 
-        _selenium.click("link=Start Page");
-        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+        clickAndWait("link=Start Page");
 
         // This comes from the Border cmponent's template
 
@@ -97,7 +96,13 @@
         assertTrue(body.contains("we have basic parameters working"));
     }
 
-    @Test(timeOut = 50000)
+    private void clickAndWait(String link)
+    {
+        _selenium.click(link);
+        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+    }
+
+    @Test
     public void app1_basic_parameters() throws Exception
     {
 
@@ -106,8 +111,7 @@
 
         _selenium.open(BASE_URL);
 
-        _selenium.click("link=Loop Page");
-        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+        clickAndWait("link=Loop Page");
 
         String body = _selenium.getBodyText();
 
@@ -116,13 +120,12 @@
         assertTrue(body.contains("Ho! Ho! Ho!"));
     }
 
-    @Test(timeOut = 50000)
+    @Test
     public void app1_injection() throws Exception
     {
         _selenium.open(BASE_URL);
 
-        _selenium.click("link=Inject Page");
-        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+        clickAndWait("link=Inject Page");
 
         String body = _selenium.getBodyText();
 
@@ -142,13 +145,12 @@
                 .contains("<Proxy for tapestry.BindingSource(org.apache.tapestry.services.BindingSource)>"));
     }
 
-    @Test(timeOut = 50000)
+    @Test
     public void app1_embedded_components()
     {
         _selenium.open(BASE_URL);
 
-        _selenium.click("link=Countdown Page");
-        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+        clickAndWait("link=Countdown Page");
 
         String body = _selenium.getBodyText();
 
@@ -158,16 +160,28 @@
                 .contains("Brought to you by the org.apache.tapestry.integration.app1.components.Loop"));
     }
 
-    @Test(timeOut = 50000)
+    @Test
     public void app1_template_overridden()
     {
         _selenium.open(BASE_URL);
 
-        _selenium.click("link=Template Overriden by Class Page");
-        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+        clickAndWait("link=Template Overriden by Class Page");
 
         String body = _selenium.getBodyText();
 
         assertTrue(body.contains("Output: ClassValue"));
+    }
+
+    @Test
+    public void app1_environmental()
+    {
+        _selenium.open(BASE_URL);
+
+        clickAndWait("link=Environmental Annotation Useage");
+
+        String source = _selenium.getHtmlSource();
+
+        assertTrue(source
+                .contains("[<strong>A message provided by the RenderableProvider component.</strong>]"));
     }
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableProvider.java Tue Sep 26 09:37:06 2006
@@ -0,0 +1,41 @@
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotations.CleanupRender;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.SetupRender;
+import org.apache.tapestry.services.Environment;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@ComponentClass
+public class RenderableProvider
+{
+    @Inject("service:tapestry.Environment")
+    private Environment _environment;
+
+    @SetupRender
+    void setup()
+    {
+        Renderable r = new Renderable()
+        {
+            public void render(MarkupWriter writer)
+            {
+                writer.element("strong");
+                writer.write("A message provided by the RenderableProvider component.");
+                writer.end();
+            }
+        };
+
+        _environment.push(Renderable.class, r);
+    }
+
+    @CleanupRender
+    void cleanup()
+    {
+        _environment.pop(Renderable.class);
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/RenderableUser.java Tue Sep 26 09:37:06 2006
@@ -0,0 +1,25 @@
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.Renderable;
+import org.apache.tapestry.annotations.BeginRender;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Environmental;
+
+/**
+ * Used, with {@link RenderableProvider}, to test the {@link Environmental} annotation.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+@ComponentClass
+public class RenderableUser
+{
+    @Environmental
+    private Renderable _renderable;
+
+    @BeginRender
+    void render(MarkupWriter writer)
+    {
+        _renderable.render(writer);
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.java Tue Sep 26 09:37:06 2006
@@ -0,0 +1,9 @@
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.ComponentClass;
+
+@ComponentClass
+public class EnvironmentalDemo
+{
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/UnclaimedFieldWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/UnclaimedFieldWorkerTest.java?view=diff&rev=450108&r1=450107&r2=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/UnclaimedFieldWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/UnclaimedFieldWorkerTest.java Tue Sep 26 09:37:06 2006
@@ -55,11 +55,11 @@
         ct.getFieldType("_fred");
         setReturnValue("foo.Bar");
 
-        ct.addField(Modifier.PRIVATE, "foo.Bar", "_fredDefault");
-        setReturnValue("_$fredDefault");
+        ct.addField(Modifier.PRIVATE, "foo.Bar", "_fred_default");
+        setReturnValue("_$fred_default");
 
-        ct.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, "_$fredDefault = _fred;");
-        ct.extendMethod(CONTAINING_PAGE_DID_DETACH_SIGNATURE, "_fred = _$fredDefault;");
+        ct.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, "_$fred_default = _fred;");
+        ct.extendMethod(CONTAINING_PAGE_DID_DETACH_SIGNATURE, "_fred = _$fred_default;");
 
         replay();
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.html?view=auto&rev=450108
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/EnvironmentalDemo.html Tue Sep 26 09:37:06 2006
@@ -0,0 +1,9 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+    <t:comp type="RenderableProvider">
+        <p> This page demonstrates how components can use the Environment service, and the @Environmental annotation, to
+            coordinate behavior. </p>
+
+        <p> RenderableUser:[<t:comp type="RenderableUser"/>]</p>
+    </t:comp>
+</t:comp>