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 f954dd70d TAP5-2742: fixing NestedBeanEditor test
f954dd70d is described below

commit f954dd70d2309cafa0c1dd76652a02f5aeda062c
Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br>
AuthorDate: Wed May 10 18:49:58 2023 -0300

    TAP5-2742: fixing NestedBeanEditor test
---
 .../services/ComponentDependencyRegistry.java      |  7 ++++
 .../services/ComponentDependencyRegistryImpl.java  | 46 ++++++++++++++++++----
 .../internal/services/PageSourceImpl.java          | 35 ++++++++++++----
 .../internal/transform/InjectPageWorker.java       | 15 +++++--
 .../integration/app1/pages/NestedBeanDisplay.java  |  5 ++-
 5 files changed, 87 insertions(+), 21 deletions(-)

diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistry.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistry.java
index e2f10469a..5eebb690e 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistry.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistry.java
@@ -77,9 +77,16 @@ public interface ComponentDependencyRegistry {
     
     /**
      * Returns the fully qualified names of the direct dependencies of a given 
component.
+     * Doesn't include dependencies that are pages.
      */
     Set<String> getDependencies(String className);
     
+    /**
+     * Returns the fully qualified names of the direct dependencies of a given 
component,
+     * but just the ones that are pages.
+     */
+    Set<String> getPageDependencies(String className);
+    
     /**
      * Signs up this registry to invalidation events from a given hub.
      */
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
index 9e5198cef..e86c701ec 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
@@ -31,7 +31,9 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.WeakHashMap;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import org.apache.tapestry5.ComponentResources;
@@ -94,6 +96,8 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
     
     final private TemplateParser templateParser;
     
+    final private Map<String, Boolean> isPageCache = new WeakHashMap<>();
+    
     @SuppressWarnings("deprecation")
     final private ComponentTemplateLocator componentTemplateLocator;
     
@@ -209,8 +213,6 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
             add(component, superclass);
         }
         
-        Set<String> dynamicDependencies;
-
         alreadyProcessed.add(className);
         
         for (Class<?> dependency : furtherDependencies) 
@@ -240,12 +242,12 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
         // by listening separaterly to ComponentTemplateSource to invalidate 
caches
         // just when template changes.
         
-        ComponentModel mock = new ComponentModelMock(component, 
resolver.isPage(component.getName()));
+        final String className = component.getName();
+        ComponentModel mock = new ComponentModelMock(component, 
isPage(className));
         final Resource templateResource = 
componentTemplateLocator.locateTemplate(mock, Locale.getDefault());
         String dependency;
         if (templateResource != null)
         {
-            final String className = component.getName();
             final ComponentTemplate template = 
templateParser.parseTemplate(templateResource);
             for (TemplateToken token:  template.getTokens())
             {
@@ -269,6 +271,22 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
             }
         }
     }
+    
+    private boolean isNotPage(final String className) 
+    {
+        return !isPage(className);
+    }
+
+    private boolean isPage(final String className) 
+    {
+        Boolean result = isPageCache.get(className);
+        if (result == null)
+        {
+            result = resolver.isPage(className);
+            isPageCache.put(className, result);
+        }
+        return result;
+    }
 
     private void registerComponentInstance(Field field, Consumer<String> 
processClassName)
     {
@@ -491,9 +509,8 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
         final Set<String> dependents = map.get(className);
         return dependents != null ? dependents : Collections.emptySet();
     }
-
-    @Override
-    public Set<String> getDependencies(String className) 
+    
+    private Set<String> getDependencies(String className, Predicate<String> 
filter) 
     {
         Set<String> dependencies = Collections.emptySet();
         if (alreadyProcessed.contains(className))
@@ -501,12 +518,25 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
             dependencies = map.entrySet().stream()
                 .filter(e -> e.getValue().contains(className))
                 .map(e -> e.getKey())
+                .filter(filter)
                 .collect(Collectors.toSet());
         }
         
         return dependencies;
     }
 
+    @Override
+    public Set<String> getDependencies(String className) 
+    {
+        return getDependencies(className, this::isNotPage);
+    }
+    
+    @Override
+    public Set<String> getPageDependencies(String className) 
+    {
+        return getDependencies(className, this::isPage);
+    }
+
     private void add(ComponentPageElement component, ComponentPageElement 
dependency) 
     {
         add(getClassName(component), getClassName(dependency));
@@ -570,7 +600,7 @@ public class ComponentDependencyRegistryImpl implements 
ComponentDependencyRegis
         }
         // Don't invalidate component dependency information when 
         // PageClassloaderContextManager is merging contexts
