You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/07/08 19:35:59 UTC
svn commit: r1144398 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/pageload/
main/resources/org/apache/tapestry5/internal/pageload/
test/groovy/org/apache/tapestry5/integration/app1/
test/java/org/apache/tape...
Author: hlship
Date: Fri Jul 8 17:35:58 2011
New Revision: 1144398
URL: http://svn.apache.org/viewvc?rev=1144398&view=rev
Log:
TAP5-1428: When a parameter is bound but does not match a formal parameter, the exception should also include a list of formal parameter names
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.tml
Modified:
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/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageloadMessages.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/pageload/PageloadStrings.properties
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
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=1144398&r1=1144397&r2=1144398&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 Fri Jul 8 17:35:58 2011
@@ -1,4 +1,4 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 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.
@@ -17,6 +17,8 @@ package org.apache.tapestry5.internal.pa
import org.apache.tapestry5.internal.structure.ComponentPageElement;
import org.apache.tapestry5.ioc.Locatable;
+import java.util.Set;
+
/**
* Encapsulates logic related to assembling an embedded component within a {@link org.apache.tapestry5.internal.pageload.ComponentAssembler}.
*/
@@ -39,7 +41,8 @@ interface EmbeddedComponentAssembler ext
* This method should only be called at page-assembly time as it requires some data that is collected during
* ComponentAssembly construction in order to handle published parameters of embedded components.
*
- * @param parameterName simple or qualified parameter name
+ * @param parameterName
+ * simple or qualified parameter name
* @return object that can bind the parameter
*/
ParameterBinder createParameterBinder(String parameterName);
@@ -59,7 +62,15 @@ interface EmbeddedComponentAssembler ext
/**
* Adds mixins to the newly created embedded element.
*
- * @param newElement new element requiring mixins
+ * @param newElement
+ * new element requiring mixins
*/
void addMixinsToElement(ComponentPageElement newElement);
+
+ /**
+ * Returns the names of all formal parameters.
+ *
+ * @since 5.3
+ */
+ Set<String> getFormalParameterNames();
}
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=1144398&r1=1144397&r2=1144398&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 Fri Jul 8 17:35:58 2011
@@ -14,8 +14,6 @@
package org.apache.tapestry5.internal.pageload;
-import java.util.Map;
-
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.internal.services.ComponentInstantiatorSource;
import org.apache.tapestry5.internal.services.Instantiator;
@@ -30,6 +28,10 @@ import org.apache.tapestry5.model.Embedd
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
public class EmbeddedComponentAssemblerImpl implements EmbeddedComponentAssembler
{
private final ComponentInstantiatorSource instantiatorSource;
@@ -60,24 +62,24 @@ public class EmbeddedComponentAssemblerI
/**
* @param assemblerSource
* @param instantiatorSource
- * used to access component models
+ * used to access component models
* @param componentClassResolver
- * used to convert mixin types to component models
+ * used to convert mixin types to component models
* @param componentClassName
- * class name of embedded component
+ * class name of embedded component
* @param selector
- * used to select template and other resources
+ * used to select template and other resources
* @param embeddedModel
- * embedded model (may be null for components defined in the template)
+ * embedded model (may be null for components defined in the template)
* @param templateMixins
- * list of mixins from the t:mixins element (possibly null)
+ * list of mixins from the t:mixins element (possibly null)
* @param location
- * location of components element in its container's template
+ * location of components element in its container's template
*/
public EmbeddedComponentAssemblerImpl(ComponentAssemblerSource assemblerSource,
- ComponentInstantiatorSource instantiatorSource, ComponentClassResolver componentClassResolver,
- String componentClassName, ComponentResourceSelector selector, EmbeddedComponentModel embeddedModel,
- String templateMixins, Location location)
+ ComponentInstantiatorSource instantiatorSource, ComponentClassResolver componentClassResolver,
+ String componentClassName, ComponentResourceSelector selector, EmbeddedComponentModel embeddedModel,
+ String templateMixins, Location location)
{
this.assemblerSource = assemblerSource;
this.instantiatorSource = instantiatorSource;
@@ -186,11 +188,13 @@ public class EmbeddedComponentAssemblerI
if (dotx >= 0)
{
String mixinId = parameterName.substring(0, dotx);
- if (!mixinIdToInstantiator.containsKey(mixinId)) { throw new TapestryException(
- PageloadMessages.mixinidForParamnotfound(parameterName, mixinIdToInstantiator.keySet()), location,
- null); }
- }
- else
+ if (!mixinIdToInstantiator.containsKey(mixinId))
+ {
+ throw new TapestryException(
+ PageloadMessages.mixinidForParamnotfound(parameterName, mixinIdToInstantiator.keySet()), location,
+ null);
+ }
+ } else
{
// Unqualified parameter name. May be a reference not to a parameter of this component, but a published
// parameter of a component embedded in this component. The ComponentAssembler for this component
@@ -251,4 +255,9 @@ public class EmbeddedComponentAssemblerI
{
return location;
}
+
+ public Set<String> getFormalParameterNames()
+ {
+ return new HashSet<String>(componentModel.getParameterNames());
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java?rev=1144398&r1=1144397&r2=1144398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java Fri Jul 8 17:35:58 2011
@@ -14,11 +14,6 @@
package org.apache.tapestry5.internal.pageload;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
@@ -26,38 +21,9 @@ import org.apache.tapestry5.MarkupWriter
import org.apache.tapestry5.internal.InternalComponentResources;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.bindings.LiteralBinding;
-import org.apache.tapestry5.internal.parser.AttributeToken;
-import org.apache.tapestry5.internal.parser.BlockToken;
-import org.apache.tapestry5.internal.parser.CDATAToken;
-import org.apache.tapestry5.internal.parser.CommentToken;
-import org.apache.tapestry5.internal.parser.ComponentTemplate;
-import org.apache.tapestry5.internal.parser.DTDToken;
-import org.apache.tapestry5.internal.parser.DefineNamespacePrefixToken;
-import org.apache.tapestry5.internal.parser.ExpansionToken;
-import org.apache.tapestry5.internal.parser.ExtensionPointToken;
-import org.apache.tapestry5.internal.parser.ParameterToken;
-import org.apache.tapestry5.internal.parser.StartComponentToken;
-import org.apache.tapestry5.internal.parser.StartElementToken;
-import org.apache.tapestry5.internal.parser.TemplateToken;
-import org.apache.tapestry5.internal.parser.TextToken;
-import org.apache.tapestry5.internal.parser.TokenType;
-import org.apache.tapestry5.internal.services.ComponentInstantiatorSource;
-import org.apache.tapestry5.internal.services.ComponentTemplateSource;
-import org.apache.tapestry5.internal.services.Instantiator;
-import org.apache.tapestry5.internal.services.PageElementFactory;
-import org.apache.tapestry5.internal.services.PageLoader;
-import org.apache.tapestry5.internal.services.PersistentFieldManager;
-import org.apache.tapestry5.internal.services.StringInterner;
-import org.apache.tapestry5.internal.structure.BlockImpl;
-import org.apache.tapestry5.internal.structure.CommentPageElement;
-import org.apache.tapestry5.internal.structure.ComponentPageElement;
-import org.apache.tapestry5.internal.structure.ComponentPageElementResources;
-import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSource;
-import org.apache.tapestry5.internal.structure.DTDPageElement;
-import org.apache.tapestry5.internal.structure.Page;
-import org.apache.tapestry5.internal.structure.PageImpl;
-import org.apache.tapestry5.internal.structure.StartElementPageElement;
-import org.apache.tapestry5.internal.structure.TextPageElement;
+import org.apache.tapestry5.internal.parser.*;
+import org.apache.tapestry5.internal.services.*;
+import org.apache.tapestry5.internal.structure.*;
import org.apache.tapestry5.ioc.Invokable;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.OperationTracker;
@@ -66,7 +32,9 @@ import org.apache.tapestry5.ioc.internal
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.ioc.services.PerthreadManager;
import org.apache.tapestry5.ioc.services.SymbolSource;
+import org.apache.tapestry5.ioc.util.AvailableValues;
import org.apache.tapestry5.ioc.util.Stack;
+import org.apache.tapestry5.ioc.util.UnknownValueException;
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.EmbeddedComponentModel;
import org.apache.tapestry5.runtime.RenderCommand;
@@ -76,6 +44,10 @@ import org.apache.tapestry5.services.Inv
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
/**
* There's still a lot of room to beef up {@link org.apache.tapestry5.internal.pageload.ComponentAssembler} and
* {@link org.apache.tapestry5.internal.pageload.EmbeddedComponentAssembler} to perform more static analysis, but
@@ -92,23 +64,19 @@ import org.apache.tapestry5.services.pag
* <p/>
* And truly, <em>This is the Tapestry Heart, This is the Tapestry Soul...</em>
*/
-public class PageLoaderImpl implements PageLoader, InvalidationListener, ComponentAssemblerSource
-{
- private static final class Key
- {
+public class PageLoaderImpl implements PageLoader, InvalidationListener, ComponentAssemblerSource {
+ private static final class Key {
private final String className;
private final ComponentResourceSelector selector;
- private Key(String className, ComponentResourceSelector selector)
- {
+ private Key(String className, ComponentResourceSelector selector) {
this.className = className;
this.selector = selector;
}
@Override
- public boolean equals(Object o)
- {
+ public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
@@ -120,32 +88,26 @@ public class PageLoaderImpl implements P
}
@Override
- public int hashCode()
- {
+ public int hashCode() {
return 31 * className.hashCode() + selector.hashCode();
}
}
- private static final PageAssemblyAction POP_EMBEDDED_COMPONENT_ACTION = new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ private static final PageAssemblyAction POP_EMBEDDED_COMPONENT_ACTION = new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
pageAssembly.createdElement.pop();
pageAssembly.bodyElement.pop();
pageAssembly.embeddedAssembler.pop();
}
};
- private static final RenderCommand END_ELEMENT = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
+ private static final RenderCommand END_ELEMENT = new RenderCommand() {
+ public void render(MarkupWriter writer, RenderQueue queue) {
writer.end();
}
@Override
- public String toString()
- {
+ public String toString() {
return "End";
}
};
@@ -175,11 +137,10 @@ public class PageLoaderImpl implements P
private final SymbolSource symbolSource;
public PageLoaderImpl(ComponentInstantiatorSource instantiatorSource, ComponentTemplateSource templateSource,
- PageElementFactory elementFactory, ComponentPageElementResourcesSource resourcesSource,
- ComponentClassResolver componentClassResolver, PersistentFieldManager persistentFieldManager,
- StringInterner interner, OperationTracker tracker, PerthreadManager perThreadManager, Request request,
- SymbolSource symbolSource)
- {
+ PageElementFactory elementFactory, ComponentPageElementResourcesSource resourcesSource,
+ ComponentClassResolver componentClassResolver, PersistentFieldManager persistentFieldManager,
+ StringInterner interner, OperationTracker tracker, PerthreadManager perThreadManager, Request request,
+ SymbolSource symbolSource) {
this.instantiatorSource = instantiatorSource;
this.templateSource = templateSource;
this.elementFactory = elementFactory;
@@ -193,19 +154,15 @@ public class PageLoaderImpl implements P
this.symbolSource = symbolSource;
}
- public void objectWasInvalidated()
- {
+ public void objectWasInvalidated() {
cache.clear();
}
- public Page loadPage(final String logicalPageName, final ComponentResourceSelector selector)
- {
+ public Page loadPage(final String logicalPageName, final ComponentResourceSelector selector) {
final String pageClassName = componentClassResolver.resolvePageNameToClassName(logicalPageName);
- return tracker.invoke("Constructing instance of page class " + pageClassName, new Invokable<Page>()
- {
- public Page invoke()
- {
+ return tracker.invoke("Constructing instance of page class " + pageClassName, new Invokable<Page>() {
+ public Page invoke() {
Page page = new PageImpl(logicalPageName, selector, persistentFieldManager, perThreadManager);
ComponentAssembler assembler = getAssembler(pageClassName, selector);
@@ -225,14 +182,12 @@ public class PageLoaderImpl implements P
});
}
- public ComponentAssembler getAssembler(String className, ComponentResourceSelector selector)
- {
+ public ComponentAssembler getAssembler(String className, ComponentResourceSelector selector) {
Key key = new Key(className, selector);
ComponentAssembler result = cache.get(key);
- if (result == null)
- {
+ if (result == null) {
// There's a window here where two threads may create the same assembler simultaneously;
// the extra assembler will be discarded.
@@ -244,12 +199,9 @@ public class PageLoaderImpl implements P
return result;
}
- private ComponentAssembler createAssembler(final String className, final ComponentResourceSelector selector)
- {
- return tracker.invoke("Creating ComponentAssembler for " + className, new Invokable<ComponentAssembler>()
- {
- public ComponentAssembler invoke()
- {
+ private ComponentAssembler createAssembler(final String className, final ComponentResourceSelector selector) {
+ return tracker.invoke("Creating ComponentAssembler for " + className, new Invokable<ComponentAssembler>() {
+ public ComponentAssembler invoke() {
Instantiator instantiator = instantiatorSource.getInstantiator(className);
ComponentModel componentModel = instantiator.getModel();
@@ -275,14 +227,12 @@ public class PageLoaderImpl implements P
* "Programs" the assembler by analyzing the component, its mixins and its embedded components (both in the template
* and in the Java class), adding new PageAssemblyActions.
*/
- private void programAssembler(ComponentAssembler assembler, ComponentTemplate template)
- {
+ private void programAssembler(ComponentAssembler assembler, ComponentTemplate template) {
TokenStream stream = createTokenStream(assembler, template);
AssemblerContext context = new AssemblerContext(assembler, stream);
- if (template.isMissing())
- {
+ if (template.isMissing()) {
// Pretend the template has a single <t:body> element.
body(context);
@@ -290,8 +240,7 @@ public class PageLoaderImpl implements P
return;
}
- while (context.more())
- {
+ while (context.more()) {
processTemplateToken(context);
}
@@ -303,8 +252,7 @@ public class PageLoaderImpl implements P
* {@link org.apache.tapestry5.internal.parser.ExtensionPointToken}s
* and replacing them with appropriate overrides. Also validates that all embedded ids are accounted for.
*/
- private TokenStream createTokenStream(ComponentAssembler assembler, ComponentTemplate template)
- {
+ private TokenStream createTokenStream(ComponentAssembler assembler, ComponentTemplate template) {
List<TemplateToken> tokens = CollectionFactory.newList();
Stack<TemplateToken> queue = CollectionFactory.newStack();
@@ -318,21 +266,17 @@ public class PageLoaderImpl implements P
pushAll(queue, baseTemplate.getTokens());
- while (!queue.isEmpty())
- {
+ while (!queue.isEmpty()) {
TemplateToken token = queue.pop();
// When an ExtensionPoint is found, it is replaced with the tokens of its override.
- if (token.getTokenType().equals(TokenType.EXTENSION_POINT))
- {
+ if (token.getTokenType().equals(TokenType.EXTENSION_POINT)) {
ExtensionPointToken extensionPointToken = (ExtensionPointToken) token;
queueOverrideTokensForExtensionPoint(extensionPointToken, queue, overrideSearch);
- }
- else
- {
+ } else {
tokens.add(token);
}
}
@@ -343,8 +287,7 @@ public class PageLoaderImpl implements P
Map<String, Location> componentIds = CollectionFactory.newCaseInsensitiveMap();
- for (ComponentTemplate ct : overrideSearch)
- {
+ for (ComponentTemplate ct : overrideSearch) {
componentIds.putAll(ct.getComponentIds());
}
@@ -356,26 +299,22 @@ public class PageLoaderImpl implements P
return new TokenStreamImpl(tokens);
}
- private static <T> T getLast(List<T> list)
- {
+ private static <T> T getLast(List<T> list) {
int count = list.size();
return list.get(count - 1);
}
private void queueOverrideTokensForExtensionPoint(ExtensionPointToken extensionPointToken,
- Stack<TemplateToken> queue, List<ComponentTemplate> overrideSearch)
- {
+ Stack<TemplateToken> queue, List<ComponentTemplate> overrideSearch) {
String extensionPointId = extensionPointToken.getExtensionPointId();
// Work up from the component, through its base classes, towards the last non-extension template.
- for (ComponentTemplate t : overrideSearch)
- {
+ for (ComponentTemplate t : overrideSearch) {
List<TemplateToken> tokens = t.getExtensionPointTokens(extensionPointId);
- if (tokens != null)
- {
+ if (tokens != null) {
pushAll(queue, tokens);
return;
}
@@ -388,8 +327,7 @@ public class PageLoaderImpl implements P
extensionPointToken.getLocation(), null);
}
- private List<ComponentTemplate> buildOverrideSearch(ComponentAssembler assembler, ComponentTemplate template)
- {
+ private List<ComponentTemplate> buildOverrideSearch(ComponentAssembler assembler, ComponentTemplate template) {
List<ComponentTemplate> result = CollectionFactory.newList();
result.add(template);
@@ -397,11 +335,12 @@ public class PageLoaderImpl implements P
ComponentTemplate lastTemplate = template;
- while (lastTemplate.isExtension())
- {
+ while (lastTemplate.isExtension()) {
ComponentModel parentModel = model.getParentModel();
- if (parentModel == null) { throw new RuntimeException(PageloadMessages.noParentForExtension(model)); }
+ if (parentModel == null) {
+ throw new RuntimeException(PageloadMessages.noParentForExtension(model));
+ }
ComponentTemplate parentTemplate = templateSource.getTemplate(parentModel, assembler.getSelector());
@@ -419,19 +358,16 @@ public class PageLoaderImpl implements P
* Push all the tokens onto the stack, in reverse order, so that the last token is deepest and the first token is
* most shallow (first to come off the queue).
*/
- private void pushAll(Stack<TemplateToken> queue, List<TemplateToken> tokens)
- {
+ private void pushAll(Stack<TemplateToken> queue, List<TemplateToken> tokens) {
for (int i = tokens.size() - 1; i >= 0; i--)
queue.push(tokens.get(i));
}
- private void processTemplateToken(AssemblerContext context)
- {
+ private void processTemplateToken(AssemblerContext context) {
// These tokens can appear at the top level, or at lower levels (this method is invoked
// from token-processing loops inside element(), component(), etc.
- switch (context.peekType())
- {
+ switch (context.peekType()) {
case TEXT:
text(context);
@@ -492,20 +428,16 @@ public class PageLoaderImpl implements P
}
}
- private void cdata(AssemblerContext context)
- {
+ private void cdata(AssemblerContext context) {
final CDATAToken token = context.next(CDATAToken.class);
- RenderCommand command = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
+ RenderCommand command = new RenderCommand() {
+ public void render(MarkupWriter writer, RenderQueue queue) {
writer.cdata(token.getContent());
}
@Override
- public String toString()
- {
+ public String toString() {
return String.format("CDATA[%s]", token.getLocation());
}
};
@@ -514,20 +446,16 @@ public class PageLoaderImpl implements P
}
- private void defineNamespacePrefix(AssemblerContext context)
- {
+ private void defineNamespacePrefix(AssemblerContext context) {
final DefineNamespacePrefixToken token = context.next(DefineNamespacePrefixToken.class);
- RenderCommand command = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
+ RenderCommand command = new RenderCommand() {
+ public void render(MarkupWriter writer, RenderQueue queue) {
writer.defineNamespace(token.getNamespaceURI(), token.getNamespacePrefix());
}
@Override
- public String toString()
- {
+ public String toString() {
return String.format("DefineNamespace[%s %s]", token.getNamespacePrefix(), token.getNamespaceURI());
}
};
@@ -535,16 +463,12 @@ public class PageLoaderImpl implements P
context.addComposable(command);
}
- private void dtd(AssemblerContext context)
- {
+ private void dtd(AssemblerContext context) {
final DTDToken token = context.next(DTDToken.class);
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
- if (!pageAssembly.checkAndSetFlag("dtd-page-element-added"))
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
+ if (!pageAssembly.checkAndSetFlag("dtd-page-element-added")) {
RenderCommand command = new DTDPageElement(token.getName(), token.getPublicId(), token
.getSystemId());
@@ -557,29 +481,33 @@ public class PageLoaderImpl implements P
});
}
- private void parameter(AssemblerContext context)
- {
+ private void parameter(AssemblerContext context) {
final ParameterToken token = context.next(ParameterToken.class);
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
String parameterName = token.getName();
ComponentPageElement element = pageAssembly.createdElement.peek();
- BlockImpl block = new BlockImpl(token.getLocation(), interner.format("Parameter %s of %s",
+ Location location = token.getLocation();
+
+ BlockImpl block = new BlockImpl(location, interner.format("Parameter %s of %s",
parameterName, element.getCompleteId()));
- Binding binding = new LiteralBinding(token.getLocation(), "block parameter " + parameterName, block);
+ Binding binding = new LiteralBinding(location, "block parameter " + parameterName, block);
EmbeddedComponentAssembler embeddedAssembler = pageAssembly.embeddedAssembler.peek();
ParameterBinder binder = embeddedAssembler.createParameterBinder(parameterName);
- if (binder == null) { throw new TapestryException(PageloadMessages.parameterNotSupported(
- element.getCompleteId(), parameterName), token.getLocation(), null); }
+ if (binder == null) {
+ throw new UnknownValueException(
+ String.format("Component %s does not include a formal parameter '%s' (and does not support informal parameters).",
+ element.getCompleteId(), parameterName), location,
+ null,
+ new AvailableValues("Formal parameters", embeddedAssembler.getFormalParameterNames()));
+ }
binder.bind(pageAssembly.createdElement.peek(), binding);
@@ -590,14 +518,11 @@ public class PageLoaderImpl implements P
consumeToEndElementAndPopBodyElement(context);
}
- private void block(AssemblerContext context)
- {
+ private void block(AssemblerContext context) {
final BlockToken token = context.next(BlockToken.class);
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
String blockId = token.getId();
ComponentPageElement element = pageAssembly.activeElement.peek();
@@ -618,20 +543,15 @@ public class PageLoaderImpl implements P
consumeToEndElementAndPopBodyElement(context);
}
- private void consumeToEndElementAndPopBodyElement(AssemblerContext context)
- {
- while (true)
- {
- switch (context.peekType())
- {
+ private void consumeToEndElementAndPopBodyElement(AssemblerContext context) {
+ while (true) {
+ switch (context.peekType()) {
case END_ELEMENT:
context.next();
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
pageAssembly.bodyElement.pop();
}
});
@@ -644,8 +564,7 @@ public class PageLoaderImpl implements P
}
}
- private void comment(AssemblerContext context)
- {
+ private void comment(AssemblerContext context) {
CommentToken token = context.next(CommentToken.class);
RenderCommand commentElement = new CommentPageElement(token.getComment());
@@ -653,14 +572,11 @@ public class PageLoaderImpl implements P
context.addComposable(commentElement);
}
- private void component(AssemblerContext context)
- {
+ private void component(AssemblerContext context) {
EmbeddedComponentAssembler embeddedAssembler = startComponent(context);
- while (true)
- {
- switch (context.peekType())
- {
+ while (true) {
+ switch (context.peekType()) {
case ATTRIBUTE:
bindAttributeAsParameter(context, embeddedAssembler);
@@ -681,26 +597,22 @@ public class PageLoaderImpl implements P
}
}
- private void bindAttributeAsParameter(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler)
- {
+ private void bindAttributeAsParameter(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler) {
AttributeToken token = context.next(AttributeToken.class);
addParameterBindingAction(context, embeddedAssembler, token.getName(), token.getValue(),
- BindingConstants.LITERAL, token.getLocation());
+ BindingConstants.LITERAL, token.getLocation(), true);
}
- private void element(AssemblerContext context)
- {
+ private void element(AssemblerContext context) {
StartElementToken token = context.next(StartElementToken.class);
RenderCommand element = new StartElementPageElement(token.getNamespaceURI(), token.getName());
context.addComposable(element);
- while (true)
- {
- switch (context.peekType())
- {
+ while (true) {
+ switch (context.peekType()) {
case ATTRIBUTE:
attribute(context);
break;
@@ -721,8 +633,7 @@ public class PageLoaderImpl implements P
}
- private EmbeddedComponentAssembler startComponent(AssemblerContext context)
- {
+ private EmbeddedComponentAssembler startComponent(AssemblerContext context) {
StartComponentToken token = context.next(StartComponentToken.class);
ComponentAssembler assembler = context.assembler;
@@ -742,12 +653,13 @@ public class PageLoaderImpl implements P
if (embeddedId == null)
embeddedId = assembler.generateEmbeddedId(embeddedType);
- if (embeddedModel != null)
- {
+ if (embeddedModel != null) {
String modelType = embeddedModel.getComponentType();
- if (InternalUtils.isNonBlank(modelType) && embeddedType != null) { throw new TapestryException(
- PageloadMessages.redundantEmbeddedComponentTypes(embeddedId, embeddedType, modelType), token, null); }
+ if (InternalUtils.isNonBlank(modelType) && embeddedType != null) {
+ throw new TapestryException(
+ PageloadMessages.redundantEmbeddedComponentTypes(embeddedId, embeddedType, modelType), token, null);
+ }
embeddedType = modelType;
embeddedComponentClassName = embeddedModel.getComponentClassName();
@@ -758,19 +670,15 @@ public class PageLoaderImpl implements P
// This awkwardness is making me think that the page loader should resolve the component
// type before invoking this method (we would then remove the componentType parameter).
- if (InternalUtils.isNonBlank(embeddedType))
- {
+ if (InternalUtils.isNonBlank(embeddedType)) {
// The type actually overrides the specified class name. The class name is defined
// by the type of the field. In many scenarios, the field type is a common
// interface,
// and the type is used to determine the concrete class to instantiate.
- try
- {
+ try {
componentClassName = componentClassResolver.resolveComponentTypeToClassName(embeddedType);
- }
- catch (RuntimeException ex)
- {
+ } catch (RuntimeException ex) {
throw new TapestryException(ex.getMessage(), token, ex);
}
}
@@ -784,22 +692,17 @@ public class PageLoaderImpl implements P
addParameterBindingActions(context, embeddedAssembler, embeddedModel);
- if (embeddedModel != null && embeddedModel.getInheritInformalParameters())
- {
+ if (embeddedModel != null && embeddedModel.getInheritInformalParameters()) {
// Another two-step: The first "captures" the container and embedded component. The second
// occurs at the end of the page setup.
- assembler.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ assembler.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
final ComponentPageElement container = pageAssembly.activeElement.peek();
final ComponentPageElement embedded = pageAssembly.createdElement.peek();
- pageAssembly.deferred.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ pageAssembly.deferred.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
copyInformalParameters(container, embedded);
}
});
@@ -812,8 +715,7 @@ public class PageLoaderImpl implements P
}
- private void copyInformalParameters(ComponentPageElement container, ComponentPageElement embedded)
- {
+ private void copyInformalParameters(ComponentPageElement container, ComponentPageElement embedded) {
// TODO: Much more, this is an area where we can make things a bit more efficient by tracking
// what has and hasn't been bound in the EmbeddedComponentAssembler (and identifying what is
// and isn't informal).
@@ -822,8 +724,7 @@ public class PageLoaderImpl implements P
Map<String, Binding> informals = container.getInformalParameterBindings();
- for (String name : informals.keySet())
- {
+ for (String name : informals.keySet()) {
if (model.getParameterModel(name) != null)
continue;
@@ -834,41 +735,35 @@ public class PageLoaderImpl implements P
}
private void addParameterBindingActions(AssemblerContext context, EmbeddedComponentAssembler embeddedAssembler,
- EmbeddedComponentModel embeddedModel)
- {
+ EmbeddedComponentModel embeddedModel) {
if (embeddedModel == null)
return;
- for (String parameterName : embeddedModel.getParameterNames())
- {
+ for (String parameterName : embeddedModel.getParameterNames()) {
String parameterValue = embeddedModel.getParameterValue(parameterName);
addParameterBindingAction(context, embeddedAssembler, parameterName, parameterValue, BindingConstants.PROP,
- embeddedModel.getLocation());
+ embeddedModel.getLocation(), false);
}
}
private void addParameterBindingAction(AssemblerContext context,
- final EmbeddedComponentAssembler embeddedAssembler, final String parameterName,
- final String parameterValue, final String metaDefaultBindingPrefix, final Location location)
- {
+ final EmbeddedComponentAssembler embeddedAssembler, final String parameterName,
+ final String parameterValue, final String metaDefaultBindingPrefix, final Location location, final boolean ignoreUnmatchedFormal) {
if (embeddedAssembler.isBound(parameterName))
return;
embeddedAssembler.setBound(parameterName);
- if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX))
- {
+ if (parameterValue.startsWith(InternalConstants.INHERIT_BINDING_PREFIX)) {
String containerParameterName = parameterValue.substring(InternalConstants.INHERIT_BINDING_PREFIX.length());
addInheritedBindingAction(context, parameterName, containerParameterName);
return;
}
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
// Because of published parameters, we have to wait until page assembly time to throw out
// informal parameters bound to components that don't support informal parameters ...
// otherwise we'd throw out (sometimes!) published parameters.
@@ -877,40 +772,48 @@ public class PageLoaderImpl implements P
// Null meaning an informal parameter and the component (and mixins) doesn't support informals.
- if (binder != null)
- {
- final String defaultBindingPrefix = binder.getDefaultBindingPrefix(metaDefaultBindingPrefix);
+ if (binder == null) {
+ if (ignoreUnmatchedFormal) {
+ return;
+ }
- InternalComponentResources containerResources = pageAssembly.activeElement.peek()
- .getComponentResources();
+ throw new UnknownValueException(
+ String.format("Component %s does not include a formal parameter '%s' (and does not support informal parameters).",
+ pageAssembly.createdElement.peek().getCompleteId(), parameterName), null,
+ null,
+ new AvailableValues("Formal parameters", embeddedAssembler.getFormalParameterNames()));
+ }
- ComponentPageElement embeddedElement = pageAssembly.createdElement.peek();
- InternalComponentResources embeddedResources = embeddedElement.getComponentResources();
+ final String defaultBindingPrefix = binder.getDefaultBindingPrefix(metaDefaultBindingPrefix);
- Binding binding = elementFactory.newBinding(parameterName, containerResources, embeddedResources,
- defaultBindingPrefix, parameterValue, location);
+ InternalComponentResources containerResources = pageAssembly.activeElement.peek()
+ .getComponentResources();
- binder.bind(embeddedElement, binding);
- }
+ ComponentPageElement embeddedElement = pageAssembly.createdElement.peek();
+ InternalComponentResources embeddedResources = embeddedElement.getComponentResources();
+
+ Binding binding = elementFactory.newBinding(parameterName, containerResources, embeddedResources,
+ defaultBindingPrefix, parameterValue, location);
+
+ binder.bind(embeddedElement, binding);
}
- });
+ }
+
+ );
}
/**
* Adds a deferred action to the PageAssembly, to handle connecting the embedded components' parameter to the
* container component's parameter once everything else has been built.
- *
+ *
* @param context
* @param parameterName
* @param containerParameterName
*/
private void addInheritedBindingAction(AssemblerContext context, final String parameterName,
- final String containerParameterName)
- {
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ final String containerParameterName) {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
// At the time this action executes, we'll be able to capture the containing and embedded
// component. We can then defer the connection logic until after all other construction.
@@ -919,10 +822,8 @@ public class PageLoaderImpl implements P
// Parameters are normally bound bottom to top. Inherited parameters run differently, and should be
// top to bottom.
- pageAssembly.deferred.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ pageAssembly.deferred.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
connectInheritedParameter(container, embedded, parameterName, containerParameterName);
}
});
@@ -931,8 +832,7 @@ public class PageLoaderImpl implements P
}
private void connectInheritedParameter(ComponentPageElement container, ComponentPageElement embedded,
- String parameterName, String containerParameterName)
- {
+ String parameterName, String containerParameterName) {
// TODO: This assumes that the two parameters are both on the core component and not on
// a mixin. I think this could be improved with more static analysis.
@@ -951,13 +851,10 @@ public class PageLoaderImpl implements P
}
private void addActionForEmbeddedComponent(AssemblerContext context,
- final EmbeddedComponentAssembler embeddedAssembler, final String embeddedId, final String elementName,
- final String componentClassName)
- {
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ final EmbeddedComponentAssembler embeddedAssembler, final String embeddedId, final String elementName,
+ final String componentClassName) {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
pageAssembly.checkForRecursion(componentClassName, embeddedAssembler.getLocation());
ComponentResourceSelector selector = pageAssembly.page.getSelector();
@@ -990,15 +887,13 @@ public class PageLoaderImpl implements P
});
}
- private void attribute(AssemblerContext context)
- {
+ private void attribute(AssemblerContext context) {
final AttributeToken token = context.next(AttributeToken.class);
String value = token.getValue();
// No expansion makes this easier, more efficient.
- if (value.indexOf(InternalConstants.EXPANSION_START) < 0)
- {
+ if (value.indexOf(InternalConstants.EXPANSION_START) < 0) {
RenderCommand command = new RenderAttribute(token);
context.addComposable(command);
@@ -1006,10 +901,8 @@ public class PageLoaderImpl implements P
return;
}
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
InternalComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
RenderCommand command = elementFactory.newAttributeElement(resources, token);
@@ -1019,12 +912,9 @@ public class PageLoaderImpl implements P
});
}
- private void body(AssemblerContext context)
- {
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ private void body(AssemblerContext context) {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
ComponentPageElement element = pageAssembly.activeElement.peek();
pageAssembly.addRenderCommand(new RenderBodyElement(element));
@@ -1032,14 +922,11 @@ public class PageLoaderImpl implements P
});
}
- private void expansion(AssemblerContext context)
- {
+ private void expansion(AssemblerContext context) {
final ExpansionToken token = context.next(ExpansionToken.class);
- context.add(new PageAssemblyAction()
- {
- public void execute(PageAssembly pageAssembly)
- {
+ context.add(new PageAssemblyAction() {
+ public void execute(PageAssembly pageAssembly) {
ComponentResources resources = pageAssembly.activeElement.peek().getComponentResources();
RenderCommand command = elementFactory.newExpansionElement(resources, token);
@@ -1049,8 +936,7 @@ public class PageLoaderImpl implements P
});
}
- private void text(AssemblerContext context)
- {
+ private void text(AssemblerContext context) {
TextToken textToken = context.next(TextToken.class);
context.addComposable(new TextPageElement(textToken.getText()));
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageloadMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageloadMessages.java?rev=1144398&r1=1144397&r2=1144398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageloadMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageloadMessages.java Fri Jul 8 17:35:58 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.
@@ -71,11 +71,6 @@ final class PageloadMessages
return MESSAGES.format("token_not_implemented", type.toString());
}
- public static String parameterNotSupported(String completeId, String parameterName)
- {
- return MESSAGES.format("parameter_not_supported", completeId, parameterName);
- }
-
public static String redundantEmbeddedComponentTypes(String embeddedId, String embeddedType, String modelType)
{
return MESSAGES.format("redundant_embedded_component_types", embeddedId, embeddedType, modelType);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/pageload/PageloadStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/pageload/PageloadStrings.properties?rev=1144398&r1=1144397&r2=1144398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/pageload/PageloadStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/pageload/PageloadStrings.properties Fri Jul 8 17:35:58 2011
@@ -1,5 +1,5 @@
#
-# 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.
@@ -21,7 +21,6 @@ no_more_tokens=No more template tokens.
could_not_find_override=Could not find an override for extension point '%s'.
no_parent_for_extension=Component %s uses an extension template, but does not have a parent component.
token_not_implemented=Not yet implemented: %s
-parameter_not_supported=Component %s does not include a formal parameter '%s' (and does not support informal parameters).
redundant_embedded_component_types=Embedded component '%s' provides a type attribute in the template ('%s') \
as well as in the component class ('%s'). You should not provide a type attribute \
in the template when defining an embedded component within the component class.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy?rev=1144398&r1=1144397&r2=1144398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy Fri Jul 8 17:35:58 2011
@@ -25,7 +25,6 @@ class ParameterTests extends TapestryCor
/**
* https://issues.apache.org/jira/browse/TAP5-1227
*/
-
@Test
void null_bound_to_primitive_field_is_an_error() {
openLinks "Null Bound to Primitive Demo"
@@ -33,4 +32,15 @@ class ParameterTests extends TapestryCor
assertTextPresent "Parameter 'value' of component NullBindingToPrimitive:showint is bound to null. This parameter is not allowed to be null."
}
+ /**
+ * https://issues.apache.org/jira/browse/TAP5-1428
+ */
+ @Test
+ void parameter_specified_with_component_annotation_must_match_a_formal_parameter() {
+ openLinks "Unmatched Formal Parameter with @Component"
+
+ assertTextPresent "Component InvalidFormalParameterDemo:counter does not include a formal parameter 'step' (and does not support informal parameters).",
+ "Formal parameters", "end", "start", "value"
+
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=1144398&r1=1144397&r2=1144398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Fri Jul 8 17:35:58 2011
@@ -30,26 +30,22 @@ import java.util.List;
/**
* Have to start somewhere!
*/
-public class Index
-{
+public class Index {
@Persist(PersistenceConstants.FLASH)
private String alert;
- public static class Item implements Comparable<Item>
- {
+ public static class Item implements Comparable<Item> {
public final String pageName;
public final String label;
public final String description;
- public Item(String pageName, String label, String description)
- {
+ public Item(String pageName, String label, String description) {
this.pageName = pageName;
this.label = label;
this.description = description;
}
- public int compareTo(Item o)
- {
+ public int compareTo(Item o) {
return label.compareTo(o.label);
}
}
@@ -57,6 +53,8 @@ public class Index
private static final List<Item> ITEMS = CollectionFactory
.newList(
+ new Item("InvalidFormalParameterDemo", "Unmatched Formal Parameter with @Component", "Parameters specified with @Component annotation must match formal parameters"),
+
new Item("NullBindingToPrimitive", "Null Bound to Primitive Demo", "Correct exception when a primitive parameter is bound to null"),
new Item("TreeDemo", "Tree Component Demo", "Demo of Tree Component"),
@@ -484,8 +482,7 @@ public class Index
);
- static
- {
+ static {
Collections.sort(ITEMS);
}
@@ -498,39 +495,32 @@ public class Index
@Inject
private ComponentResources resources;
- public List<Item> getItems()
- {
+ public List<Item> getItems() {
return ITEMS;
}
- Object onActionFromSecurePage()
- {
+ Object onActionFromSecurePage() {
return securePage.initialize("Triggered from Index");
}
- public Link getInjectDemoLink()
- {
+ public Link getInjectDemoLink() {
return resources.createPageLink(InjectDemo.class, false);
}
- public List getDemoContext()
- {
+ public List getDemoContext() {
return Arrays.asList(1, 2, 3);
}
/* This will fail, because component classes are not instantiable. */
- public Object onActionFromInstantiatePage()
- {
+ public Object onActionFromInstantiatePage() {
return new Music();
}
- public void setAlert(String alert)
- {
+ public void setAlert(String alert) {
this.alert = alert;
}
- public String getAlert()
- {
+ public String getAlert() {
return alert;
}
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.java?rev=1144398&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.java Fri Jul 8 17:35:58 2011
@@ -0,0 +1,35 @@
+// Copyright 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.
+// 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;
+
+import org.apache.tapestry5.annotations.Component;
+import org.apache.tapestry5.integration.app1.components.Count;
+
+/**
+ * @since 5.3
+ */
+public class InvalidFormalParameterDemo {
+
+ // This has to be done using @Component, because non-matching attributes
+ // in the template are quietly dropped. By placing it here, in the @Component annotation,
+ // there's no ambiguity ... the developer expects there to be a parameter with the given name.
+ @Component(parameters = {
+ "start=5",
+ "end=100",
+ "value=var:index",
+ "step=5" // not a formal parameter
+ })
+ private Count counter;
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.tml?rev=1144398&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/InvalidFormalParameterDemo.tml Fri Jul 8 17:35:58 2011
@@ -0,0 +1,11 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+
+<t:remove>step is not a formal parameter</t:remove>
+<span t:id="counter">
+
+ ... ${var:index}
+
+
+
+</span>
+</html>