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 2009/02/15 20:01:04 UTC
svn commit: r744720 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/pageload/ test/app1/
test/java/org/apache/tapestry5/integration/
test/java/org/apache/tapestry5/integration/app1/components/
test/java/org/apa...
Author: hlship
Date: Sun Feb 15 19:01:03 2009
New Revision: 744720
URL: http://svn.apache.org/viewvc?rev=744720&view=rev
Log:
TAP5-487: Easier way to expose parameters of an embedded component in a containing component
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PublishUnknownParameterDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishUnknownParameterDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.tml
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Index.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java?rev=744720&r1=744719&r2=744720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java Sun Feb 15 19:01:03 2009
@@ -51,12 +51,9 @@
private final IdAllocator allocator = new IdAllocator();
- private final Map<String, String> publishedParameterToEmbeddedId = CollectionFactory.newCaseInsensitiveMap();
+ private Map<String, String> publishedParameterToEmbeddedId;
- // Doesn't have to be case-insensitive, because the embeddedIds are always known alues from
- // publishedParameterToEmbeddedId.
-
- private final Map<String, String> embeddedIdToComponentClassName = CollectionFactory.newMap();
+ private Map<String, EmbeddedComponentAssembler> embeddedIdToAssembler;
public ComponentAssemblerImpl(ComponentAssemblerSource assemblerSource,
ComponentInstantiatorSource instantiatorSource,
@@ -263,12 +260,18 @@
mixins,
location);
+ if (embeddedIdToAssembler == null)
+ embeddedIdToAssembler = CollectionFactory.newMap();
+
+ embeddedIdToAssembler.put(embeddedId, embedded);
+
if (embeddedModel != null)
{
- // ComponentModel embeddedComponentModel = instantiatorSource.getInstantiator(componentClassName).getModel();
-
for (String publishedParameterName : embeddedModel.getPublishedParameters())
{
+ if (publishedParameterToEmbeddedId == null)
+ publishedParameterToEmbeddedId = CollectionFactory.newCaseInsensitiveMap();
+
String existingEmbeddedId = publishedParameterToEmbeddedId.get(publishedParameterName);
if (existingEmbeddedId != null)
@@ -283,35 +286,23 @@
throw new TapestryException(message, location, null);
}
-// if (embeddedComponentModel.getParameterModel(publishedParameterName) == null)
-// {
-// String message = String.format(
-// "Component %s does not include a parameter named '%s' to publish. Possible parameters: %s.",
-// componentClassName, publishedParameterName,
-// InternalUtils.joinSorted(embeddedComponentModel.getParameterNames()));
-//
-// throw new TapestryException(message, location, null);
-// }
-
publishedParameterToEmbeddedId.put(publishedParameterName, embeddedId);
}
}
- embeddedIdToComponentClassName.put(embeddedId, componentClassName);
-
return embedded;
}
public ParameterBinder getBinder(final String parameterName)
{
- final String embeddedId = publishedParameterToEmbeddedId.get(parameterName);
+ final String embeddedId = InternalUtils.get(publishedParameterToEmbeddedId, parameterName);
if (embeddedId == null) return null;
- String componentClassName = embeddedIdToComponentClassName.get(embeddedId);
+ final EmbeddedComponentAssembler embededdedComponentAssembler = embeddedIdToAssembler.get(embeddedId);
- final ComponentAssembler embeddedAssembler = assemblerSource.getAssembler(componentClassName, locale);
+ final ComponentAssembler embeddedAssembler = embededdedComponentAssembler.getComponentAssembler();
final ParameterBinder embeddedBinder = embeddedAssembler.getBinder(parameterName);
@@ -336,6 +327,20 @@
};
}
+
+ final ParameterBinder innerBinder = embededdedComponentAssembler.createParameterBinder(parameterName);
+
+ if (innerBinder == null)
+ {
+ String message = String.format(
+ "Parameter '%s' of component %s is improperly published from embedded component '%s' (where it does not exist). " +
+ "This may be a typo in the publishParameters attribute of the @Component annotation.",
+ parameterName,
+ instantiator.getModel().getComponentClassName(),
+ embeddedId);
+
+ throw new TapestryException(message, embededdedComponentAssembler.getLocation(), null);
+ }
// The simple case, publishing a parameter of a subcomponent as if it were a parameter
// of this component.
@@ -345,12 +350,12 @@
{
ComponentPageElement subelement = element.getEmbeddedElement(embeddedId);
- subelement.bindParameter(parameterName, binding);
+ innerBinder.bind(subelement, binding);
}
public String getDefaultBindingPrefix(String metaDefault)
{
- return embeddedAssembler.getModel().getParameterModel(parameterName).getDefaultBindingPrefix();
+ return innerBinder.getDefaultBindingPrefix(metaDefault);
}
};
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java?rev=744720&r1=744719&r2=744720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java Sun Feb 15 19:01:03 2009
@@ -23,6 +23,11 @@
interface EmbeddedComponentAssembler extends Locatable
{
/**
+ * Returns the assembler responsible for creating instances of this embedded component.
+ */
+ ComponentAssembler getComponentAssembler();
+
+ /**
* Creates a binder that can later be used to bind the parameter. The parameter name may be unqualified ("value") or
* have a mixin prefix ("mymixin.value"). In the former case, the correct mixin is located (though the more typical
* case is to bind a parameter of the component itself, not a parameter of a mixin attached to the component). In
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java?rev=744720&r1=744719&r2=744720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java Sun Feb 15 19:01:03 2009
@@ -41,7 +41,7 @@
private final Location location;
- private final Map<String, ComponentModel> mixinIdToComponentModel = CollectionFactory.newCaseInsensitiveMap();
+ private final Map<String, Instantiator> mixinIdToInstantiator = CollectionFactory.newCaseInsensitiveMap();
/**
* Maps parameter names (both simple, and qualified with the mixin id) to the corresponding QualifiedParameterName.
@@ -69,7 +69,8 @@
ComponentInstantiatorSource instantiatorSource,
ComponentClassResolver componentClassResolver,
String componentClassName,
- Locale locale, EmbeddedComponentModel embeddedModel,
+ Locale locale,
+ EmbeddedComponentModel embeddedModel,
String templateMixins,
Location location)
{
@@ -113,12 +114,14 @@
private String prescanMixins()
{
+ // Mixin id found to support informal parameters
+
String supportsInformals = null;
- for (Map.Entry<String, ComponentModel> entry : mixinIdToComponentModel.entrySet())
+ for (Map.Entry<String, Instantiator> entry : mixinIdToInstantiator.entrySet())
{
String mixinId = entry.getKey();
- ComponentModel mixinModel = entry.getValue();
+ ComponentModel mixinModel = entry.getValue().getModel();
updateParameterNameToQualified(mixinId, mixinModel);
@@ -151,18 +154,18 @@
private void addMixin(String className)
{
- ComponentModel model = getModel(className);
+ Instantiator mixinInstantiator = instantiatorSource.getInstantiator(className);
String mixinId = InternalUtils.lastTerm(className);
- if (mixinIdToComponentModel.containsKey(mixinId))
+ if (mixinIdToInstantiator.containsKey(mixinId))
throw new TapestryException(
String.format("Mixins applied to a component must be unique. Mixin '%s' has already been applied.",
mixinId),
location, null);
- mixinIdToComponentModel.put(mixinId, model);
+ mixinIdToInstantiator.put(mixinId, mixinInstantiator);
}
private ComponentModel getModel(String className)
@@ -170,17 +173,22 @@
return instantiatorSource.getInstantiator(className).getModel();
}
+ public ComponentAssembler getComponentAssembler()
+ {
+ return assemblerSource.getAssembler(componentModel.getComponentClassName(), locale);
+ }
+
public ParameterBinder createParameterBinder(String parameterName)
{
int dotx = parameterName.indexOf('.');
if (dotx >= 0)
{
String mixinId = parameterName.substring(0, dotx);
- if (!mixinIdToComponentModel.containsKey(mixinId))
+ if (!mixinIdToInstantiator.containsKey(mixinId))
{
String message = String.format("Mixin id for parameter '%s' not found. Attached mixins: %s.",
parameterName,
- InternalUtils.joinSorted(mixinIdToComponentModel.keySet()));
+ InternalUtils.joinSorted(mixinIdToInstantiator.keySet()));
throw new TapestryException(message, location, null);
}
@@ -231,15 +239,10 @@
public void addMixinsToElement(ComponentPageElement newElement)
{
- for (Map.Entry<String, ComponentModel> entry : mixinIdToComponentModel.entrySet())
+ for (Map.Entry<String, Instantiator> entry : mixinIdToInstantiator.entrySet())
{
String mixinId = entry.getKey();
- ComponentModel model = entry.getValue();
-
- // TODO: Change mixinIdTo... to be to Instantiator instead, so we don't have to
- // keep asking the IS for them.
-
- Instantiator instantiator = instantiatorSource.getInstantiator(model.getComponentClassName());
+ Instantiator instantiator = entry.getValue();
newElement.addMixin(mixinId, instantiator);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Index.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Index.tml?rev=744720&r1=744719&r2=744720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Index.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/Index.tml Sun Feb 15 19:01:03 2009
@@ -107,6 +107,10 @@
</a>
-- error checking for conflict between @Component.type and t:type.
</li>
+ <li>
+ <a href="PublishUnknownParameterDemo">Publish Unknown Parameter Demo</a>
+ -- publishing a parameter which does not exist
+ </li>
</ul>
</html>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PublishUnknownParameterDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PublishUnknownParameterDemo.tml?rev=744720&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PublishUnknownParameterDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/PublishUnknownParameterDemo.tml Sun Feb 15 19:01:03 2009
@@ -0,0 +1,4 @@
+<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
+ xmlns:p="tapestry:parameter">
+ <t:badpublishunknown xyzzyx="whatever"/>
+</t:border>
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=744720&r1=744719&r2=744720&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Sun Feb 15 19:01:03 2009
@@ -2573,4 +2573,14 @@
"as well as in the component class ('textfield'). You should not provide a type attribute in " +
"the template when defining an embedded component within the component class.");
}
+
+ public void publish_unknown_parameter()
+ {
+ start("Publish Unknown Parameter Demo");
+
+ assertTextPresent(
+ "Parameter 'xyzzyx' of component org.apache.tapestry5.integration.app1.components.BadPublishUnknown " +
+ "is improperly published from embedded component 'publish1' (where it does not exist). " +
+ "This may be a typo in the publishParameters attribute of the @Component annotation.");
+ }
}
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.java?rev=744720&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.java Sun Feb 15 19:01:03 2009
@@ -0,0 +1,23 @@
+// Copyright 2009 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.tapestry5.integration.app1.components;
+
+import org.apache.tapestry5.annotations.Component;
+
+public class BadPublishUnknown
+{
+ @Component(publishParameters = "xyzzyx")
+ private Publish1 publish1;
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishUnknownParameterDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishUnknownParameterDemo.java?rev=744720&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishUnknownParameterDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/PublishUnknownParameterDemo.java Sun Feb 15 19:01:03 2009
@@ -0,0 +1,19 @@
+// Copyright 2009 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.tapestry5.integration.app1.pages;
+
+public class PublishUnknownParameterDemo
+{
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.tml?rev=744720&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/BadPublishUnknown.tml Sun Feb 15 19:01:03 2009
@@ -0,0 +1,6 @@
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"
+ xmlns:p="tapestry:parameter">
+
+ <span t:id="publish1"/>
+
+</t:container>
\ No newline at end of file