-        // TODO is this still needed since the inception of 
INVALIDATIONS_ENABLED? 
+        // TODO: is this still needed since the inception of 
INVALIDATIONS_ENABLED? 
         else if (!pageClassloaderContextManager.isMerging())
         {
             furtherDependents = new ArrayList<>();
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 afcb51fdb..e95056278 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
@@ -143,12 +143,20 @@ public class PageSourceImpl implements PageSource
             // Avoiding problems in PlasticClassPool.createTransformation()
             // when the class being loaded has a page superclass
             final String className = 
componentClassResolver.resolvePageNameToClassName(canonicalPageName);
-            PageClassloaderContext context = 
pageClassloaderContextManager.get(className);
-            final Class<?> superclass = getSuperclass(className, context);
-            final String superclassName = superclass.getName();
-            if (componentClassResolver.isPage(superclassName)) 
+//            PageClassloaderContext context = 
pageClassloaderContextManager.get(className);
+//            final Class<?> superclass = getSuperclass(className, context);
+//            final String superclassName = superclass.getName();
+//            if (componentClassResolver.isPage(superclassName)) 
+//            {
+//                
getPage(componentClassResolver.resolvePageClassNameToPageName(superclassName), 
false);
+//            }
+            final Set<String> pageDependencies = 
componentDependencyRegistry.getPageDependencies(className);
+            
+            preprocessPageClassLoaderContexts(className, pageDependencies);
+            
+            for (String pageClassName : pageDependencies)
             {
-                
getPage(componentClassResolver.resolvePageClassNameToPageName(superclassName), 
false);
+                page = 
getPage(componentClassResolver.resolvePageClassNameToPageName(pageClassName), 
false);
             }
 
             // In rare race conditions, we may see the same page loaded 
multiple times across
@@ -167,20 +175,31 @@ public class PageSourceImpl implements PageSource
                 final ComponentPageElement rootElement = page.getRootElement();
                 componentDependencyRegistry.clear(rootElement);
                 componentDependencyRegistry.register(rootElement);
-                context = pageClassloaderContextManager.get(className);
-                if (context.isUnknown())
+                PageClassloaderContext context = 
pageClassloaderContextManager.get(className);
+                if (invalidateUnknownContext && context.isUnknown())
                 {
                     componentDependencyRegistry.disableInvalidations();
                     
pageClassloaderContextManager.invalidateAndFireInvalidationEvents(context);
                     componentDependencyRegistry.enableInvalidations();
                     pageClassloaderContextManager.get(className);
-                    return getPage(canonicalPageName);
+                    return getPage(canonicalPageName, false);
                 }
             }
             
         }
     }
 
+    private void preprocessPageClassLoaderContexts(String className, final 
Set<String> pageDependencies) {
+        for (int i = 0; i < 2; i++)
+        {
+            pageClassloaderContextManager.get(className);
+            for (String pageClassName : pageDependencies)
+            {
+                pageClassloaderContextManager.get(pageClassName);
+            }
+        }
+    }
+
     private Class<?> getSuperclass(final String className, 
PageClassloaderContext context) 
     {
         try {
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectPageWorker.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectPageWorker.java
index dc36b58f4..e7f4ba399 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectPageWorker.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/InjectPageWorker.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010, 2011, 2023 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.
@@ -16,6 +16,7 @@ package org.apache.tapestry5.internal.transform;
 
 import org.apache.tapestry5.annotations.InjectPage;
 import org.apache.tapestry5.commons.ObjectCreator;
+import org.apache.tapestry5.internal.services.ComponentDependencyRegistry;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.PerthreadManager;
 import org.apache.tapestry5.model.MutableComponentModel;
@@ -65,22 +66,26 @@ public class InjectPageWorker implements 
ComponentClassTransformWorker2
 
     private final PerthreadManager perThreadManager;
 
-    public InjectPageWorker(ComponentSource componentSource, 
ComponentClassResolver resolver, PerthreadManager perThreadManager)
+    private final ComponentDependencyRegistry componentDependencyRegistry;
+
+    public InjectPageWorker(ComponentSource componentSource, 
ComponentClassResolver resolver, PerthreadManager perThreadManager,
+            ComponentDependencyRegistry componentDependencyRegistry)
     {
         this.componentSource = componentSource;
         this.resolver = resolver;
         this.perThreadManager = perThreadManager;
+        this.componentDependencyRegistry = componentDependencyRegistry;
     }
 
     public void transform(PlasticClass plasticClass, TransformationSupport 
support, MutableComponentModel model)
     {
         for (PlasticField field : 
plasticClass.getFieldsWithAnnotation(InjectPage.class))
         {
-            addInjectedPage(field);
+            addInjectedPage(field, model);
         }
     }
 
-    private void addInjectedPage(PlasticField field)
+    private void addInjectedPage(PlasticField field, MutableComponentModel 
model)
     {
         InjectPage annotation = field.getAnnotation(InjectPage.class);
 
@@ -94,5 +99,7 @@ public class InjectPageWorker implements 
ComponentClassTransformWorker2
                 .resolvePageClassNameToPageName(field.getTypeName()) : 
pageName;
 
         field.setConduit(new 
InjectedPageConduit(field.getPlasticClass().getClassName(), fieldName, 
injectedPageName));
+        
+        componentDependencyRegistry.register(field, model);
     }
 }
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
index 157ef7df8..02c434039 100644
--- 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/NestedBeanDisplay.java
@@ -24,7 +24,10 @@ public class NestedBeanDisplay
     @Property
     private Person parent;
 
-    Object initialize(Person person)
+    // Visibility changed from package-private to public due to smarter page 
invalidation
+    // (classes in different classloaders cannot access non-public method
+    // TODO: maybe find some way to avoid this?
+    public Object initialize(Person person)
     {
         parent = person;
 

Reply via email to