This is an automated email from the ASF dual-hosted git repository.
thiagohp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
The following commit(s) were added to refs/heads/master by this push:
new 39f6cb203 TAP5-2803: support for global per-thread ES module config
callbacks
39f6cb203 is described below
commit 39f6cb20315b8b5fa7d9c6953a0863a989ba26cd
Author: Thiago H. de Paula Figueiredo <[email protected]>
AuthorDate: Sat May 3 12:38:44 2025 -0300
TAP5-2803: support for global per-thread ES module config callbacks
---
.../services/javascript/EsModuleManagerImpl.java | 42 ++++++++++------
.../javascript/EsModuleConfigurationCallback.java | 28 +++++++++++
.../services/javascript/EsModuleManager.java | 57 ++++++++++++++++++++-
.../tapestry5/integration/app1/EsModuleTests.java | 8 +++
.../integration/app1/pages/EsModuleDemo.java | 5 ++
.../integration/app1/services/AppModule.java | 58 +++++++++++++++-------
6 files changed, 163 insertions(+), 35 deletions(-)
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/EsModuleManagerImpl.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/EsModuleManagerImpl.java
index 9f9bf5aea..97f95a554 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/EsModuleManagerImpl.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/javascript/EsModuleManagerImpl.java
@@ -13,6 +13,7 @@
package org.apache.tapestry5.internal.services.javascript;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -27,7 +28,6 @@ import org.apache.tapestry5.http.TapestryHttpSymbolConstants;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.services.ajax.EsModuleInitializationImpl;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
-import org.apache.tapestry5.ioc.annotations.PostInjection;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.services.ClasspathMatcher;
import org.apache.tapestry5.ioc.services.ClasspathScanner;
@@ -70,10 +70,12 @@ public class EsModuleManagerImpl implements EsModuleManager
private final ResourceChangeTracker resourceChangeTracker;
- private final List<EsModuleConfigurationCallback> globalCallbacks;
+ private final List<EsModuleConfigurationCallback> baseCallbacks;
+
+ private final List<EsModuleConfigurationCallback>
globalPerRequestCallbacks;
public EsModuleManagerImpl(
- List<EsModuleConfigurationCallback>
globalCallbacks,
+ List<EsModuleManagerContribution> contributions,
AssetSource assetSource,
StreamableResourceSource streamableResourceSource,
@Symbol(SymbolConstants.COMPACT_JSON)
@@ -86,9 +88,24 @@ public class EsModuleManagerImpl implements EsModuleManager
this.compactJSON = compactJSON;
this.assetSource = assetSource;
this.classpathScanner = classpathScanner;
- this.globalCallbacks = globalCallbacks;
this.productionMode = productionMode;
this.resourceChangeTracker = resourceChangeTracker;
+
+ baseCallbacks = new ArrayList<>();
+ globalPerRequestCallbacks = new ArrayList<>();
+
+ for (EsModuleManagerContribution contribution : contributions)
+ {
+ if (contribution.isBase())
+ {
+ baseCallbacks.add(contribution.getCallback());
+ }
+ else
+ {
+ globalPerRequestCallbacks.add(contribution.getCallback());
+ }
+ }
+
importMap = new JSONObject();
extensions = CollectionFactory.newSet("js");
@@ -114,12 +131,14 @@ public class EsModuleManagerImpl implements
EsModuleManager
imports.put(name, cache.get(name));
}
- this.importMap = executeCallbacks(importMap, globalCallbacks);
+ executeCallbacks(importMap, baseCallbacks);
for (String id : imports.keySet())
{
cache.put(id, imports.getString(id));
}
+
+ this.importMap = importMap;
}
@@ -145,12 +164,6 @@ public class EsModuleManagerImpl implements EsModuleManager
}
}
- @PostInjection
- public void setupInvalidation(ResourceChangeTracker tracker)
- {
-
- }
-
@Override
public void writeImportMap(Element head,
List<EsModuleConfigurationCallback> moduleConfigurationCallbacks) {
@@ -160,7 +173,8 @@ public class EsModuleManagerImpl implements EsModuleManager
JSONObject newImportMap = new JSONObject(
EsModuleConfigurationCallback.IMPORTS_ATTRIBUTE, imports);
- newImportMap = executeCallbacks(newImportMap,
moduleConfigurationCallbacks);
+ executeCallbacks(newImportMap, moduleConfigurationCallbacks);
+ executeCallbacks(newImportMap, globalPerRequestCallbacks);
head.element("script")
.attribute("type", "importmap")
@@ -332,14 +346,12 @@ public class EsModuleManagerImpl implements
EsModuleManager
script.attribute("type", "module");
}
- private JSONObject executeCallbacks(JSONObject importMap,
List<EsModuleConfigurationCallback> callbacks)
+ private void executeCallbacks(JSONObject importMap,
List<EsModuleConfigurationCallback> callbacks)
{
for (EsModuleConfigurationCallback callback : callbacks)
{
callback.configure(importMap);
}
-
- return importMap;
}
}
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleConfigurationCallback.java
b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleConfigurationCallback.java
index eb0e6adf9..2916b6374 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleConfigurationCallback.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleConfigurationCallback.java
@@ -13,6 +13,7 @@
package org.apache.tapestry5.services.javascript;
import org.apache.tapestry5.json.JSONObject;
+import
org.apache.tapestry5.services.javascript.EsModuleManager.EsModuleManagerContribution;
/**
* Interface used to to change the JSON configuration object which will be
used in the
@@ -59,4 +60,31 @@ public interface EsModuleConfigurationCallback
{
object.in(IMPORTS_ATTRIBUTE).put(id, url);
}
+
+ /**
+ * Creates a base contribution (one that contributes a callback used
+ * when creating the base import map to be used for all requests).
+ * Utility method to call {@linkplain
EsModuleManagerContribution#base(EsModuleConfigurationCallback)}
+ * @param callback an {@linkplain EsModuleConfigurationCallback} instance.
+ * @return a corresponding {@linkplain EsModuleManagerContribution}.
+ */
+ public static EsModuleManagerContribution
toBaseContribution(EsModuleConfigurationCallback callback)
+ {
+ return EsModuleManagerContribution.base(callback);
+ }
+
+ /**
+ * Creates a global per-request contribution (one that contributes a
callback used
+ * in all requests after the callbacks added through
+ * {@linkplain
JavaScriptSupport#addEsModuleConfigurationCallback(EsModuleConfigurationCallback)}
+ * were called).
+ * Utility method to call {@linkplain
EsModuleManagerContribution#globalPerRequest(EsModuleConfigurationCallback)}
+ * @param callback an {@linkplain EsModuleConfigurationCallback} instance.
+ * @return a corresponding {@linkplain EsModuleManagerContribution}.
+ */
+ public static EsModuleManagerContribution
toGlobalPerRequestContribution(EsModuleConfigurationCallback callback)
+ {
+ return EsModuleManagerContribution.globalPerRequest(callback);
+ }
+
}
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleManager.java
b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleManager.java
index 19cfec30b..70a3b00b0 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleManager.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/services/javascript/EsModuleManager.java
@@ -16,6 +16,7 @@ import java.util.List;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.ioc.annotations.UsesOrderedConfiguration;
+import
org.apache.tapestry5.services.javascript.EsModuleManager.EsModuleManagerContribution;
/**
* Responsible for managing access to the ES modules. This service's
distributed
@@ -25,7 +26,7 @@ import
org.apache.tapestry5.ioc.annotations.UsesOrderedConfiguration;
* @since 5.10.0
* @see EsModuleConfigurationCallback
*/
-@UsesOrderedConfiguration(EsModuleConfigurationCallback.class)
+@UsesOrderedConfiguration(EsModuleManagerContribution.class)
public interface EsModuleManager
{
/**
@@ -53,5 +54,59 @@ public interface EsModuleManager
* specify initialization on the page, based on loading modules,
extacting functions from modules, and invoking those functions
*/
void writeImports(Element root, List<EsModuleInitialization> inits);
+
+ /**
+ * Encapsulates a contribution to {@linkplain EsModuleManager}.
+ *
+ * @since 5.10.0
+ * @see EsModuleManager
+ * @see EsModuleConfigurationCallback
+ */
+ public final class EsModuleManagerContribution
+ {
+ private final EsModuleConfigurationCallback callback;
+
+ private final boolean isBase;
+
+ EsModuleManagerContribution(EsModuleConfigurationCallback callback,
boolean isBase)
+ {
+ super();
+ this.callback = callback;
+ this.isBase = isBase;
+ }
+
+ /**
+ * Creates a base contribution (one that contributes a callback used
+ * when creating the base import map to be used for all requests).
+ * @param callback an {@linkplain EsModuleConfigurationCallback}
instance.
+ * @return a corresponding {@linkplain EsModuleManagerContribution}.
+ */
+ public static EsModuleManagerContribution
base(EsModuleConfigurationCallback callback)
+ {
+ return new EsModuleManagerContribution(callback, true);
+ }
+
+ /**
+ * Creates a global per-request contribution (one that contributes a
callback used
+ * in all requests after the callbacks added through
+ * {@linkplain
JavaScriptSupport#addEsModuleConfigurationCallback(EsModuleConfigurationCallback)}
+ * were called).
+ * @param callback an {@linkplain EsModuleConfigurationCallback}
instance.
+ * @return a corresponding {@linkplain EsModuleManagerContribution}.
+ */
+ public static EsModuleManagerContribution
globalPerRequest(EsModuleConfigurationCallback callback)
+ {
+ return new EsModuleManagerContribution(callback, false);
+ }
+
+ public EsModuleConfigurationCallback getCallback() {
+ return callback;
+ }
+
+ public boolean isBase() {
+ return isBase;
+ }
+
+ }
}
diff --git
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/EsModuleTests.java
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/EsModuleTests.java
index 786d9ce0b..aeb433496 100644
---
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/EsModuleTests.java
+++
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/EsModuleTests.java
@@ -12,10 +12,13 @@
package org.apache.tapestry5.integration.app1;
+
import static
org.apache.tapestry5.integration.app1.services.AppModule.NON_OVERRIDDEN_ES_MODULE_ID;
import static
org.apache.tapestry5.integration.app1.services.AppModule.NON_OVERRIDDEN_ES_MODULE_URL;
import static
org.apache.tapestry5.integration.app1.services.AppModule.OVERRIDDEN_ES_MODULE_ID;
import static
org.apache.tapestry5.integration.app1.services.AppModule.OVERRIDDEN_ES_MODULE_NEW_URL;
+import static
org.apache.tapestry5.integration.app1.services.AppModule.OVERRIDDEN_GLOBALLY_ES_MODULE_ID;
+import static
org.apache.tapestry5.integration.app1.services.AppModule.OVERRIDDEN_GLOBALLY_ES_MODULE_NEW_URL;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.integration.app1.pages.EsModuleDemo;
@@ -83,6 +86,11 @@ public class EsModuleTests extends App1TestCase
JSONObject importMap = getImportMap();
assertModuleUrl(NON_OVERRIDDEN_ES_MODULE_ID,
NON_OVERRIDDEN_ES_MODULE_URL, importMap);
assertModuleUrl(OVERRIDDEN_ES_MODULE_ID,
EsModuleDemo.REQUEST_OVERRIDEN_MODULE_URL, importMap);
+
+ // Module first defined through callback added to JavaScriptSupport,
+ // then overriden by a global per-request callback.
+ assertModuleUrl(OVERRIDDEN_GLOBALLY_ES_MODULE_ID,
OVERRIDDEN_GLOBALLY_ES_MODULE_NEW_URL, importMap);
+
// Now without import map changed by request callbacks, so we can test
// the global import map wasn't affected.
diff --git
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EsModuleDemo.java
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EsModuleDemo.java
index 49c38710d..e6eb761e3 100644
---
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EsModuleDemo.java
+++
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EsModuleDemo.java
@@ -79,6 +79,11 @@ public class EsModuleDemo
AppModule.OVERRIDDEN_ES_MODULE_ID,
REQUEST_OVERRIDEN_MODULE_URL));
}
+ javaScriptSupport.addEsModuleConfigurationCallback(
+ o -> EsModuleConfigurationCallback.setImport(o,
+ AppModule.OVERRIDDEN_GLOBALLY_ES_MODULE_ID,
+
AppModule.OVERRIDDEN_GLOBALLY_ES_MODULE_ORIGINAL_URL));
+
}
void onActivate(boolean overrideEsModuleImportAgain)
diff --git
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
index e8b91f4d0..d067f8cac 100644
---
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
+++
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
@@ -14,6 +14,9 @@ package org.apache.tapestry5.integration.app1.services;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static
org.apache.tapestry5.services.javascript.EsModuleConfigurationCallback.setImport;
+import static
org.apache.tapestry5.services.javascript.EsModuleConfigurationCallback.toBaseContribution;
+import static
org.apache.tapestry5.services.javascript.EsModuleConfigurationCallback.toGlobalPerRequestContribution;
import java.io.IOException;
import java.lang.annotation.Documented;
@@ -60,6 +63,7 @@ import org.apache.tapestry5.services.ResourceDigestGenerator;
import org.apache.tapestry5.services.ValueEncoderFactory;
import org.apache.tapestry5.services.ValueLabelProvider;
import org.apache.tapestry5.services.javascript.EsModuleConfigurationCallback;
+import
org.apache.tapestry5.services.javascript.EsModuleManager.EsModuleManagerContribution;
import org.apache.tapestry5.services.pageload.PageCachingReferenceTypeService;
import org.apache.tapestry5.services.pageload.PagePreloader;
import org.apache.tapestry5.services.pageload.PreloaderMode;
@@ -488,32 +492,48 @@ public class AppModule
public static final String OVERRIDDEN_ES_MODULE_ORIGINAL_URL =
"/originalURL";
public static final String OVERRIDDEN_ES_MODULE_NEW_URL = "/overridenURL";
+
+ public static final String OVERRIDDEN_GLOBALLY_ES_MODULE_ID =
"globallyPerRequestOverriden";
+
+ public static final String OVERRIDDEN_GLOBALLY_ES_MODULE_ORIGINAL_URL =
"/globallyPerRequestOverridenOriginalURL";
+
+ public static final String OVERRIDDEN_GLOBALLY_ES_MODULE_NEW_URL =
"/globallyPerRequestOverridenURL";
+
public static void contributeEsModuleManager(
- OrderedConfiguration<EsModuleConfigurationCallback> configuration,
+ OrderedConfiguration<EsModuleManagerContribution> configuration,
AssetSource assetSource)
{
- final String original = "OriginalCallback";
- final String override = "OverrideCallback";
+ final String originalId = "OriginalCallback";
+ final String overrideId = "OverrideCallback";
- configuration.add(override,
- o -> EsModuleConfigurationCallback.setImport(o,
OVERRIDDEN_ES_MODULE_ID, OVERRIDDEN_ES_MODULE_NEW_URL),
- "after:" + original);
+ configuration.add(overrideId,
+ toBaseContribution(o -> setImport(o, OVERRIDDEN_ES_MODULE_ID,
OVERRIDDEN_ES_MODULE_NEW_URL)),
+ "after:" + originalId);
+
+ configuration.add(originalId,
+ toBaseContribution(
+ o -> {
+ setImport(o, NON_OVERRIDDEN_ES_MODULE_ID,
NON_OVERRIDDEN_ES_MODULE_URL);
+ setImport(o, OVERRIDDEN_ES_MODULE_ID,
OVERRIDDEN_ES_MODULE_ORIGINAL_URL);
+ }));
+
+ final String outsideMetaInfAssetUrl = assetSource
+
.getClasspathAsset("/org/apache/tapestry5/integration/app1/es-module-outside-metainf.js")
+ .toClientURL();
+
+ configuration.add("Outside META-INF",
+ toBaseContribution(o -> setImport(o, "outside-metainf",
outsideMetaInfAssetUrl)));
+
+ configuration.add("External URL", toBaseContribution(
+ o -> setImport(o, "external/url",
"https://example.com/module.js")));
- configuration.add(original,
- o -> {
- EsModuleConfigurationCallback.setImport(o,
NON_OVERRIDDEN_ES_MODULE_ID, NON_OVERRIDDEN_ES_MODULE_URL);
- EsModuleConfigurationCallback.setImport(o,
OVERRIDDEN_ES_MODULE_ID, OVERRIDDEN_ES_MODULE_ORIGINAL_URL);
- });
+ configuration.add("Globally per-request overriden",
+ toGlobalPerRequestContribution(
+ o -> setImport(o,
+ OVERRIDDEN_GLOBALLY_ES_MODULE_ID,
+ OVERRIDDEN_GLOBALLY_ES_MODULE_NEW_URL)));
- configuration.add("Outside META-INF", o ->
- EsModuleConfigurationCallback.setImport(o, "outside-metainf",
-
assetSource.getClasspathAsset("/org/apache/tapestry5/integration/app1/es-module-outside-metainf.js").toClientURL())
- );
-
- configuration.add("External URL", o ->
- EsModuleConfigurationCallback.setImport(o, "external/url",
"https://example.com/module.js")
- );
}