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/09 20:04:45 UTC
[sling-org-apache-sling-scripting-sightly] 01/02: SLING-9328 -
Allow loading template libraries from bundles
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
commit fde8c6e0155b2d966051cc6170ea3ad79dad3362
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Apr 9 21:58:46 2020 +0200
SLING-9328 - Allow loading template libraries from bundles
---
pom.xml | 2 +-
.../sightly/impl/engine/SightlyScriptEngine.java | 12 +-
.../impl/engine/SightlyScriptEngineFactory.java | 6 +-
.../impl/engine/bundled/BundledUnitManager.java | 264 +++++++++++++++++++++
.../impl/engine/extension/use/JavaUseProvider.java | 12 +-
.../engine/extension/use/RenderUnitProvider.java | 10 +
.../engine/precompiled/PrecompiledUnitManager.java | 112 ---------
7 files changed, 290 insertions(+), 128 deletions(-)
diff --git a/pom.xml b/pom.xml
index 942cb77..e759385 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,7 @@
The versioning scheme defined here corresponds to SLING-7406 (<module_version>-<htl_specification_version>). Take care when
releasing to only increase the first part, unless the module provides support for a newer version of the HTL specification.
-->
- <version>1.3.3-1.4.0-SNAPSHOT</version>
+ <version>1.4.0-1.4.0-SNAPSHOT</version>
<name>Apache Sling Scripting HTL Engine</name>
<description>
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 b07d65a..ef0baf1 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,7 @@ import javax.script.ScriptContext;
import javax.script.ScriptException;
import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
-import org.apache.sling.scripting.sightly.impl.engine.precompiled.PrecompiledUnitManager;
+import org.apache.sling.scripting.sightly.impl.engine.bundled.BundledUnitManager;
import org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.apache.sling.scripting.sightly.render.RenderUnit;
import org.slf4j.Logger;
@@ -42,15 +42,15 @@ public class SightlyScriptEngine extends AbstractSlingScriptEngine implements Co
private static final Logger LOGGER = LoggerFactory.getLogger(SightlyScriptEngine.class);
private SlingHTLMasterCompiler slingHTLMasterCompiler;
- private PrecompiledUnitManager precompiledUnitManager;
+ private BundledUnitManager bundledUnitManager;
private ExtensionRegistryService extensionRegistryService;
SightlyScriptEngine(SightlyScriptEngineFactory factory, ExtensionRegistryService extensionRegistryService,
- SlingHTLMasterCompiler slingHTLMasterCompiler, PrecompiledUnitManager precompiledUnitManager) {
+ SlingHTLMasterCompiler slingHTLMasterCompiler, BundledUnitManager bundledUnitManager) {
super(factory);
this.extensionRegistryService = extensionRegistryService;
this.slingHTLMasterCompiler = slingHTLMasterCompiler;
- this.precompiledUnitManager = precompiledUnitManager;
+ this.bundledUnitManager = bundledUnitManager;
}
@Override
@@ -71,10 +71,10 @@ public class SightlyScriptEngine extends AbstractSlingScriptEngine implements Co
checkArguments(reader, scriptContext);
try {
SightlyCompiledScript compiledScript = null;
- if (precompiledUnitManager != null) {
+ if (bundledUnitManager != null) {
Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
if (bindings != null) {
- RenderUnit renderUnit = precompiledUnitManager.getRenderUnit(bindings);
+ RenderUnit renderUnit = bundledUnitManager.getRenderUnit(bindings);
if (renderUnit != null) {
compiledScript = new SightlyCompiledScript(this, renderUnit);
}
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 e6b1afd..86ba1dc 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,8 +22,8 @@ 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.compiled.SlingHTLMasterCompiler;
-import org.apache.sling.scripting.sightly.impl.engine.precompiled.PrecompiledUnitManager;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -49,7 +49,7 @@ public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private PrecompiledUnitManager precompiledUnitManager;
+ private BundledUnitManager bundledUnitManager;
@Reference
private ExtensionRegistryService extensionRegistryService;
@@ -77,6 +77,6 @@ public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
@Override
public ScriptEngine getScriptEngine() {
- return new SightlyScriptEngine(this, extensionRegistryService, slingHTLMasterCompiler, precompiledUnitManager);
+ return new SightlyScriptEngine(this, extensionRegistryService, slingHTLMasterCompiler, bundledUnitManager);
}
}
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/BundledUnitManager.java
new file mode 100644
index 0000000..75732de
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/bundled/BundledUnitManager.java
@@ -0,0 +1,264 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.impl.engine.bundled;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+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;
+
+import org.apache.sling.api.resource.Resource;
+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.bundle.tracker.BundledRenderUnit;
+import org.apache.sling.scripting.bundle.tracker.ResourceType;
+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.impl.utils.BindingsUtils;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+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
+ * the {@link Bindings} maps passed to the HTL Script Engine.
+ */
+@Component(
+ service = {}
+ /*
+ * this component will register itself as a service only if the org.apache.sling.scripting.bundle.tracker API is present
+ */
+ )
+public class BundledUnitManager {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BundledUnitManager.class);
+
+ private final ServiceRegistration<?> serviceRegistration;
+
+ @Reference
+ private ScriptEngineManager scriptEngineManager;
+
+ @Reference
+ private ScriptCache scriptCache;
+
+ @Activate
+ public BundledUnitManager(BundleContext bundleContext) {
+ serviceRegistration = register(bundleContext);
+ }
+
+ @Deactivate
+ public void deactivate() {
+ if (serviceRegistration != null) {
+ serviceRegistration.unregister();
+ }
+ }
+
+
+ /**
+ * Given a {@link Bindings} map, this method will check if the {@code bindings} contain a value for the {@link
+ * BundledRenderUnit#VARIABLE} property and return the object provided by {@link BundledRenderUnit#getUnit()} if this is an instance of
+ * a {@link RenderUnit}.
+ *
+ * @param bindings the bindings passed initially to the HTL Script Engine
+ * @return a {@link RenderUnit} if one is found, {@code null} otherwise
+ */
+ @Nullable
+ public RenderUnit getRenderUnit(@NotNull Bindings bindings) {
+ BundledRenderUnit bundledRenderUnit = getBundledRenderUnit(bindings);
+ if (bundledRenderUnit != null) {
+ Object renderUnit = bundledRenderUnit.getUnit();
+ if (renderUnit instanceof RenderUnit) {
+ return (RenderUnit) renderUnit;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <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 try to locate another {@link RenderUnit} based on the passed {@code identifier} and the
+ * coordinates of the {@link RenderUnit} found in the {@code bindings} map.
+ * </p>
+ * <p>
+ * This method is suited for finding template libraries (collections of templates provided by the same {@link RenderUnit}).
+ * </p>
+ *
+ * @param bindings the bindings passed initially to the HTL Script Engine
+ * @param identifier the identifier of the {@link RenderUnit} that has to be retrieved and returned
+ * @return a {@link RenderUnit} if one is found, {@code null} otherwise
+ */
+ @Nullable
+ public RenderUnit getRenderUnit(@NotNull Bindings bindings, @NotNull String identifier) {
+ 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() + "/");
+ }
+ if (provider.isPrecompiled()) {
+ String classResourcePath = renderUnitIdentifier.toString();
+ if (classResourcePath.startsWith("/")) {
+ classResourcePath = classResourcePath.substring(1);
+ }
+ 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);
+ if (bundledScriptURL != null) {
+ try {
+ SightlyScriptEngine sightlyScriptEngine = (SightlyScriptEngine) scriptEngineManager.getEngineByName(
+ "htl");
+ if (sightlyScriptEngine != null) {
+ CachedScript cachedScript = scriptCache.getScript(bundledScriptURL.toExternalForm());
+ 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)) {
+ 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) {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <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
+ public ClassLoader getBundledRenderUnitClassloader(Bindings bindings) {
+ Object bru = bindings.get(BundledRenderUnit.VARIABLE);
+ if (bru instanceof BundledRenderUnit) {
+ BundledRenderUnit bundledRenderUnit = (BundledRenderUnit) bru;
+ return bundledRenderUnit.getBundle().adapt(BundleWiring.class).getClassLoader();
+ }
+ return null;
+ }
+
+ /**
+ * <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 try to get a reference to a service of type {@code clazz} and return the service object. The
+ * service will be retrieved using the bundle context of the {@link BundledRenderUnit} found in the {@code bindings} map.</p>
+ *
+ * @param bindings the bindings passed initially to the HTL Script Engine
+ * @param clazz the class identifying the type of the service
+ * @param <T> the service type
+ * @return a service object, if one is found, {@code null} otherwise
+ */
+ @Nullable
+ public <T> T getServiceForBundledRenderUnit(Bindings bindings, Class<T> clazz) {
+ Object bru = bindings.get(BundledRenderUnit.VARIABLE);
+ if (bru instanceof BundledRenderUnit) {
+ BundledRenderUnit bundledRenderUnit = (BundledRenderUnit) bru;
+ return bundledRenderUnit.getService(clazz.getName());
+ }
+ return null;
+ }
+
+ private ServiceRegistration<?> register(BundleContext bundleContext) {
+ try {
+ BundledUnitManager.class.getClassLoader().loadClass("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
+ return bundleContext.registerService(BundledUnitManager.class, this, null);
+ } catch (ClassNotFoundException e) {
+ LOGGER.info("No support for bundled RenderUnits.");
+ }
+ return null;
+ }
+
+ @Nullable
+ private BundledRenderUnit getBundledRenderUnit(Bindings bindings) {
+ Object bru = bindings.get(BundledRenderUnit.VARIABLE);
+ if (bru instanceof BundledRenderUnit) {
+ return (BundledRenderUnit) bru;
+ }
+ return null;
+ }
+
+}
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 d2ceed3..c792921 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,8 +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.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
-import org.apache.sling.scripting.sightly.impl.engine.precompiled.PrecompiledUnitManager;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.Patterns;
import org.apache.sling.scripting.sightly.pojo.Use;
@@ -77,7 +77,7 @@ public class JavaUseProvider implements UseProvider {
private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
- private PrecompiledUnitManager precompiledUnitManager;
+ private BundledUnitManager bundledUnitManager;
@Override
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
@@ -91,20 +91,20 @@ public class JavaUseProvider implements UseProvider {
try {
Exception failure = null;
- if (precompiledUnitManager != null) {
- ClassLoader unitClassLoader = precompiledUnitManager.getBundledRenderUnitClassloader(globalBindings);
+ if (bundledUnitManager != null) {
+ ClassLoader unitClassLoader = bundledUnitManager.getBundledRenderUnitClassloader(globalBindings);
if (unitClassLoader != null) {
try {
String className = identifier;
if (className.indexOf('.') < 0) {
// the class name is not fully qualified; need to prepend the package name of the current rendering unit
- RenderUnit renderUnit = precompiledUnitManager.getRenderUnit(globalBindings);
+ RenderUnit renderUnit = bundledUnitManager.getRenderUnit(globalBindings);
if (renderUnit != null) {
className = renderUnit.getClass().getPackage().getName() + "." + className;
}
}
Class<?> clazz = unitClassLoader.loadClass(className);
- return loadObject(clazz, cls -> precompiledUnitManager.getServiceForBundledRenderUnit(globalBindings, clazz),
+ return loadObject(clazz, cls -> bundledUnitManager.getServiceForBundledRenderUnit(globalBindings, clazz),
globalBindings,
arguments);
} catch (Exception e) {
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 df29230..4e51995 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,6 +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.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -76,6 +77,9 @@ public class RenderUnitProvider implements UseProvider {
private ScriptCache scriptCache;
@Reference
+ private BundledUnitManager bundledUnitManager;
+
+ @Reference
private ScriptEngineManager scriptEngineManager;
@Reference
@@ -85,6 +89,12 @@ public class RenderUnitProvider implements UseProvider {
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
Bindings globalBindings = renderContext.getBindings();
+ if (bundledUnitManager != null) {
+ RenderUnit renderUnit = bundledUnitManager.getRenderUnit(globalBindings, identifier);
+ if (renderUnit != null) {
+ return ProviderOutcome.success(renderUnit);
+ }
+ }
SlingScriptHelper sling = BindingsUtils.getHelper(globalBindings);
SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
final Resource renderUnitResource = ScriptUtils.resolveScript(scriptingResourceResolverProvider
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/precompiled/PrecompiledUnitManager.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/precompiled/PrecompiledUnitManager.java
deleted file mode 100644
index 94de4c9..0000000
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/precompiled/PrecompiledUnitManager.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~ 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.impl.engine.precompiled;
-
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-
-import org.apache.sling.scripting.bundle.tracker.BundledRenderUnit;
-import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
-import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine;
-import org.apache.sling.scripting.sightly.render.RenderUnit;
-import org.jetbrains.annotations.Nullable;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Component(
- service = {}
- /*
- * this component will register itself as a service only if the org.apache.sling.scripting.bundle.tracker API is present
- */
-)
-public class PrecompiledUnitManager {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(PrecompiledUnitManager.class);
-
- private final ServiceRegistration<?> serviceRegistration;
-
- @Activate
- public PrecompiledUnitManager(BundleContext bundleContext) {
- serviceRegistration = register(bundleContext);
- }
-
- @Deactivate
- public void deactivate() {
- if (serviceRegistration != null) {
- serviceRegistration.unregister();
- }
- }
-
-
- /**
- * Provides support for extracting precompiled HTL scripts passed through the {@code scriptContext}. This feature works only when the
- * {@link org.apache.sling.scripting.bundle.tracker.BundledRenderUnit} API is deployed to the platform as well.
- *
- * @param bindings the global bindings of the script execution context
- * @return an instance of the compiled script, if a precompiled {@link RenderUnit} was present in the {@link ScriptContext}, {@code
- * null} otherwise
- */
- @Nullable
- public RenderUnit getRenderUnit(Bindings bindings) {
- Object bundledRenderUnit = bindings.get(BundledRenderUnit.VARIABLE);
- if (bundledRenderUnit instanceof BundledRenderUnit) {
- Object renderUnit = ((BundledRenderUnit) bundledRenderUnit).getUnit();
- if (renderUnit instanceof RenderUnit) {
- return (RenderUnit) renderUnit;
- }
- }
- return null;
- }
-
- @Nullable
- public ClassLoader getBundledRenderUnitClassloader(Bindings bindings) {
- Object bru = bindings.get(BundledRenderUnit.VARIABLE);
- if (bru instanceof BundledRenderUnit) {
- BundledRenderUnit bundledRenderUnit = (BundledRenderUnit) bru;
- return bundledRenderUnit.getBundle().adapt(BundleWiring.class).getClassLoader();
- }
- return null;
- }
-
- @Nullable
- public <T> T getServiceForBundledRenderUnit(Bindings bindings, Class<?> clazz) {
- Object bru = bindings.get(BundledRenderUnit.VARIABLE);
- if (bru instanceof BundledRenderUnit) {
- BundledRenderUnit bundledRenderUnit = (BundledRenderUnit) bru;
- return bundledRenderUnit.getService(clazz.getName());
- }
- return null;
- }
-
- private ServiceRegistration<?> register(BundleContext bundleContext) {
- try {
- PrecompiledUnitManager.class.getClassLoader().loadClass("org.apache.sling.scripting.bundle.tracker.BundledRenderUnit");
- return bundleContext.registerService(PrecompiledUnitManager.class, this, null);
- } catch (ClassNotFoundException e) {
- LOGGER.info("No support for precompiled scripts.");
- }
- return null;
- }
-}