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 2010/01/22 17:29:49 UTC

svn commit: r902146 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/internal/services/ main/java/org/apache/tapestry5/services/ test/java/org/apache/tapestry5/integration/app1/pages/ test/java/org/apache/tapestry5/inter...

Author: hlship
Date: Fri Jan 22 16:29:49 2010
New Revision: 902146

URL: http://svn.apache.org/viewvc?rev=902146&view=rev
Log:
Add ability to assign a read-only value to a component field, from a ComponentValueProvider, within a specific method

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BlockDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/BlockInjectionProviderTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java?rev=902146&r1=902145&r2=902146&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/BlockInjectionProvider.java Fri Jan 22 16:29:49 2010
@@ -1,10 +1,10 @@
-// Copyright 2007, 2008 The Apache Software Foundation
+// Copyright 2007, 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,
@@ -15,53 +15,60 @@
 package org.apache.tapestry5.internal.services;
 
 import org.apache.tapestry5.Block;
+import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.annotations.Id;
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.ClassTransformation;
+import org.apache.tapestry5.services.ComponentValueProvider;
 import org.apache.tapestry5.services.InjectionProvider;
 import org.apache.tapestry5.services.TransformConstants;
 
 /**
- * Identifies fields of type {@link Block} that have the {@link Inject} annotation and converts them into read-only
- * fields containing the injected Block from the template. The annotation's value is the id of the block to inject; if
+ * Identifies fields of type {@link Block} that have the {@link Inject} annotation and converts them
+ * into read-only
+ * fields containing the injected Block from the template. The annotation's value is the id of the
+ * block to inject; if
  * omitted, the block id is deduced from the field id.
  * <p/>
- * Must be scheduled before {@link DefaultInjectionProvider} because it uses the same annotation, Inject, with a
- * different interpretation.
+ * Must be scheduled before {@link DefaultInjectionProvider} because it uses the same annotation,
+ * Inject, with a different interpretation.
  */
 public class BlockInjectionProvider implements InjectionProvider
 {
 
     public boolean provideInjection(String fieldName, Class fieldType, ObjectLocator locator,
-                                    ClassTransformation transformation, MutableComponentModel componentModel)
+            ClassTransformation transformation, MutableComponentModel componentModel)
     {
-        if (!fieldType.equals(Block.class)) return false;
-
-        String resourcesFieldName = transformation.getResourcesFieldName();
+        if (!fieldType.equals(Block.class))
+            return false;
 
         Id annotation = transformation.getFieldAnnotation(fieldName, Id.class);
 
-        String blockId = getBlockId(fieldName, annotation);
+        final String blockId = getBlockId(fieldName, annotation);
 
-        transformation.makeReadOnly(fieldName);
+        ComponentValueProvider<Block> provider = new ComponentValueProvider<Block>()
+        {
 
-        String body = String.format(
-                "%s = %s.getBlock(\"%s\");",
-                fieldName,
-                resourcesFieldName,
-                blockId);
+            @Override
+            public Block get(ComponentResources resources)
+            {
+                return resources.getBlock(blockId);
+            }
+        };
 
-        transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, body);
+        transformation.assignFieldIndirect(fieldName,
+                TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, provider);
 
         return true; // claim the field
     }
 
     private String getBlockId(String fieldName, Id annotation)
     {
-        if (annotation != null) return annotation.value();
+        if (annotation != null)
+            return annotation.value();
 
         return InternalUtils.stripMemberName(fieldName);
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=902146&r1=902145&r2=902146&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Fri Jan 22 16:29:49 2010
@@ -1985,4 +1985,26 @@
 
         return "$" + constructorArgs.size();
     }
+
+    @Override
+    public <T> void assignFieldIndirect(String fieldName, TransformMethodSignature methodSig,
+            ComponentValueProvider<T> provider)
+    {
+        Defense.notBlank(fieldName, "fieldName");
+        Defense.notNull(methodSig, "methodSig");
+        Defense.notNull(provider, "provider");
+
+        String providerFieldName = addInjectedField(ComponentValueProvider.class, fieldName
+                + "$provider", provider);
+
+        CtClass fieldType = getFieldCtType(fieldName);
+
+        String body = String.format("%s = (%s) %s.get(%s);", fieldName, fieldType.getName(),
+                providerFieldName, resourcesFieldName);
+
+        extendMethod(methodSig, body);
+
+        makeReadOnly(fieldName);
+    }
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java?rev=902146&r1=902145&r2=902146&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java Fri Jan 22 16:29:49 2010
@@ -500,4 +500,23 @@
      * @return true if the parent class contains a method with the name signature
      */
     boolean isMethodOverride(TransformMethodSignature methodSignature);
