You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2020/03/09 21:04:05 UTC
[sling-org-apache-sling-scripting-bundle-tracker] branch master
updated: SLING-9182 - The Scripting Bundle Tracker should require bundles
to provide information about the needed Script Engines
This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-bundle-tracker.git
The following commit(s) were added to refs/heads/master by this push:
new ac7d153 SLING-9182 - The Scripting Bundle Tracker should require bundles to provide information about the needed Script Engines
ac7d153 is described below
commit ac7d153cdaadcb3e99285a5b0f5b5f4431597ae2
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Mar 9 22:02:35 2020 +0100
SLING-9182 - The Scripting Bundle Tracker should require bundles to provide information about the needed Script Engines
* scripts or precompiled units are only executed if the bundles provide a
sling.resourceType;scriptEngine attribute whose value identifies a script
engine installed on the platform
---
.../tracker/internal/BundledScriptFinder.java | 82 ++++++++++++++++++----
.../tracker/internal/BundledScriptServlet.java | 4 +-
.../tracker/internal/BundledScriptTracker.java | 18 ++---
.../tracker/internal/ResourceTypeParser.java | 5 ++
.../bundle/tracker/internal/TypeProvider.java | 18 ++---
5 files changed, 93 insertions(+), 34 deletions(-)
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java
index 0bc350d..a5a3c82 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java
@@ -25,14 +25,22 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.commons.compiler.source.JavaEscapeHelper;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -52,15 +60,16 @@ public class BundledScriptFinder {
Executable getScript(SlingHttpServletRequest request, LinkedHashSet<TypeProvider> typeProviders, boolean precompiledScripts) {
List<String> scriptMatches;
for (TypeProvider provider : typeProviders) {
- scriptMatches = buildScriptMatches(request, provider.getType());
- for (String match : scriptMatches) {
- for (String extension : getScriptEngineExtensions()) {
+ scriptMatches = buildScriptMatches(request, provider.getResourceType());
+ String scriptEngineName = getScriptEngineName(request, provider);
+ if (StringUtils.isNotEmpty(scriptEngineName)) {
+ for (String match : scriptMatches) {
URL bundledScriptURL;
if (precompiledScripts) {
String className = JavaEscapeHelper.makeJavaPackage(match);
try {
Class clazz = provider.getBundle().loadClass(className);
- return new PrecompiledScript(provider.getBundle(), scriptEngineManager.getEngineByExtension(extension),
+ return new PrecompiledScript(provider.getBundle(), scriptEngineManager.getEngineByName(scriptEngineName),
clazz.getDeclaredConstructor().newInstance());
} catch (ClassNotFoundException e) {
// do nothing here
@@ -68,9 +77,26 @@ public class BundledScriptFinder {
throw new RuntimeException("Cannot correctly instantiate class " + className + ".");
}
} else {
- bundledScriptURL = provider.getBundle().getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT + extension);
- if (bundledScriptURL != null) {
- return new Script(provider.getBundle(), bundledScriptURL, scriptEngineManager.getEngineByExtension(extension));
+ ScriptEngine scriptEngine = null;
+ List<String> scriptEngineExtensions = Collections.emptyList();
+ for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
+ for (String shortName : factory.getNames()) {
+ if (shortName.equals(scriptEngineName)) {
+ scriptEngine = factory.getScriptEngine();
+ scriptEngineExtensions = factory.getExtensions();
+ break;
+ }
+ }
+ }
+ if (scriptEngine != null) {
+ for (String scriptEngineExtension : scriptEngineExtensions) {
+ bundledScriptURL =
+ provider.getBundle()
+ .getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT + scriptEngineExtension);
+ if (bundledScriptURL != null) {
+ return new Script(provider.getBundle(), bundledScriptURL, scriptEngine);
+ }
+ }
}
}
}
@@ -79,11 +105,10 @@ public class BundledScriptFinder {
return null;
}
- private List<String> buildScriptMatches(SlingHttpServletRequest request, String providerType) {
+ private List<String> buildScriptMatches(SlingHttpServletRequest request, ResourceTypeParser.ResourceType resourceType) {
List<String> matches = new ArrayList<>();
String method = request.getMethod();
boolean defaultMethod = DEFAULT_METHODS.contains(method);
- ResourceTypeParser.ResourceType resourceType = ResourceTypeParser.parseResourceType(providerType);
String extension = request.getRequestPathInfo().getExtension();
String[] selectors = request.getRequestPathInfo().getSelectors();
if (selectors.length > 0) {
@@ -125,12 +150,39 @@ public class BundledScriptFinder {
return Collections.unmodifiableList(matches);
}
- private List<String> getScriptEngineExtensions() {
- List<String> _scriptEngineExtensions = new ArrayList<>();
- for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
- _scriptEngineExtensions.addAll(factory.getExtensions());
+ private String getScriptEngineName(SlingHttpServletRequest request, TypeProvider typeProvider) {
+ String scriptEngineName = null;
+ Bundle bundle = typeProvider.getBundle();
+ BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
+ List<BundleCapability> capabilities = bundleWiring.getCapabilities(BundledScriptTracker.NS_SLING_RESOURCE_TYPE);
+ String[] selectors = request.getRequestPathInfo().getSelectors();
+ String requestExtension = request.getRequestPathInfo().getExtension();
+ String requestMethod = request.getMethod();
+ for (BundleCapability capability : capabilities) {
+ Map<String, Object> attributes = capability.getAttributes();
+ if (typeProvider.getResourceType().getType().equals(attributes.get(BundledScriptTracker.NS_SLING_RESOURCE_TYPE)) && Arrays.equals(selectors,
+ PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_SELECTORS), new String[]{}))) {
+ String version = typeProvider.getResourceType().getVersion();
+ Version capabilityVersion = (Version) attributes.get(BundledScriptTracker.AT_VERSION);
+ if (version != null && capabilityVersion!= null && !version.equals(capabilityVersion.toString())) {
+ continue;
+ }
+ Set<String> capabilityRequestExtensions = new HashSet<>(
+ Arrays.asList(PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_EXTENSIONS), new String[0]))
+ );
+ Set<String> capabilityRequestMethods = new HashSet<>(
+ Arrays.asList(
+ PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_METHODS), new String[0]))
+ );
+ if (
+ ((capabilityRequestExtensions.isEmpty() && "html".equals(requestExtension)) || capabilityRequestExtensions.contains(requestExtension)) &&
+ ((capabilityRequestMethods.isEmpty() && ("GET".equals(requestMethod) || "HEAD".equals(requestMethod))) || capabilityRequestMethods.contains(requestMethod)) &&
+ StringUtils.isEmpty(scriptEngineName)
+ ) {
+ scriptEngineName = (String) attributes.get(BundledScriptTracker.AT_SCRIPT_ENGINE);
+ }
+ }
}
- Collections.reverse(_scriptEngineExtensions);
- return Collections.unmodifiableList(_scriptEngineExtensions);
+ return scriptEngineName;
}
}
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java
index 9555dae..8d8a0e1 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java
@@ -97,8 +97,8 @@ class BundledScriptServlet extends GenericServlet {
scriptsMap.put(scriptsMapKey, executable);
}
}
- lock.readLock().lock();
} finally {
+ lock.readLock().lock();
lock.writeLock().unlock();
}
}
@@ -108,7 +108,7 @@ class BundledScriptServlet extends GenericServlet {
if (executable != null) {
Set<String> wiredResourceTypes = new HashSet<>();
for (TypeProvider typeProvider : m_wiredTypeProviders) {
- wiredResourceTypes.add(typeProvider.getType());
+ wiredResourceTypes.add(typeProvider.getResourceType().toString());
}
RequestWrapper requestWrapper = new RequestWrapper(request, wiredResourceTypes);
ScriptContext scriptContext = m_scriptContextProvider.prepareScriptContext(requestWrapper, response, executable);
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java
index b4841e5..1d69b3a 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java
@@ -82,10 +82,11 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
static final String NS_SLING_RESOURCE_TYPE = "sling.resourceType";
private static final Logger LOGGER = LoggerFactory.getLogger(BundledScriptTracker.class);
- private static final String AT_SLING_SELECTORS = "sling.resourceType.selectors";
- private static final String AT_SLING_EXTENSIONS = "sling.resourceType.extensions";
+ static final String AT_SLING_SELECTORS = "sling.resourceType.selectors";
+ static final String AT_SLING_EXTENSIONS = "sling.resourceType.extensions";
private static final String REGISTERING_BUNDLE = "org.apache.sling.scripting.bundle.tracker.internal.BundledScriptTracker.registering_bundle";
static final String AT_VERSION = "version";
+ static final String AT_SCRIPT_ENGINE = "scriptEngine";
private static final String AT_EXTENDS = "extends";
@Reference
@@ -170,8 +171,8 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
List<ServiceRegistration<Servlet>> regs = new ArrayList<>();
LinkedHashSet<TypeProvider> wiredProviders = new LinkedHashSet<>();
- wiredProviders.add(new TypeProvider(resourceType, bundle));
- wiredProviders.add(new TypeProvider(resourceTypeString, bundle));
+ wiredProviders.add(new TypeProvider(ResourceTypeParser.parseResourceType(resourceType), bundle));
+ wiredProviders.add(new TypeProvider(ResourceTypeParser.parseResourceType(resourceTypeString), bundle));
if (optionalWire.isPresent()) {
BundleWire extendsWire = optionalWire.get();
Bundle providerBundle = extendsWire.getProvider().getBundle();
@@ -180,8 +181,8 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
Version wireResourceTypeVersion = (Version) wireCapabilityAttributes.get(AT_VERSION);
String wireResourceTypeString = wireResourceType + (wireResourceTypeVersion != null ? "/" +
wireResourceTypeVersion.toString() : "");
- wiredProviders.add(new TypeProvider(wireResourceType, providerBundle));
- wiredProviders.add(new TypeProvider(wireResourceTypeString, providerBundle));
+ wiredProviders.add(new TypeProvider(ResourceTypeParser.parseResourceType(wireResourceType), providerBundle));
+ wiredProviders.add(new TypeProvider(ResourceTypeParser.parseResourceType(wireResourceTypeString), providerBundle));
properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_SUPER_TYPE, wireResourceTypeString);
}
populateWiredProviders(wiredProviders);
@@ -209,7 +210,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
Set<String> initialResourceTypes = new HashSet<>(initialProviders.size());
Set<Bundle> bundles = new HashSet<>(initialProviders.size());
for (TypeProvider provider : initialProviders) {
- initialResourceTypes.add(provider.getType());
+ initialResourceTypes.add(provider.getResourceType().toString());
bundles.add(provider.getBundle());
}
for (Bundle bundle : bundles) {
@@ -222,7 +223,8 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
Version version = (Version) bundleWire.getCapability().getAttributes().get(BundledScriptTracker
.AT_VERSION);
if (!initialResourceTypes.contains(resourceType)) {
- initialProviders.add(new TypeProvider(resourceType + (version == null ? "" : "/" + version.toString()),
+ initialProviders.add(new TypeProvider(
+ ResourceTypeParser.parseResourceType(resourceType + (version == null ? "" : "/" + version.toString())),
bundleWire.getProvider().getBundle()));
}
}
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeParser.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeParser.java
index 122a85c..0dbe226 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeParser.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeParser.java
@@ -92,6 +92,11 @@ final class ResourceTypeParser {
String getVersion() {
return version;
}
+
+ @Override
+ public String toString() {
+ return type + (version == null ? "" : "/" + version);
+ }
}
/**
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java
index 65d71d6..d1db81d 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java
@@ -25,17 +25,17 @@ import org.osgi.framework.Bundle;
*/
public class TypeProvider {
- private String type;
- private Bundle bundle;
+ private final ResourceTypeParser.ResourceType resourceType;
+ private final Bundle bundle;
/**
* Builds a {@code TypeProvider}.
*
- * @param type the resource type
+ * @param resourceType the resource type
* @param bundle the bundle that provides the resource type
*/
- TypeProvider(String type, Bundle bundle) {
- this.type = type;
+ TypeProvider(ResourceTypeParser.ResourceType resourceType, Bundle bundle) {
+ this.resourceType = resourceType;
this.bundle = bundle;
}
@@ -44,8 +44,8 @@ public class TypeProvider {
*
* @return the resource type
*/
- String getType() {
- return type;
+ ResourceTypeParser.ResourceType getResourceType() {
+ return resourceType;
}
/**
@@ -59,7 +59,7 @@ public class TypeProvider {
@Override
public int hashCode() {
- return type.hashCode() ^ bundle.hashCode();
+ return resourceType.hashCode() ^ bundle.hashCode();
}
@Override
@@ -68,6 +68,6 @@ public class TypeProvider {
return false;
}
TypeProvider other = (TypeProvider) obj;
- return other.bundle.equals(bundle) && other.type.equals(type);
+ return other.bundle.equals(bundle) && other.resourceType.equals(resourceType);
}
}