You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2008/12/22 20:50:28 UTC
svn commit: r728754 [2/3] - in /tapestry/tapestry5/trunk: ./ src/site/apt/
src/site/apt/guide/ tapestry-core/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/
tapestry-core/src/main/java/org/apache/tapestry5/dom/ tapestry-core/src/m...
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java Mon Dec 22 11:50:26 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.internal.structure;
import org.apache.tapestry5.*;
+import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.internal.InternalComponentResources;
import org.apache.tapestry5.internal.TapestryInternalUtils;
@@ -31,21 +32,20 @@
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.model.ComponentModel;
import org.apache.tapestry5.model.ParameterModel;
+import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.runtime.*;
import org.slf4j.Logger;
import java.util.*;
/**
- * Implements {@link org.apache.tapestry5.internal.structure.PageElement} and represents a component within an overall
- * page. Much of a component page element's behavior is delegated to user code, via a {@link
- * org.apache.tapestry5.runtime.Component} instance.
+ * Implements {@link RenderCommand} and represents a component within an overall page. Much of a component page
+ * element's behavior is delegated to user code, via a {@link org.apache.tapestry5.runtime.Component} instance.
* <p/>
* Once instantiated, a ComponentPageElement should be registered as a {@linkplain
* org.apache.tapestry5.internal.structure.Page#addLifecycleListener(org.apache.tapestry5.runtime.PageLifecycleListener)
* lifecycle listener}. This could be done inside the constructors, but that tends to complicate unit tests, so its done
* by {@link org.apache.tapestry5.internal.services.PageElementFactoryImpl}.
- * <p/>
*/
public class ComponentPageElementImpl extends BaseLocatable implements ComponentPageElement, PageLifecycleListener
{
@@ -67,16 +67,6 @@
private static final Block PLACEHOLDER_BLOCK = new PlaceholderBlock();
- /**
- * @see #render(org.apache.tapestry5.MarkupWriter, org.apache.tapestry5.runtime.RenderQueue)
- */
- private static final RenderCommand POP_COMPONENT_ID = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
- queue.endComponent();
- }
- };
private static final ComponentCallback CONTAINING_PAGE_DID_ATTACH = new LifecycleNotificationComponentCallback()
{
@@ -113,7 +103,7 @@
// For the moment, every component will have a template, even if it consists of
// just a page element to queue up a BeforeRenderBody phase.
- private static void pushElements(RenderQueue queue, List<PageElement> list)
+ private static void pushElements(RenderQueue queue, List<RenderCommand> list)
{
int count = size(list);
for (int i = count - 1; i >= 0; i--)
@@ -125,316 +115,339 @@
return list == null ? 0 : list.size();
}
- private static class RenderPhaseEventHandler implements ComponentEventCallback
+ private abstract class AbstractPhase extends AbstractComponentCallback implements RenderCommand
{
- private boolean result = true;
+ private final String name;
- private List<RenderCommand> commands;
+ private MarkupWriter writer;
- boolean getResult()
+ public AbstractPhase(String name)
{
- return result;
+ super(sharedEvent);
+
+ this.name = name;
}
- public boolean handleResult(Object result)
+ @Override
+ public String toString()
{
- if (result instanceof Boolean)
- {
- this.result = (Boolean) result;
- return true; // abort other handler methods
- }
-
- if (result instanceof RenderCommand)
- {
- RenderCommand command = (RenderCommand) result;
-
- add(command);
-
- return false; // do not abort!
- }
+ return phaseToString(name);
+ }
- if (result instanceof Renderable)
- {
- final Renderable renderable = (Renderable) result;
+ void reset(RenderQueue queue)
+ {
+ sharedEventHandler.queueCommands(queue);
- RenderCommand wrapper = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
- renderable.render(writer);
- }
- };
+ sharedEventHandler.reset();
- add(wrapper);
+ sharedEvent.reset();
- return false;
- }
-
- throw new RuntimeException(StructureMessages.wrongPhaseResultType(Boolean.class));
+ writer = null;
}
- private void add(RenderCommand command)
+ void callback(boolean reverse, MarkupWriter writer)
{
- if (commands == null) commands = CollectionFactory.newList();
+ this.writer = writer;
- commands.add(command);
+ invoke(reverse, this);
}
- public void queueCommands(RenderQueue queue)
+ public void run(Component component)
{
- if (commands == null) return;
+ invokeComponent(component, writer, sharedEvent);
+ }
- for (RenderCommand command : commands)
- queue.push(command);
+ protected boolean getResult()
+ {
+ return sharedEventHandler.getResult();
}
+
+ protected abstract void invokeComponent(Component component, MarkupWriter writer, Event event);
}
- private final RenderCommand afterRender = new RenderCommand()
+ private class SetupRenderPhase extends AbstractPhase
{
- public void render(final MarkupWriter writer, RenderQueue queue)
+ public SetupRenderPhase()
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ super("SetupRender");
+ }
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.afterRender(writer, event);
- }
- };
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.setupRender(writer, event);
+ }
- invoke(true, callback);
+ public void render(final MarkupWriter writer, RenderQueue queue)
+ {
+ callback(false, writer);
- if (!handler.getResult()) queue.push(beginRender);
+ push(queue, getResult(), beginRenderPhase, cleanupRenderPhase);
- handler.queueCommands(queue);
+ reset(queue);
}
+ }
- @Override
- public String toString()
+ private class BeginRenderPhase extends AbstractPhase
+ {
+ private BeginRenderPhase()
{
- return phaseToString("AfterRender");
+ super("BeginRender");
}
- };
- private final RenderCommand afterRenderBody = new RenderCommand()
- {
- public void render(final MarkupWriter writer, RenderQueue queue)
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ component.beginRender(writer, event);
+ }
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.afterRenderBody(writer, event);
- }
- };
+ public void render(final MarkupWriter writer, final RenderQueue queue)
+ {
+ callback(false, writer);
- invoke(true, callback);
+ push(queue, afterRenderPhase);
+ push(queue, getResult(), beforeRenderTemplatePhase, null);
- if (!handler.getResult()) queue.push(beforeRenderBody);
+ reset(queue);
+ }
+ }
- handler.queueCommands(queue);
+ /**
+ * Replaces {@link org.apache.tapestry5.internal.structure.ComponentPageElementImpl.BeginRenderPhase} when there a
+ * handler for AfterRender but not BeginRender.
+ */
+ private class OptimizedBeginRenderPhase implements RenderCommand
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ push(queue, afterRenderPhase);
+ push(queue, beforeRenderTemplatePhase);
}
@Override
public String toString()
{
- return phaseToString("AfterRenderBody");
+ return phaseToString("OptimizedBeginRenderPhase");
}
- };
+ }
- private final RenderCommand afterRenderTemplate = new RenderCommand()
+ /**
+ * Reponsible for rendering the component's template. Even a component that doesn't have a template goes through
+ * this phase, as a synthetic template (used to trigger the rendering of the component's body) will be supplied.
+ */
+ private class BeforeRenderTemplatePhase extends AbstractPhase
{
+ private BeforeRenderTemplatePhase()
+ {
+ super("BeforeRenderTemplate");
+ }
+
+
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.beforeRenderTemplate(writer, event);
+ }
+
public void render(final MarkupWriter writer, final RenderQueue queue)
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ callback(false, writer);
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.afterRenderTemplate(writer, event);
- }
- };
+ push(queue, afterRenderTemplatePhase);
- invoke(true, callback);
+ if (getResult())
+ pushElements(queue, template);
- if (!handler.getResult()) queue.push(beforeRenderTemplate);
+ reset(queue);
+ }
+ }
- handler.queueCommands(queue);
+ /**
+ * Alternative version of BeforeRenderTemplatePhase used when the BeforeRenderTemplate render phase is not handled.
+ */
+ private class RenderTemplatePhase implements RenderCommand
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ push(queue, afterRenderTemplatePhase);
+
+ pushElements(queue, template);
}
@Override
public String toString()
{
- return phaseToString("AfterRenderTemplate");
+ return phaseToString("RenderTemplate");
}
- };
+ }
- private final RenderCommand beforeRenderBody = new RenderCommand()
+ private class BeforeRenderBodyPhase extends AbstractPhase
{
- public void render(final MarkupWriter writer, RenderQueue queue)
+ private BeforeRenderBodyPhase()
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ super("BeforeRenderBody");
+ }
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.beforeRenderBody(writer, event);
- }
- };
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.beforeRenderBody(writer, event);
+ }
- invoke(false, callback);
+ public void render(final MarkupWriter writer, RenderQueue queue)
+ {
+ callback(false, writer);
- queue.push(afterRenderBody);
+ push(queue, afterRenderBodyPhase);
- if (handler.getResult() && bodyBlock != null) queue.push(bodyBlock);
+ if (getResult() && bodyBlock != null)
+ queue.push(bodyBlock);
- handler.queueCommands(queue);
+ reset(queue);
}
+ }
- @Override
- public String toString()
- {
- return phaseToString("BeforeRenderBody");
- }
- };
- private final RenderCommand beforeRenderTemplate = new RenderCommand()
+ private class AfterRenderBodyPhase extends AbstractPhase
{
- public void render(final MarkupWriter writer, final RenderQueue queue)
+
+ private AfterRenderBodyPhase()
{
- final RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ super("AfterRenderBody");
+ }
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.beforeRenderTemplate(writer, event);
- }
- };
- invoke(false, callback);
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.afterRenderBody(writer, event);
+ }
- queue.push(afterRenderTemplate);
+ public void render(final MarkupWriter writer, RenderQueue queue)
+ {
+ callback(true, writer);
- if (handler.getResult()) pushElements(queue, template);
+ push(queue, getResult(), null, beforeRenderBodyPhase);
- handler.queueCommands(queue);
+ reset(queue);
}
+ }
- @Override
- public String toString()
+ private class AfterRenderTemplatePhase extends AbstractPhase
+ {
+ private AfterRenderTemplatePhase()
{
- return phaseToString("BeforeRenderTemplate");
+ super("AfterRenderTemplate");
}
- };
- private final RenderCommand beginRender = new RenderCommand()
- {
- public void render(final MarkupWriter writer, final RenderQueue queue)
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
-
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.beginRender(writer, event);
- }
- };
-
- invoke(false, callback);
+ component.afterRenderTemplate(writer, event);
+ }
- queue.push(afterRender);
+ public void render(final MarkupWriter writer, final RenderQueue queue)
+ {
+ callback(true, writer);
- // If the component has no template whatsoever, then a
- // renderBody element is added as the lone element of the component's template.
- // So every component will have a non-empty template.
+ push(queue, getResult(), null, beforeRenderTemplatePhase);
- if (handler.getResult()) queue.push(beforeRenderTemplate);
+ reset(queue);
+ }
+ }
- handler.queueCommands(queue);
+ private class AfterRenderPhase extends AbstractPhase
+ {
+ private AfterRenderPhase()
+ {
+ super("AfterRender");
}
- @Override
- public String toString()
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
{
- return phaseToString("BeginRender");
+ component.afterRender(writer, event);
}
- };
- private Map<String, Block> blocks;
+ public void render(final MarkupWriter writer, RenderQueue queue)
+ {
+ callback(true, writer);
- private BlockImpl bodyBlock;
+ push(queue, getResult(), cleanupRenderPhase, beginRenderPhase);
- private Map<String, ComponentPageElement> children;
+ reset(queue);
+ }
+ }
- private final String elementName;
private final ComponentPageElementResources elementResources;
- private final Logger logger;
-
- private final RenderCommand cleanupRender = new RenderCommand()
+ private class CleanupRenderPhase extends AbstractPhase
{
+ private CleanupRenderPhase()
+ {
+ super("CleanupRender");
+ }
+
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.cleanupRender(writer, event);
+ }
+
public void render(final MarkupWriter writer, RenderQueue queue)
{
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
+ callback(true, writer);
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.cleanupRender(writer, event);
- }
- };
+ push(queue, getResult(), null, setupRenderPhase);
- invoke(true, callback);
+ reset(queue);
+ }
+ }
- if (handler.getResult())
- {
- rendering = false;
+ private class PostRenderCleanupPhase implements RenderCommand
+ {
+ /**
+ * Used to detect mismatches calls to {@link MarkupWriter#element(String, Object[])} } and {@link
+ * org.apache.tapestry5.MarkupWriter#end()}. The expectation is that any element(s) begun by this component
+ * during rendering will be balanced by end() calls, resulting in the current element reverting to its initial
+ * value.
+ */
+ private final Element expectedElementAtCompletion;
- Element current = writer.getElement();
+ PostRenderCleanupPhase(Element expectedElementAtCompletion)
+ {
+ this.expectedElementAtCompletion = expectedElementAtCompletion;
+ }
+
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ rendering = false;
- if (current != elementAtSetup)
- throw new TapestryException(StructureMessages.unbalancedElements(completeId), getLocation(), null);
+ Element current = writer.getElement();
- elementAtSetup = null;
+ if (current != expectedElementAtCompletion)
+ throw new TapestryException(StructureMessages.unbalancedElements(completeId), getLocation(), null);
- invoke(false, POST_RENDER_CLEANUP);
+ invoke(false, POST_RENDER_CLEANUP);
- // NOW and only now the component is done rendering and fully cleaned up. Decrement
- // the page's dirty count. If the entire render goes well, then the page will be
- // clean and can be stored into the pool for later reuse.
+ queue.endComponent();
- page.decrementDirtyCount();
- }
- else
- {
- queue.push(setupRender);
- }
+ // Now and only now the component is done rendering and fully cleaned up. Decrement
+ // the page's dirty count. If the entire render goes well, then the page will be
+ // clean and can be stored into the pool for later reuse.
- handler.queueCommands(queue);
+ page.decrementDirtyCount();
}
@Override
public String toString()
{
- return phaseToString("CleanupRender");
+ return phaseToString("PostRenderCleanup");
}
- };
+ }
+
+ private Map<String, Block> blocks;
+
+ private BlockImpl bodyBlock;
+
+ private Map<String, ComponentPageElement> children;
+
+ private final String elementName;
+
+ private final Logger eventLogger;
private final String completeId;
@@ -468,65 +481,21 @@
private boolean rendering;
- /**
- * Used to detect mismatches calls to {@link MarkupWriter#element(String, Object[])} } and {@link
- * org.apache.tapestry5.MarkupWriter#end()}. The expectation is that any element(s) begun by this component during
- * rendering will be balanced by end() calls, resulting in the current element reverting to its initial value.
- */
- private Element elementAtSetup;
-
- private final RenderCommand setupRender = new RenderCommand()
- {
- public void render(final MarkupWriter writer, RenderQueue queue)
- {
- // TODO: Check for recursive rendering.
-
- rendering = true;
-
- elementAtSetup = writer.getElement();
-
- RenderPhaseEventHandler handler = new RenderPhaseEventHandler();
- final Event event = new EventImpl(handler, getEventLogger());
-
- ComponentCallback callback = new AbstractComponentCallback(event)
- {
- public void run(Component component)
- {
- component.setupRender(writer, event);
- }
- };
-
- invoke(false, callback);
-
- queue.push(cleanupRender);
-
- if (handler.getResult()) queue.push(beginRender);
-
- handler.queueCommands(queue);
- }
-
- @Override
- public String toString()
- {
- return phaseToString("SetupRender");
- }
- };
// 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 = CollectionFactory.newList();
+ private final List<RenderCommand> template = CollectionFactory.newList();
+ private boolean renderPhasesInitalized;
- public ComponentPageElement newChild(String id, String elementName, Instantiator instantiator, Location location)
- {
- ComponentPageElementImpl child = new ComponentPageElementImpl(page, this, id, elementName, instantiator,
- location, elementResources);
+ private RenderCommand setupRenderPhase, beginRenderPhase, beforeRenderTemplatePhase, beforeRenderBodyPhase,
+ afterRenderBodyPhase, afterRenderTemplatePhase, afterRenderPhase, cleanupRenderPhase;
- addEmbeddedElement(child);
- return child;
- }
+ private final RenderPhaseEventHandler sharedEventHandler = new RenderPhaseEventHandler();
+
+ private final EventImpl sharedEvent;
/**
* Constructor for other components embedded within the root component or at deeper levels of the hierarchy.
@@ -593,7 +562,10 @@
coreComponent = coreResources.getComponent();
- logger = coreResources.getLogger();
+ Logger logger = coreResources.getLogger();
+ eventLogger = elementResources.getEventLogger(logger);
+
+ sharedEvent = new EventImpl(sharedEventHandler, eventLogger);
}
/**
@@ -605,6 +577,82 @@
this(page, null, null, null, instantiator, null, elementResources);
}
+ private void initializeRenderPhases()
+ {
+ setupRenderPhase = new SetupRenderPhase();
+ beginRenderPhase = new BeginRenderPhase();
+ beforeRenderTemplatePhase = new BeforeRenderTemplatePhase();
+ beforeRenderBodyPhase = new BeforeRenderBodyPhase();
+ afterRenderBodyPhase = new AfterRenderBodyPhase();
+ afterRenderTemplatePhase = new AfterRenderTemplatePhase();
+ afterRenderPhase = new AfterRenderPhase();
+ cleanupRenderPhase = new CleanupRenderPhase();
+
+
+ // Now the optimization, where we remove, replace and collapse unused phases. We use
+ // the component models to determine which phases have handler methods for the
+ // render phases.
+
+ Set<Class> handled = coreResources.getComponentModel().getHandledRenderPhases();
+
+ if (mixinIdToComponentResources != null)
+ {
+ for (ComponentResources r : mixinIdToComponentResources.values())
+ handled.addAll(r.getComponentModel().getHandledRenderPhases());
+ }
+
+ if (!handled.contains(CleanupRender.class)) cleanupRenderPhase = null;
+
+ // Now, work back to front.
+
+ if (!handled.contains(AfterRender.class))
+ afterRenderPhase = cleanupRenderPhase;
+
+ if (!handled.contains(AfterRenderTemplate.class))
+ afterRenderTemplatePhase = null;
+
+ if (!handled.contains(AfterRenderBody.class))
+ afterRenderBodyPhase = null;
+
+ if (!handled.contains(BeforeRenderTemplate.class))
+ beforeRenderTemplatePhase = new RenderTemplatePhase();
+
+ if (!handled.contains(BeginRender.class))
+ {
+ RenderCommand replacement = handled.contains(AfterRender.class)
+ ? new OptimizedBeginRenderPhase()
+ : beforeRenderTemplatePhase;
+
+ beginRenderPhase = replacement;
+ }
+
+ if (!handled.contains(SetupRender.class))
+ setupRenderPhase = beginRenderPhase;
+
+ renderPhasesInitalized = true;
+ }
+
+ public ComponentPageElement newChild(String id, String elementName, Instantiator instantiator, Location location)
+ {
+ ComponentPageElementImpl child = new ComponentPageElementImpl(page, this, id, elementName, instantiator,
+ location, elementResources);
+
+ addEmbeddedElement(child);
+
+ return child;
+ }
+
+ void push(RenderQueue queue, boolean forward, RenderCommand forwardPhase, RenderCommand backwardPhase)
+ {
+ push(queue, forward ? forwardPhase : backwardPhase);
+ }
+
+ void push(RenderQueue queue, RenderCommand nextPhase)
+ {
+ if (nextPhase != null)
+ queue.push(nextPhase);
+ }
+
void addEmbeddedElement(ComponentPageElement child)
{
if (children == null) children = CollectionFactory.newCaseInsensitiveMap();
@@ -612,6 +660,7 @@
String childId = child.getId();
ComponentPageElement existing = children.get(childId);
+
if (existing != null)
throw new TapestryException(StructureMessages.duplicateChildComponent(this, childId), child, null);
@@ -698,14 +747,14 @@
if (informalParameterResources != null) informalParameterResources.bindParameter(parameterName, binding);
}
- public void addToBody(PageElement element)
+ public void addToBody(RenderCommand element)
{
if (bodyBlock == null) bodyBlock = new BlockImpl(getLocation(), "Body of " + getCompleteId());
bodyBlock.addToBody(element);
}
- public void addToTemplate(PageElement element)
+ public void addToTemplate(RenderCommand element)
{
template.add(element);
}
@@ -789,7 +838,8 @@
{
// If no body, then no beforeRenderBody or afterRenderBody
- if (bodyBlock != null) queue.push(beforeRenderBody);
+ if (bodyBlock != null)
+ push(queue, beforeRenderBodyPhase);
}
public String getCompleteId()
@@ -960,6 +1010,12 @@
*/
public final void render(MarkupWriter writer, RenderQueue queue)
{
+ // We assume that by the time we start to render, the structure (i.e., mixins) is nailed down.
+ // We could add a lock, but that seems wasteful.
+
+ if (!renderPhasesInitalized)
+ initializeRenderPhases();
+
// TODO: An error if the _render flag is already set (recursive rendering not
// allowed or advisable).
@@ -967,14 +1023,15 @@
page.incrementDirtyCount();
- queue.startComponent(coreResources);
+ // TODO: Check for recursive rendering.
+
+ rendering = true;
- // POP_COMPONENT_ID will remove the component we just started.
+ queue.startComponent(coreResources);
- queue.push(POP_COMPONENT_ID);
+ queue.push(new PostRenderCleanupPhase(writer.getElement()));
- // This is the start of the real state machine for the component.
- queue.push(setupRender);
+ push(queue, setupRenderPhase);
}
@Override
@@ -1217,7 +1274,7 @@
public Logger getEventLogger()
{
- return elementResources.getEventLogger(logger);
+ return eventLogger;
}
public Link createEventLink(String eventType, Object... context)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/DTDPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/DTDPageElement.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/DTDPageElement.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/DTDPageElement.java Mon Dec 22 11:50:26 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -12,17 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-/*
- * Created on Mar 15, 2007
- *
- *
- */
package org.apache.tapestry5.internal.structure;
import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
-public class DTDPageElement implements PageElement
+public class DTDPageElement implements RenderCommand
{
private final String name;
@@ -47,5 +43,4 @@
{
return String.format("DTD[name=%s; publicId=%s; systemId=%s]", name, publicId, systemId);
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ExpansionPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ExpansionPageElement.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ExpansionPageElement.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ExpansionPageElement.java Mon Dec 22 11:50:26 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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,12 +17,10 @@
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
-/**
- *
- */
-public class ExpansionPageElement implements PageElement
+public class ExpansionPageElement implements RenderCommand
{
private final Binding binding;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java Mon Dec 22 11:50:26 2008
@@ -16,6 +16,7 @@
import org.apache.tapestry5.*;
import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.ParameterAccess;
import org.apache.tapestry5.internal.services.Instantiator;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.Location;
@@ -59,9 +60,12 @@
private final ComponentPageElementResources elementResources;
- // Case insensitive
+ // Case insensitive map from parameter name to binding
private Map<String, Binding> bindings;
+ // Case insensitive map from parameter name to ParameterAccess
+ private Map<String, ParameterAccess> access;
+
private Messages messages;
// Case insensitive
@@ -69,6 +73,48 @@
private static final Object[] EMPTY = new Object[0];
+ private boolean informalsComputed;
+
+ /**
+ * We keep a linked list of informal parameters, which saves us the expense of determining which bindings are formal
+ * and which are informal. Each Informal points to the next.
+ */
+ private class Informal
+ {
+ private final String name;
+
+ private final Binding binding;
+
+ final Informal next;
+
+ private Informal(String name, Binding binding, Informal next)
+ {
+ this.name = name;
+ this.binding = binding;
+ this.next = next;
+ }
+
+ void write(MarkupWriter writer)
+ {
+ Object value = binding.get();
+
+ if (value == null) return;
+
+ if (value instanceof Block) return;
+
+ // If it's already a String, don't use the TypeCoercer (renderInformalParameters is
+ // a CPU hotspot, as is TypeCoercer.coerce).
+
+ String valueString = value instanceof String
+ ? (String) value
+ : elementResources.coerce(value, String.class);
+
+ writer.attributes(name, valueString);
+ }
+ }
+
+ private Informal firstInformal;
+
public InternalComponentResourcesImpl(Page page, ComponentPageElement element,
ComponentResources containerResources,
ComponentPageElementResources elementResources,
@@ -164,9 +210,7 @@
public <T> T getInformalParameter(String name, Class<T> type)
{
- if (getBinding(name) != null) return readParameter(name, type);
-
- return null;
+ return getParameterAccess(name).read(type);
}
public Block getBody()
@@ -196,11 +240,7 @@
public <T extends Annotation> T getParameterAnnotation(String parameterName, Class<T> annotationType)
{
- Binding b = getBinding(parameterName);
-
- if (b == null) return null;
-
- return b.getAnnotation(annotationType);
+ return getParameterAccess(parameterName).getAnnotation(annotationType);
}
public boolean isRendering()
@@ -213,7 +253,7 @@
return element.triggerEvent(eventType, defaulted(context), handler);
}
- private Object[] defaulted(Object[] input)
+ private static Object[] defaulted(Object[] input)
{
return input == null ? EMPTY : input;
}
@@ -233,13 +273,6 @@
return element.getContainingPage().getRootComponent();
}
- public boolean isInvariant(String parameterName)
- {
- Binding b = getBinding(parameterName);
-
- return b != null && b.isInvariant();
- }
-
public boolean isLoaded()
{
return element.isLoaded();
@@ -265,86 +298,20 @@
bindings.put(parameterName, binding);
}
- @SuppressWarnings("unchecked")
- public <T> T readParameter(String parameterName, Class<T> expectedType)
- {
- Binding b = getBinding(parameterName);
- T result;
-
- try
- {
- // Will throw NPE if binding is null, but this should never be called if the
- // parameter is not bound.
-
- Object boundValue = b.get();
-
- result = elementResources.coerce(boundValue, expectedType);
- }
- catch (Exception ex)
- {
- throw new TapestryException(StructureMessages.getParameterFailure(parameterName, getCompleteId(), ex), b,
- ex);
- }
-
- if (result == null && !isAllowNull(parameterName))
- throw new TapestryException(String.format(
- "Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
- parameterName,
- getCompleteId()), b, null);
-
- return result;
- }
-
- private boolean isAllowNull(String parameterName)
- {
- ParameterModel parameterModel = getComponentModel().getParameterModel(parameterName);
-
- return parameterModel == null ? true : parameterModel.isAllowNull();
- }
-
-
- public Object readParameter(String parameterName, String desiredTypeName)
- {
- Class parameterType = elementResources.toClass(desiredTypeName);
-
- return readParameter(parameterName, parameterType);
- }
public Class getBoundType(String parameterName)
{
- Binding b = getBinding(parameterName);
-
- return b != null ? b.getBindingType() : null;
- }
-
- @SuppressWarnings("unchecked")
- public <T> void writeParameter(String parameterName, T parameterValue)
- {
- Binding b = getBinding(parameterName);
-
- Class bindingType = b.getBindingType();
-
- try
- {
- Object coerced = elementResources.coerce(parameterValue, bindingType);
-
- b.set(coerced);
- }
- catch (Exception ex)
- {
- throw new TapestryException(StructureMessages.writeParameterFailure(parameterName, getCompleteId(), ex), b,
- ex);
- }
+ return getParameterAccess(parameterName).getBoundType();
}
private Binding getBinding(String parameterName)
{
- return bindings == null ? null : bindings.get(parameterName);
+ return InternalUtils.get(bindings, parameterName);
}
public AnnotationProvider getAnnotationProvider(String parameterName)
{
- return getBinding(parameterName);
+ return getParameterAccess(parameterName);
}
public Logger getLogger()
@@ -361,27 +328,18 @@
{
if (bindings == null) return;
- for (String name : bindings.keySet())
+ if (!informalsComputed)
{
- // Skip all formal parameters.
-
- if (componentModel.getParameterModel(name) != null) continue;
-
- Binding b = bindings.get(name);
-
- Object value = b.get();
-
- if (value == null) continue;
-
- // Because Blocks can be passed in (right from the template),
- // we want to skip those when rending informal parameters.
-
- if (value instanceof Block) continue;
-
- String valueString = elementResources.coerce(value, String.class);
+ for (Map.Entry<String, Binding> e : getInformalParameterBindings().entrySet())
+ {
+ firstInformal = new Informal(e.getKey(), e.getValue(), firstInformal);
+ }
- writer.attributes(name, valueString);
+ informalsComputed = true;
}
+
+ for (Informal i = firstInformal; i != null; i = i.next)
+ i.write(writer);
}
public Component getContainer()
@@ -470,9 +428,10 @@
{
Object result = InternalUtils.get(renderVariables, name);
- if (result == null) throw new IllegalArgumentException(StructureMessages.missingRenderVariable(getCompleteId(),
- name,
- renderVariables == null ? null : renderVariables.keySet()));
+ if (result == null)
+ throw new IllegalArgumentException(StructureMessages.missingRenderVariable(getCompleteId(),
+ name,
+ renderVariables == null ? null : renderVariables.keySet()));
return result;
}
@@ -499,4 +458,109 @@
{
page.addLifecycleListener(listener);
}
+
+ public ParameterAccess getParameterAccess(final String parameterName)
+ {
+ if (access == null) access = CollectionFactory.newCaseInsensitiveMap();
+
+ ParameterAccess result = access.get(parameterName);
+
+ if (result == null)
+ {
+ result = createParameterAccess(parameterName);
+ access.put(parameterName, result);
+ }
+
+ return result;
+ }
+
+ private ParameterAccess createParameterAccess(final String parameterName)
+ {
+ final Binding binding = getBinding(parameterName);
+
+ ParameterModel parameterModel = getComponentModel().getParameterModel(parameterName);
+
+ final boolean allowNull = parameterModel == null ? true : parameterModel.isAllowNull();
+
+ return new ParameterAccess()
+ {
+ public boolean isBound()
+ {
+ return binding != null;
+ }
+
+ public Object read(String desiredTypeName)
+ {
+ Class desiredType = elementResources.toClass(desiredTypeName);
+
+ return read(desiredType);
+ }
+
+ public <T> T read(Class<T> desiredType)
+ {
+ if (binding == null) return null;
+
+ T result;
+
+ try
+ {
+ // Will throw NPE if binding is null, but this should never be called if the
+ // parameter is not bound.
+
+ Object boundValue = binding.get();
+
+ result = elementResources.coerce(boundValue, desiredType);
+ }
+ catch (Exception ex)
+ {
+ throw new TapestryException(
+ StructureMessages.getParameterFailure(parameterName, getCompleteId(), ex), binding,
+ ex);
+ }
+
+ if (result == null && !allowNull)
+ throw new TapestryException(String.format(
+ "Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
+ parameterName,
+ getCompleteId()), binding, null);
+
+ return result;
+ }
+
+ public <T> void write(T parameterValue)
+ {
+ if (binding == null) return;
+
+ Class bindingType = binding.getBindingType();
+
+ try
+ {
+ Object coerced = elementResources.coerce(parameterValue, bindingType);
+
+ binding.set(coerced);
+ }
+ catch (Exception ex)
+ {
+ throw new TapestryException(
+ StructureMessages.writeParameterFailure(parameterName, getCompleteId(), ex), binding,
+ ex);
+ }
+ }
+
+ public boolean isInvariant()
+ {
+ return binding != null && binding.isInvariant();
+ }
+
+ public Class getBoundType()
+ {
+ return binding == null ? null : binding.getBindingType();
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ return binding == null ? null : binding.getAnnotation(annotationClass);
+ }
+ };
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StartElementPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StartElementPageElement.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StartElementPageElement.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/StartElementPageElement.java Mon Dec 22 11:50:26 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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.
@@ -15,12 +15,10 @@
package org.apache.tapestry5.internal.structure;
import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
-/**
- *
- */
-public class StartElementPageElement implements PageElement
+public class StartElementPageElement implements RenderCommand
{
private final String namespaceURI;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/TextPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/TextPageElement.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/TextPageElement.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/TextPageElement.java Mon Dec 22 11:50:26 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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.
@@ -15,12 +15,10 @@
package org.apache.tapestry5.internal.structure;
import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
-/**
- *
- */
-public class TextPageElement implements PageElement
+public class TextPageElement implements RenderCommand
{
private final String text;
@@ -39,5 +37,4 @@
{
return String.format("Text[%s]", text);
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java Mon Dec 22 11:50:26 2008
@@ -16,6 +16,7 @@
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.internal.services.ComponentResourcesOperation;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.services.SymbolSource;
@@ -94,6 +95,8 @@
// the integration test, thank you.
transformation.extendMethod(TransformConstants.SETUP_RENDER_SIGNATURE, body);
+
+ model.addRenderPhase(SetupRender.class);
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EnvironmentalWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EnvironmentalWorker.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EnvironmentalWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EnvironmentalWorker.java Mon Dec 22 11:50:26 2008
@@ -15,11 +15,10 @@
package org.apache.tapestry5.internal.transform;
import org.apache.tapestry5.annotations.Environmental;
+import org.apache.tapestry5.ioc.services.Builtin;
+import org.apache.tapestry5.ioc.services.ClassFactory;
import org.apache.tapestry5.model.MutableComponentModel;
-import org.apache.tapestry5.services.ClassTransformation;
-import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.Environment;
-import org.apache.tapestry5.services.TransformMethodSignature;
+import org.apache.tapestry5.services.*;
import java.lang.reflect.Modifier;
import java.util.List;
@@ -32,9 +31,13 @@
{
private final Environment environment;
- public EnvironmentalWorker(Environment environment)
+ private final ClassLoader classLoader;
+
+ public EnvironmentalWorker(Environment environment, @Builtin ClassFactory servicesLayerClassFactory)
{
this.environment = environment;
+
+ classLoader = servicesLayerClassFactory.getClassLoader();
}
public void transform(ClassTransformation transformation, MutableComponentModel model)
@@ -56,23 +59,57 @@
for (String name : names)
{
Environmental annotation = transformation.getFieldAnnotation(name, Environmental.class);
-
+
transformation.claimField(name, annotation);
- String type = transformation.getFieldType(name);
+ String typeName = transformation.getFieldType(name);
// TODO: Check for primitives
- // Caching might be good for efficiency at some point.
+ // TAP5-417: Calls to javassist.runtime.Desc.getType() are showing up as method hot spots.
+
+ Class type = null;
+
+ try
+ {
+ type = classLoader.loadClass(typeName);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ // TAP5-417: Changed the code to use EnvironmentalAccess, which encapsulates
+ // efficient caching.
+
+ String injectedTypeFieldName = transformation.addInjectedField(Class.class, "type", type);
+
+ // First we need (at page attach) to acquire the closure for the type.
+
+ String accessFieldName = transformation.addField(Modifier.PRIVATE, EnvironmentalAccess.class.getName(),
+ name + "_access");
+
+ String attachBody = String.format("%s = %s.getAccess(%s);",
+ accessFieldName, envField, injectedTypeFieldName);
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, attachBody);
+
+ // Clear the closure field when the page detaches. We'll get a new one when we next attach.
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE,
+ accessFieldName + " = null;");
+
+ // Now build a read method that invokes peek() or peekRequired() on the closure. The closure
+ // is responsible for safe caching of the environmental value.
String methodName = transformation.newMemberName("environment_read", name);
- TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, type, methodName, null,
+ TransformMethodSignature sig = new TransformMethodSignature(Modifier.PRIVATE, typeName, methodName, null,
null);
String body = String.format(
- "return ($r) %s.%s($type);",
- envField,
+ "return ($r) %s.%s();",
+ accessFieldName,
annotation.value() ? "peekRequired" : "peek");
transformation.addMethod(sig, body);
@@ -82,5 +119,4 @@
transformation.removeField(name);
}
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Mon Dec 22 11:50:26 2008
@@ -17,6 +17,7 @@
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.ParameterAccess;
import org.apache.tapestry5.internal.bindings.LiteralBinding;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.util.BodyBuilder;
@@ -93,14 +94,15 @@
String resourcesFieldName = transformation.getResourcesFieldName();
- String invariantFieldName = addParameterSetup(name, annotation.defaultPrefix(), annotation.value(),
- parameterName, cachedFieldName, cache, type, resourcesFieldName,
- transformation, annotation.autoconnect());
+ String accessFieldName = addParameterSetup(name, annotation.defaultPrefix(), annotation.value(),
+ parameterName, cachedFieldName, cache, type, resourcesFieldName,
+ transformation, annotation.autoconnect());
- addReaderMethod(name, cachedFieldName, invariantFieldName, cache, parameterName, type, resourcesFieldName,
+ addReaderMethod(name, cachedFieldName, accessFieldName, cache, parameterName, type, resourcesFieldName,
transformation);
- addWriterMethod(name, cachedFieldName, cache, parameterName, type, resourcesFieldName, transformation);
+ addWriterMethod(name, cachedFieldName, accessFieldName, cache, parameterName, type, resourcesFieldName,
+ transformation);
}
/**
@@ -110,16 +112,22 @@
String parameterName, String cachedFieldName, boolean cache, String fieldType,
String resourcesFieldName, ClassTransformation transformation, boolean autoconnect)
{
- String defaultFieldName = transformation.addField(Modifier.PRIVATE, fieldType, fieldName + "_default");
- String invariantFieldName = transformation.addField(Modifier.PRIVATE, "boolean", fieldName + "_invariant");
+ String accessFieldName = transformation.addField(Modifier.PRIVATE, ParameterAccess.class.getName(),
+ fieldName + "_access");
+
+ String defaultFieldName = transformation.addField(Modifier.PRIVATE, fieldType, fieldName + "_default");
BodyBuilder builder = new BodyBuilder().begin();
- addDefaultBindingSetup(parameterName, defaultPrefix, defaultBinding, resourcesFieldName, transformation,
+ addDefaultBindingSetup(parameterName, defaultPrefix, defaultBinding, resourcesFieldName,
+ transformation,
builder, autoconnect);
- builder.addln("%s = %s.isInvariant(\"%s\");", invariantFieldName, resourcesFieldName, parameterName);
+ // Order is (alas) important here: must invoke getParameterAccess() after the binding setup, as
+ // that code may invoke InternalComponentResources.bindParameter().
+
+ builder.addln("%s = %s.getParameterAccess(\"%s\");", accessFieldName, resourcesFieldName, parameterName);
// Store the current value of the field into the default field. This value will
// be used to reset the field after rendering.
@@ -139,7 +147,7 @@
{
builder.clear();
- builder.addln("if (! %s)", invariantFieldName);
+ builder.addln("if (! %s.isInvariant())", accessFieldName);
builder.begin();
builder.addln("%s = %s;", fieldName, defaultFieldName);
builder.addln("%s = false;", cachedFieldName);
@@ -156,11 +164,12 @@
transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, builder.toString());
}
- return invariantFieldName;
+ return accessFieldName;
}
private void addDefaultBindingSetup(String parameterName, String defaultPrefix, String defaultBinding,
- String resourcesFieldName, ClassTransformation transformation,
+ String resourcesFieldName,
+ ClassTransformation transformation,
BodyBuilder builder, boolean autoconnect)
{
if (InternalUtils.isNonBlank(defaultBinding))
@@ -192,13 +201,14 @@
// If no default binding expression provided in the annotation, then look for a default
// binding method to provide the binding.
- final String methodName = "default" + InternalUtils.capitalize(parameterName);
+ final String methodName = "default" + parameterName;
MethodFilter filter = new MethodFilter()
{
public boolean accept(TransformMethodSignature signature)
{
- return signature.getParameterTypes().length == 0 && signature.getMethodName().equals(methodName);
+ return signature.getParameterTypes().length == 0
+ && signature.getMethodName().equalsIgnoreCase(methodName);
}
};
@@ -209,12 +219,23 @@
if (signatures.isEmpty()) return;
+ // Because the check was case-insensitive, we need to determine the actual
+ // name.
+
+ String actualMethodName = signatures.get(0).getMethodName();
+
builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
- builder.addln(" %s(\"%s\", %s, ($w) %s());", BIND_METHOD_NAME, parameterName, resourcesFieldName, methodName);
+ builder.addln(" %s(\"%s\", %s, ($w) %s());",
+ BIND_METHOD_NAME,
+ parameterName,
+ resourcesFieldName,
+ actualMethodName);
}
- private void addWriterMethod(String fieldName, String cachedFieldName, boolean cache, String parameterName,
- String fieldType, String resourcesFieldName, ClassTransformation transformation)
+ private void addWriterMethod(String fieldName, String cachedFieldName, String accessFieldName, boolean cache,
+ String parameterName,
+ String fieldType, String resourcesFieldName,
+ ClassTransformation transformation)
{
BodyBuilder builder = new BodyBuilder();
builder.begin();
@@ -233,8 +254,7 @@
// read-only or unbound parameters. $1 is the single parameter
// to the method.
- builder.addln("if (%s.isBound(\"%s\"))", resourcesFieldName, parameterName);
- builder.addln(" %s.writeParameter(\"%s\", ($w)$1);", resourcesFieldName, parameterName);
+ builder.addln("%s.write(($w)$1);", accessFieldName);
builder.addln("%s = $1;", fieldName);
@@ -255,7 +275,7 @@
/**
* Adds a private method that will be the replacement for read-access to the field.
*/
- private void addReaderMethod(String fieldName, String cachedFieldName, String invariantFieldName, boolean cache,
+ private void addReaderMethod(String fieldName, String cachedFieldName, String accessFieldName, boolean cache,
String parameterName, String fieldType, String resourcesFieldName,
ClassTransformation transformation)
{
@@ -265,8 +285,8 @@
// While the component is still loading, or when the value for the component is cached,
// or if the value is not bound, then return the current value of the field.
- builder.addln("if (%s || ! %s.isLoaded() || ! %<s.isBound(\"%s\")) return %s;", cachedFieldName,
- resourcesFieldName, parameterName, fieldName);
+ builder.addln("if (%s || ! %s.isLoaded() || ! %s.isBound()) return %s;", cachedFieldName,
+ resourcesFieldName, accessFieldName, fieldName);
String cast = TransformUtils.getWrapperTypeName(fieldType);
@@ -276,14 +296,13 @@
// to readParameter(), since its easier to convert it properly to
// a type on that end than in the generated code.
- builder.addln("%s result = ($r) ((%s) %s.readParameter(\"%s\", \"%2$s\"));", fieldType, cast,
- resourcesFieldName, parameterName);
+ builder.addln("%s result = ($r) ((%s) %s.read(\"%2$s\"));", fieldType, cast, accessFieldName);
// If the binding is invariant, then it's ok to cache. Othewise, its only
// ok to cache if a) the @Parameter says to cache and b) the component
// is rendering at the point when field is accessed.
- builder.add("if (%s", invariantFieldName);
+ builder.add("if (%s.isInvariant()", accessFieldName);
if (cache) builder.add(" || %s.isRendering()", resourcesFieldName);
@@ -313,6 +332,9 @@
return InternalUtils.stripMemberName(fieldName);
}
+ /**
+ * Invoked from generated code as part of the handling of parameter default methods.
+ */
public static void bind(String parameterName, InternalComponentResources resources, Object value)
{
if (value == null) return;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java Mon Dec 22 11:50:26 2008
@@ -112,6 +112,8 @@
if (methods.isEmpty()) return;
+ model.addRenderPhase(methodAnnotation);
+
BodyBuilder builder = new BodyBuilder();
builder.begin();
@@ -188,5 +190,4 @@
else
builder.addln(";");
}
-
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java Mon Dec 22 11:50:26 2008
@@ -21,6 +21,7 @@
import org.slf4j.Logger;
import java.util.List;
+import java.util.Set;
/**
* Defines a component in terms of its capabilities, parameters, sub-components, etc. During <em>runtime</em>, the
@@ -146,4 +147,13 @@
* @return the value for the key (possibly inherited from a parent model), or null
*/
String getMeta(String key);
+
+ /**
+ * Returns a set of all the render phases that this model (including parent models) that are handled. Render phases
+ * are represented by the corresponding annotation ({@link org.apache.tapestry5.annotations.BeginRender}, {@link
+ * org.apache.tapestry5.annotations.AfterRender}, etc.).
+ *
+ * @return set of classes
+ */
+ Set<Class> getHandledRenderPhases();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java Mon Dec 22 11:50:26 2008
@@ -85,4 +85,13 @@
* Stores a meta data value under the indicated key.
*/
void setMeta(String key, String value);
+
+ /**
+ * Identifies that the component does handle the render phase.
+ *
+ * @param renderPhase annotation class corresponding to the render phase
+ * @see ComponentModel#getHandledRenderPhases()
+ * @since 5.0.19
+ */
+ void addRenderPhase(Class renderPhase);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Environment.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Environment.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Environment.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/Environment.java Mon Dec 22 11:50:26 2008
@@ -72,4 +72,16 @@
* Clears all stacks; used when initializing the Environment before a render.
*/
void clear();
+
+ /**
+ * For some type, returns a temporary access object for the type. The access object is efficient because it ties
+ * directly to the thread's instance of the Environment service, it also caches the current value. <p>The access
+ * object must be discarded at the end of the request (it will be unusable at that point anyway).
+ *
+ * @param type type of environmental object
+ * @param <T>
+ * @return access object that can be used to see the current environmental object of the type
+ * @since 5.0.19
+ */
+ <T> EnvironmentalAccess<T> getAccess(Class<T> type);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Mon Dec 22 11:50:26 2008
@@ -149,7 +149,6 @@
binder.bind(ApplicationGlobals.class, ApplicationGlobalsImpl.class);
binder.bind(AssetSource.class, AssetSourceImpl.class);
binder.bind(Cookies.class, CookiesImpl.class);
- binder.bind(Environment.class, EnvironmentImpl.class);
binder.bind(FieldValidatorDefaultSource.class, FieldValidatorDefaultSourceImpl.class);
binder.bind(RequestGlobals.class, RequestGlobalsImpl.class);
binder.bind(ResourceDigestGenerator.class, ResourceDigestGeneratorImpl.class);
@@ -1988,6 +1987,7 @@
configuration.add("li", RelativeElementPosition.INSIDE);
}
+
/**
* @since 5.1
*/
@@ -2032,4 +2032,14 @@
return service;
}
+
+ @Scope(ScopeConstants.PERTHREAD)
+ public Environment buildEnvironment(PerthreadManager perthreadManager)
+ {
+ EnvironmentImpl service = new EnvironmentImpl();
+
+ perthreadManager.addThreadCleanupListener(service);
+
+ return service;
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java Mon Dec 22 11:50:26 2008
@@ -22,13 +22,17 @@
/**
* Constants used by implementations of {@link org.apache.tapestry5.services.ComponentClassTransformWorker}.
+ * <p/>
+ * Note: methods on transformed components will not be invoked <em>unless</em> {@linkplain
+ * org.apache.tapestry5.model.MutableComponentModel#addRenderPhase(Class) the component model is updated to identify the
+ * use of the corresponding render phase}.
*/
public final class TransformConstants
{
// Shared parameters of a whole bunch of lifecycle methods, representing the different
// component render states.
- private static final String[] RENDER_PHASE_METHOD_PARAMETERS = { MarkupWriter.class.getName(),
- Event.class.getName() };
+ private static final String[] RENDER_PHASE_METHOD_PARAMETERS = {MarkupWriter.class.getName(),
+ Event.class.getName()};
/**
* Signature for {@link org.apache.tapestry5.runtime.Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)}.
@@ -36,7 +40,7 @@
* @see org.apache.tapestry5.annotations.OnEvent
*/
public static final TransformMethodSignature DISPATCH_COMPONENT_EVENT = new TransformMethodSignature(
- Modifier.PUBLIC, "boolean", "dispatchComponentEvent", new String[] { ComponentEvent.class.getName() },
+ Modifier.PUBLIC, "boolean", "dispatchComponentEvent", new String[] {ComponentEvent.class.getName()},
null);
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java Mon Dec 22 11:50:26 2008
@@ -645,7 +645,7 @@
protected final void train_getParameterModel(ComponentModel model, String parameterName,
ParameterModel parameterModel)
{
- expect(model.getParameterModel(parameterName)).andReturn(parameterModel);
+ expect(model.getParameterModel(parameterName)).andReturn(parameterModel).atLeastOnce();
}
protected final void train_getParameterNames(ComponentModel model, String... names)
@@ -1180,4 +1180,9 @@
{
expect(formSupport.getFormValidationId()).andReturn(validationId).atLeastOnce();
}
+
+ protected final void train_isAllowNull(ParameterModel model, boolean allowNull)
+ {
+ expect(model.isAllowNull()).andReturn(allowNull).atLeastOnce();
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/LoopTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/LoopTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/LoopTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/LoopTest.java Mon Dec 22 11:50:26 2008
@@ -14,6 +14,7 @@
package org.apache.tapestry5.corelib.components;
+import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.services.Heartbeat;
import org.easymock.EasyMock;
@@ -28,6 +29,7 @@
public void non_empty_iterator()
{
Heartbeat hb = mockHeartbeat();
+ MarkupWriter writer = mockMarkupWriter();
// Really hard to test the exact timing of all this; it will have to
// be "proven" by integration tests.
@@ -49,21 +51,21 @@
assertTrue(loop.setup());
assertEquals(loop.getIndex(), 0);
- loop.begin();
+ loop.begin(writer);
assertEquals(loop.getValue(), "alpha");
assertEquals(loop.getIndex(), 0);
- assertFalse(loop.after());
- loop.begin();
+ assertFalse(loop.after(writer));
+ loop.begin(writer);
assertEquals(loop.getValue(), "beta");
assertEquals(loop.getIndex(), 1);
- assertFalse(loop.after());
- loop.begin();
+ assertFalse(loop.after(writer));
+ loop.begin(writer);
assertEquals(loop.getValue(), "gamma");
assertEquals(loop.getIndex(), 2);
- assertTrue(loop.after());
+ assertTrue(loop.after(writer));
verify();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java Mon Dec 22 11:50:26 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.internal.model;
import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.Resource;
@@ -548,7 +549,6 @@
}
verify();
-
}
@Test
@@ -722,4 +722,65 @@
verify();
}
+
+ /**
+ * @since 5.0.19
+ */
+ @Test
+ public void does_not_handle_render_phase_and_no_parent()
+ {
+ Resource r = mockResource();
+ Logger logger = mockLogger();
+
+ replay();
+
+ MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+
+ assertFalse(model.getHandledRenderPhases().contains(BeginRender.class));
+
+ verify();
+ }
+
+ /**
+ * @since 5.0.19
+ */
+ @Test
+ public void handles_render_phase()
+ {
+ Resource r = mockResource();
+ Logger logger = mockLogger();
+
+ replay();
+
+ MutableComponentModel model = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+
+ model.addRenderPhase(BeginRender.class);
+
+ assertTrue(model.getHandledRenderPhases().contains(BeginRender.class));
+
+ verify();
+ }
+
+ /**
+ * @since 5.0.19
+ */
+ @Test
+ public void parent_handles_render_phase()
+ {
+ Resource r = mockResource();
+ Logger logger = mockLogger();
+
+ replay();
+
+ MutableComponentModel parent = new MutableComponentModelImpl(CLASS_NAME, logger, r, null);
+ MutableComponentModel child = new MutableComponentModelImpl(CLASS_NAME, logger, r, parent);
+
+ parent.addRenderPhase(BeginRender.class);
+
+
+ assertTrue(child.getHandledRenderPhases().contains(BeginRender.class));
+
+ verify();
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java Mon Dec 22 11:50:26 2008
@@ -50,12 +50,15 @@
{
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_getCount(context, 0);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
assertTrue(event.matches("eventType", "someId", 0));
assertFalse(event.matches("foo", "someId", 0));
@@ -68,12 +71,15 @@
{
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_getCount(context, 0);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
assertTrue(event.matches("EVENTTYPE", "someid", 0));
@@ -85,12 +91,15 @@
{
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_getCount(context, 0);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
assertTrue(event.matches("eventType", "someId", 0));
@@ -104,12 +113,15 @@
{
ComponentEventCallback handler = mockComponentEventHandler();
EventContext context = mockEventContext();
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_getCount(context, 0);
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null, logger);
assertTrue(event.matches("eventtype", "SOMEID", 0));
@@ -123,6 +135,9 @@
ComponentPageElementResources resources = mockComponentPageElementResources();
EventContext context = mockEventContext();
Integer value = new Integer(27);
+ Logger logger = mockLogger();
+
+ train_isDebugEnabled(logger, false);
train_toClass(resources, "java.lang.Integer", Integer.class);
@@ -131,7 +146,7 @@
replay();
- ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources, null);
+ ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources, logger);
assertSame(event.coerceContext(0, "java.lang.Integer"), value);
@@ -145,7 +160,8 @@
EventContext context = mockEventContext();
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_getCount(context, 0);
@@ -176,7 +192,8 @@
ComponentPageElementResources resources = mockComponentPageElementResources();
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_toClass(resources, Integer.class.getName(), Integer.class);
@@ -213,7 +230,10 @@
String methodDescription = "foo.Bar.baz()";
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
ComponentEventCallback handler = mockComponentEventHandler();
@@ -242,7 +262,8 @@
ComponentEventCallback handler = mockComponentEventHandler();
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_handleResult(handler, result, false);
@@ -265,7 +286,8 @@
ComponentEventCallback handler = mockComponentEventHandler();
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
replay();
@@ -288,7 +310,10 @@
ComponentEventCallback handler = mockComponentEventHandler();
Logger logger = mockLogger();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ train_isDebugEnabled(logger, true);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
EasyMock.expectLastCall().atLeastOnce();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PageElementFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PageElementFactoryImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PageElementFactoryImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PageElementFactoryImplTest.java Mon Dec 22 11:50:26 2008
@@ -19,11 +19,11 @@
import org.apache.tapestry5.dom.MarkupModel;
import org.apache.tapestry5.dom.XMLMarkupModel;
import org.apache.tapestry5.internal.parser.AttributeToken;
-import org.apache.tapestry5.internal.structure.PageElement;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
import org.apache.tapestry5.services.BindingSource;
import org.apache.tapestry5.services.ComponentClassResolver;
@@ -47,7 +47,7 @@
PageElementFactory factory = new PageElementFactoryImpl(source, resolver, null, null, null);
AttributeToken token = new AttributeToken(null, "name", "value", l);
- PageElement element = factory.newAttributeElement(null, token);
+ RenderCommand element = factory.newAttributeElement(null, token);
writer.element("root");
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/BlockImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/BlockImplTest.java?rev=728754&r1=728753&r2=728754&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/BlockImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/BlockImplTest.java Mon Dec 22 11:50:26 2008
@@ -20,6 +20,7 @@
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
import org.apache.tapestry5.ioc.internal.util.LocationImpl;
+import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
import org.testng.annotations.Test;
@@ -45,8 +46,8 @@
BlockImpl block = new BlockImpl(null, null);
RenderQueue queue = mockRenderQueue();
MarkupWriter writer = mockMarkupWriter();
- PageElement element1 = mockPageElement();
- PageElement element2 = mockPageElement();
+ RenderCommand element1 = mockRenderCommand();
+ RenderCommand element2 = mockRenderCommand();
getMocksControl().checkOrder(true);