This is an automated email from the ASF dual-hosted git repository.

thiagohp pushed a commit to branch better-page-invalidation
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git


The following commit(s) were added to refs/heads/better-page-invalidation by 
this push:
     new abdd80ea1 TAP-2742: production mode fixed, PageCatalog too
abdd80ea1 is described below

commit abdd80ea18e765289810d318708deb34a38cbb1e
Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br>
AuthorDate: Fri Apr 28 23:30:39 2023 -0300

    TAP-2742: production mode fixed, PageCatalog too
---
 .../tapestry5/corelib/pages/PageCatalog.java       | 191 ++++++++++++++++++++-
 .../internal/services/PageSourceImpl.java          |   1 +
 .../PageClassloaderContextManagerImpl.java         |  52 ++----
 .../integration/app1/components/Border.tml         |   2 +-
 4 files changed, 203 insertions(+), 43 deletions(-)

diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
index abaedb62d..e887c0da1 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
@@ -14,31 +14,53 @@
 
 package org.apache.tapestry5.corelib.pages;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.alerts.AlertManager;
-import org.apache.tapestry5.annotations.*;
+import org.apache.tapestry5.annotations.InjectComponent;
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.UnknownActivationContextCheck;
+import org.apache.tapestry5.annotations.WhitelistAccessOnly;
 import org.apache.tapestry5.beaneditor.Validate;
 import org.apache.tapestry5.beanmodel.BeanModel;
 import org.apache.tapestry5.beanmodel.services.BeanModelSource;
 import org.apache.tapestry5.commons.Messages;
+import org.apache.tapestry5.commons.services.InvalidationEventHub;
 import org.apache.tapestry5.commons.util.CollectionFactory;
 import org.apache.tapestry5.corelib.components.Zone;
-import org.apache.tapestry5.func.*;
+import org.apache.tapestry5.dom.Element;
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Flow;
+import org.apache.tapestry5.func.Mapper;
+import org.apache.tapestry5.func.Predicate;
+import org.apache.tapestry5.func.Reducer;
 import org.apache.tapestry5.http.TapestryHttpSymbolConstants;
+import org.apache.tapestry5.http.services.Request;
 import org.apache.tapestry5.internal.PageCatalogTotals;
+import 
org.apache.tapestry5.internal.services.ComponentDependencyGraphvizGenerator;
+import org.apache.tapestry5.internal.services.ComponentDependencyRegistry;
 import org.apache.tapestry5.internal.services.PageSource;
 import org.apache.tapestry5.internal.services.ReloadHelper;
+import org.apache.tapestry5.internal.structure.ComponentPageElement;
 import org.apache.tapestry5.internal.structure.Page;
 import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.annotations.ComponentClasses;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.annotations.Symbol;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.runtime.Component;
 import org.apache.tapestry5.services.ComponentClassResolver;
