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 2007/01/11 05:45:05 UTC
svn commit: r495111 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/internal/
main/java/org/apache/tapestry/internal/services/
main/java/org/apache/tapestry/internal/structure/
main/java/org/apache/tapestry/runtime/ main...
Author: hlship
Date: Wed Jan 10 20:45:04 2007
New Revision: 495111
URL: http://svn.apache.org/viewvc?view=rev&rev=495111
Log:
Add support for render phase methods returning component instances (which are then rendered).
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderCommandWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Render.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResourcesCommon.java Wed Jan 10 20:45:04 2007
@@ -12,61 +12,65 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal;
-
+package org.apache.tapestry.internal;
+
import org.apache.tapestry.Binding;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.services.PersistentFieldManager;
-
-/**
- * Operations shared by {@link InternalComponentResources} and {@link ComponentPageElement}.
- * Typically, these means methods of InternalComponentResources that are delegated to the component
- * page element.
- */
-public interface InternalComponentResourcesCommon
-{
- /**
- * Get the current persisted value of the field.
- *
- * @param fieldName
- * the name of the field to access
- * @return the value stored for the field, or null if no value is currently stored
- */
- Object getFieldChange(String fieldName);
-
- /**
- * Posts a change to a persistent field. If the component is still loading, then this change is
- * ignored. Otherwise, it is propogated, via the
- * {@link Page#persistFieldChange(org.apache.tapestry.internal.structure.ComponentPageElement, String, Object) page}
- * to the {@link PersistentFieldManager}.
- */
- void persistFieldChange(String fieldName, Object newValue);
-
- /** Checks to see if there is a value stored for the indicated field. */
- boolean hasFieldChange(String fieldName);
-
- /**
- * Returns true if the component has finished loading. Initially, this value will be false.
- *
- * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()
- */
- boolean isLoaded();
-
- /**
- * Used during construction of the page to identify the binding for a particular parameter.
- * <p>
- * TODO: Would prefer to move this to a sub-interface, say "MutableInternalComponentResources".
- */
- void addParameter(String parameterName, Binding binding);
-
- /**
- * Returns the mixin instance for the fully qualfied mixin class name.
- *
- * @param mixinClassName
- * fully qualified class name
- * @return IllegalArgumentException if no such mixin is associated with the core component
- */
- Component getMixinByClassName(String mixinClassName);
-}
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.PersistentFieldManager;
+
+/**
+ * Operations shared by {@link InternalComponentResources} and {@link ComponentPageElement}.
+ * Typically, these means methods of InternalComponentResources that are delegated to the component
+ * page element.
+ */
+public interface InternalComponentResourcesCommon
+{
+ /**
+ * Get the current persisted value of the field.
+ *
+ * @param fieldName
+ * the name of the field to access
+ * @return the value stored for the field, or null if no value is currently stored
+ */
+ Object getFieldChange(String fieldName);
+
+ /**
+ * Posts a change to a persistent field. If the component is still loading, then this change is
+ * ignored. Otherwise, it is propogated, via the
+ * {@link Page#persistFieldChange(org.apache.tapestry.internal.structure.ComponentPageElement, String, Object) page}
+ * to the {@link PersistentFieldManager}.
+ */
+ void persistFieldChange(String fieldName, Object newValue);
+
+ /** Checks to see if there is a value stored for the indicated field. */
+ boolean hasFieldChange(String fieldName);
+
+ /**
+ * Returns true if the component has finished loading. Initially, this value will be false.
+ *
+ * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()
+ */
+ boolean isLoaded();
+
+ /**
+ * Used during construction of the page to identify the binding for a particular parameter.
+ * <p>
+ * TODO: Would prefer to move this to a sub-interface, say "MutableInternalComponentResources".
+ */
+ void addParameter(String parameterName, Binding binding);
+
+ /**
+ * Returns the mixin instance for the fully qualfied mixin class name.
+ *
+ * @param mixinClassName
+ * fully qualified class name
+ * @return IllegalArgumentException if no such mixin is associated with the core component
+ */
+ Component getMixinByClassName(String mixinClassName);
+
+ /** Invoked to make the receiver queue itself to be rendered. */
+ void queueRender(RenderQueue queue);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/EventImpl.java Wed Jan 10 20:45:04 2007
@@ -1,3 +1,17 @@
+// Copyright 2007 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.tapestry.internal.services;
import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderCommandWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderCommandWorker.java?view=auto&rev=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderCommandWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RenderCommandWorker.java Wed Jan 10 20:45:04 2007
@@ -0,0 +1,51 @@
+// Copyright 2007 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.tapestry.internal.services;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.InternalComponentResourcesCommon;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.MethodSignature;
+
+/**
+ * Ensures that all components implement {@link RenderCommand} by delegating to
+ * {@link InternalComponentResourcesCommon#queueRender(org.apache.tapestry.runtime.RenderQueue)}.
+ */
+public class RenderCommandWorker implements ComponentClassTransformWorker
+{
+ private final MethodSignature RENDER_SIGNATURE = new MethodSignature(Modifier.PUBLIC, "void",
+ "render", new String[]
+ { MarkupWriter.class.getName(), RenderQueue.class.getName() }, null);
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ // Subclasses don't need to bother, they'll inherit from super-classes.
+
+ if (model.getParentModel() != null)
+ return;
+
+ transformation.addImplementedInterface(RenderCommand.class);
+
+ String body = String.format("%s.queueRender($2);", transformation.getResourcesFieldName());
+
+ transformation.addMethod(RENDER_SIGNATURE, body);
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Wed Jan 10 20:45:04 2007
@@ -115,6 +115,8 @@
{
private boolean _result;
+ private List<RenderCommand> _commands;
+
public RenderPhaseEventHandler(boolean defaultResult)
{
_result = defaultResult;
@@ -130,15 +132,38 @@
if (result instanceof Boolean)
{
_result = (Boolean) result;
+ return true; // abort other handler methods
}
- else
+
+ if (result instanceof RenderCommand)
{
- throw new TapestryException(StructureMessages.wrongEventResultType(
- methodDescription,
- Boolean.class), component, null);
+ RenderCommand command = (RenderCommand) result;
+
+ add(command);
+
+ return false; // do not abort!
}
- return true; // Abort the event
+ throw new TapestryException(StructureMessages.wrongEventResultType(
+ methodDescription,
+ Boolean.class), component, null);
+ }
+
+ private void add(RenderCommand command)
+ {
+ if (_commands == null)
+ _commands = newList();
+
+ _commands.add(command);
+ }
+
+ public void queueCommands(RenderQueue queue)
+ {
+ if (_commands == null)
+ return;
+
+ for (RenderCommand command : _commands)
+ queue.push(command);
}
};
@@ -161,6 +186,8 @@
if (handler.getResult())
queue.push(_beginRender);
+
+ handler.queueCommands(queue);
}
@Override
@@ -189,6 +216,8 @@
if (handler.getResult())
queue.push(_beforeRenderBody);
+
+ handler.queueCommands(queue);
}
@Override
@@ -217,6 +246,8 @@
if (handler.getResult())
queue.push(_beforeRenderTemplate);
+
+ handler.queueCommands(queue);
}
@Override
@@ -247,6 +278,8 @@
if (handler.getResult())
pushElements(queue, _body);
+
+ handler.queueCommands(queue);
}
@Override
@@ -277,6 +310,8 @@
if (handler.getResult())
pushElements(queue, _template);
+
+ handler.queueCommands(queue);
}
@Override
@@ -313,6 +348,7 @@
queue.push(_beforeRenderTemplate);
}
+ handler.queueCommands(queue);
}
@Override
@@ -362,6 +398,7 @@
_page.decrementDirtyCount();
}
+ handler.queueCommands(queue);
}
@Override
@@ -394,8 +431,6 @@
private boolean _loaded;
- private final Log _log;
-
/** Map from mixin name to resources for the mixin. Created when first mixin is added. */
private Map<String, InternalComponentResources> _mixinsByShortName;
@@ -428,6 +463,8 @@
if (handler.getResult())
queue.push(_beginRender);
+
+ handler.queueCommands(queue);
}
@Override
@@ -437,6 +474,9 @@
}
};
+ // We know that, at the very least, there will be an element to force the component to render its body,
+ // so there's no reason to wait to initialize the list.
+
private final List<PageElement> _template = newList();
private final TypeCoercer _typeCoercer;
@@ -471,15 +511,12 @@
{
super(location);
- ComponentModel model = instantiator.getModel();
-
_page = page;
_container = container;
_id = id;
_elementName = elementName;
_typeCoercer = typeCoercer;
_messagesSource = messagesSource;
- _log = model.getLog();
_coreResources = new InternalComponentResourcesImpl(this, instantiator, _typeCoercer,
_messagesSource);
@@ -900,6 +937,9 @@
/** Pushes the SetupRender phase state onto the queue. */
public final void render(MarkupWriter writer, RenderQueue queue)
{
+ // TODO: An error if the _render flag is already set (recursive rendering not
+ // allowed or advisable).
+
// Once we start rendering, the page is considered dirty, until we cleanup post render.
_page.incrementDirtyCount();
@@ -963,6 +1003,11 @@
public String getElementName()
{
return _elementName;
+ }
+
+ public void queueRender(RenderQueue queue)
+ {
+ queue.push(this);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Wed Jan 10 20:45:04 2007
@@ -33,6 +33,7 @@
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.model.ComponentModel;
import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderQueue;
import org.apache.tapestry.services.ComponentMessagesSource;
/**
@@ -285,6 +286,11 @@
public String getElementName()
{
return _element.getElementName();
+ }
+
+ public void queueRender(RenderQueue queue)
+ {
+ _element.queueRender(queue);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Event.java Wed Jan 10 20:45:04 2007
@@ -1,3 +1,17 @@
+// Copyright 2007 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.tapestry.runtime;
import org.apache.tapestry.ComponentEventHandler;
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Wed Jan 10 20:45:04 2007
@@ -98,6 +98,7 @@
import org.apache.tapestry.internal.services.ParameterWorker;
import org.apache.tapestry.internal.services.PersistWorker;
import org.apache.tapestry.internal.services.PersistentFieldManagerImpl;
+import org.apache.tapestry.internal.services.RenderCommandWorker;
import org.apache.tapestry.internal.services.RequestGlobalsImpl;
import org.apache.tapestry.internal.services.RequestImpl;
import org.apache.tapestry.internal.services.RequestPageCache;
@@ -142,6 +143,7 @@
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.ioc.util.StrategyRegistry;
import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
import org.apache.tapestry.translator.IntegerTranslator;
import org.apache.tapestry.translator.StringTranslator;
import org.apache.tapestry.validator.Required;
@@ -630,6 +632,7 @@
* <li>SupportsInformalParameters -- checks for the annotation</li>
* <li>UnclaimedField -- identifies unclaimed fields and resets them to null/0/false at the end
* of the request</li>
+ * <li>RenderCommand -- ensures all components also implement {@link RenderCommand}</li>
* <li>SetupRender, BeginRender, etc. -- correspond to component render phases and annotations</li>
* </ul>
*/
@@ -662,6 +665,7 @@
configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
configuration.add("InjectPage", new InjectPageWorker(requestPageCache));
configuration.add("InjectComponent", new InjectComponentWorker());
+ configuration.add("RenderCommand", new RenderCommandWorker());
// Default values for parameters are often some form of injection, so make sure
// that Parameter fields are processed after injections.
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/rendering.apt Wed Jan 10 20:45:04 2007
@@ -263,6 +263,23 @@
to some eyes, more descriptive).
You can, of course, mix and match, using specifically named render phase methods in some cases, and annotated render phase methods in other cases.
+
+Rendering Components
+
+ Instead of returning true or false, a render phase method may return a component. The component may have been injected via the
+ {{{.../apidocs/org/apache/tapestry/annotations/Component.html}Component}} annotation, or may have been passed to the
+ as a parameter.
+
+ In any case, returning a component will queue that component to be rendered <<before>> the active component continues rendering.
+
+ The component to render may even be from a completely different page of the application.
+
+ Recursive rendering of components is not allowed.
+
+ This technique allows the rendering of Tapestry pages to be <highly> dynamic.
+
+ Returning a component instance does <<not>> short circuit method invocation, the way returning a boolean would. It is possible
+ that multiple methods may return components (this is not advised -- insanity may ensue).
Method Conflicts and Ordering
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html?view=auto&rev=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/RenderComponentDemo.html Wed Jan 10 20:45:04 2007
@@ -0,0 +1,28 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Render Component Demo</h1>
+
+ <p>
+ This page demonstrates how a component may return a component instance from one of its render phase methods to allow that object to render.
+ </p>
+
+ <t:comp type="NeverRender">
+ <span t:id="optional">
+ Optional Text
+ </span>
+ </t:comp>
+
+ <form t:type="Form">
+ <input t:type="Checkbox" t:id="enabled" onchange="'this.form.submit();'"/> <label for="enabled">Enable optional text</label>
+ </form>
+
+ <t:comp type="If" test="enabled">
+ Should now show up:
+ </t:comp>
+ <t:comp type="If" test="disabled">
+ Should be blank:
+ </t:comp>
+ <span id="container">[<t:comp type="Render" value="thing"/>]</span>
+
+
+</html>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Wed Jan 10 20:45:04 2007
@@ -6,70 +6,87 @@
<p>
<em>This page is static.</em>
</p>
- <p> Tapestry 5 Integration Application 1: <ul>
- <li>
- <a href="Start.html">Start Page</a>
- </li>
- <li>
- <a href="MerryChristmas.html">Count Page</a>
- </li>
- <li>
- <a href="InjectDemo.html">Inject Demo</a>
- </li>
- <li>
- <a href="Countdown.html">Countdown Page</a>
- </li>
- <li>
- <a href="ParameterConflict.html">Template Overriden by Class Page</a>
- </li>
- <li>
- <a href="EnvironmentalDemo.html">Environmental Annotation Useage</a>
- </li>
- <li>
- <a href="Expansion.html">Expansion Page</a>
- </li>
- <li>
- <a href="MissingPage.html">Missing Page</a> -- Used to test exception reporting </li>
- <li>
- <a href="BadTemplate.html">BadTemplate Page</a> -- More exception reporting </li>
- <li>
- <a href="ActionPage.html">Action Page</a> -- tests fixture for ActionLink
- component </li>
- <li>
- <a href="InstanceMixin.html">InstanceMixin</a> -- Mixin added to particular
- component instance </li>
- <li>
- <a href="RenderPhaseOrder.html">RenderPhaseOrder</a> -- Order of operations when
- invoking render phase methods </li>
- <li>
- <a href="SimpleForm.html">SimpleForm</a> -- first pass at writing Form and
- TextField components </li>
- <li>
- <a href="NumberSelect.html">NumberSelect</a> -- passivate/activate page context
- demo </li>
- <li>
- <a href="Localization.html">Localization</a> -- accessing localized messages
- from the component catalog </li>
- <li>
- <a href="AssetDemo.html">AssetDemo</a> -- declaring an using Assets </li>
- <li>
- <a href="ExpansionSubclass.html">ExpansionSubclass</a> -- components can inherit
- templates from base classes </li>
- <li>
- <a href="InjectComponentMismatch.html">InjectComponentMismatch</a> -- check
- error reporting when @InjectComponent doesn't match the actual field type </li>
- <li>
- <a href="ParameterDefault.html">ParameterDefault</a> -- defaulter methods for
- component parameters </li>
- <li>
- <a href="ValidForm.html">ValidForm</a> -- server-side input validation</li>
- <li>
- <a href="AnyDemo.html">AnyDemo</a> -- test out the Any component
- </li>
- <li>
- <a href="PasswordFieldDemo.html">PasswordFieldDemo</a> -- test for the PasswordField component
- </li>
- </ul>
- </p>
+ <p> Tapestry 5 Integration Application 1: </p>
+
+ <table>
+ <tr>
+ <td>
+ <ul>
+ <li>
+ <a href="Start.html">Start Page</a>
+ </li>
+ <li>
+ <a href="MerryChristmas.html">Count Page</a>
+ </li>
+ <li>
+ <a href="InjectDemo.html">Inject Demo</a>
+ </li>
+ <li>
+ <a href="Countdown.html">Countdown Page</a>
+ </li>
+ <li>
+ <a href="ParameterConflict.html">Template Overriden by Class Page</a>
+ </li>
+ <li>
+ <a href="EnvironmentalDemo.html">Environmental Annotation Useage</a>
+ </li>
+ <li>
+ <a href="Expansion.html">Expansion Page</a>
+ </li>
+ <li>
+ <a href="MissingPage.html">Missing Page</a> -- Used to test exception
+ reporting </li>
+ <li>
+ <a href="BadTemplate.html">BadTemplate Page</a> -- More exception
+ reporting </li>
+ <li>
+ <a href="ActionPage.html">Action Page</a> -- tests fixture for
+ ActionLink component </li>
+ <li>
+ <a href="InstanceMixin.html">InstanceMixin</a> -- Mixin added to
+ particular component instance </li>
+ <li>
+ <a href="RenderPhaseOrder.html">RenderPhaseOrder</a> -- Order of
+ operations when invoking render phase methods </li>
+ </ul>
+ </td>
+ <td>
+ <ul>
+ <li><a href="SimpleForm.html">SimpleForm</a> -- first pass at writing Form
+ and TextField components </li>
+ <li>
+ <a href="NumberSelect.html">NumberSelect</a> -- passivate/activate page
+ context demo </li>
+ <li>
+ <a href="Localization.html">Localization</a> -- accessing localized
+ messages from the component catalog </li>
+ <li>
+ <a href="AssetDemo.html">AssetDemo</a> -- declaring an using Assets </li>
+ <li>
+ <a href="ExpansionSubclass.html">ExpansionSubclass</a> -- components can
+ inherit templates from base classes </li>
+ <li>
+ <a href="InjectComponentMismatch.html">InjectComponentMismatch</a> --
+ check error reporting when @InjectComponent doesn't match the actual
+ field type </li>
+ <li>
+ <a href="ParameterDefault.html">ParameterDefault</a> -- defaulter
+ methods for component parameters </li>
+ <li>
+ <a href="ValidForm.html">ValidForm</a> -- server-side input validation</li>
+ <li>
+ <a href="AnyDemo.html">AnyDemo</a> -- test out the Any component </li>
+ <li>
+ <a href="PasswordFieldDemo.html">PasswordFieldDemo</a> -- test for the
+ PasswordField component </li>
+ <li>
+ <a href="RenderComponentDemo.html">RenderComponentDemo</a> -- components that "nominate" other components to render
+ </li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+
+
</body>
</html>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Jan 10 20:45:04 2007
@@ -477,6 +477,23 @@
assertTextPresent("[Show me the money!]");
}
+ @Test
+ public void render_phase_method_returns_a_component() throws Exception
+ {
+ _selenium.open(BASE_URL);
+ clickAndWait("link=RenderComponentDemo");
+
+ assertText("//span[@id='container']", "[]");
+
+ clickAndWait("enabled");
+
+ // After clicking the link (which submits the form), the page re-renders and shows us
+ // the optional component from inside the NeverRender, resurrected to render on the page
+ // after all.
+
+ assertText("//span[@id='optional']", "Optional Text");
+ }
+
private byte[] readContent(URL url) throws Exception
{
InputStream is = new BufferedInputStream(url.openStream());
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java?view=auto&rev=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/NeverRender.java Wed Jan 10 20:45:04 2007
@@ -0,0 +1,32 @@
+// Copyright 2007 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.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotations.ComponentClass;
+
+/**
+ * A component that doesn't render any tag, or its body. It is used as a container of other
+ * components. This will eventually be replaced with something akin to the Block component from
+ * Tapestry 4.
+ */
+@ComponentClass
+public class NeverRender
+{
+ boolean beforeRenderBody()
+ {
+ return false;
+
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Render.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Render.java?view=auto&rev=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Render.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/components/Render.java Wed Jan 10 20:45:04 2007
@@ -0,0 +1,36 @@
+// Copyright 2007 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.tapestry.integration.app1.components;
+
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Parameter;
+
+@ComponentClass
+public class Render
+{
+ @Parameter(required = true)
+ private Object _value;
+
+ /**
+ * Returns the value parameter, which allows another object (presumably, a component) to render
+ * first.
+ *
+ * @return
+ */
+ Object beginRender()
+ {
+ return _value;
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java?view=auto&rev=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/RenderComponentDemo.java Wed Jan 10 20:45:04 2007
@@ -0,0 +1,50 @@
+// Copyright 2007 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.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.annotations.Component;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.corelib.components.Any;
+
+@ComponentClass
+public class RenderComponentDemo
+{
+ @Persist
+ private boolean _enabled;
+
+ @Component
+ private Any _optional;
+
+ public boolean isEnabled()
+ {
+ return _enabled;
+ }
+
+ public void setEnabled(boolean enable)
+ {
+ _enabled = enable;
+ }
+
+ public boolean isDisabled()
+ {
+ return !_enabled;
+ }
+
+ public Object getThing()
+ {
+ return _enabled ? _optional : null;
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java?view=diff&rev=495111&r1=495110&r2=495111
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java Wed Jan 10 20:45:04 2007
@@ -14,7 +14,6 @@
package org.apache.tapestry.internal.structure;
-import org.apache.commons.logging.Log;
import org.apache.tapestry.Binding;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.internal.InternalComponentResources;
@@ -42,8 +41,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, newLog());
-
train_getParameterModel(model, "barney", null);
train_getSupportsInformalParameters(model, true);
@@ -75,8 +72,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, newLog());
-
train_getParameterNames(model, "barney");
train_getParameterModel(model, "barney", pmodel);
@@ -104,8 +99,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, newLog());
-
train_getParameterNames(model, "barney");
train_getParameterModel(model, "barney", pmodel);
train_isRequired(pmodel, false);
@@ -124,7 +117,6 @@
@Test
public void verify_required_parameters_unbound_and_required()
{
- Log log = newLog();
Page page = newPage();
ComponentPageElement container = newComponentPageElement();
Component component = newComponent();
@@ -135,8 +127,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, log);
-
train_getNestedId(container, null);
train_getName(page, "foo.pages.MyPage");
@@ -179,7 +169,6 @@
@Test
public void is_invariant()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -189,8 +178,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, log);
-
train_getParameterModel(model, "barney", pmodel);
train_isInvariant(binding, true);
@@ -224,8 +211,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, newLog());
-
train_getParameterModel(model, "barney", null);
train_get(binding, boundValue);
@@ -251,7 +236,6 @@
@Test
public void write_binding()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -264,8 +248,6 @@
train_getSupportsInformalParameters(model, true);
- train_getLog(model, log);
-
expect(binding.getBindingType()).andReturn(Integer.class);
train_coerce(coercer, 23, Integer.class, 23);
@@ -293,8 +275,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, newLog());
-
replay();
ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, coercer, null);
@@ -316,7 +296,6 @@
@Test
public void get_existing_embedded_component()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -326,8 +305,6 @@
Instantiator ins = newInstantiator(component, model);
- train_getLog(model, log);
-
train_getId(childElement, "child");
train_getComponent(childElement, childComponent);
@@ -345,7 +322,6 @@
@Test
public void get_mixin_by_class_name()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -359,8 +335,6 @@
train_getComponentClassName(mixinModel, mixinClassName);
- train_getLog(model, log);
-
replay();
ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, coercer, null);
@@ -375,7 +349,6 @@
@Test
public void get_mixin_by_unknown_class_name()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -388,8 +361,6 @@
train_getComponentClassName(mixinModel, "foo.Bar");
- train_getLog(model, log);
-
replay();
ComponentPageElement cpe = new ComponentPageElementImpl(page, ins, coercer, null);
@@ -413,7 +384,6 @@
@Test
public void set_explicit_parameter_of_unknown_mixin()
{
- Log log = newLog();
Page page = newPage();
Component component = newComponent();
ComponentModel model = newComponentModel();
@@ -424,8 +394,6 @@
Instantiator ins = newInstantiator(component, model);
Instantiator mixinInstantiator = newInstantiator(mixin, mixinModel);
-
- train_getLog(model, log);
train_getComponentClassName(mixinModel, "foo.Fred");