+
+    /**
+     * Uses {@link #extendMethod(TransformMethodSignature, String)} to make an assignment to
+     * a field within the provided method. In addition, the field is marked as read-only. This
+     * is an alternative to {@link #injectFieldIndirect(String, ComponentValueProvider)} for values
+     * that <em>can not</em> be calculated at the constructor.
+     * 
+     * @param <T>
+     * @param fieldName
+     *            name of field to assign
+     * @param methodSig
+     *            identifies the method where the assignment will occur, often this is
+     *            {@link TransformConstants#CONTAINING_PAGE_DID_LOAD_SIGNATURE}
+     * @param provider
+     *            provides the value of the field
+     * @since 5.2.0
+     */
+    <T> void assignFieldIndirect(String fieldName, TransformMethodSignature methodSig,
+            ComponentValueProvider<T> provider);
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BlockDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BlockDemo.java?rev=902146&r1=902145&r2=902146&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BlockDemo.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BlockDemo.java Fri Jan 22 16:29:49 2010
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.integration.app1.pages;
 
 import org.apache.tapestry5.Block;
+import org.apache.tapestry5.annotations.Id;
 import org.apache.tapestry5.annotations.Persist;
 import org.apache.tapestry5.annotations.Retain;
 import org.apache.tapestry5.ioc.annotations.Inject;
@@ -24,8 +25,8 @@
 
 public class BlockDemo
 {
-    @Inject
-    private Block fred;
+    @Inject @Id("fred")
+    private Block fredBlock;
 
     @Inject
     private Block barney;
@@ -42,7 +43,7 @@
         if (blocks == null)
         {
             blocks = CollectionFactory.newMap();
-            blocks.put("fred", fred);
+            blocks.put("fred", fredBlock);
             blocks.put("barney", barney);
         }
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/BlockInjectionProviderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/BlockInjectionProviderTest.java?rev=902146&r1=902145&r2=902146&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/BlockInjectionProviderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/BlockInjectionProviderTest.java Fri Jan 22 16:29:49 2010
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 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.
@@ -14,13 +14,11 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.Block;
 import org.apache.tapestry5.annotations.Id;
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.services.ClassTransformation;
 import org.apache.tapestry5.services.InjectionProvider;
-import org.apache.tapestry5.services.TransformConstants;
 import org.apache.tapestry5.test.TapestryTestCase;
 import org.testng.annotations.Test;
 
@@ -46,76 +44,4 @@
     {
         return newMock(Id.class);
     }
-
-    /**
-     * This doesn't prove anything; later there will be integration tests that prove that the generated code is valid
-     * and works.
-     */
-    @Test
-    public void explicit_block_id_provided_as_annotation()
-    {
-        ClassTransformation ct = mockClassTransformation();
-        MutableComponentModel model = mockMutableComponentModel();
-        ObjectLocator locator = mockObjectLocator();
-        Id barneyId = newId();
-
-        String barneyFieldName = "_barneyBlock";
-
-        train_getResourcesFieldName(ct, "rez");
-
-        train_getFieldAnnotation(ct, barneyFieldName, Id.class, barneyId);
-
-        train_value(barneyId, "barney");
-
-        ct.makeReadOnly(barneyFieldName);
-
-        train_extendMethod(
-                ct,
-                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
-                "_barneyBlock = rez.getBlock(\"barney\");");
-
-        replay();
-
-        assertTrue(new BlockInjectionProvider().provideInjection(
-                barneyFieldName,
-                Block.class,
-                locator,
-                ct,
-                model));
-
-        verify();
-    }
-
-    @Test
-    public void default_id_for_block_from_field_name()
-    {
-        ClassTransformation ct = mockClassTransformation();
-        MutableComponentModel model = mockMutableComponentModel();
-        ObjectLocator locator = mockObjectLocator();
-
-        String barneyFieldName = "_barney";
-
-        train_getResourcesFieldName(ct, "rez");
-
-        train_getFieldAnnotation(ct, barneyFieldName, Id.class, null);
-
-        ct.makeReadOnly(barneyFieldName);
-
-        train_extendMethod(
-                ct,
-                TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
-                "_barney = rez.getBlock(\"barney\");");
-
-        replay();
-
-        assertTrue(new BlockInjectionProvider().provideInjection(
-                barneyFieldName,
-                Block.class,
-                locator,
-                ct,
-                model));
-
-        verify();
-    }
-
 }