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


Reply via email to