Author: dadams Date: Mon Dec 20 23:44:31 2010 New Revision: 1051319 URL: http://svn.apache.org/viewvc?rev=1051319&view=rev Log: (closed TAP5-742) Add optional component tracing comments to rendered output
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/ComponentPageElementImpl.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/GeneralComponentTests.java Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=1051319&r1=1051318&r2=1051319&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java Mon Dec 20 23:44:31 2010 @@ -325,4 +325,13 @@ public class SymbolConstants * @since 5.2.0 */ public static final String PAGE_POOL_ENABLED = "tapestry.page-pool-enabled"; + + /** + * If "true" and {...@link #PRODUCTION_MODE} is off, comments will be rendered before and after the rendering of any component + * allowing more visibility into which components rendered which markup. Defaults to "false". Component render tracing may be + * enabled per-request by the presence of a request parameter "t:component-trace" with a value of "true". + * + * @since 5.2.5 + */ + public static final String COMPONENT_RENDER_TRACING_ENABLED = "tapestry.component-render-tracing-enabled"; } Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java?rev=1051319&r1=1051318&r2=1051319&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java Mon Dec 20 23:44:31 2010 @@ -25,11 +25,13 @@ import org.apache.tapestry5.ioc.Resource import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.ioc.internal.util.TapestryException; +import org.apache.tapestry5.ioc.services.SymbolSource; import org.apache.tapestry5.ioc.util.IdAllocator; import org.apache.tapestry5.model.ComponentModel; import org.apache.tapestry5.model.EmbeddedComponentModel; import org.apache.tapestry5.runtime.RenderCommand; import org.apache.tapestry5.services.ComponentClassResolver; +import org.apache.tapestry5.services.Request; import java.util.List; import java.util.Locale; @@ -54,14 +56,18 @@ class ComponentAssemblerImpl implements private final IdAllocator allocator = new IdAllocator(); private final OperationTracker tracker; + + private final Request request; + + private final SymbolSource symbolSource; private Map<String, String> publishedParameterToEmbeddedId; private Map<String, EmbeddedComponentAssembler> embeddedIdToAssembler; - + public ComponentAssemblerImpl(ComponentAssemblerSource assemblerSource, ComponentInstantiatorSource instantiatorSource, ComponentClassResolver componentClassResolver, - Instantiator instantiator, ComponentPageElementResources resources, Locale locale, OperationTracker tracker) + Instantiator instantiator, ComponentPageElementResources resources, Locale locale, OperationTracker tracker, Request request, SymbolSource symbolSource) { this.assemblerSource = assemblerSource; this.instantiatorSource = instantiatorSource; @@ -70,6 +76,8 @@ class ComponentAssemblerImpl implements this.resources = resources; this.locale = locale; this.tracker = tracker; + this.request = request; + this.symbolSource = symbolSource; } public ComponentPageElement assembleRootComponent(final Page page) @@ -90,7 +98,7 @@ class ComponentAssemblerImpl implements try { - ComponentPageElement newElement = new ComponentPageElementImpl(pageAssembly.page, instantiator, resources); + ComponentPageElement newElement = new ComponentPageElementImpl(pageAssembly.page, instantiator, resources, request, symbolSource); pageAssembly.componentName.push(new ComponentName(pageAssembly.page.getName())); Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java?rev=1051319&r1=1051318&r2=1051319&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageLoaderImpl.java Mon Dec 20 23:44:31 2010 @@ -33,6 +33,7 @@ import org.apache.tapestry5.ioc.internal import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.ioc.internal.util.TapestryException; import org.apache.tapestry5.ioc.services.PerthreadManager; +import org.apache.tapestry5.ioc.services.SymbolSource; import org.apache.tapestry5.ioc.util.Stack; import org.apache.tapestry5.model.ComponentModel; import org.apache.tapestry5.model.EmbeddedComponentModel; @@ -40,6 +41,7 @@ import org.apache.tapestry5.runtime.Rend import org.apache.tapestry5.runtime.RenderQueue; import org.apache.tapestry5.services.ComponentClassResolver; import org.apache.tapestry5.services.InvalidationListener; +import org.apache.tapestry5.services.Request; import java.util.Collections; import java.util.List; @@ -139,13 +141,17 @@ public class PageLoaderImpl implements P private final OperationTracker tracker; private final PerthreadManager perThreadManager; + + private final Request request; + + private final SymbolSource symbolSource; private final boolean poolingEnabled; public PageLoaderImpl(ComponentInstantiatorSource instantiatorSource, ComponentTemplateSource templateSource, PageElementFactory elementFactory, ComponentPageElementResourcesSource resourcesSource, ComponentClassResolver componentClassResolver, PersistentFieldManager persistentFieldManager, - StringInterner interner, OperationTracker tracker, PerthreadManager perThreadManager, + StringInterner interner, OperationTracker tracker, PerthreadManager perThreadManager, Request request, SymbolSource symbolSource, @Symbol(SymbolConstants.PAGE_POOL_ENABLED) boolean poolingEnabled) { @@ -159,6 +165,8 @@ public class PageLoaderImpl implements P this.tracker = tracker; this.perThreadManager = perThreadManager; this.poolingEnabled = poolingEnabled; + this.request = request; + this.symbolSource = symbolSource; } public void objectWasInvalidated() @@ -228,7 +236,7 @@ public class PageLoaderImpl implements P ComponentPageElementResources resources = resourcesSource.get(locale); ComponentAssembler assembler = new ComponentAssemblerImpl(PageLoaderImpl.this, instantiatorSource, - componentClassResolver, instantiator, resources, locale, tracker); + componentClassResolver, instantiator, resources, locale, tracker, request, symbolSource); // "Program" the assembler by adding actions to it. The actions interact with a // PageAssembly object (a fresh one for each new page being created). 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=1051319&r1=1051318&r2=1051319&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 20 23:44:31 2010 @@ -43,6 +43,7 @@ import org.apache.tapestry5.ioc.internal import org.apache.tapestry5.ioc.internal.util.Orderer; import org.apache.tapestry5.ioc.internal.util.TapestryException; import org.apache.tapestry5.ioc.services.PerThreadValue; +import org.apache.tapestry5.ioc.services.SymbolSource; import org.apache.tapestry5.ioc.util.AvailableValues; import org.apache.tapestry5.ioc.util.UnknownValueException; import org.apache.tapestry5.model.ComponentModel; @@ -54,6 +55,7 @@ import org.apache.tapestry5.runtime.Even import org.apache.tapestry5.runtime.PageLifecycleListener; import org.apache.tapestry5.runtime.RenderCommand; import org.apache.tapestry5.runtime.RenderQueue; +import org.apache.tapestry5.services.Request; import org.slf4j.Logger; /** @@ -236,6 +238,9 @@ public class ComponentPageElementImpl ex protected void invokeComponent(Component component, MarkupWriter writer, Event event) { + if (isRenderTracingEnabled()) + writer.comment("BEGIN " + component.getComponentResources().getCompleteId() + " (" + getLocation() + ")"); + component.beginRender(writer, event); } @@ -410,6 +415,9 @@ public class ComponentPageElementImpl ex protected void invokeComponent(Component component, MarkupWriter writer, Event event) { component.afterRender(writer, event); + + if (isRenderTracingEnabled()) + writer.comment("END " + component.getComponentResources().getCompleteId()); } public void render(final MarkupWriter writer, RenderQueue queue) @@ -543,6 +551,12 @@ public class ComponentPageElementImpl ex private final PerThreadValue<RenderPhaseEvent> renderEvent; private final PerThreadValue<Boolean> rendering; + + // should be okay since it's a shadow service object + private final Request request; + private final SymbolSource symbolSource; + private final boolean productionMode; + private final boolean componentTracingEnabled; // 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. @@ -576,7 +590,7 @@ public class ComponentPageElementImpl ex */ ComponentPageElementImpl(Page page, ComponentPageElement container, String id, String nestedId, String completeId, String elementName, Instantiator instantiator, Location location, - ComponentPageElementResources elementResources) + ComponentPageElementResources elementResources, Request request, SymbolSource symbolSource) { super(location); @@ -587,7 +601,13 @@ public class ComponentPageElementImpl ex this.completeId = completeId; this.elementName = elementName; this.elementResources = elementResources; - + this.request = request; + this.symbolSource = symbolSource; + + // evaluate this once because it gets referenced a lot during rendering + this.productionMode = "true".equals(symbolSource.valueForSymbol(SymbolConstants.PRODUCTION_MODE)); + this.componentTracingEnabled = "true".equals(symbolSource.valueForSymbol(SymbolConstants.COMPONENT_RENDER_TRACING_ENABLED)); + ComponentResources containerResources = container == null ? null : container.getComponentResources(); coreResources = new InternalComponentResourcesImpl(this.page, this, containerResources, this.elementResources, @@ -604,9 +624,9 @@ public class ComponentPageElementImpl ex /** * Constructor for the root component of a page. */ - public ComponentPageElementImpl(Page page, Instantiator instantiator, ComponentPageElementResources elementResources) + public ComponentPageElementImpl(Page page, Instantiator instantiator, ComponentPageElementResources elementResources, Request request, SymbolSource symbolSource) { - this(page, null, null, null, page.getName(), null, instantiator, null, elementResources); + this(page, null, null, null, page.getName(), null, instantiator, null, elementResources, request, symbolSource); } private void initializeRenderPhases() @@ -665,7 +685,7 @@ public class ComponentPageElementImpl ex Instantiator instantiator, Location location) { ComponentPageElementImpl child = new ComponentPageElementImpl(page, this, id, nestedId, completeId, - elementName, instantiator, location, elementResources); + elementName, instantiator, location, elementResources, request, symbolSource); addEmbeddedElement(child); @@ -1299,4 +1319,8 @@ public class ComponentPageElementImpl ex return result; } + + boolean isRenderTracingEnabled() { + return !productionMode && (componentTracingEnabled || "true".equals(request.getParameter("t:component-trace"))); + } } 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=1051319&r1=1051318&r2=1051319&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 20 23:44:31 2010 @@ -2477,6 +2477,7 @@ public final class TapestryModule configuration.add(InternalSymbols.PRE_SELECTED_FORM_NAMES, "reset,submit,select,id,method,action,onsubmit"); configuration.add(InternalSymbols.ALIAS_MODE, "servlet"); + configuration.add(SymbolConstants.COMPONENT_RENDER_TRACING_ENABLED, "false"); } /** Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/GeneralComponentTests.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/GeneralComponentTests.java?rev=1051319&r1=1051318&r2=1051319&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/GeneralComponentTests.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/GeneralComponentTests.java Mon Dec 20 23:44:31 2010 @@ -14,6 +14,9 @@ package org.apache.tapestry5.integration.app1; +import java.net.URL; + +import org.apache.commons.io.IOUtils; import org.apache.tapestry5.integration.TapestryCoreTestCase; import org.testng.annotations.Test; @@ -93,4 +96,18 @@ public class GeneralComponentTests exten assertText("xpath=(//p...@class='superhero'])[1]", "Steve Rogers"); assertText("xpath=(//p...@class='superhero'])[2]", "Bruce Banner"); } + + /** TAP5-742 */ + @Test public void component_tracing_comments() throws Exception { + String contents = IOUtils.toString(new URL(getBaseURL()).openStream()); + + // off by default + assertFalse(contents.contains("Index:loop")); + assertFalse(contents.contains("Index:pagelink")); + + // enable with a query parameter + contents = IOUtils.toString(new URL(getBaseURL() + "?t:component-trace=true").openStream()); + assertTrue(contents.contains("Index:loop")); + assertTrue(contents.contains("Index:pagelink")); + } } Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java?rev=1051319&view=auto ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java (added) +++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/ComponentPageElementImplTest.java Mon Dec 20 23:44:31 2010 @@ -0,0 +1,65 @@ +package org.apache.tapestry5.internal.structure; + +import static org.apache.tapestry5.SymbolConstants.COMPONENT_RENDER_TRACING_ENABLED; +import static org.apache.tapestry5.SymbolConstants.PRODUCTION_MODE; + +import org.apache.tapestry5.internal.services.Instantiator; +import org.apache.tapestry5.ioc.Location; +import org.apache.tapestry5.ioc.services.SymbolSource; +import org.apache.tapestry5.ioc.test.TestBase; +import org.apache.tapestry5.model.ComponentModel; +import org.apache.tapestry5.services.Request; +import org.testng.annotations.Test; + +public class ComponentPageElementImplTest extends TestBase { + /** TAP5-742 */ + @Test public void component_render_tracing() { + Request request = newMock(Request.class); + SymbolSource symbolSource = newMock(SymbolSource.class); + + Page page = getMocksControl().createMock(Page.class); + Instantiator instantiator = newMock(Instantiator.class); + Location location = newMock(Location.class); + ComponentPageElementResources elementResources = newMock(ComponentPageElementResources.class); + ComponentModel model = newMock(ComponentModel.class); + + getMocksControl().resetToNice(); + + expect(instantiator.getModel()).andReturn(model).anyTimes(); + + // off by default + expect(symbolSource.valueForSymbol(PRODUCTION_MODE)).andReturn("false"); + expect(symbolSource.valueForSymbol(COMPONENT_RENDER_TRACING_ENABLED)).andReturn("false"); + expect(request.getParameter("t:component-trace")).andReturn("false"); + + // enable by query parameter + expect(symbolSource.valueForSymbol(PRODUCTION_MODE)).andReturn("false"); + expect(symbolSource.valueForSymbol(COMPONENT_RENDER_TRACING_ENABLED)).andReturn("false"); + expect(request.getParameter("t:component-trace")).andReturn("true"); + + // enable by symbol + expect(symbolSource.valueForSymbol(PRODUCTION_MODE)).andReturn("false"); + expect(symbolSource.valueForSymbol(COMPONENT_RENDER_TRACING_ENABLED)).andReturn("true"); + expect(request.getParameter("t:component-trace")).andReturn("false"); + + // off no matter what in production mode + expect(symbolSource.valueForSymbol(PRODUCTION_MODE)).andReturn("true"); + expect(symbolSource.valueForSymbol(COMPONENT_RENDER_TRACING_ENABLED)).andReturn("true"); + expect(request.getParameter("t:component-trace")).andReturn("false"); + + replay(); + ComponentPageElementImpl c; // need to create every time because of changing symbols + + c = new ComponentPageElementImpl(page, null, "id", "nestedId", "completeid", "elementname", instantiator, location, elementResources, request, symbolSource); + assertFalse(c.isRenderTracingEnabled()); + + c = new ComponentPageElementImpl(page, null, "id", "nestedId", "completeid", "elementname", instantiator, location, elementResources, request, symbolSource); + assertTrue(c.isRenderTracingEnabled()); + + c = new ComponentPageElementImpl(page, null, "id", "nestedId", "completeid", "elementname", instantiator, location, elementResources, request, symbolSource); + assertTrue(c.isRenderTracingEnabled()); + + c = new ComponentPageElementImpl(page, null, "id", "nestedId", "completeid", "elementname", instantiator, location, elementResources, request, symbolSource); + assertFalse(c.isRenderTracingEnabled()); + } +}