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/18 00:36:02 UTC
svn commit: r727577 - in /tapestry/tapestry5/branches/hlship-5.0-perf:
src/site/apt/
tapestry-core/src/main/java/org/apache/tapestry5/internal/model/
tapestry-core/src/main/java/org/apache/tapestry5/internal/services/
tapestry-core/src/main/java/org/ap...
Author: hlship
Date: Wed Dec 17 15:36:02 2008
New Revision: 727577
URL: http://svn.apache.org/viewvc?rev=727577&view=rev
Log:
TAP5-417: Tapestry 5.0 Performance Improvements
- Optimize each component's render state machine
Added:
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/RenderPhaseEventHandler.java
Modified:
tapestry/tapestry5/branches/hlship-5.0-perf/src/site/apt/upgrade.apt
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageResponseRendererImpl.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/resources/log4j.properties
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/src/site/apt/upgrade.apt?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/src/site/apt/upgrade.apt Wed Dec 17 15:36:02 2008
@@ -12,6 +12,16 @@
You should also check the {{{release-notes.html}project-wide release notes}} for information
about bugs fixes and other improvements.
+Release 5.0.19
+
+ As part of the changes related to
+ {{{https://issues.apache.org/jira/browse/TAP5-417}TAP5-417: Tapestry 5.0 Performance Improvements}},
+ you should be aware that Tapestry will now optimize the render phase state machine.
+ This is only relevant to advanced users who have written a ComponentClassTransformWorker
+ that adds logic to a render phase: it is necessary to
+ {{{apidocs/org/apache/tapestry5/model/MutableComponentModel.html#addRenderPhase(Class)}inform
+ Tapestry that the render phase should be invoked}}.
+
Release 5.0.16
The client-side class Tapestry.Zone has been renamed to Tapestry.ZoneManager.
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/model/MutableComponentModelImpl.java Wed Dec 17 15:36:02 2008
@@ -26,6 +26,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Internal implementation of {@link org.apache.tapestry5.model.MutableComponentModel}.
@@ -59,6 +60,8 @@
private Map<String, String> metaData;
+ private Set<Class> handledRenderPhases;
+
public MutableComponentModelImpl(String componentClassName, Logger logger, Resource baseResource,
ComponentModel parentModel)
{
@@ -272,6 +275,15 @@
metaData.put(key, value);
}
+ public void addRenderPhase(Class renderPhase)
+ {
+ Defense.notNull(renderPhase, "renderPhase");
+
+ if (handledRenderPhases == null) handledRenderPhases = CollectionFactory.newSet();
+
+ handledRenderPhases.add(renderPhase);
+ }
+
public String getMeta(String key)
{
String result = InternalUtils.get(metaData, key);
@@ -281,4 +293,16 @@
return result;
}
+ public Set<Class> getHandledRenderPhases()
+ {
+ Set<Class> result = CollectionFactory.newSet();
+
+ if (parentModel != null)
+ result.addAll(parentModel.getHandledRenderPhases());
+
+ if (handledRenderPhases != null)
+ result.addAll(handledRenderPhases);
+
+ return result;
+ }
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/EventImpl.java Wed Dec 17 15:36:02 2008
@@ -30,6 +30,8 @@
private final Logger logger;
+ private final boolean debugEnabled;
+
/**
* @param handler informed of return values from methods, deems when the event is aborted
* @param logger used to log method invocations
@@ -38,6 +40,8 @@
{
this.handler = notNull(handler, "handler");
this.logger = logger;
+
+ debugEnabled = logger.isDebugEnabled();
}
public boolean isAborted()
@@ -47,8 +51,8 @@
public void setMethodDescription(String methodDescription)
{
- if (logger.isDebugEnabled())
- logger.debug(TapestryMarkers.EVENT_HANDLER_METHOD, "Invoking: {}", methodDescription);
+ if (debugEnabled)
+ logger.debug(TapestryMarkers.EVENT_HANDLER_METHOD, "Invoking: " + methodDescription);
this.methodDescription = methodDescription;
}
@@ -65,7 +69,8 @@
throw new IllegalStateException(ServicesMessages.componentEventIsAborted(methodDescription));
- if (result != null) aborted |= handler.handleResult(result);
+ if (result != null)
+ aborted |= handler.handleResult(result);
return aborted;
}
@@ -74,4 +79,10 @@
{
return methodDescription;
}
+
+ public void reset()
+ {
+ aborted = false;
+ methodDescription = null;
+ }
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageLoaderProcessor.java Wed Dec 17 15:36:02 2008
@@ -561,15 +561,19 @@
return result;
}
- private void cdata(CDATAToken token)
+ private void cdata(final CDATAToken token)
{
- final String content = token.getContent();
-
PageElement element = new PageElement()
{
public void render(MarkupWriter writer, RenderQueue queue)
{
- writer.cdata(content);
+ writer.cdata(token.getContent());
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("CDATA[%s]", token.getLocation());
}
};
@@ -584,6 +588,12 @@
{
writer.defineNamespace(token.getNamespaceURI(), token.getNamespacePrefix());
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("DefineNamespace[%s %s]", token.getNamespacePrefix(), token.getNamespaceURI());
+ }
};
addToBody(element);
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageResponseRendererImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageResponseRendererImpl.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageResponseRendererImpl.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageResponseRendererImpl.java Wed Dec 17 15:36:02 2008
@@ -20,6 +20,7 @@
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.services.MarkupWriterFactory;
import org.apache.tapestry5.services.Response;
+import org.slf4j.Logger;
import java.io.IOException;
import java.io.PrintWriter;
@@ -34,13 +35,16 @@
private final Response response;
+ private final Logger logger;
+
public PageResponseRendererImpl(MarkupWriterFactory markupWriterFactory, PageMarkupRenderer markupRenderer,
- PageContentTypeAnalyzer pageContentTypeAnalyzer, Response response)
+ PageContentTypeAnalyzer pageContentTypeAnalyzer, Response response, Logger logger)
{
this.markupWriterFactory = markupWriterFactory;
this.markupRenderer = markupRenderer;
this.pageContentTypeAnalyzer = pageContentTypeAnalyzer;
this.response = response;
+ this.logger = logger;
}
public void renderPageResponse(Page page) throws IOException
@@ -58,8 +62,21 @@
PrintWriter pw = response.getPrintWriter(contentType.toString());
+ long startNanos = System.nanoTime();
+
writer.toMarkup(pw);
+ long endNanos = System.nanoTime();
+
+ if (logger.isDebugEnabled())
+ {
+ long elapsedNanos = endNanos - startNanos;
+ double elapsedSeconds = ((float) elapsedNanos) / 1000000000F;
+
+ logger.debug(String.format("Response DOM streamed to markup in %.3f seconds",
+ elapsedSeconds));
+ }
+
pw.flush();
}
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RenderQueueImpl.java Wed Dec 17 15:36:02 2008
@@ -41,6 +41,8 @@
public void push(RenderCommand command)
{
+ Defense.notNull(command, "command");
+
queue.push(command);
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java Wed Dec 17 15:36:02 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,6 +32,7 @@
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;
@@ -67,16 +69,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()
{
@@ -125,318 +117,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!
- }
-
- if (result instanceof Renderable)
- {
- final Renderable renderable = (Renderable) result;
+ return phaseToString(name);
+ }
- RenderCommand wrapper = new RenderCommand()
- {
- public void render(MarkupWriter writer, RenderQueue queue)
- {
- renderable.render(writer);
- }
- };
+ void reset(RenderQueue queue)
+ {
+ sharedEventHandler.queueCommands(queue);
- add(wrapper);
+ sharedEventHandler.reset();
- return false;
- }
+ sharedEvent.reset();
- 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);
+ }
+ }
+
+ /**
+ * 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);
- handler.queueCommands(queue);
+ 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);
-
- queue.push(afterRender);
+ component.afterRenderTemplate(writer, event);
+ }
- // 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.
+ public void render(final MarkupWriter writer, final RenderQueue queue)
+ {
+ callback(true, writer);
- if (handler.getResult()) queue.push(beforeRenderTemplate);
+ push(queue, getResult(), null, beforeRenderTemplatePhase);
- handler.queueCommands(queue);
+ reset(queue);
}
+ }
- @Override
- public String toString()
+ private class AfterRenderPhase extends AbstractPhase
+ {
+ private AfterRenderPhase()
{
- return phaseToString("BeginRender");
+ super("AfterRender");
}
- };
- private Map<String, Block> blocks;
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.afterRender(writer, event);
+ }
- private BlockImpl bodyBlock;
+ public void render(final MarkupWriter writer, RenderQueue queue)
+ {
+ callback(true, writer);
- private Map<String, ComponentPageElement> children;
+ push(queue, getResult(), cleanupRenderPhase, beginRenderPhase);
- private final String elementName;
+ reset(queue);
+ }
+ }
- private final PageResources pageResources;
- private final Logger logger;
+ private class CleanupRenderPhase extends AbstractPhase
+ {
+ private CleanupRenderPhase()
+ {
+ super("CleanupRender");
+ }
- private final Logger eventLogger;
+ protected void invokeComponent(Component component, MarkupWriter writer, Event event)
+ {
+ component.cleanupRender(writer, event);
+ }
- private final RenderCommand cleanupRender = new RenderCommand()
- {
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;
+ }
- if (current != elementAtSetup)
- throw new TapestryException(StructureMessages.unbalancedElements(completeId), getLocation(), null);
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ rendering = false;
- elementAtSetup = null;
+ Element current = writer.getElement();
- invoke(false, POST_RENDER_CLEANUP);
+ if (current != expectedElementAtCompletion)
+ throw new TapestryException(StructureMessages.unbalancedElements(completeId), getLocation(), null);
- // 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.
+ invoke(false, POST_RENDER_CLEANUP);
- page.decrementDirtyCount();
- }
- else
- {
- queue.push(setupRender);
- }
+ queue.endComponent();
- handler.queueCommands(queue);
+ // 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.
+
+ 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 PageResources pageResources;
+
+ private final Logger eventLogger;
private final String completeId;
@@ -470,65 +483,20 @@
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 boolean renderPhasesInitalized;
- public ComponentPageElement newChild(String id, String elementName, Instantiator instantiator, Location location)
- {
- ComponentPageElementImpl child = new ComponentPageElementImpl(page, this, id, elementName, instantiator,
- location, pageResources);
+ private RenderCommand setupRenderPhase, beginRenderPhase, beforeRenderTemplatePhase, beforeRenderBodyPhase,
+ afterRenderBodyPhase, afterRenderTemplatePhase, afterRenderPhase, cleanupRenderPhase;
- addEmbeddedElement(child);
+ private final RenderPhaseEventHandler sharedEventHandler = new RenderPhaseEventHandler();
- return child;
- }
+ private final EventImpl sharedEvent;
/**
* Constructor for other components embedded within the root component or at deeper levels of the hierarchy.
@@ -593,8 +561,10 @@
coreComponent = coreResources.getComponent();
- logger = coreResources.getLogger();
+ Logger logger = coreResources.getLogger();
eventLogger = pageResources.getEventLogger(logger);
+
+ sharedEvent = new EventImpl(sharedEventHandler, eventLogger);
}
/**
@@ -605,6 +575,82 @@
this(page, null, null, null, instantiator, null, pageResources);
}
+ 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, pageResources);
+
+ 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 +658,7 @@
String childId = child.getId();
ComponentPageElement existing = children.get(childId);
+
if (existing != null)
throw new TapestryException(StructureMessages.duplicateChildComponent(this, childId), child, null);
@@ -789,7 +836,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 +1008,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 +1021,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
Added: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/RenderPhaseEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/RenderPhaseEventHandler.java?rev=727577&view=auto
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/RenderPhaseEventHandler.java (added)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/RenderPhaseEventHandler.java Wed Dec 17 15:36:02 2008
@@ -0,0 +1,101 @@
+// Copyright 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.structure;
+
+import org.apache.tapestry5.ComponentEventCallback;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.Renderable;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.runtime.RenderCommand;
+import org.apache.tapestry5.runtime.RenderQueue;
+
+import java.util.List;
+
+/**
+ * Used by {@link org.apache.tapestry5.internal.structure.ComponentPageElementImpl} to track the results of invoking the
+ * component methods for a render phase event.
+ *
+ * @since 5.0.19
+ */
+class RenderPhaseEventHandler implements ComponentEventCallback
+{
+ private boolean result = true;
+
+ private List<RenderCommand> commands;
+
+ boolean getResult()
+ {
+ return result;
+ }
+
+ void reset()
+ {
+ result = true;
+
+ commands = null;
+ }
+
+ public boolean handleResult(Object result)
+ {
+ 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!
+ }
+
+ if (result instanceof Renderable)
+ {
+ final Renderable renderable = (Renderable) result;
+
+ RenderCommand wrapper = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ renderable.render(writer);
+ }
+ };
+
+ add(wrapper);
+
+ return false;
+ }
+
+ throw new RuntimeException(StructureMessages.wrongPhaseResultType(Boolean.class));
+ }
+
+ private void add(RenderCommand command)
+ {
+ if (commands == null) commands = CollectionFactory.newList();
+
+ commands.add(command);
+ }
+
+ public void queueCommands(RenderQueue queue)
+ {
+ if (commands == null) return;
+
+ for (RenderCommand command : commands)
+ queue.push(command);
+ }
+}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/AbstractIncludeAssetWorker.java Wed Dec 17 15:36:02 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/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java Wed Dec 17 15:36:02 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/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java Wed Dec 17 15:36:02 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/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java Wed Dec 17 15:36:02 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 org.apache.tapestry5.model.ComponentModel#handlesRenderPhase(Class)
+ * @since 5.0.19
+ */
+ void addRenderPhase(Class renderPhase);
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformConstants.java Wed Dec 17 15:36:02 2008
@@ -22,13 +22,18 @@
/**
* Constants used by implementations of {@link org.apache.tapestry5.services.ComponentClassTransformWorker}.
+ * <p/>
+ * <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 +41,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/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/model/MutableComponentModelImplTest.java Wed Dec 17 15:36:02 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/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentEventImplTest.java Wed Dec 17 15:36:02 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 @@
PageResources resources = mockPageResources();
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);
@@ -146,7 +161,7 @@
Logger logger = mockLogger();
train_isDebugEnabled(logger, true);
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_getCount(context, 0);
@@ -178,7 +193,7 @@
Logger logger = mockLogger();
train_isDebugEnabled(logger, true);
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_toClass(resources, Integer.class.getName(), Integer.class);
@@ -218,7 +233,7 @@
train_isDebugEnabled(logger, true);
EasyMock.expectLastCall().atLeastOnce();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
ComponentEventCallback handler = mockComponentEventHandler();
@@ -248,7 +263,7 @@
Logger logger = mockLogger();
train_isDebugEnabled(logger, true);
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
train_handleResult(handler, result, false);
@@ -272,7 +287,7 @@
Logger logger = mockLogger();
train_isDebugEnabled(logger, true);
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
replay();
@@ -298,7 +313,7 @@
train_isDebugEnabled(logger, true);
EasyMock.expectLastCall().atLeastOnce();
- logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class), isA(String.class));
+ logger.debug(eq(TapestryMarkers.EVENT_HANDLER_METHOD), isA(String.class));
EasyMock.expectLastCall().atLeastOnce();
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java Wed Dec 17 15:36:02 2008
@@ -54,6 +54,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -91,6 +92,7 @@
Instantiator ins = mockInstantiator(component, model);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
replay();
@@ -121,6 +123,7 @@
Instantiator ins = mockInstantiator(component, model);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
train_getParameterModel(model, "barney", null);
@@ -154,6 +157,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -190,6 +194,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -221,6 +226,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -254,6 +260,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -323,6 +330,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -356,6 +364,7 @@
PageResources resources = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
train_getSupportsInformalParameters(model, true);
@@ -393,6 +402,7 @@
PageResources resources = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -428,11 +438,13 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
Instantiator ins2 = mockInstantiator(component, model);
train_getEventLogger(pr, logger, eventLogger);
+ train_isDebugEnabled(eventLogger, false);
replay();
@@ -466,6 +478,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
@@ -501,6 +514,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(pageComponent, model);
@@ -543,6 +557,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
Instantiator mixinIns = mockInstantiator(mixin, mixinModel);
@@ -573,6 +588,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
Instantiator mixinIns = mockInstantiator(mixin, mixinModel);
@@ -612,6 +628,7 @@
PageResources pr = mockPageResources(logger, eventLogger);
train_getLogger(model, logger);
+ train_isDebugEnabled(eventLogger, false);
Instantiator ins = mockInstantiator(component, model);
Instantiator mixinInstantiator = mockInstantiator(mixin, mixinModel);
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java Wed Dec 17 15:36:02 2008
@@ -23,10 +23,6 @@
import org.apache.tapestry5.test.TapestryTestCase;
import org.testng.annotations.Test;
-/**
- * Of course, we're committing the cardinal sin of testing the code that's generated, rather than the *behavior* of the
- * generated code. Fortunately, we back all this up with lots and lots of integration testing.
- */
public class RenderPhaseMethodWorkerTest extends TapestryTestCase
{
@Test
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/resources/log4j.properties?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/test/resources/log4j.properties Wed Dec 17 15:36:02 2008
@@ -23,5 +23,8 @@
log4j.category.org.apache.tapestry5.integration.app2=debug
+log4j.category.tapestry.render=debug
+log4j.category.org.apache.tapestry5.internal.services.InternalModule.PageResponseRenderer=debug
+
# log4j.category.org.apache.tapestry5.corelib.components=debug
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java?rev=727577&r1=727576&r2=727577&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java Wed Dec 17 15:36:02 2008
@@ -39,14 +39,12 @@
*/
public final class CollectionFactory
{
- private static final int INITIAL_HASHMAP_CAPACITY = 31;
-
/**
* Constructs and returns a generic {@link HashMap} instance.
*/
public static <K, V> Map<K, V> newMap()
{
- return new HashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+ return new HashMap<K, V>();
}
/**
@@ -84,7 +82,7 @@
*/
public static <K, V> ConcurrentMap<K, V> newConcurrentMap()
{
- return new ConcurrentHashMap<K, V>(INITIAL_HASHMAP_CAPACITY);
+ return new ConcurrentHashMap<K, V>();
}
/**