Author: robertdzeigler
Date: Tue Oct 25 13:42:33 2011
New Revision: 1188655

URL: http://svn.apache.org/viewvc?rev=1188655&view=rev
Log:
TAP5-1663: The @BindParameter annotation should support inherited parameters

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BindParameterWorker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.tml

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BindParameterWorker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BindParameterWorker.java?rev=1188655&r1=1188654&r2=1188655&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BindParameterWorker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BindParameterWorker.java
 Tue Oct 25 13:42:33 2011
@@ -1,4 +1,4 @@
-// Copyright 2009, 2010 The Apache Software Foundation
+// Copyright 2009, 2010, 2011 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.
@@ -26,6 +26,7 @@ import org.apache.tapestry5.ioc.services
 import org.apache.tapestry5.ioc.util.AvailableValues;
 import org.apache.tapestry5.ioc.util.UnknownValueException;
 import org.apache.tapestry5.model.ComponentModel;
+import org.apache.tapestry5.model.EmbeddedComponentModel;
 import org.apache.tapestry5.model.MutableComponentModel;
 import org.apache.tapestry5.plastic.*;
 import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
@@ -71,7 +72,12 @@ public class BindParameterWorker impleme
         {
             if (conduit == null)
             {
-                conduit = 
containerResources.getParameterConduit(containerParameterName);
+                // if the parameter is not a formal parameter then it must be 
a published parameter
+                if 
(containerResources.getComponentModel().isFormalParameter(containerParameterName))
+                    conduit = 
containerResources.getParameterConduit(containerParameterName);
+                else
+                       conduit = 
getEmbeddedComponentResourcesForPublishedParameter(containerResources, 
containerParameterName)
+                                       
.getParameterConduit(containerParameterName);
             }
 
             return conduit;
@@ -184,9 +190,12 @@ public class BindParameterWorker impleme
         {
             if (model.isFormalParameter(name))
                 return name;
+            
+            if(isPublishedParameter(model, name))
+               return name;
         }
-
-        String message = String.format("Containing component %s does not 
contain a formal parameter %s %s.",
+        
+        String message = String.format("Containing component %s does not 
contain a formal parameter or a published parameter %s %s.",
 
                 model.getComponentClassName(),
 
@@ -194,7 +203,78 @@ public class BindParameterWorker impleme
 
                 InternalUtils.joinSorted(guesses));
 
-        throw new UnknownValueException(message, new AvailableValues("Formal 
parameters", model
-                .getDeclaredParameterNames()));
+        List<String> formalAndPublishedParameters = 
CollectionFactory.newList(model.getParameterNames());
+        formalAndPublishedParameters.addAll(getPublishedParameters(model));
+
+        throw new UnknownValueException(message, new AvailableValues("Formal 
and published parameters", formalAndPublishedParameters));
+    }
+    
+    /**
+     * Returns true if the parameter with the given parameterName is a 
published parameter
+     * of any of the embedded components for the component with the given 
model.
+     */
+    private boolean isPublishedParameter(ComponentModel model,  String 
parameterName)
+       {
+       for (String embeddedComponentId : model.getEmbeddedComponentIds())
+               {
+               EmbeddedComponentModel embeddedComponentModel = model
+                                               
.getEmbeddedComponentModel(embeddedComponentId);
+               if 
(embeddedComponentModel.getPublishedParameters().contains(parameterName)) 
return true;
+               }
+       
+       return false;
+       }
+    
+    private List<String> getPublishedParameters(ComponentModel model)
+    {
+       List<String> publishedParameters = CollectionFactory.newList();
+       for (String embeddedComponentId : model.getEmbeddedComponentIds())
+       {
+               EmbeddedComponentModel embeddedComponentModel = 
model.getEmbeddedComponentModel(embeddedComponentId);
+           
publishedParameters.addAll(embeddedComponentModel.getPublishedParameters());
+       }
+       return publishedParameters;
     }
+
+       /**
+     * Returns the {@link InternalComponentResources} of an embeddedComponent 
that contains the published parameter
+     * publishedParameterName. This is basically a recursive search for 
published parameters.
+     */
+       private InternalComponentResources 
getEmbeddedComponentResourcesForPublishedParameter(InternalComponentResources 
containerResources, 
+                       String publishedParameterName)
+       {
+               List<InternalComponentResources> embeddedComponentResourcesList 
= CollectionFactory.newList();
+               
+               embeddedComponentResourcesList.add(containerResources);
+               
+               while(!embeddedComponentResourcesList.isEmpty())
+               {
+                       InternalComponentResources resources = 
embeddedComponentResourcesList.remove(0);
+                       
+                       ComponentModel containerComponentModel = 
resources.getComponentModel();
+                       
+                       for(String embeddedComponentId : 
containerComponentModel.getEmbeddedComponentIds())
+                       {
+                               EmbeddedComponentModel embeddedComponentModel = 
containerComponentModel
+                                               
.getEmbeddedComponentModel(embeddedComponentId);
+                               
+                               InternalComponentResources 
embeddedComponentResources = (InternalComponentResources) resources
+                                               
.getEmbeddedComponent(embeddedComponentId).getComponentResources();
+                               /**
+                        * If the parameter is not a formal parameter, then the 
parameter must be a published parameter
+                        * of an embeddedComponent of the component we are 
currently examining.
+                        */
+                               
if(embeddedComponentModel.getPublishedParameters().contains(publishedParameterName)
+                                               && 
embeddedComponentResources.getComponentModel().isFormalParameter(publishedParameterName))
+                               {
+                                       return embeddedComponentResources;
+                               }
+                               
+                               
embeddedComponentResourcesList.add(embeddedComponentResources);
+                       }
+               }
+               
+               return null;
+       }
 }
+

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=1188655&r1=1188654&r2=1188655&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
 Tue Oct 25 13:42:33 2011
@@ -1261,6 +1261,12 @@ public class CoreBehaviorsTests extends 
         // load invocation order)
         assertEchoMixins("defaultbinding", "goodbye", 0, -1, -1, 1, false);
         assertText("mypropertyoutput5", "goodbye");
+        
+        // binding to a published parameter
+        assertText("publishedparameter_before", "publishedvalue-before");
+        assertText("p3-value", "publishedvaluetemporaryvalue");
+        assertText("publishedparameter_after", "publishedvalue-after");
+        assertText("mypropertyoutput6", "publishedvalue");
     }
 
     /**
@@ -1429,7 +1435,7 @@ public class CoreBehaviorsTests extends 
 
                 "Failure binding parameter field 'boundParameter' of mixin 
BindParameterNoSuchParameter:throwexception$echovalue2 (type 
org.apache.tapestry5.integration.app1.mixins.EchoValue2)",
 
-                "Containing component 
org.apache.tapestry5.corelib.components.Any does not contain a formal parameter 
matching any of boundParameter, value.");
+                "Containing component 
org.apache.tapestry5.corelib.components.Any does not contain a formal parameter 
or a published parameter matching any of boundParameter, value.");
     }
 
     @Test

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.java?rev=1188655&r1=1188654&r2=1188655&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.java
 Tue Oct 25 13:42:33 2011
@@ -38,6 +38,9 @@ public class BindParameterDemo
     @Property
     private String myproperty5;
     
+    @Property
+    private String myproperty6;
+    
     @SetupRender
     void initMyprop()
     {
@@ -46,5 +49,6 @@ public class BindParameterDemo
         myproperty3="hello";
         myproperty4="supervalue";
         myproperty5="goodbye";
+        myproperty6="publishedvalue";
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.tml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.tml?rev=1188655&r1=1188654&r2=1188655&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.tml
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/BindParameterDemo.tml
 Tue Oct 25 13:42:33 2011
@@ -22,6 +22,7 @@
       <t:textfield t:id="testmixin3" value="myproperty3" 
t:mixins="echovalue3"/>
       <t:textfield t:id="multimixins" value="myproperty4" 
t:mixins="echovalue::before:*, echovalue2::before:echovalue3, echovalue3"/>
       <t:textonlyondisabledtextfield t:id="defaultbinding" value="myproperty5" 
disabled="true" t:mixins="echovalue"/>
+      <t:publish1 value="prop:myproperty6" t:mixins="echoValueWithId" 
id="literal:publishedparameter"/>
   </t:form>
 
   <div id="mypropertyoutput">${myproperty}</div>
@@ -29,4 +30,5 @@
   <div id="mypropertyoutput3">${myproperty3}</div>
   <div id="mypropertyoutput4">${myproperty4}</div>
   <div id="mypropertyoutput5">${myproperty5}</div>
+  <div id="mypropertyoutput6">${myproperty6}</div>
 </html>


Reply via email to