You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by da...@apache.org on 2010/12/21 00:44:32 UTC

svn commit: r1051319 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/pageload/ main/java/org/apache/tapestry5/internal/structure/ main/java/org/apache/tapestry5/services/ test/ja...

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());
+	}
+}