+import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
 import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
 /**
  * Lists out the currently loaded pages, using a {@link 
org.apache.tapestry5.corelib.components.Grid}.
  * Provides an option to force all pages to be loaded. In development mode, 
includes an option to clear the page cache.
@@ -64,6 +86,9 @@ public class PageCatalog
 
     @Inject
     private ComponentClassResolver resolver;
+    
+    @Inject
+    private ComponentDependencyRegistry componentDependencyRegistry;
 
     @Inject
     private AlertManager alertManager;
@@ -71,8 +96,17 @@ public class PageCatalog
     @Property
     private Page page;
 
+    @Property
+    private Page selectedPage;
+
+    @Property
+    private String dependency;
+
     @InjectComponent
     private Zone pagesZone;
+    
+    @InjectComponent
+    private Zone pageStructureZone;
 
     @Persist
     private Set<String> failures;
@@ -90,13 +124,32 @@ public class PageCatalog
 
     @Inject
     private BeanModelSource beanModelSource;
-
+    
     @Inject
     private Messages messages;
 
     @Property
     public static BeanModel<Page> model;
 
+    @Inject 
+    private Request request;
+    
+    @Inject
+    @ComponentClasses 
+    private InvalidationEventHub classesInvalidationEventHub;
+    
+    @Inject
+    private JavaScriptSupport javaScriptSupport;
+    
+    @Inject
+    private ComponentDependencyGraphvizGenerator 
componentDependencyGraphvizGenerator;
+
+    @Inject
+    private ComponentClassResolver componentClassResolver;
+
+    @Inject
+    private AjaxResponseRenderer ajaxResponseRenderer;
+    
     void pageLoaded()
     {
         model = beanModelSource.createDisplayModel(Page.class, messages);
@@ -105,6 +158,7 @@ public class PageCatalog
         model.addExpression("assemblyTime", "stats.assemblyTime");
         model.addExpression("componentCount", "stats.componentCount");
         model.addExpression("weight", "stats.weight");
+        model.add("clear", null);
 
         model.reorder("name", "selector", "assemblyTime", "componentCount", 
"weight");
     }
@@ -153,7 +207,16 @@ public class PageCatalog
     {
         return pageSource.getAllPages();
     }
-
+    
+    Object onClearPage(String className)
+    {
+        final String logicalName = resolver.getLogicalName(className);
+        
classesInvalidationEventHub.fireInvalidationEvent(Arrays.asList(className));
+        alertManager.warn(String.format("Page %s (%s) has been cleared from 
the page cache",
+                className, logicalName));
+        return pagesZone.getBody();
+    }
+    
     Object onSuccessFromSinglePageLoad()
     {
         boolean found = !F.flow(getPages()).filter(new Predicate<Page>()
@@ -270,6 +333,19 @@ public class PageCatalog
 
         return pagesZone.getBody();
     }
+    
+    Object onActionFromStoreDependencyInformation()
+    {
+        
+        componentDependencyRegistry.writeFile();
+        
+        alertManager.warn(String.format(
+                "Component dependency information written to %s.", 
+                ComponentDependencyRegistry.FILENAME));
+        
+        return pagesZone.getBody();
+        
+    }
 
     Object onActionFromRunGC()
     {
@@ -291,4 +367,103 @@ public class PageCatalog
     {
         return String.format("%,.3f ms", millis);
     }
+    
+    public List<String> getDependencies() 
+    {
+        List<String> dependencies = new 
ArrayList<>(componentDependencyRegistry.getDependencies(getSelectedPageClassName()));
+        Collections.sort(dependencies);
+        return dependencies;
+    }
+    
+    public void onPageStructure(String pageName)
+    {
+        selectedPage = pageSource.getPage(pageName);
+        ajaxResponseRenderer.addRender("pageStructureZone", 
pageStructureZone.getBody());
+    }
+    
+    public String getDisplayLogicalName() 
+    {
+        return getDisplayLogicalName(dependency);
+    }
+
+    public String getPageClassName() 
+    {
+        return getClassName(page);
+    }
+
+    public String getSelectedPageClassName() 
+    {
+        return getClassName(selectedPage);
+    }
+    
+    private String getClassName(Page page) 
+    {
+        return 
page.getRootComponent().getComponentResources().getComponentModel().getComponentClassName();
+    }
+
+    private String getClassName(Component component) 
+    {
+        return 
component.getComponentResources().getComponentModel().getComponentClassName();
+    }
+
+    public void onComponentTree(MarkupWriter writer) 
+    {
+        render(selectedPage.getRootElement(), writer);
+    }
+    
+    private void render(ComponentPageElement componentPageElement, 
MarkupWriter writer) 
+    {
+        final Element li = writer.element("li");
+        final String className = 
getClassName(componentPageElement.getComponent());
+        final Set<String> embeddedElementIds = 
componentPageElement.getEmbeddedElementIds();
+        
+        if 
(componentPageElement.getComponent().getComponentResources().getComponentModel().isPage())
 
+        {
+            li.text(componentPageElement.getPageName());
+        }
+        else {
+            li.text(String.format("%s (%s)", getDisplayLogicalName(className), 
componentPageElement.getId()));
+        }
+        
+        if (!embeddedElementIds.isEmpty())
+        {
+            writer.element("ul");
+            for (String id : embeddedElementIds)
+            {
+                render(componentPageElement.getEmbeddedElement(id), writer);
+            }
+            writer.end();
+        }
+        
+        writer.end();
+    }
+
+    private String getDisplayLogicalName(final String className) 
+    {
+        final String logicalName = resolver.getLogicalName(className);
+        String displayName = logicalName;
+        if (logicalName == null || logicalName.trim().length() == 0)
+        {
+            if (className.contains(".base."))
+            {
+                displayName = "(base class)";
+            }
+            if (className.contains(".mixins."))
+            {
+                displayName = "(mixin)";
+            }
+        }
+        return displayName;
+    }
+
+    public String getLogicalName(String className) 
+    {
+        return resolver.getLogicalName(className);
+    }
+    
+    public String getGraphvizValue()
+    {
+        return 
componentDependencyGraphvizGenerator.generate(getClassName(selectedPage));
+    }
+    
 }
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
index b442646c6..a93720f72 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
@@ -182,6 +182,7 @@ public class PageSourceImpl implements PageSource
 
             pageCache.put(key, ref);
             
+            // TODO: remove this?
             if (!productionMode)
             {
                 final ComponentPageElement rootElement = page.getRootElement();
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassloaderContextManagerImpl.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassloaderContextManagerImpl.java
index 054129f44..52fb9300c 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassloaderContextManagerImpl.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassloaderContextManagerImpl.java
@@ -24,14 +24,12 @@ import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.commons.internal.util.TapestryException;
 import org.apache.tapestry5.commons.services.InvalidationEventHub;
 import org.apache.tapestry5.commons.services.PlasticProxyFactory;
 import org.apache.tapestry5.internal.services.ComponentDependencyRegistry;
 import 
org.apache.tapestry5.internal.services.InternalComponentInvalidationEventHub;
 import org.apache.tapestry5.ioc.annotations.ComponentClasses;
-import org.apache.tapestry5.ioc.annotations.Symbol;
 import org.apache.tapestry5.plastic.PlasticUtils;
 import org.apache.tapestry5.services.ComponentClassResolver;
 import org.slf4j.Logger;
@@ -55,8 +53,6 @@ public class PageClassloaderContextManagerImpl implements 
PageClassloaderContext
     
     private final InvalidationEventHub componentClassesInvalidationEventHub;
     
-    private final boolean productionMode;
-    
     private final static ThreadLocal<Integer> NESTED_MERGE_COUNT = 
ThreadLocal.withInitial(() -> 0);
     
     private final static ThreadLocal<Boolean> INVALIDATING_CONTEXT = 
ThreadLocal.withInitial(() -> false);
@@ -71,15 +67,13 @@ public class PageClassloaderContextManagerImpl implements 
PageClassloaderContext
             final ComponentDependencyRegistry componentDependencyRegistry, 
             final ComponentClassResolver componentClassResolver,
             final InternalComponentInvalidationEventHub invalidationHub,
-            final @ComponentClasses InvalidationEventHub 
componentClassesInvalidationEventHub,
-            @Symbol(SymbolConstants.PRODUCTION_MODE) final boolean 
productionMode) 
+            final @ComponentClasses InvalidationEventHub 
componentClassesInvalidationEventHub) 
     {
         super();
         this.componentDependencyRegistry = componentDependencyRegistry;
         this.componentClassResolver = componentClassResolver;
         this.invalidationHub = invalidationHub;
         this.componentClassesInvalidationEventHub = 
componentClassesInvalidationEventHub;
-        this.productionMode = productionMode;
         invalidationHub.addInvalidationCallback(this::listen);
         NESTED_MERGE_COUNT.set(0);
     }
@@ -105,38 +99,28 @@ public class PageClassloaderContextManagerImpl implements 
PageClassloaderContext
     {
         PageClassloaderContext context;
         
-        if (productionMode)
-        {
-            root.addClass(className);
-            context = root;
-        }
-        else
+        final String enclosingClassName = 
PlasticUtils.getEnclosingClassName(className);
+        context = root.findByClassName(enclosingClassName);
+        
+        if (context == null)
         {
+            Set<String> classesToInvalidate = new HashSet<>();
             
-            final String enclosingClassName = 
PlasticUtils.getEnclosingClassName(className);
-            context = root.findByClassName(enclosingClassName);
+            context = processUsingDependencies(
+                    enclosingClassName, 
+                    root, 
+                    () -> getUnknownContext(root, plasticProxyFactoryProvider),
+                    plasticProxyFactoryProvider,
+                    classesToInvalidate);
             
-            if (context == null)
+            if (!classesToInvalidate.isEmpty())
             {
-                Set<String> classesToInvalidate = new HashSet<>();
-                
-                context = processUsingDependencies(
-                        enclosingClassName, 
-                        root, 
-                        () -> getUnknownContext(root, 
plasticProxyFactoryProvider),
-                        plasticProxyFactoryProvider,
-                        classesToInvalidate);
-                
-                if (!classesToInvalidate.isEmpty())
-                {
-                    invalidate(classesToInvalidate);
-                }
+                invalidate(classesToInvalidate);
+            }
 
-                if (!className.equals(enclosingClassName))
-                {
-                    loadClass(className, context);
-                }
-                
+            if (!className.equals(enclosingClassName))
+            {
+                loadClass(className, context);
             }
             
         }
diff --git 
a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
index 2a2941e0e..908c91961 100644
--- 
a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
+++ 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/Border.tml
@@ -44,7 +44,7 @@
         <t:devtool class="pull-right"/>
 
         <t:remove>alert-class is for the AlertsTest.check_informal_parameters 
test</t:remove>
-        <pre>${pccm.root.toRecursiveString().trim()}</pre>
+<!--         <pre>${pccm.root.toRecursiveString().trim()}</pre> -->
         <t:alerts class="alert-class"/>
 
         <t:body/>

Reply via email to