You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by ro...@apache.org on 2011/10/25 15:42:33 UTC

svn commit: r1188655 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/internal/transform/ test/java/org/apache/tapestry5/integration/app1/ test/java/org/apache/tapestry5/integration/app1/pages/ test/resources/org/apache/...

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>