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/04/17 18:29:15 UTC
[sling-org-apache-sling-scripting-sightly] branch master updated:
SLING-9320 - Allow bundled render units to access objects from the same
bundle through the Use API
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-sightly.git
The following commit(s) were added to refs/heads/master by this push:
new bcd4602 SLING-9320 - Allow bundled render units to access objects from the same bundle through the Use API
bcd4602 is described below
commit bcd46027e09182911c55bb244d42debb1bd367c7
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri Apr 17 20:26:02 2020 +0200
SLING-9320 - Allow bundled render units to access objects from the same bundle through the Use API
* merged the code from the SlingModelsUseProvider into the JavaUseProvider, with an
optional import of the org.apache.sling.models API
* updated the RenderUnitProvider and ScriptUseProvider to work with bundled
render units
---
bnd.bnd | 1 +
pom.xml | 6 ++
.../sightly/engine/BundledUnitManager.java | 57 +++++++++++
.../scripting/sightly/engine/package-info.java | 2 +-
.../sightly/impl/engine/SightlyScriptEngine.java | 7 +-
.../impl/engine/SightlyScriptEngineFactory.java | 4 +-
...nitManager.java => BundledUnitManagerImpl.java} | 106 ++++++++++++---------
.../engine/compiled/SlingHTLMasterCompiler.java | 24 ++++-
.../impl/engine/extension/use/JavaUseProvider.java | 40 ++++++--
.../engine/extension/use/RenderUnitProvider.java | 4 +-
.../engine/extension/use/ScriptUseProvider.java | 66 ++++++++++++-
11 files changed, 251 insertions(+), 66 deletions(-)
diff --git a/bnd.bnd b/bnd.bnd
index ce8c192..1afbf00 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -12,4 +12,5 @@ Import-Package: org.apache.sling.scripting.sightly.compiler.*;resolution:=op
org.apache.sling.commons.compiler.*;resolution:=optional, \\
org.apache.sling.commons.classloader.*;resolution:=optional, \\
org.apache.sling.scripting.bundle.tracker.*;resolution:=optional, \\
+ org.apache.sling.models.*;resolution:=optional, \\
*
diff --git a/pom.xml b/pom.xml
index 953bdf3..0d8ede1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -218,6 +218,12 @@
<version>2.2.8</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.models.api</artifactId>
+ <version>1.3.8</version>
+ <scope>provided</scope>
+ </dependency>
<!-- javax.servlet, remove if we do not need a response wrapper -->
<dependency>
diff --git a/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java b/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java
new file mode 100644
index 0000000..3a04d88
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/engine/BundledUnitManager.java
@@ -0,0 +1,57 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.sightly.engine;
+
+import java.net.URL;
+
+import javax.script.Bindings;
+
+import org.apache.sling.scripting.bundle.tracker.BundledRenderUnit;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public interface BundledUnitManager {
+
+ /**
+ * <p>
+ * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
+ * BundledRenderUnit#VARIABLE} property and if the object provided by {@link BundledRenderUnit#getUnit()} is an instance of a {@link
+ * RenderUnit}. If so, this service will return the {@link ClassLoader} of the {@link org.osgi.framework.Bundle} providing the {@link
+ * BundledRenderUnit}.</p>
+ *
+ * @param bindings the bindings passed initially to the HTL Script Engine
+ * @return the {@link BundledRenderUnit}'s classloader if one is found, {@code null} otherwise
+ */
+ @Nullable ClassLoader getBundledRenderUnitClassloader(Bindings bindings);
+
+ /**
+ * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
+ * BundledRenderUnit#VARIABLE} property and, if a {@link BundledRenderUnit} is found, attempt to return the URL of dependency that the
+ * {@link BundledRenderUnit} needs to load. This will take into account the bundle wirings of the unit's providing bundle (see {@link
+ * BundledRenderUnit#getBundle()}).
+ *
+ * @param bindings the bindings passed initially to the HTL Script Engine
+ * @param identifier the identifier of the dependency that a {@link BundledRenderUnit} from the {@link Bindings} needs to load
+ * @return the URL of the {@code identifier} dependency, if one was found
+ */
+ URL getScript(Bindings bindings, String identifier);
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
index 2b25aa5..88631ad 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/engine/package-info.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
-@Version("1.0.0")
+@Version("1.1.0")
package org.apache.sling.scripting.sightly.engine;
import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
index ef0baf1..e7ceeaf 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
@@ -28,7 +28,8 @@ import javax.script.ScriptContext;
import javax.script.ScriptException;
import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.engine.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.apache.sling.scripting.sightly.render.RenderUnit;
import org.slf4j.Logger;
@@ -42,11 +43,11 @@ public class SightlyScriptEngine extends AbstractSlingScriptEngine implements Co
private static final Logger LOGGER = LoggerFactory.getLogger(SightlyScriptEngine.class);
private SlingHTLMasterCompiler slingHTLMasterCompiler;
- private BundledUnitManager bundledUnitManager;
+ private BundledUnitManagerImpl bundledUnitManager;
private ExtensionRegistryService extensionRegistryService;
SightlyScriptEngine(SightlyScriptEngineFactory factory, ExtensionRegistryService extensionRegistryService,
- SlingHTLMasterCompiler slingHTLMasterCompiler, BundledUnitManager bundledUnitManager) {
+ SlingHTLMasterCompiler slingHTLMasterCompiler, BundledUnitManagerImpl bundledUnitManager) {
super(factory);
this.extensionRegistryService = extensionRegistryService;
this.slingHTLMasterCompiler = slingHTLMasterCompiler;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
index 86ba1dc..93275a1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
@@ -22,7 +22,7 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
@@ -49,7 +49,7 @@ public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private BundledUnitManager bundledUnitManager;
+ private BundledUnitManagerImpl bundledUnitManager;
@Reference
private ExtensionRegistryService extensionRegistryService;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
similarity index 76%
rename from src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java
rename to src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
index 75732de..f000927 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManagerImpl.java
@@ -20,11 +20,11 @@ package org.apache.sling.scripting.sightly.impl.engine.bundled;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import javax.script.Bindings;
-import javax.script.CompiledScript;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
@@ -38,6 +38,7 @@ import org.apache.sling.scripting.bundle.tracker.TypeProvider;
import org.apache.sling.scripting.core.ScriptNameAwareReader;
import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine;
+import org.apache.sling.scripting.sightly.engine.BundledUnitManager;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderUnit;
import org.jetbrains.annotations.NotNull;
@@ -55,7 +56,7 @@ import org.slf4j.LoggerFactory;
/**
* The {@code BundledUnitManager} is an optional service, which is made available only if the {@link
* org.apache.sling.scripting.bundle.tracker} APIs are available. This service allows various components to work with {@link
- * org.apache.sling.scripting.bundle.tracker.BundledRenderUnit} instance and perform dependency resolution based on their availability in
+ * BundledRenderUnit} instance and perform dependency resolution based on their availability in
* the {@link Bindings} maps passed to the HTL Script Engine.
*/
@Component(
@@ -64,9 +65,9 @@ import org.slf4j.LoggerFactory;
* this component will register itself as a service only if the org.apache.sling.scripting.bundle.tracker API is present
*/
)
-public class BundledUnitManager {
+public class BundledUnitManagerImpl implements BundledUnitManager {
- private static final Logger LOGGER = LoggerFactory.getLogger(BundledUnitManager.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BundledUnitManagerImpl.class);
private final ServiceRegistration<?> serviceRegistration;
@@ -77,7 +78,7 @@ public class BundledUnitManager {
private ScriptCache scriptCache;
@Activate
- public BundledUnitManager(BundleContext bundleContext) {
+ public BundledUnitManagerImpl(BundleContext bundleContext) {
serviceRegistration = register(bundleContext);
}
@@ -129,35 +130,21 @@ public class BundledUnitManager {
BundledRenderUnit bundledRenderUnit = getBundledRenderUnit(bindings);
Resource currentResource = BindingsUtils.getResource(bindings);
if (currentResource != null && bundledRenderUnit != null) {
- boolean absolute = identifier.charAt(0) == '/';
for (TypeProvider provider : bundledRenderUnit.getTypeProviders()) {
for (ResourceType type : provider.getBundledRenderUnitCapability().getResourceTypes()) {
- StringBuilder renderUnitIdentifier = new StringBuilder(identifier);
- if (!absolute) {
- renderUnitIdentifier = renderUnitIdentifier.insert(0, type.toString() + "/");
+ String renderUnitIdentifier = getResourceTypeQualifiedPath(identifier, type);
+ String renderUnitBundledPath = renderUnitIdentifier;
+ if (renderUnitBundledPath.startsWith("/")) {
+ renderUnitBundledPath = renderUnitBundledPath.substring(1);
}
- if (provider.isPrecompiled()) {
- String classResourcePath = renderUnitIdentifier.toString();
- if (classResourcePath.startsWith("/")) {
- classResourcePath = classResourcePath.substring(1);
+ String className = JavaEscapeHelper.makeJavaPackage(renderUnitBundledPath);
+ try {
+ Class<?> clazz = provider.getBundle().loadClass(className);
+ if (clazz.getSuperclass() == RenderUnit.class) {
+ return (RenderUnit) clazz.getDeclaredConstructor().newInstance();
}
- String className = JavaEscapeHelper.makeJavaPackage(classResourcePath);
- try {
- Class<?> clazz = provider.getBundle().loadClass(className);
- if (clazz.getSuperclass() == RenderUnit.class) {
- return (RenderUnit) clazz.getDeclaredConstructor().newInstance();
- }
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception ignored) {
- // do nothing here
- }
- } else {
- String scriptResourcePath = renderUnitIdentifier.toString();
- if (scriptResourcePath.startsWith("/")) {
- scriptResourcePath = scriptResourcePath.substring(1);
- }
- URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + scriptResourcePath);
+ } catch (ClassNotFoundException e) {
+ URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + renderUnitBundledPath);
if (bundledScriptURL != null) {
try {
SightlyScriptEngine sightlyScriptEngine = (SightlyScriptEngine) scriptEngineManager.getEngineByName(
@@ -167,32 +154,40 @@ public class BundledUnitManager {
if (cachedScript != null) {
return ((SightlyCompiledScript) cachedScript.getCompiledScript()).getRenderUnit();
} else {
- final String finalRenderUnitIdentifier = renderUnitIdentifier.toString();
try (ScriptNameAwareReader reader =
new ScriptNameAwareReader(new InputStreamReader(bundledScriptURL.openStream(),
- StandardCharsets.UTF_8),
- finalRenderUnitIdentifier)) {
+ StandardCharsets.UTF_8), renderUnitIdentifier)) {
SightlyCompiledScript compiledScript =
(SightlyCompiledScript) sightlyScriptEngine.compile(reader);
- scriptCache.putScript(new CachedScript() {
- @Override
- public String getScriptPath() {
- return bundledScriptURL.toExternalForm();
- }
-
- @Override
- public CompiledScript getCompiledScript() {
- return compiledScript;
- }
- });
return compiledScript.getRenderUnit();
}
}
}
- } catch (IOException | ScriptException ignored) {
-
+ } catch (IOException | ScriptException compileException) {
+ throw new IllegalStateException(compileException);
}
}
+ } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public URL getScript(Bindings bindings, String identifier) {
+ BundledRenderUnit bundledRenderUnit = getBundledRenderUnit(bindings);
+ Resource currentResource = BindingsUtils.getResource(bindings);
+ if (currentResource != null && bundledRenderUnit != null) {
+ for (TypeProvider provider : bundledRenderUnit.getTypeProviders()) {
+ for (ResourceType type : provider.getBundledRenderUnitCapability().getResourceTypes()) {
+ String scriptResourcePath = getResourceTypeQualifiedPath(identifier, type);
+ URL bundledScriptURL = provider.getBundle().getEntry("javax.script" + "/" + scriptResourcePath);
+ if (bundledScriptURL != null) {
+ return bundledScriptURL;
}
}
}
@@ -200,6 +195,20 @@ public class BundledUnitManager {
return null;
}
+ @NotNull
+ private String getResourceTypeQualifiedPath(String identifier, ResourceType type) {
+ boolean absolute = identifier.charAt(0) == '/';
+ StringBuilder renderUnitIdentifier = new StringBuilder(identifier);
+ if (!absolute) {
+ renderUnitIdentifier = renderUnitIdentifier.insert(0, type.toString() + "/");
+ }
+ String scriptResourcePath = renderUnitIdentifier.toString();
+ if (scriptResourcePath.startsWith("/")) {
+ scriptResourcePath = scriptResourcePath.substring(1);
+ }
+ return scriptResourcePath;
+ }
+
/**
* <p>
* Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
@@ -210,6 +219,7 @@ public class BundledUnitManager {
* @param bindings the bindings passed initially to the HTL Script Engine
* @return the {@link BundledRenderUnit}'s classloader if one is found, {@code null} otherwise
*/
+ @Override
@Nullable
public ClassLoader getBundledRenderUnitClassloader(Bindings bindings) {
Object bru = bindings.get(BundledRenderUnit.VARIABLE);
@@ -245,7 +255,9 @@ public class BundledUnitManager {
private ServiceRegistration<?> register(BundleContext bundleContext) {
try {
BundledUnitManager.class.getClassLoader().loadClass("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
- return bundleContext.registerService(BundledUnitManager.class, this, null);
+ return bundleContext.registerService(new String[] {BundledUnitManager.class.getName(),
+ BundledUnitManagerImpl.class.getName()}, this,
+ null);
} catch (ClassNotFoundException e) {
LOGGER.info("No support for bundled RenderUnits.");
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
index 14aa3ab..bfa4b3c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompiler.java
@@ -33,6 +33,7 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import javax.script.Bindings;
+import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
@@ -47,6 +48,8 @@ import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
import org.apache.sling.commons.compiler.JavaCompiler;
import org.apache.sling.commons.compiler.Options;
import org.apache.sling.commons.compiler.source.JavaEscapeHelper;
+import org.apache.sling.scripting.api.CachedScript;
+import org.apache.sling.scripting.api.ScriptCache;
import org.apache.sling.scripting.api.ScriptNameAware;
import org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
import org.apache.sling.scripting.sightly.SightlyException;
@@ -100,6 +103,9 @@ public class SlingHTLMasterCompiler {
@Reference
private ResourceBackedPojoChangeMonitor resourceBackedPojoChangeMonitor;
+ @Reference
+ private ScriptCache scriptCache;
+
private static final String NO_SCRIPT = "NO_SCRIPT";
private static final String JAVA_EXTENSION = ".java";
static final String SIGHTLY_CONFIG_FILE = "/sightly.config";
@@ -204,6 +210,10 @@ public class SlingHTLMasterCompiler {
sName = getScriptName(scriptContext);
}
final String scriptName = sName;
+ CachedScript cachedScript = scriptCache.getScript(scriptName);
+ if (cachedScript != null && cachedScript.getCompiledScript() instanceof SightlyCompiledScript) {
+ return (SightlyCompiledScript) cachedScript.getCompiledScript();
+ }
CompilationUnit compilationUnit = new CompilationUnit() {
@Override
public String getScriptName() {
@@ -241,7 +251,19 @@ public class SlingHTLMasterCompiler {
String javaSourceCode = javaClassBackendCompiler.build(sourceIdentifier);
Object renderUnit = compileSource(sourceIdentifier, javaSourceCode);
if (renderUnit instanceof RenderUnit) {
- return new SightlyCompiledScript(engine, (RenderUnit) renderUnit);
+ SightlyCompiledScript compiledScript = new SightlyCompiledScript(engine, (RenderUnit) renderUnit);
+ scriptCache.putScript(new CachedScript() {
+ @Override
+ public String getScriptPath() {
+ return scriptName;
+ }
+
+ @Override
+ public CompiledScript getCompiledScript() {
+ return compiledScript;
+ }
+ });
+ return compiledScript;
} else {
throw new SightlyException("Expected a RenderUnit.");
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
index c792921..17e3b12 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
@@ -30,7 +30,8 @@ import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.Adaptable;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.scripting.SlingScriptHelper;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.models.factory.ModelFactory;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.Patterns;
@@ -77,7 +78,10 @@ public class JavaUseProvider implements UseProvider {
private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private BundledUnitManager bundledUnitManager;
+ private BundledUnitManagerImpl bundledUnitManager;
+
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
+ private ModelFactory modelFactory;
@Override
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
@@ -149,11 +153,12 @@ public class JavaUseProvider implements UseProvider {
@NotNull Bindings arguments)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException,
InstantiationException {
- // attempt OSGi service load
+ // OSGi service
Object result = serviceLoader.getService(cls);
if (result != null) {
return ProviderOutcome.success(result);
}
+ // adaptable
Object adaptableCandidate = arguments.get(ADAPTABLE);
if (adaptableCandidate instanceof Adaptable) {
Adaptable adaptable = (Adaptable) adaptableCandidate;
@@ -163,20 +168,37 @@ public class JavaUseProvider implements UseProvider {
}
}
SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
+ Resource resource = BindingsUtils.getResource(globalBindings);
+ // Sling Model
+ if (modelFactory != null && modelFactory.isModelClass(cls)) {
+ try {
+ // try to instantiate class via Sling Models (first via request, then via resource)
+ if (request != null && modelFactory.canCreateFromAdaptable(request, cls)) {
+ LOG.debug("Trying to instantiate class {} as Sling Model from request.", cls);
+ return ProviderOutcome.notNullOrFailure(modelFactory.createModel(request, cls));
+ }
+ if (resource != null && modelFactory.canCreateFromAdaptable(resource, cls)) {
+ LOG.debug("Trying to instantiate class {} as Sling Model from resource.", cls);
+ return ProviderOutcome.notNullOrFailure(modelFactory.createModel(resource, cls));
+ }
+ return ProviderOutcome.failure(
+ new IllegalStateException("Could not adapt the given Sling Model from neither request nor resource: " + cls));
+ } catch (Exception e) {
+ return ProviderOutcome.failure(e);
+ }
+ }
if (request != null) {
result = request.adaptTo(cls);
}
- if (result == null) {
- Resource resource = BindingsUtils.getResource(globalBindings);
- if (resource != null) {
- result = resource.adaptTo(cls);
- }
+ if (result == null && resource != null) {
+ result = resource.adaptTo(cls);
}
if (result != null) {
return ProviderOutcome.success(result);
} else if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers())) {
LOG.debug("Won't attempt to instantiate an interface or abstract class {}", cls.getName());
- return ProviderOutcome.failure();
+ return ProviderOutcome.failure(new IllegalArgumentException(String.format(" %s represents an interface or an abstract " +
+ "class which cannot be instantiated.", cls.getName())));
} else {
/*
* the object was cached by the class loader but it's not adaptable from {@link Resource} or {@link
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
index 4e51995..d3398d1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
@@ -39,7 +39,7 @@ import org.apache.sling.scripting.sightly.engine.ResourceResolution;
import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine;
import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
-import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -77,7 +77,7 @@ public class RenderUnitProvider implements UseProvider {
private ScriptCache scriptCache;
@Reference
- private BundledUnitManager bundledUnitManager;
+ private BundledUnitManagerImpl bundledUnitManager;
@Reference
private ScriptEngineManager scriptEngineManager;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
index 10305f0..c525f6b 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
@@ -19,14 +19,32 @@
package org.apache.sling.scripting.sightly.impl.engine.extension.use;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import javax.script.SimpleScriptContext;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScript;
+import org.apache.sling.scripting.api.CachedScript;
+import org.apache.sling.scripting.api.ScriptCache;
import org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
+import org.apache.sling.scripting.core.ScriptNameAwareReader;
import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManagerImpl;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -35,6 +53,8 @@ import org.apache.sling.scripting.sightly.use.UseProvider;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +62,7 @@ import org.slf4j.LoggerFactory;
/**
* Use provider that interprets the identifier as a script path, and runs the respective script using a script engine that matches the
* script extension.
- *
+ * <p>
* This provider returns a non-failure outcome only if the evaluated script actually returns something. For more details check the
* implementation of the {@link SlingScript#eval(SlingBindings)} method for the available script engines from your platform.
*/
@@ -71,6 +91,15 @@ public class ScriptUseProvider implements UseProvider {
@Reference
private ScriptingResourceResolverProvider scriptingResourceResolverProvider;
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
+ private BundledUnitManagerImpl bundledUnitManager;
+
+ @Reference
+ private ScriptEngineManager scriptEngineManager;
+
+ @Reference
+ private ScriptCache scriptCache;
+
@Override
public ProviderOutcome provide(String scriptName, RenderContext renderContext, Bindings arguments) {
Bindings globalBindings = renderContext.getBindings();
@@ -79,6 +108,41 @@ public class ScriptUseProvider implements UseProvider {
if (extension == null || extension.equals(SightlyScriptEngineFactory.EXTENSION)) {
return ProviderOutcome.failure();
}
+ if (bundledUnitManager != null) {
+ URL script = bundledUnitManager.getScript(bindings, scriptName);
+ if (script != null) {
+ String scriptUrlAsString = script.toExternalForm();
+ bindings.remove("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
+ bindings.put(ScriptEngine.FILENAME, scriptUrlAsString);
+ try {
+ ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension(extension);
+ if (scriptEngine != null) {
+ if (scriptEngine instanceof Compilable) {
+ CompiledScript compiledScript;
+ CachedScript cachedScript = scriptCache.getScript(scriptUrlAsString);
+ if (cachedScript == null) {
+ Compilable compilableScriptEngine = (Compilable) scriptEngine;
+ ScriptNameAwareReader reader =
+ new ScriptNameAwareReader(new StringReader(IOUtils.toString(script, StandardCharsets.UTF_8)),
+ scriptUrlAsString);
+ compiledScript = compilableScriptEngine.compile(reader);
+ } else {
+ compiledScript = cachedScript.getCompiledScript();
+ }
+ return ProviderOutcome.notNullOrFailure(compiledScript.eval(bindings));
+ } else {
+ ScriptNameAwareReader reader =
+ new ScriptNameAwareReader(new StringReader(IOUtils.toString(script, StandardCharsets.UTF_8)),
+ scriptUrlAsString);
+ return ProviderOutcome
+ .notNullOrFailure(scriptEngine.eval(reader, bindings));
+ }
+ }
+ } catch (Exception e) {
+ return ProviderOutcome.failure(e);
+ }
+ }
+ }
Resource scriptResource = ScriptUtils.resolveScript(scriptingResourceResolverProvider.getRequestScopedResourceResolver(),
renderContext, scriptName);
if (scriptResource == null) {