Author: hlship
Date: Fri Feb 13 18:18:49 2009
New Revision: 744203
URL: http://svn.apache.org/viewvc?rev=744203&view=rev
Log:
TAP5-95: Optimize page construction for repeated construction of the same page
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssembler.java
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/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssemblyAction.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/ParameterBinder.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderAttribute.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/RenderBodyElement.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStream.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/TokenStreamImpl.java
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PageLoaderImplTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-component-report/src/test/java/org/apache/tapestry/mojo/ComponentReportTest.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Component.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalComponentResourcesCommon.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableEmbeddedComponentModelImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommand.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSource.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentTemplateSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactory.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageElementFactoryImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElement.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/EmbeddedComponentModel.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableEmbeddedComponentModel.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/MarkupUtilsTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/pagelevel/DTDTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/TapestryInternalUtilsTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/beaneditor/BeanModelUtilsTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/PropBindingFactoryTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommandTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetAliasManagerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestPathOptimizerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RequestSecurityManagerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TemplateParserImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/URLEncoderImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/CodeEqTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/test/InternalBaseTestCase.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/json/JSONObjectTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/GlobPatternMatcherTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/util/InternalUtilsTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/services/ClassFabUtilsTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/util/TimeIntervalTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-component-report/src/test/java/org/apache/tapestry/mojo/ComponentReportTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-component-report/src/test/java/org/apache/tapestry/mojo/ComponentReportTest.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-component-report/src/test/java/org/apache/tapestry/mojo/ComponentReportTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-component-report/src/test/java/org/apache/tapestry/mojo/ComponentReportTest.java
Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 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.
@@ -14,26 +14,26 @@
package org.apache.tapestry.mojo;
+import org.apache.maven.doxia.module.xhtml.XhtmlSink;
+import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext;
+import org.apache.maven.model.Model;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.model.Model;
import org.apache.maven.reporting.MavenReportException;
-import org.apache.maven.doxia.module.xhtml.decoration.render.RenderingContext;
-import org.apache.maven.doxia.module.xhtml.XhtmlSink;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
-import org.testng.annotations.Test;
-import org.testng.annotations.DataProvider;
-import org.testng.Assert;
+import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
import org.codehaus.plexus.util.FileUtils;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
+import java.lang.reflect.Field;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.lang.reflect.Field;
/**
* Tests {...@link ComponentReport}.
@@ -42,7 +42,7 @@
{
@Test(dataProvider = "docData")
public void doc_generation(final Map<String, ClassDescription>
javadocResults, String createdFile,
- String tapestryDoc, String[]
expectedSummaryParts, String[] expectedFileParts)
+ String tapestryDoc, String[]
expectedSummaryParts, String[] expectedFileParts)
throws MojoExecutionException, IOException, MavenReportException
{
String tempDir = System.getProperty("java.io.tmpdir");
@@ -79,10 +79,10 @@
try
{
initializeMojo(report, ComponentReport.class,
- "rootPackage", "org.apache.tapestry5.corelib",
- "apidocs", "apidocs",
- "tapestryJavadoc", tapestryDoc,
- "generatedDocsDirectory", tempFolder
+ "rootPackage", "org.apache.tapestry5.corelib",
+ "apidocs", "apidocs",
+ "tapestryJavadoc", tapestryDoc,
+ "generatedDocsDirectory", tempFolder
);
}
catch (NoSuchFieldException e)
@@ -144,24 +144,27 @@
}
}
- @DataProvider(name = "docData")
- private Object[][] testData() {
+ @DataProvider
+ private Object[][] docData()
+ {
return new Object[][] {
{
- javadocDescriptionForForm(),
- "ref/org/apache/tapestry5/corelib/components/Form.xml",
- "http://tapestry.apache.org/tapestry5/apidocs",
- new
String[]{"org.apache.tapestry5.corelib.components.Form"},
- new String[]{"<title>Component Reference:
org.apache.tapestry5.corelib.components.Form</title>",
- "<a
href=\"http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/EventConstants.html#PREPARE\">"}
+ javadocDescriptionForForm(),
+ "ref/org/apache/tapestry5/corelib/components/Form.xml",
+ "http://tapestry.apache.org/tapestry5/apidocs",
+ new String[] {
"org.apache.tapestry5.corelib.components.Form" },
+ new String[] {
+ "<title>Component Reference:
org.apache.tapestry5.corelib.components.Form</title>",
+ "<a
href=\"http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/EventConstants.html#PREPARE\">"
}
},
{
- javadocDescriptionForForm(),
- "ref/org/apache/tapestry5/corelib/components/Form.xml",
- "../apidocs",
- new
String[]{"org.apache.tapestry5.corelib.components.Form"},
- new String[]{"<title>Component Reference:
org.apache.tapestry5.corelib.components.Form</title>",
- "<a
href=\"../../../../../../../apidocs/org/apache/tapestry5/EventConstants.html#PREPARE\">"}
+ javadocDescriptionForForm(),
+ "ref/org/apache/tapestry5/corelib/components/Form.xml",
+ "../apidocs",
+ new String[] {
"org.apache.tapestry5.corelib.components.Form" },
+ new String[] {
+ "<title>Component Reference:
org.apache.tapestry5.corelib.components.Form</title>",
+ "<a
href=\"../../../../../../../apidocs/org/apache/tapestry5/EventConstants.html#PREPARE\">"
}
},
};
@@ -174,15 +177,15 @@
"org.apache.tapestry5.corelib.components.Form",
"java.lang.Object",
"When it renders, it fires a
org.apache.tapestry5.EventConstants#PREPARE_FOR_RENDER\n" +
- " notification, followed by a
org.apache.tapestry5.EventConstants#PREPARE",
+ " notification, followed by a
org.apache.tapestry5.EventConstants#PREPARE",
false
);
ParameterDescription paramDesc = new ParameterDescription(
"validationId", "String", "", "prop", false, false, true,
"Prefix value used when searching for validation messages and
constraints. " +
- "The default is the Form component's\n" +
- " id. This is overriden by
org.apache.tapestry5.corelib.components.BeanEditForm."
+ "The default is the Form component's\n" +
+ " id. This is overriden by
org.apache.tapestry5.corelib.components.BeanEditForm."
);
classDesc.getParameters().put(paramDesc.getName(), paramDesc);
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Component.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Component.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Component.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/annotations/Component.java
Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 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.
@@ -44,11 +44,20 @@
* Parameter bindings for the component. Each value in the array is of the
form "name=value". The value is a binding
* expression, with a default binding prefix of "prop:".
*/
- String[] parameters() default {};
+ String[] parameters() default { };
/**
* If true, then the component will inherit all informal parameters from
its parent component. The default is
* false.
*/
boolean inheritInformalParameters() default false;
+
+ /**
+ * A comma-separated list of parameters of the component that should be
published as parameters of the containing
+ * component. Binding the parameter of the outer component will bind the
inner component's parameter, as with the
+ * "inhert:" binding prefix.
+ *
+ * @since 5.1.0.0
+ */
+ String publishParameters() default "";
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalComponentResourcesCommon.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalComponentResourcesCommon.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalComponentResourcesCommon.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalComponentResourcesCommon.java
Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 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.
@@ -40,6 +40,15 @@
void bindParameter(String parameterName, Binding binding);
/**
+ * Returns the binding for the given parameter name, or null.
+ *
+ * @param parameterName name of component parameter
+ * @return binding if bound, or null
+ * @since 5.1.0.0
+ */
+ Binding getBinding(String parameterName);
+
+ /**
* Returns the mixin instance for the fully qualfied mixin class name.
*
* @param mixinClassName fully qualified class name
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
Fri Feb 13 18:18:49 2009
@@ -110,4 +110,12 @@
* @since 5.1.0.0
*/
public static final String GZIP_CONTENT_ENCODING = "gzip";
+ /**
+ * Identifies the start of an expansion inside a template.
+ */
+ public static final String EXPANSION_START = "${";
+ /**
+ * Special prefix for parameters that are inherited from named parameters
of their container.
+ */
+ public static final String INHERIT_BINDING_PREFIX = "inherit:";
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
Fri Feb 13 18:18:49 2009
@@ -383,13 +383,16 @@
}
/**
- * Splits a value around commas.
+ * Splits a value around commas. Whitespace around the commas is removed,
as is leading and trailing whitespace.
*
* @since 5.1.0.0
*/
public static String[] splitAtCommas(String value)
{
- return COMMA_PATTERN.split(value);
+ if (value == null)
+ return new String[0];
+
+ return COMMA_PATTERN.split(value.trim());
}
/**
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableEmbeddedComponentModelImpl.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableEmbeddedComponentModelImpl.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableEmbeddedComponentModelImpl.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableEmbeddedComponentModelImpl.java
Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 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.
@@ -17,6 +17,7 @@
import org.apache.tapestry5.ioc.BaseLocatable;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.model.MutableEmbeddedComponentModel;
@@ -38,6 +39,8 @@
private Map<String, String> parameters;
+ private List<String> publishedParameters = Collections.emptyList();
+
/**
* List of mixin class names.
*/
@@ -122,4 +125,16 @@
{
return inheritInformalParameters;
}
+
+ public void setPublishedParameters(List<String> parameterNames)
+ {
+ Defense.notNull(parameterNames, "parameterNames");
+
+ publishedParameters = parameterNames;
+ }
+
+ public List<String> getPublishedParameters()
+ {
+ return publishedParameters;
+ }
}
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssembler.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssembler.java?rev=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssembler.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssembler.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,73 @@
+// 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.internal.pageload;
+
+import org.apache.tapestry5.internal.parser.ComponentTemplate;
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
+import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.model.ComponentModel;
+
+/**
+ * Encapsulates a series of actions that are used to assemble a new page
instance (or a comoponent within the page).
+ */
+interface ComponentAssembler
+{
+ /**
+ * The model defining the component assembled by this assembler.
+ */
+ ComponentModel getModel();
+
+ /**
+ * Assembles and returns page's root component
+ *
+ * @param page to assemble
+ */
+ ComponentPageElement assembleRootComponent(Page page);
+
+ /**
+ * Assembles a component embedded within another component, leaving the
new component on the {...@link
+ * org.apache.tapestry5.internal.pageload.PageAssembly#createdElement}
stack.
+ *
+ * @param pageAssembly holds dynamic state while assembling the comopnent
+ * @param embeddedId the unique id for the component within its container
+ * @param elementName element name in the template for the component (or
null if defined via a Tapestry namespaced
+ * element)
+ * @param location location of the embedded component in its
container's template
+ */
+ void assembleEmbeddedComponent(PageAssembly pageAssembly, String
embeddedId, String elementName,
+ Location location);
+
+ /**
+ * Adds a page assembly action for this component
+ *
+ * @param action to be performed when assembling a page
+ */
+ void add(PageAssemblyAction action);
+
+ /**
+ * Validates that all component ids defined by the model are accounted for
in the template. In addition, takes care
+ * of id pre-allocation.
+ */
+ void validateEmbeddedIds(ComponentTemplate template);
+
+ /**
+ * Generates an id for an otherwise anonymous component, based on the
component's type.
+ *
+ * @param componentType
+ * @return unique id based on the type
+ */
+ String generateEmbeddedId(String componentType);
+}
Added:
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=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,200 @@
+// 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.internal.pageload;
+
+import org.apache.tapestry5.internal.parser.ComponentTemplate;
+import org.apache.tapestry5.internal.services.Instantiator;
+import org.apache.tapestry5.internal.structure.*;
+import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.IdAllocator;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.model.ComponentModel;
+import org.apache.tapestry5.runtime.RenderCommand;
+
+import java.util.List;
+import java.util.Map;
+
+class ComponentAssemblerImpl implements ComponentAssembler
+{
+ private final Instantiator instantiator;
+
+ private final ComponentPageElementResources resources;
+
+ private final List<PageAssemblyAction> actions =
CollectionFactory.newList();
+
+ private final IdAllocator allocator = new IdAllocator();
+
+ public ComponentAssemblerImpl(Instantiator instantiator,
ComponentPageElementResources resources)
+ {
+ this.instantiator = instantiator;
+ this.resources = resources;
+ }
+
+ public ComponentPageElement assembleRootComponent(Page page)
+ {
+ PageAssembly pageAssembly = new PageAssembly(page);
+
+ try
+ {
+ ComponentPageElement newElement = new
ComponentPageElementImpl(pageAssembly.page, instantiator, resources);
+
+ buildRecursively(pageAssembly, newElement);
+
+ for (PageAssemblyAction action : pageAssembly.deferred)
+ {
+ action.execute(pageAssembly);
+ }
+
+ return pageAssembly.createdElement.peek();
+ }
+ catch (RuntimeException ex)
+ {
+ throw new RuntimeException(String.format("Exception assembling
root component of page %s: %s",
+
pageAssembly.page.getLogicalName(),
+
InternalUtils.toMessage(ex)),
+ ex);
+ }
+ }
+
+ public void assembleEmbeddedComponent(PageAssembly pageAssembly, String
embeddedId, String elementName,
+ Location location)
+ {
+ ComponentPageElement container = pageAssembly.activeElement.peek();
+
+ try
+ {
+ ComponentPageElement newElement = container.newChild(embeddedId,
elementName, instantiator, location);
+
+ buildRecursively(pageAssembly, newElement);
+ }
+ catch (RuntimeException ex)
+ {
+ String message = String.format("Exception assembling embedded
component '%s' (of type %s, within %s): %s",
+ embeddedId,
+
instantiator.getModel().getComponentClassName(),
+ container.getCompleteId(),
+ InternalUtils.toMessage(ex));
+
+ throw new TapestryException(message, location, ex);
+ }
+ }
+
+ private void buildRecursively(PageAssembly pageAssembly,
ComponentPageElement newElement)
+ {
+ pageAssembly.page.addLifecycleListener(newElement);
+
+ pushNewElement(pageAssembly, newElement);
+
+ runActions(pageAssembly);
+
+ popNewElement(pageAssembly);
+ }
+
+ private void pushNewElement(PageAssembly pageAssembly, final
ComponentPageElement componentElement)
+ {
+ // This gets popped after all actions have executed.
+ pageAssembly.activeElement.push(componentElement);
+
+ // The container pops this one.
+ pageAssembly.createdElement.push(componentElement);
+
+ BodyPageElement shunt = new BodyPageElement()
+ {
+ public void addToBody(RenderCommand element)
+ {
+ componentElement.addToTemplate(element);
+ }
+ };
+
+ pageAssembly.bodyElement.push(shunt);
+ }
+
+ private void popNewElement(PageAssembly pageAssembly)
+ {
+ pageAssembly.bodyElement.pop();
+ pageAssembly.activeElement.pop();
+
+ // But the component itself stays on the createdElement stack!
+ }
+
+ private void runActions(PageAssembly pageAssembly)
+ {
+ for (PageAssemblyAction action : actions)
+ action.execute(pageAssembly);
+ }
+
+ public ComponentModel getModel()
+ {
+ return instantiator.getModel();
+ }
+
+ public void add(PageAssemblyAction action)
+ {
+ actions.add(action);
+ }
+
+
+ public void validateEmbeddedIds(ComponentTemplate template)
+ {
+ Map<String, Boolean> embeddedIds =
CollectionFactory.newCaseInsensitiveMap();
+
+ for (String id : getModel().getEmbeddedComponentIds())
+ embeddedIds.put(id, true);
+
+ for (String id : template.getComponentIds().keySet())
+ {
+ allocator.allocateId(id);
+ embeddedIds.remove(id);
+ }
+
+ if (!embeddedIds.isEmpty())
+ {
+
+ String className = getModel().getComponentClassName();
+
+ throw new RuntimeException(
+ String.format(
+ "Embedded component(s) %s are defined within
component class %s (or a super-class of %s), " +
+ "but are not present in the component
template (%s).",
+ InternalUtils.joinSorted(embeddedIds.keySet()),
+ className,
+ InternalUtils.lastTerm(className),
+ template.getResource()));
+ }
+ }
+
+ public String generateEmbeddedId(String componentType)
+ {
+ // Component types may be in folders; strip off the folder part for
starters.
+
+ int slashx = componentType.lastIndexOf("/");
+
+ String baseId = componentType.substring(slashx + 1).toLowerCase();
+
+ // The idAllocator is pre-loaded with all the component ids from the
template, so even
+ // if the lower-case type matches the id of an existing component,
there won't be a name
+ // collision.
+
+ return allocator.allocateId(baseId);
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("ComponentAssembler[%s]",
instantiator.getModel().getComponentClassName());
+ }
+}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommand.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommand.java?rev=744203&r1=744202&r2=744203&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommand.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/CompositeRenderCommand.java
Fri Feb 13 18:18:49 2009
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 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.
@@ -23,11 +23,11 @@
* A RenderCommand wrapper that renders internally a series of render
commands. This is intended for static content
* (commands that may write content, but won't affect the render queue itself.
*/
-public class CompositeRenderCommand implements RenderCommand
+class CompositeRenderCommand implements RenderCommand
{
/**
* Composite commands are intended for static elements; elements that
won't invoke methods on the RenderQueue. To
- * enforce this, we have a NO-OP version of RenderQueue that is passed ot
the composed render commands.
+ * enforce this, we have a NO-OP version of RenderQueue that is passed to
the composed render commands.
*/
private static final RenderQueue NOOP = new RenderQueue()
{
Added:
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=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssembler.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,63 @@
+// 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.internal.pageload;
+
+import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.model.ComponentModel;
+
+/**
+ * Encapsulates logic related to assembling an embedded component within a
{...@link org.apache.tapestry5.internal.pageload.ComponentAssembler}.
+ */
+interface EmbeddedComponentAssembler
+{
+ void addInstanceMixin(ComponentModel mixinModel);
+
+ /**
+ * 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
+ * the latter case, the mixinId is validated (to ensure it exists).
+ * <p/>
+ * If the name of the parameter does not match a formal parameter of the
component (or mixin) and the component (or
+ * mixin) does not support informal parameters, then null is returned.
+ *
+ * @param parameterName simple or qualified parameter name
+ * @param parameterValue value of parameter (possibly having a
binding prefix)
+ * @param defaultBindingPrefix default binding prefix to use if the
parameter is informal
+ * @return object that can bind the parameter once the container and
component have been instantiated, or null
+ */
+ ParameterBinder createBinder(String parameterName, String parameterValue,
String defaultBindingPrefix);
+
+ /**
+ * Creates a ParameterBinding where the binding is already instantiated.
Follows the same logic as {...@link
+ * #createBinder(String, String, String)} in terms of finding the correct
mixin and parameter name.
+ *
+ * @param parameterName simple or qualified parameter name
+ * @param binding binding for parameter
+ * @return object that can perform the binding, or null
+ */
+ ParameterBinder createBinder(String parameterName, Binding binding);
+
+ /**
+ * Checks to see if the parameter name has been bound.
+ */
+ boolean isBound(String parameterName);
+
+ /**
+ * Marks the parameter name as bound. This is necessary to keep template
bindings from overriding bindings in the
+ * {...@link org.apache.tapestry5.annotations.Component} annotation (even
inherited bindings).
+ */
+ void setBound(String parameterName);
+}
Added:
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=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/EmbeddedComponentAssemblerImpl.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,236 @@
+// 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.internal.pageload;
+
+import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.internal.services.ComponentInstantiatorSource;
+import org.apache.tapestry5.internal.services.PageElementFactory;
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
+import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.TapestryException;
+import org.apache.tapestry5.model.ComponentModel;
+import org.apache.tapestry5.model.ParameterModel;
+
+import java.util.Map;
+
+public class EmbeddedComponentAssemblerImpl implements
EmbeddedComponentAssembler
+{
+ private final Map<String, ComponentModel> mixinIdToComponentModel =
CollectionFactory.newCaseInsensitiveMap();
+
+ private final ComponentInstantiatorSource instantiatorSource;
+
+ private final ComponentModel componentModel;
+
+ private final PageElementFactory elementFactory;
+
+ private final Location location;
+
+ private Map<String, Boolean> bound;
+
+ interface BindingCreator
+ {
+ Binding newBinding(String parameterName, ComponentResources
loadingComponentResources,
+ ComponentResources embeddedComponentResources,
String defaultBindingPrefix);
+ }
+
+ public EmbeddedComponentAssemblerImpl(ComponentInstantiatorSource
instantiatorSource,
+ PageElementFactory elementFactory,
+ String componentClassName,
+ Location location)
+ {
+ this.instantiatorSource = instantiatorSource;
+ this.elementFactory = elementFactory;
+ this.location = location;
+
+ componentModel = getModel(componentClassName);
+
+ // Add the implementation mixins defined by the component model.
+
+ for (String className : componentModel.getMixinClassNames())
+ {
+ addInstanceMixin(getModel(className));
+ }
+
+ // Instance mixins will be added later.
+ }
+
+ private ComponentModel getModel(String className)
+ {
+ return instantiatorSource.getInstantiator(className).getModel();
+ }
+
+ public void addInstanceMixin(ComponentModel mixinModel)
+ {
+ String mixinId =
InternalUtils.lastTerm(mixinModel.getComponentClassName());
+
+ // TODO: Check for conflicts here?
+
+ mixinIdToComponentModel.put(mixinId, mixinModel);
+ }
+
+ public ParameterBinder createBinder(String parameterName, final String
parameterValue, String defaultBindingPrefix)
+ {
+ BindingCreator creator = new BindingCreator()
+ {
+ public Binding newBinding(String parameterName, ComponentResources
loadingComponentResources,
+ ComponentResources
embeddedComponentResources, String defaultBindingPrefix)
+ {
+ return elementFactory.newBinding(parameterName,
loadingComponentResources, embeddedComponentResources,
+ defaultBindingPrefix,
parameterValue, location);
+ }
+ };
+
+
+ return createBinder(parameterName, defaultBindingPrefix, creator);
+ }
+
+ public ParameterBinder createBinder(String parameterName, final Binding
binding)
+ {
+ BindingCreator creator = new BindingCreator()
+ {
+ public Binding newBinding(String parameterName, ComponentResources
loadingComponentResources,
+ ComponentResources
embeddedComponentResources, String defaultBindingPrefix)
+ {
+ return binding;
+ }
+ };
+
+ return createBinder(parameterName, null, creator);
+ }
+
+
+ private ParameterBinder createBinder(String parameterName, String
defaultBindingPrefix,
+ BindingCreator creator)
+ {
+ int dotx = parameterName.indexOf('.');
+
+ if (dotx > 0)
+ return createQualifiedParameterBinder(parameterName.substring(0,
dotx),
+ parameterName.substring(dotx
+ 1),
+ defaultBindingPrefix,
+ creator);
+
+ // OK, see if its a parameter of the component (that takes precedence).
+
+ ParameterModel pmodel =
componentModel.getParameterModel(parameterName);
+
+ if (pmodel != null)
+ return createBinder(null, parameterName,
pmodel.getDefaultBindingPrefix(), creator);
+
+ String informalMixinId = null;
+
+ for (Map.Entry<String, ComponentModel> me :
mixinIdToComponentModel.entrySet())
+ {
+ String mixinId = me.getKey();
+ ComponentModel model = me.getValue();
+
+ if (informalMixinId == null &&
model.getSupportsInformalParameters())
+ informalMixinId = mixinId;
+
+ pmodel = model.getParameterModel(parameterName);
+
+ if (pmodel != null)
+ return createBinder(mixinId, parameterName,
pmodel.getDefaultBindingPrefix(), creator);
+ }
+
+ // OK, it doesn't match any formal parameter of the component or any
mixin.
+
+ // If neither the component nor any of its mixins supports informal
parameters,
+ // then return null to ignore the parameter.
+
+ if (informalMixinId == null &&
!componentModel.getSupportsInformalParameters()) return null;
+
+ // Add as an informal parameter either to a mixin (if an mixin
supprting informatl parameters
+ // was found) or to the component itself (otherwise).
+
+ return createBinder(informalMixinId, parameterName,
defaultBindingPrefix, creator);
+ }
+
+ private ParameterBinder createQualifiedParameterBinder(String mixinId,
String parameterName,
+ String
defaultBindingPrefix,
+ BindingCreator
creator)
+ {
+ ComponentModel mixinModel = mixinIdToComponentModel.get(mixinId);
+
+ if (mixinModel == null)
+ {
+ String message = String.format(
+ "Parameter '%s.%s' does not match any defined mixins for
this component. Available mixins: %s.",
+ mixinId, parameterName,
+ InternalUtils.sortedKeys(mixinIdToComponentModel));
+
+ throw new TapestryException(message, location, null);
+ }
+
+ return createBinder(mixinId, mixinModel, parameterName,
defaultBindingPrefix, creator);
+ }
+
+ private ParameterBinder createBinder(String mixinId,
+ ComponentModel model,
+ String parameterName,
+ String defaultBindingPrefix,
+ BindingCreator creator)
+ {
+ ParameterModel pmodel = model.getParameterModel(parameterName);
+
+ // Ignore informal parameters for mixins that don't support them.
+
+ if (pmodel == null && !model.getSupportsInformalParameters())
+ return null;
+
+ final String bindingPrefix = pmodel == null ? defaultBindingPrefix :
pmodel.getDefaultBindingPrefix();
+
+ return createBinder(mixinId, parameterName, bindingPrefix, creator);
+ }
+
+ private ParameterBinder createBinder(final String mixinId,
+ final String parameterName,
+ final String defaultBindingPrefix,
+ final BindingCreator creator)
+ {
+ return new ParameterBinder()
+ {
+ public void bind(ComponentPageElement container,
ComponentPageElement embedded)
+ {
+ Binding binding =
+ creator.newBinding(parameterName,
+ container.getComponentResources(),
+ embedded.getComponentResources(),
+ defaultBindingPrefix);
+
+ if (mixinId == null)
+ embedded.bindParameter(parameterName, binding);
+ else
+ embedded.bindMixinParameter(mixinId, parameterName,
binding);
+ }
+ };
+ }
+
+ public boolean isBound(String parameterName)
+ {
+ return InternalUtils.get(bound, parameterName) != null;
+ }
+
+ public void setBound(String parameterName)
+ {
+ if (bound == null)
+ bound = CollectionFactory.newCaseInsensitiveMap();
+
+ bound.put(parameterName, true);
+ }
+}
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java?rev=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,116 @@
+// 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.internal.pageload;
+
+import org.apache.tapestry5.internal.structure.BodyPageElement;
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
+import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.util.Stack;
+import org.apache.tapestry5.runtime.RenderCommand;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Mutable data used when {...@link
org.apache.tapestry5.internal.pageload.ComponentAssembler}s are assembling a
page
+ * instance.
+ */
+class PageAssembly
+{
+ public final Page page;
+
+ public final Stack<ComponentPageElement> activeElement =
CollectionFactory.newStack();
+
+ public final Stack<BodyPageElement> bodyElement =
CollectionFactory.newStack();
+
+ public final Stack<ComponentPageElement> createdElement =
CollectionFactory.newStack();
+
+ public final Stack<EmbeddedComponentAssembler> embeddedAssembler =
CollectionFactory.newStack();
+
+ public final List<PageAssemblyAction> deferred =
CollectionFactory.newList();
+
+ private final List<RenderCommand> composableRenderCommands =
CollectionFactory.newList();
+
+ private final Set<String> flags = CollectionFactory.newSet();
+
+ PageAssembly(Page page)
+ {
+ this.page = page;
+ }
+
+ /**
+ * Adds the command to the top element of the {...@link #bodyElement}
stack. {...@linkplain
+ * #flushComposableRenderCommands() Flushes} composable render commands
first.
+ *
+ * @param command
+ */
+ public void addRenderCommand(RenderCommand command)
+ {
+ flushComposableRenderCommands();
+
+ bodyElement.peek().addToBody(command);
+ }
+
+ /**
+ * Adds the command to the list of composable commands. Composable
commands are added to the top element of the body
+ * element stack when {...@linkplain #flushComposableRenderCommands()
flushed}.
+ *
+ * @param command
+ */
+ public void addComposableRenderCommand(RenderCommand command)
+ {
+ composableRenderCommands.add(command);
+ }
+
+ /**
+ * Adds any composed render commands to the top element of the bodyElement
stack. Render commands may be combined as
+ * a {...@link
org.apache.tapestry5.internal.pageload.CompositeRenderCommand}.
+ */
+ public void flushComposableRenderCommands()
+ {
+ int count = composableRenderCommands.size();
+
+ switch (count)
+ {
+ case 0:
+ break;
+
+ case 1:
+ bodyElement.peek().addToBody(composableRenderCommands.get(0));
+ break;
+
+ default:
+ RenderCommand[] commands =
composableRenderCommands.toArray(new RenderCommand[count]);
+
+ bodyElement.peek().addToBody(new
CompositeRenderCommand(commands));
+ break;
+ }
+
+ composableRenderCommands.clear();
+ }
+
+ public boolean checkAndSetFlag(String flagName)
+ {
+ boolean result = flags.contains(flagName);
+
+ if (!result)
+ flags.add(flagName);
+
+ return result;
+ }
+}
+
+
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssemblyAction.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssemblyAction.java?rev=744203&view=auto
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssemblyAction.java
(added)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssemblyAction.java
Fri Feb 13 18:18:49 2009
@@ -0,0 +1,25 @@
+// 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.internal.pageload;
+
+interface PageAssemblyAction
+{
+ /**
+ * Execute some action related to assembling a page.
+ *
+ * @param pageAssembly identifies the page being assembled
+ */
+ void execute(PageAssembly pageAssembly);
+}