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 5f0175f SLING-8012 - Extract an HTL runtime bundle from the existing
HTL modules
5f0175f is described below
commit 5f0175fc727033030a4cfc728acb43b3ed3165ce
Author: Radu Cotescu <[email protected]>
AuthorDate: Thu Oct 18 16:20:55 2018 +0200
SLING-8012 - Extract an HTL runtime bundle from the existing HTL modules
* refactored code so that compilation becomes completely optional, depending
on which modules are available at runtime
---
pom.xml | 24 +-
.../sightly/impl/engine/SightlyCompiledScript.java | 15 +-
.../impl/engine/SightlyJavaCompilerService.java | 280 -------------------
.../sightly/impl/engine/SightlyScriptEngine.java | 144 ++--------
.../impl/engine/SightlyScriptEngineFactory.java | 94 +------
.../impl/engine/compiled/SourceIdentifier.java | 155 +----------
.../engine/extension/FormatFilterExtension.java | 5 +-
.../engine/extension/I18nRuntimeExtension.java | 5 +-
.../engine/extension/IncludeRuntimeExtension.java | 5 +-
.../impl/engine/extension/JoinFilterExtension.java | 5 +-
.../engine/extension/ResourceRuntimeExtension.java | 5 +-
.../extension/URIManipulationFilterExtension.java | 5 +-
.../impl/engine/extension/XSSRuntimeExtension.java | 60 ++++-
.../impl/engine/extension/use/JavaUseProvider.java | 89 ++++---
.../engine/extension/use/RenderUnitProvider.java | 2 +-
.../engine/extension/use/UseRuntimeExtension.java | 5 +-
.../impl/engine/runtime/RenderContextImpl.java | 14 +-
.../compiler/SightlyJavaCompilerServiceTest.java | 189 -------------
.../impl/engine/SightlyCompiledScriptTest.java | 6 +-
.../engine/SightlyScriptEngineFactoryTest.java | 121 ---------
.../compiled/SlingHTLMasterCompilerTest.java | 296 +++++++++++++++++++++
.../impl/engine/compiled/SourceIdentifierTest.java | 29 +-
22 files changed, 490 insertions(+), 1063 deletions(-)
diff --git a/pom.xml b/pom.xml
index cdf3d74..09a7d3b 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.0.57-1.4.0-SNAPSHOT</version>
+ <version>1.1.0-1.4.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Apache Sling Scripting HTL Engine</name>
@@ -89,9 +89,15 @@
io.sightly; version:Version=1.4
</Provide-Capability>
<Require-Capability>
- io.sightly.compiler;
filter:="(&(version>=1.0)(version<=1.4))",
- io.sightly.compiler.java;
filter:="(&(version>=1.0)(version<=1.4))"
+ io.sightly.runtime;
filter:="(&(version>=1.0)(!(version>=2.0)))"
</Require-Capability>
+ <Import-Package>
+
org.apache.sling.scripting.sightly.compiler.*;resolution:=optional,
+
org.apache.sling.scripting.sightly.java.compiler.*;resolution:=optional,
+
org.apache.sling.commons.compiler.*;resolution:=optional,
+
org.apache.sling.commons.classloader.*;resolution:=optional,
+ *
+ </Import-Package>
</instructions>
</configuration>
</plugin>
@@ -168,17 +174,25 @@
<!-- D E P E N D E N C I E S
-->
<!--
======================================================================= -->
<dependencies>
+ <!-- HTL Runtime -->
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.scripting.sightly.runtime</artifactId>
+ <version>1.0.0-1.4.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- HTL Compilers -->
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.scripting.sightly.compiler</artifactId>
- <version>1.0.22-1.4.0</version>
+ <version>1.0.23-1.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.scripting.sightly.compiler.java</artifactId>
- <version>1.0.26-1.4.0</version>
+ <version>1.0.27-1.4.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScript.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScript.java
index cf2c9ea..c43e297 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScript.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScript.java
@@ -19,33 +19,32 @@
package org.apache.sling.scripting.sightly.impl.engine;
import java.io.PrintWriter;
+
import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
-import javax.script.ScriptException;
import javax.script.SimpleBindings;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.scripting.SlingBindings;
-import org.apache.sling.api.scripting.SlingScriptConstants;
import org.apache.sling.scripting.sightly.SightlyException;
import
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
-import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
public class SightlyCompiledScript extends CompiledScript {
- private ScriptEngine scriptEngine;
- private RenderUnit renderUnit;
+ private final SightlyScriptEngine scriptEngine;
+ private final RenderUnit renderUnit;
- public SightlyCompiledScript(ScriptEngine scriptEngine, RenderUnit
renderUnit) {
+ public SightlyCompiledScript(SightlyScriptEngine scriptEngine, RenderUnit
renderUnit) {
this.scriptEngine = scriptEngine;
this.renderUnit = renderUnit;
}
@Override
- public Object eval(ScriptContext context) throws ScriptException {
+ public Object eval(ScriptContext context) {
Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
SlingBindings slingBindings = new SlingBindings();
slingBindings.putAll(bindings);
@@ -56,7 +55,7 @@ public class SightlyCompiledScript extends CompiledScript {
Object oldBindings =
request.getAttribute(SlingBindings.class.getName());
try {
request.setAttribute(SlingBindings.class.getName(), slingBindings);
- RenderContext renderContext = new RenderContextImpl(context);
+ RenderContext renderContext = new
RenderContextImpl(scriptEngine.getExtensionRegistryService(), context);
PrintWriter out = new PrintWriter(context.getWriter());
renderUnit.render(out, renderContext, new SimpleBindings());
} finally {
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyJavaCompilerService.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyJavaCompilerService.java
deleted file mode 100644
index 0827f9c..0000000
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyJavaCompilerService.java
+++ /dev/null
@@ -1,280 +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;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.commons.compiler.CompilationResult;
-import org.apache.sling.commons.compiler.CompilationUnit;
-import org.apache.sling.commons.compiler.CompilerMessage;
-import org.apache.sling.commons.compiler.JavaCompiler;
-import org.apache.sling.commons.compiler.Options;
-import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
-import org.apache.sling.scripting.sightly.SightlyException;
-import
org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier;
-import org.apache.sling.scripting.sightly.impl.utils.Patterns;
-import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
-import org.apache.sling.scripting.sightly.render.RenderContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * The {@code SightlyJavaCompiler} allows for simple instantiation of
arbitrary classes that are either stored in the repository
- * or in regular OSGi bundles. It also compiles Java sources on-the-fly and
can discover class' source files based on
- * {@link Resource}s (typically Sling components). It supports Sling Resource
type inheritance.
- */
-@Component(
- service = SightlyJavaCompilerService.class
-)
-public class SightlyJavaCompilerService {
-
- private static final Logger LOG =
LoggerFactory.getLogger(SightlyJavaCompilerService.class);
-
- @Reference
- private ClassLoaderWriter classLoaderWriter = null;
-
- @Reference
- private JavaCompiler javaCompiler = null;
-
- @Reference
- private ResourceBackedPojoChangeMonitor resourceBackedPojoChangeMonitor =
null;
-
- @Reference
- private SightlyEngineConfiguration sightlyEngineConfiguration = null;
-
- @Reference
- private ScriptingResourceResolverProvider
scriptingResourceResolverProvider = null;
-
- private Map<String, Lock> compilationLocks = new HashMap<>();
-
- private Options options;
-
- /**
- * This method returns an Object instance based on a {@link
Resource}-backed class that is either found through regular classloading
- * mechanisms or on-the-fly compilation. In case the requested class does
not denote a fully qualified class name, this service will
- * try to find the class through Sling's resource resolution mechanism and
compile the class on-the-fly if required.
- *
- * @param renderContext the render context
- * @param className name of class to use for object instantiation
- * @return object instance of the requested class or {@code null} if the
specified class is not backed by a {@link Resource}
- */
- public Object getResourceBackedUseObject(RenderContext renderContext,
String className) {
- LOG.debug("Attempting to load class {}.", className);
- try {
- if (className.contains(".")) {
- Resource pojoResource =
-
SourceIdentifier.getPOJOFromFQCN(scriptingResourceResolverProvider.getRequestScopedResourceResolver()
- , null, className);
- if (pojoResource != null) {
- return getUseObjectAndRecompileIfNeeded(pojoResource);
- }
- } else {
- Resource pojoResource = ScriptUtils.resolveScript(
-
scriptingResourceResolverProvider.getRequestScopedResourceResolver(),
- renderContext,
- className + ".java"
- );
- if (pojoResource != null) {
- return getUseObjectAndRecompileIfNeeded(pojoResource);
- }
- }
- } catch (Exception e) {
- throw new SightlyException("Cannot obtain an instance for class "
+ className + ".", e);
- }
- return null;
- }
-
- /**
- * Compiles a class using the passed fully qualified class name and its
source code.
- *
- * @param sourceIdentifier the source identifier
- * @param sourceCode the source code from which to generate the class
- * @return object instance of the class to compile
- */
- public Object compileSource(SourceIdentifier sourceIdentifier, String
sourceCode) {
- Lock lock;
- final String fqcn = sourceIdentifier.getFullyQualifiedClassName();
- synchronized (compilationLocks) {
- lock = compilationLocks.get(fqcn);
- if (lock == null) {
- lock = new ReentrantLock();
- compilationLocks.put(fqcn, lock);
- }
- }
- lock.lock();
- try {
- if (sightlyEngineConfiguration.keepGenerated()) {
- String path = "/" + fqcn.replaceAll("\\.", "/") + ".java";
- OutputStream os = classLoaderWriter.getOutputStream(path);
- IOUtils.write(sourceCode, os, "UTF-8");
- IOUtils.closeQuietly(os);
- }
- String[] sourceCodeLines =
sourceCode.split("\\r\\n|[\\n\\x0B\\x0C\\r\\u0085\\u2028\\u2029]");
- boolean foundPackageDeclaration = false;
- for (String line : sourceCodeLines) {
- Matcher matcher =
Patterns.JAVA_PACKAGE_DECLARATION.matcher(line);
- if (matcher.matches()) {
- /*
- * This matching might return false positives like:
- * // package a.b.c;
- *
- * where from a syntactic point of view the source code
doesn't have a package declaration and the expectancy is that our
- * SightlyJavaCompilerService will add one.
- */
- foundPackageDeclaration = true;
- break;
- }
- }
-
- if (!foundPackageDeclaration) {
- sourceCode = "package " + sourceIdentifier.getPackageName() +
";\n" + sourceCode;
- }
-
- CompilationUnit compilationUnit = new
SightlyCompilationUnit(sourceCode, fqcn);
- long start = System.currentTimeMillis();
- CompilationResult compilationResult = javaCompiler.compile(new
CompilationUnit[]{compilationUnit}, options);
- long end = System.currentTimeMillis();
- List<CompilerMessage> errors = compilationResult.getErrors();
- if (errors != null && errors.size() > 0) {
- throw new SightlyException(createErrorMsg(errors));
- }
- if (compilationResult.didCompile()) {
- LOG.debug("Class {} was compiled in {}ms.", fqcn, end - start);
- }
- /*
- * the class loader might have become dirty, so let the {@link
ClassLoaderWriter} decide which class loader to return
- */
- return
classLoaderWriter.getClassLoader().loadClass(fqcn).newInstance();
- } catch (Exception e) {
- throw new SightlyException(e);
- } finally {
- lock.unlock();
- }
- }
-
-
- private Object getUseObjectAndRecompileIfNeeded(Resource pojoResource)
- throws IOException, InstantiationException,
IllegalAccessException, ClassNotFoundException {
- SourceIdentifier sourceIdentifier = new
SourceIdentifier(sightlyEngineConfiguration, pojoResource.getPath());
- long sourceLastModifiedDateFromCache =
-
resourceBackedPojoChangeMonitor.getLastModifiedDateForJavaUseObject(pojoResource.getPath());
- long classLastModifiedDate = classLoaderWriter.getLastModified("/" +
sourceIdentifier.getFullyQualifiedClassName()
- .replaceAll("\\.", "/") + ".class");
- if (sourceLastModifiedDateFromCache == 0) {
- // first access; let's check the real last modified date of the
source
- long sourceLastModifiedDate =
pojoResource.getResourceMetadata().getModificationTime();
-
resourceBackedPojoChangeMonitor.recordLastModifiedTimestamp(pojoResource.getPath(),
sourceLastModifiedDate);
- if (classLastModifiedDate < 0 || sourceLastModifiedDate >
classLastModifiedDate) {
- return compileSource(sourceIdentifier,
IOUtils.toString(pojoResource.adaptTo(InputStream.class), "UTF-8"));
- } else {
- return
classLoaderWriter.getClassLoader().loadClass(sourceIdentifier.getFullyQualifiedClassName()).newInstance();
- }
- } else {
- if (sourceLastModifiedDateFromCache > classLastModifiedDate) {
- return compileSource(sourceIdentifier,
IOUtils.toString(pojoResource.adaptTo(InputStream.class), "UTF-8"));
- } else {
- return
classLoaderWriter.getClassLoader().loadClass(sourceIdentifier.getFullyQualifiedClassName()).newInstance();
- }
- }
- }
-
- @Activate
- protected void activate() {
- LOG.info("Activating {}", getClass().getName());
-
- String version = System.getProperty("java.specification.version");
- options = new Options();
- options.put(Options.KEY_GENERATE_DEBUG_INFO, true);
- options.put(Options.KEY_SOURCE_VERSION, version);
- options.put(Options.KEY_TARGET_VERSION, version);
- options.put(Options.KEY_CLASS_LOADER_WRITER, classLoaderWriter);
- options.put(Options.KEY_FORCE_COMPILATION, true);
- }
-
- //---------------------------------- private
-----------------------------------
- private String createErrorMsg(List<CompilerMessage> errors) {
- final StringBuilder buffer = new StringBuilder();
- buffer.append("Compilation errors in ");
- buffer.append(errors.get(0).getFile());
- buffer.append(":");
- StringBuilder errorsBuffer = new StringBuilder();
- boolean duplicateVariable = false;
- for (final CompilerMessage e : errors) {
- if (!duplicateVariable) {
- if (e.getMessage().contains("Duplicate local variable")) {
- duplicateVariable = true;
- buffer.append(" Maybe you defined more than one identical
block elements without defining a different variable for "
- + "each one?");
- }
- }
- errorsBuffer.append("\nLine ");
- errorsBuffer.append(e.getLine());
- errorsBuffer.append(", column ");
- errorsBuffer.append(e.getColumn());
- errorsBuffer.append(" : ");
- errorsBuffer.append(e.getMessage());
- }
- buffer.append(errorsBuffer);
- return buffer.toString();
- }
-
- private static class SightlyCompilationUnit implements CompilationUnit {
-
- private String fqcn;
- private String sourceCode;
-
- SightlyCompilationUnit(String sourceCode, String fqcn) throws
Exception {
- this.sourceCode = sourceCode;
- this.fqcn = fqcn;
- }
-
- @Override
- public Reader getSource() throws IOException {
- return new InputStreamReader(IOUtils.toInputStream(sourceCode,
"UTF-8"), "UTF-8");
- }
-
- @Override
- public String getMainClassName() {
- return fqcn;
- }
-
- @Override
- public long getLastModified() {
- return System.currentTimeMillis();
- }
- }
-}
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 4d08e8c..fdb6456 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
@@ -20,32 +20,14 @@ package org.apache.sling.scripting.sightly.impl.engine;
import java.io.Reader;
import java.io.StringReader;
-import java.util.Set;
-import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
-import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
-import org.apache.sling.scripting.api.ScriptNameAware;
-import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
-import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.CompilationResult;
-import org.apache.sling.scripting.sightly.compiler.CompilationUnit;
-import org.apache.sling.scripting.sightly.compiler.CompilerMessage;
-import org.apache.sling.scripting.sightly.compiler.SightlyCompiler;
-import
org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier;
-import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
-import
org.apache.sling.scripting.sightly.java.compiler.GlobalShadowCheckBackendCompiler;
-import
org.apache.sling.scripting.sightly.java.compiler.JavaClassBackendCompiler;
-import org.apache.sling.scripting.sightly.java.compiler.JavaEscapeUtils;
-import org.apache.sling.scripting.sightly.java.compiler.JavaImportsAnalyzer;
-import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
+import
org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,25 +38,13 @@ public class SightlyScriptEngine extends
AbstractSlingScriptEngine implements Co
private static final Logger LOGGER =
LoggerFactory.getLogger(SightlyScriptEngine.class);
- public static final String NO_SCRIPT = "NO_SCRIPT";
+ private SlingHTLMasterCompiler slingHTLMasterCompiler;
+ private ExtensionRegistryService extensionRegistryService;
- private SightlyCompiler sightlyCompiler;
- private SightlyJavaCompilerService javaCompilerService;
- private final SightlyEngineConfiguration configuration;
- private final ScriptingResourceResolverProvider
scriptingResourceResolverProvider;
- private final SlingJavaImportsAnalyser importsAnalyser;
-
- public SightlyScriptEngine(ScriptEngineFactory scriptEngineFactory,
- SightlyCompiler sightlyCompiler,
- SightlyJavaCompilerService javaCompilerService,
- SightlyEngineConfiguration configuration,
- ScriptingResourceResolverProvider
scriptingResourceResolverProvider) {
- super(scriptEngineFactory);
- this.sightlyCompiler = sightlyCompiler;
- this.javaCompilerService = javaCompilerService;
- this.configuration = configuration;
- this.scriptingResourceResolverProvider =
scriptingResourceResolverProvider;
- importsAnalyser = new SlingJavaImportsAnalyser();
+ SightlyScriptEngine(SightlyScriptEngineFactory factory,
ExtensionRegistryService extensionRegistryService, SlingHTLMasterCompiler
slingHTLMasterCompiler) {
+ super(factory);
+ this.extensionRegistryService = extensionRegistryService;
+ this.slingHTLMasterCompiler = slingHTLMasterCompiler;
}
@Override
@@ -84,72 +54,32 @@ public class SightlyScriptEngine extends
AbstractSlingScriptEngine implements Co
@Override
public CompiledScript compile(final Reader script) throws ScriptException {
- return internalCompile(script, null);
+ if (slingHTLMasterCompiler != null) {
+ return slingHTLMasterCompiler.compileHTLScript(this, script, null);
+ }
+ throw new ScriptException("Missing compilation support.");
}
@Override
public Object eval(Reader reader, ScriptContext scriptContext) throws
ScriptException {
checkArguments(reader, scriptContext);
try {
- SightlyCompiledScript compiledScript = internalCompile(reader,
scriptContext);
- return compiledScript.eval(scriptContext);
+ SightlyCompiledScript compiledScript = null;
+ if (slingHTLMasterCompiler != null) {
+ compiledScript = slingHTLMasterCompiler.compileHTLScript(this,
reader, scriptContext);
+ }
+ if (compiledScript != null) {
+ return compiledScript.eval(scriptContext);
+ }
} catch (Exception e) {
throw new ScriptException(e);
}
+ LOGGER.warn("Did not find a compilable or executable unit.");
+ return null;
}
- private SightlyCompiledScript internalCompile(final Reader script,
ScriptContext scriptContext) throws ScriptException {
- ClassLoader old = Thread.currentThread().getContextClassLoader();
-
Thread.currentThread().setContextClassLoader(((SightlyScriptEngineFactory)
getFactory()).getClassLoader());
- try {
- String sName = NO_SCRIPT;
- if (script instanceof ScriptNameAware) {
- sName = ((ScriptNameAware) script).getScriptName();
- }
- if (sName.equals(NO_SCRIPT)) {
- sName = getScriptName(scriptContext);
- }
- final String scriptName = sName;
- CompilationUnit compilationUnit = new CompilationUnit() {
- @Override
- public String getScriptName() {
- return scriptName;
- }
-
- @Override
- public Reader getScriptReader() {
- return script;
- }
- };
- JavaClassBackendCompiler javaClassBackendCompiler = new
JavaClassBackendCompiler(importsAnalyser);
- GlobalShadowCheckBackendCompiler shadowCheckBackendCompiler = null;
- if (scriptContext != null) {
- Bindings bindings =
scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
- Set<String> globals = bindings.keySet();
- shadowCheckBackendCompiler = new
GlobalShadowCheckBackendCompiler(javaClassBackendCompiler, globals);
- }
- CompilationResult result = shadowCheckBackendCompiler == null ?
sightlyCompiler.compile(compilationUnit,
- javaClassBackendCompiler) :
sightlyCompiler.compile(compilationUnit, shadowCheckBackendCompiler);
- if (result.getWarnings().size() > 0) {
- for (CompilerMessage warning : result.getWarnings()) {
- LOGGER.warn("Script {} {}:{}: {}",
warning.getScriptName(), warning.getLine(), warning.getColumn(),
warning.getMessage());
- }
- }
- if (result.getErrors().size() > 0) {
- CompilerMessage error = result.getErrors().get(0);
- throw new ScriptException(error.getMessage(),
error.getScriptName(), error.getLine(), error.getColumn());
- }
- SourceIdentifier sourceIdentifier = new
SourceIdentifier(configuration, scriptName);
- String javaSourceCode =
javaClassBackendCompiler.build(sourceIdentifier);
- Object renderUnit =
javaCompilerService.compileSource(sourceIdentifier, javaSourceCode);
- if (renderUnit instanceof RenderUnit) {
- return new SightlyCompiledScript(this, (RenderUnit)
renderUnit);
- } else {
- throw new SightlyException("Expected a RenderUnit.");
- }
- } finally {
- Thread.currentThread().setContextClassLoader(old);
- }
+ public ExtensionRegistryService getExtensionRegistryService() {
+ return extensionRegistryService;
}
private void checkArguments(Reader reader, ScriptContext scriptContext) {
@@ -161,35 +91,5 @@ public class SightlyScriptEngine extends
AbstractSlingScriptEngine implements Co
}
}
- private String getScriptName(ScriptContext scriptContext) {
- if (scriptContext != null) {
- Bindings bindings =
scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
- String scriptName = (String) bindings.get(ScriptEngine.FILENAME);
- if (scriptName != null && !"".equals(scriptName)) {
- return scriptName;
- }
- SlingScriptHelper sling = BindingsUtils.getHelper(bindings);
- if (sling != null) {
- return sling.getScript().getScriptResource().getPath();
- }
- }
- return NO_SCRIPT;
- }
- /**
- * This custom imports analyser makes sure that no import statements are
generated for repository-based use objects, since these are
- * not compiled ahead of the HTL scripts.
- */
- class SlingJavaImportsAnalyser implements JavaImportsAnalyzer {
- @Override
- public boolean allowImport(String importedClass) {
- for (String searchPath :
scriptingResourceResolverProvider.getRequestScopedResourceResolver().getSearchPath())
{
- String subPackage =
JavaEscapeUtils.makeJavaPackage(searchPath);
- if (importedClass.startsWith(subPackage)) {
- return false;
- }
- }
- return true;
- }
- }
}
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 76ba78d..d80f13b 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
@@ -18,30 +18,17 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.engine;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
-import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
-import org.apache.sling.scripting.sightly.compiler.SightlyCompiler;
-import org.apache.sling.scripting.sightly.java.compiler.JavaEscapeUtils;
+import
org.apache.sling.scripting.sightly.impl.engine.compiled.SlingHTLMasterCompiler;
import org.osgi.framework.Constants;
-import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* HTL template engine factory
@@ -58,35 +45,17 @@ import org.slf4j.LoggerFactory;
)
public class SightlyScriptEngineFactory extends AbstractScriptEngineFactory {
- private static final Logger LOGGER =
LoggerFactory.getLogger(SightlyScriptEngineFactory.class);
-
- @Reference
- private DynamicClassLoaderManager dynamicClassLoaderManager;
-
- @Reference
- private SightlyEngineConfiguration sightlyEngineConfiguration;
-
- @Reference
- private ClassLoaderWriter classLoaderWriter;
-
- @Reference
- private SightlyCompiler sightlyCompiler;
-
- @Reference
- private SightlyJavaCompilerService sightlyJavaCompilerService;
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption =
ReferencePolicyOption.GREEDY)
+ private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Reference
- private ScriptingResourceResolverProvider
scriptingResourceResolverProvider;
+ private ExtensionRegistryService extensionRegistryService;
public final static String SHORT_NAME = "sightly";
-
- public final static String LANGUAGE_NAME = "The HTL Templating Language";
-
- public final static String LANGUAGE_VERSION = "1.3";
-
public final static String EXTENSION = "html";
- public static final String SIGHTLY_CONFIG_FILE = "/sightly.config";
+ private final static String LANGUAGE_NAME = "The HTL Templating Language";
+ private final static String LANGUAGE_VERSION = "1.4";
public SightlyScriptEngineFactory() {
setNames("htl", "HTL", SHORT_NAME);
@@ -105,49 +74,6 @@ public class SightlyScriptEngineFactory extends
AbstractScriptEngineFactory {
@Override
public ScriptEngine getScriptEngine() {
- return new SightlyScriptEngine(this, sightlyCompiler,
sightlyJavaCompilerService, sightlyEngineConfiguration,
scriptingResourceResolverProvider);
- }
-
- protected ClassLoader getClassLoader() {
- return dynamicClassLoaderManager.getDynamicClassLoader();
- }
-
- @Activate
- protected void activate() {
- InputStream is;
- boolean newVersion = true;
- String versionInfo = null;
- String newVersionString =
sightlyEngineConfiguration.getEngineVersion();
- try {
- is = classLoaderWriter.getInputStream(SIGHTLY_CONFIG_FILE);
- if (is != null) {
- versionInfo = IOUtils.toString(is, "UTF-8");
- if (newVersionString.equals(versionInfo)) {
- newVersion = false;
- } else {
- LOGGER.info("Detected stale classes generated by Apache
Sling Scripting HTL engine version {}.", versionInfo);
- }
- IOUtils.closeQuietly(is);
- }
- } catch (IOException e) {
- // do nothing; if we didn't find any previous version information
we're considering our version to be new
- }
- if (newVersion) {
- OutputStream os =
classLoaderWriter.getOutputStream(SIGHTLY_CONFIG_FILE);
- try {
- IOUtils.write(sightlyEngineConfiguration.getEngineVersion(),
os, "UTF-8");
- } catch (IOException e) {
- // ignore
- } finally {
- IOUtils.closeQuietly(os);
- }
- String scratchFolder =
sightlyEngineConfiguration.getScratchFolder();
- boolean scratchFolderDeleted =
classLoaderWriter.delete(scratchFolder);
- if (scratchFolderDeleted) {
- if (StringUtils.isNotEmpty(versionInfo)) {
- LOGGER.info("Deleted stale classes generated by Apache
Sling Scripting HTL engine version {}.", versionInfo);
- }
- }
- }
+ return new SightlyScriptEngine(this, extensionRegistryService,
slingHTLMasterCompiler);
}
}
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java
index d32b5cb..5d2fb03 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java
@@ -18,17 +18,7 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.engine.compiled;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
import
org.apache.sling.scripting.sightly.impl.engine.SightlyEngineConfiguration;
import org.apache.sling.scripting.sightly.java.compiler.ClassInfo;
import org.apache.sling.scripting.sightly.java.compiler.JavaEscapeUtils;
@@ -39,14 +29,13 @@ import
org.apache.sling.scripting.sightly.java.compiler.JavaEscapeUtils;
*/
public class SourceIdentifier implements ClassInfo {
- private static final Pattern MANGLED_CHAR_PATTERN =
Pattern.compile("(.*)(__[0-9a-f]{4}__)(.*)");
private SightlyEngineConfiguration engineConfiguration;
private String scriptName;
private String simpleClassName;
private String packageName;
private String fullyQualifiedClassName;
- public SourceIdentifier(SightlyEngineConfiguration engineConfiguration,
String resourcePath) {
+ SourceIdentifier(SightlyEngineConfiguration engineConfiguration, String
resourcePath) {
this.engineConfiguration = engineConfiguration;
this.scriptName = resourcePath;
}
@@ -96,146 +85,4 @@ public class SourceIdentifier implements ClassInfo {
}
return fullyQualifiedClassName;
}
-
- /**
- * Given a {@code fullyQualifiedClassName} and optionally a sub-package
that should be stripped ({@code slashSubpackage}), this
- * method will try to locate a {@code Resource} in the repository that
provides the source code for the Java class.
- *
- * @param resolver a resource resolver with access to the
script paths
- * @param slashSubpackage an optional sub-package that will be
stripped from the {@code fullyQualifiedClassName}
- * @param fullyQualifiedClassName the FQCN
- * @return the {@code Resource} backing the class, or {@code null} if one
cannot be found
- */
- public static Resource getPOJOFromFQCN(ResourceResolver resolver, String
slashSubpackage, String fullyQualifiedClassName) {
- String className = fullyQualifiedClassName;
- StringBuilder pathElements = new StringBuilder("/");
- if (StringUtils.isNotEmpty(slashSubpackage) &&
className.contains(slashSubpackage)) {
- className = className.replaceAll(slashSubpackage + "\\.", "");
- }
- String[] classElements = StringUtils.split(className, '.');
- for (int i = 0; i < classElements.length; i++) {
- String classElem = classElements[i];
- Matcher matcher = MANGLED_CHAR_PATTERN.matcher(classElem);
- if (matcher.matches()) {
- String group = matcher.group(2);
- char unmangled = JavaEscapeUtils.unmangle(group);
- classElem = classElem.replaceAll(group,
Character.toString(unmangled));
- while (matcher.find()) {
- group = matcher.group(2);
- unmangled = JavaEscapeUtils.unmangle(group);
- classElem = classElem.replaceAll(group,
Character.toString(unmangled));
- }
- } else {
- int underscoreIndex = classElem.indexOf('_');
- if (underscoreIndex > -1) {
- if (underscoreIndex == classElem.length() - 1) {
- classElem = classElem.substring(0, classElem.length()
-1);
- } else if (underscoreIndex == 0 &&
!Character.isJavaIdentifierStart(classElem.charAt(1))){
- classElem = classElem.substring(1);
- }
- }
- }
- pathElements.append(classElem);
- if (i < classElements.length - 1) {
- pathElements.append("/");
- }
- }
- Set<String> possiblePOJOPaths =
getPossiblePojoPaths(pathElements.toString() + ".java");
- for (String possiblePath : possiblePOJOPaths) {
- Resource r = resolver.getResource(possiblePath);
- if (r != null) {
- return r;
- }
- }
- return null;
- }
-
- /**
- * For a JCR path obtained from expanding a generated class name this
method generates all the alternative path names that can be
- * obtained by expanding the mentioned class' name.
- *
- * @param originalPath one of the possible paths
- * @return a {@link Set} containing all the alternative paths if symbol
replacement was needed; otherwise the set will contain just
- * the {@code originalPath}
- */
- private static Set<String> getPossiblePojoPaths(String originalPath) {
- Set<String> possiblePaths = new LinkedHashSet<>();
- possiblePaths.add(originalPath);
- Map<Integer, String> chars = new HashMap<>();
- AmbiguousPathSymbol[] symbols = AmbiguousPathSymbol.values();
- for (AmbiguousPathSymbol symbol : symbols) {
- String pathCopy = originalPath.substring(0,
originalPath.lastIndexOf("/"));
- int actualIndex = 0;
- boolean firstPass = true;
- while (pathCopy.indexOf(symbol.getSymbol()) != -1) {
- int pos = pathCopy.indexOf(symbol.getSymbol());
- actualIndex += pos;
- if (!firstPass) {
- actualIndex += 1;
- }
- chars.put(actualIndex, symbol.getSymbol().toString());
- pathCopy = pathCopy.substring(pos + 1);
- firstPass = false;
- }
- }
- if (chars.size() > 0) {
- ArrayList<AmbiguousPathSymbol[]> possibleArrangements = new
ArrayList<>();
- populateArray(possibleArrangements, new
AmbiguousPathSymbol[chars.size()], 0);
- Integer[] indexes = chars.keySet().toArray(new
Integer[chars.size()]);
- for (AmbiguousPathSymbol[] arrangement : possibleArrangements) {
- char[] possiblePath = originalPath.toCharArray();
- for (int i = 0; i < arrangement.length; i++) {
- char currentSymbol = arrangement[i].getSymbol();
- int currentIndex = indexes[i];
- possiblePath[currentIndex] = currentSymbol;
- }
- possiblePaths.add(new String(possiblePath));
- }
- }
- return possiblePaths;
- }
-
- /**
- * Given an initial array with its size equal to the number of elements of
a needed arrangement, this method will generate all
- * the possible arrangements of values for this array in the provided
{@code arrayCollection}. The values with which the array is
- * populated are the {@link AmbiguousPathSymbol} constants.
- *
- * @param arrayCollection the collection that will store the arrays
- * @param symbolsArrangementArray an initial array that will be used for
collecting the results
- * @param index the initial index of the array that will be populated
(needed for recursion purposes; start with 0 for the initial call)
- */
- private static void populateArray(ArrayList<AmbiguousPathSymbol[]>
arrayCollection, AmbiguousPathSymbol[] symbolsArrangementArray, int
- index) {
- if (symbolsArrangementArray.length > 0) {
- if (index == symbolsArrangementArray.length) {
- arrayCollection.add(symbolsArrangementArray.clone());
- } else {
- for (AmbiguousPathSymbol symbol :
AmbiguousPathSymbol.values()) {
- symbolsArrangementArray[index] = symbol;
- populateArray(arrayCollection, symbolsArrangementArray,
index + 1);
- }
- }
- }
- }
-
- /**
- * The {@code AmbiguousPathSymbol} holds symbols that are valid for a JCR
path but that will get transformed to a "_" to obey the
- * Java naming conventions.
- */
- enum AmbiguousPathSymbol {
- DASH('-'),
- UNDERSCORE('_'),
- POINT('.');
-
- private Character symbol;
-
- AmbiguousPathSymbol(Character symbol) {
- this.symbol = symbol;
- }
-
- public Character getSymbol() {
- return symbol;
- }
- }
-
}
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
index 4ab9185..bd7d2b8 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
@@ -33,7 +33,6 @@ import java.util.regex.Pattern;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
@@ -42,7 +41,7 @@ import org.osgi.service.component.annotations.Component;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.FORMAT
+ RuntimeExtension.NAME + "=" + RuntimeExtension.FORMAT
}
)
public class FormatFilterExtension implements RuntimeExtension {
@@ -60,7 +59,7 @@ public class FormatFilterExtension implements
RuntimeExtension {
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.FORMAT, arguments,
2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.FORMAT, arguments,
2);
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
String source = runtimeObjectModel.toString(arguments[0]);
Map<String, Object> options = (Map<String, Object>) arguments[1];
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java
index b22b1e7..39a8236 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java
@@ -30,7 +30,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.i18n.ResourceBundleProvider;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -42,7 +41,7 @@ import org.slf4j.LoggerFactory;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.I18N
+ RuntimeExtension.NAME + "=" + RuntimeExtension.I18N
}
)
public class I18nRuntimeExtension implements RuntimeExtension {
@@ -51,7 +50,7 @@ public class I18nRuntimeExtension implements RuntimeExtension
{
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.I18N, arguments, 2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.I18N, arguments, 2);
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
String text = runtimeObjectModel.toString(arguments[0]);
Map<String, Object> options = (Map<String, Object>) arguments[1];
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java
index 27c2da8..b79dadd 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java
@@ -31,7 +31,6 @@ import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.api.servlets.ServletResolver;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -46,7 +45,7 @@ import org.slf4j.LoggerFactory;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.INCLUDE
+ RuntimeExtension.NAME + "=" + RuntimeExtension.INCLUDE
}
)
public class IncludeRuntimeExtension implements RuntimeExtension {
@@ -60,7 +59,7 @@ public class IncludeRuntimeExtension implements
RuntimeExtension {
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.INCLUDE, arguments,
2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.INCLUDE, arguments,
2);
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
String originalPath = runtimeObjectModel.toString(arguments[0]);
Map options = (Map) arguments[1];
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java
index b3f5bee..37b021b 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java
@@ -21,7 +21,6 @@ package
org.apache.sling.scripting.sightly.impl.engine.extension;
import java.util.Collection;
import java.util.Iterator;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
@@ -30,14 +29,14 @@ import org.osgi.service.component.annotations.Component;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.JOIN
+ RuntimeExtension.NAME + "=" + RuntimeExtension.JOIN
}
)
public class JoinFilterExtension implements RuntimeExtension {
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.JOIN, arguments, 2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.JOIN, arguments, 2);
Object joinArgument = arguments[0];
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
Collection<?> collection =
runtimeObjectModel.toCollection(joinArgument);
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java
index 45b1f4a..3a71e13 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java
@@ -37,7 +37,6 @@ import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.SyntheticResource;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -52,7 +51,7 @@ import org.slf4j.LoggerFactory;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.RESOURCE
+ RuntimeExtension.NAME + "=" + RuntimeExtension.RESOURCE
}
)
public class ResourceRuntimeExtension implements RuntimeExtension {
@@ -70,7 +69,7 @@ public class ResourceRuntimeExtension implements
RuntimeExtension {
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.RESOURCE, arguments,
2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.RESOURCE,
arguments, 2);
return provideResource(renderContext, arguments[0], (Map<String,
Object>) arguments[1]);
}
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
index e5a6b03..7ce8354 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
@@ -36,7 +36,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
@@ -48,7 +47,7 @@ import org.slf4j.LoggerFactory;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.URI_MANIPULATION
+ RuntimeExtension.NAME + "=" + RuntimeExtension.URI_MANIPULATION
}
)
public class URIManipulationFilterExtension implements RuntimeExtension {
@@ -75,7 +74,7 @@ public class URIManipulationFilterExtension implements
RuntimeExtension {
@Override
@SuppressWarnings("unchecked")
public Object call(RenderContext renderContext, Object... arguments) {
- ExtensionUtils.checkArgumentCount(RuntimeFunction.URI_MANIPULATION,
arguments, 2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.URI_MANIPULATION,
arguments, 2);
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
String uriString = runtimeObjectModel.toString(arguments[0]);
Map<String, Object> options = runtimeObjectModel.toMap(arguments[1]);
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java
index a56c825..40d78bb 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java
@@ -18,19 +18,18 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.engine.extension;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
-import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.xss.XSSAPI;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,12 +39,12 @@ import org.slf4j.LoggerFactory;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.XSS
+ RuntimeExtension.NAME + "=" + RuntimeExtension.XSS
}
)
public class XSSRuntimeExtension implements RuntimeExtension {
- @Reference(policyOption = ReferencePolicyOption.GREEDY)
+ @Reference
private XSSAPI xssApi;
private static final Set<String> elementNameWhiteList = new HashSet<>();
@@ -57,7 +56,7 @@ public class XSSRuntimeExtension implements RuntimeExtension {
public Object call(final RenderContext renderContext, Object... arguments)
{
if (arguments.length < 2) {
throw new SightlyException(
- String.format("Extension %s requires at least %d
arguments", RuntimeFunction.XSS, 2));
+ String.format("Extension %s requires at least %d
arguments", RuntimeExtension.XSS, 2));
}
Object original = arguments[0];
Object option = arguments[1];
@@ -237,4 +236,53 @@ public class XSSRuntimeExtension implements
RuntimeExtension {
private boolean isSensitiveAttribute(String name) {
return ATTRIBUTE_BLACKLIST.matcher(name).matches();
}
+
+ private enum MarkupContext {
+
+ HTML("html"),
+ TEXT("text"),
+ ELEMENT_NAME("elementName"),
+ ATTRIBUTE_NAME("attributeName"),
+ ATTRIBUTE("attribute"),
+ URI("uri"),
+ SCRIPT_TOKEN("scriptToken"),
+ SCRIPT_STRING("scriptString"),
+ SCRIPT_COMMENT("scriptComment"),
+ SCRIPT_REGEXP("scriptRegExp"),
+ STYLE_TOKEN("styleToken"),
+ STYLE_STRING("styleString"),
+ STYLE_COMMENT("styleComment"),
+ COMMENT("comment"),
+ NUMBER("number"),
+ UNSAFE("unsafe");
+
+ private final String name;
+
+ MarkupContext(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the render context with the given name.
+ *
+ * @param name the name of the render context
+ * @return the rendering context value or {@code null} if the name
matches no value
+ */
+ static MarkupContext lookup(String name) {
+ return reverseMap.get(name);
+ }
+
+ private static final Map<String, MarkupContext> reverseMap = new
HashMap<>();
+
+ static {
+ for (MarkupContext markupContext : MarkupContext.values()) {
+ reverseMap.put(markupContext.getName(), markupContext);
+ }
+ }
+ }
+
}
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 e85a2fd..1cb5919 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
@@ -21,7 +21,7 @@ package
org.apache.sling.scripting.sightly.impl.engine.extension.use;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
-import java.util.regex.Pattern;
+
import javax.script.Bindings;
import javax.servlet.ServletRequest;
@@ -29,8 +29,7 @@ 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.commons.classloader.ClassLoaderWriter;
-import
org.apache.sling.scripting.sightly.impl.engine.SightlyJavaCompilerService;
+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;
import org.apache.sling.scripting.sightly.pojo.Use;
@@ -40,6 +39,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;
@@ -64,14 +65,11 @@ public class JavaUseProvider implements UseProvider {
}
- public static final String ADAPTABLE = "adaptable";
+ private static final String ADAPTABLE = "adaptable";
private static final Logger LOG =
LoggerFactory.getLogger(JavaUseProvider.class);
- @Reference
- private SightlyJavaCompilerService sightlyJavaCompilerService = null;
-
- @Reference
- private ClassLoaderWriter classLoaderWriter = null;
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption =
ReferencePolicyOption.GREEDY)
+ private SlingHTLMasterCompiler slingHTLMasterCompiler;
@Override
public ProviderOutcome provide(String identifier, RenderContext
renderContext, Bindings arguments) {
@@ -84,9 +82,11 @@ public class JavaUseProvider implements UseProvider {
SlingHttpServletRequest request =
BindingsUtils.getRequest(globalBindings);
Map<String, Object> overrides = setRequestAttributes(request,
arguments);
- Object result;
+ Object result = null;
try {
- result =
sightlyJavaCompilerService.getResourceBackedUseObject(renderContext,
identifier);
+ if (slingHTLMasterCompiler != null) {
+ result =
slingHTLMasterCompiler.getResourceBackedUseObject(renderContext, identifier);
+ }
if (result != null) {
if (result instanceof Use) {
((Use) result).init(BindingsUtils.merge(globalBindings,
arguments));
@@ -94,41 +94,50 @@ public class JavaUseProvider implements UseProvider {
return ProviderOutcome.success(result);
} else {
LOG.debug("Attempting to load class {} from the classloader
cache.", identifier);
- Class<?> cls =
classLoaderWriter.getClassLoader().loadClass(identifier);
- // attempt OSGi service load
- result = sling.getService(cls);
- if (result != null) {
- return ProviderOutcome.success(result);
+ ClassLoader classLoader = null;
+ if (slingHTLMasterCompiler != null) {
+ classLoader = slingHTLMasterCompiler.getClassLoader();
}
- Object adaptableCandidate = arguments.get(ADAPTABLE);
- if (adaptableCandidate != null && adaptableCandidate
instanceof Adaptable) {
- Adaptable adaptable = (Adaptable) adaptableCandidate;
- result = adaptable.adaptTo(cls);
+
+ // attempt OSGi service load
+ if (classLoader != null) {
+ Class<?> cls = classLoader.loadClass(identifier);
+
+ result = sling.getService(cls);
if (result != null) {
return ProviderOutcome.success(result);
}
- }
- result = request.adaptTo(cls);
- if (result == null) {
- Resource resource =
BindingsUtils.getResource(globalBindings);
- result = resource.adaptTo(cls);
- }
- if (result != null) {
- return ProviderOutcome.success(result);
- } else if(cls.isInterface() ||
Modifier.isAbstract(cls.getModifiers())){
- LOG.debug("Wont attempt to instantiate an interface or
abstract class {}",cls.getName());
- return ProviderOutcome.failure();
- } else {
- /*
- * the object was cached by the class loader but it's not
adaptable from {@link Resource} or {@link
- * SlingHttpServletRequest}; attempt to load it like a
regular POJO that optionally could implement {@link Use}
- */
- result = cls.newInstance();
- if (result instanceof Use) {
- ((Use)
result).init(BindingsUtils.merge(globalBindings, arguments));
+ Object adaptableCandidate = arguments.get(ADAPTABLE);
+ if (adaptableCandidate instanceof Adaptable) {
+ Adaptable adaptable = (Adaptable) adaptableCandidate;
+ result = adaptable.adaptTo(cls);
+ if (result != null) {
+ return ProviderOutcome.success(result);
+ }
+ }
+ result = request.adaptTo(cls);
+ if (result == null) {
+ Resource resource =
BindingsUtils.getResource(globalBindings);
+ result = resource.adaptTo(cls);
+ }
+ if (result != null) {
+ return ProviderOutcome.success(result);
+ } else if (cls.isInterface() ||
Modifier.isAbstract(cls.getModifiers())) {
+ LOG.debug("Wont attempt to instantiate an interface or
abstract class {}", cls.getName());
+ return ProviderOutcome.failure();
+ } else {
+ /*
+ * the object was cached by the class loader but it's
not adaptable from {@link Resource} or {@link
+ * SlingHttpServletRequest}; attempt to load it like a
regular POJO that optionally could implement {@link Use}
+ */
+ result = cls.newInstance();
+ if (result instanceof Use) {
+ ((Use)
result).init(BindingsUtils.merge(globalBindings, arguments));
+ }
+ return ProviderOutcome.notNullOrFailure(result);
}
- return ProviderOutcome.notNullOrFailure(result);
}
+ return ProviderOutcome.failure();
}
} catch (Exception e) {
// any other exception is an error
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 0008251..df29230 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
@@ -41,8 +41,8 @@ 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.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.impl.utils.ScriptUtils;
-import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
import org.apache.sling.scripting.sightly.use.ProviderOutcome;
import org.apache.sling.scripting.sightly.use.UseProvider;
import org.osgi.framework.Constants;
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
index 4d7789a..242228b 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
@@ -29,7 +29,6 @@ import javax.script.SimpleBindings;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.scripting.sightly.SightlyException;
-import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.impl.engine.extension.ExtensionUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -49,7 +48,7 @@ import org.osgi.service.component.annotations.ReferencePolicy;
@Component(
service = RuntimeExtension.class,
property = {
- RuntimeExtension.NAME + "=" + RuntimeFunction.USE
+ RuntimeExtension.NAME + "=" + RuntimeExtension.USE
}
)
public class UseRuntimeExtension implements RuntimeExtension {
@@ -58,7 +57,7 @@ public class UseRuntimeExtension implements RuntimeExtension {
@Override
public Object call(final RenderContext renderContext, Object... arguments)
{
- ExtensionUtils.checkArgumentCount(RuntimeFunction.USE, arguments, 2);
+ ExtensionUtils.checkArgumentCount(RuntimeExtension.USE, arguments, 2);
RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
String identifier = runtimeObjectModel.toString(arguments[0]);
if (StringUtils.isEmpty(identifier)) {
diff --git
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
index e70d6e4..605b8e7 100644
---
a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
+++
b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
@@ -19,16 +19,19 @@
package org.apache.sling.scripting.sightly.impl.engine.runtime;
import java.util.Map;
+
import javax.script.Bindings;
import javax.script.ScriptContext;
+import org.apache.sling.api.scripting.SlingScriptConstants;
import org.apache.sling.scripting.sightly.SightlyException;
import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
import org.apache.sling.scripting.sightly.impl.engine.ExtensionRegistryService;
-import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.AbstractRuntimeObjectModel;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
/**
* Rendering context for HTL rendering units.
@@ -40,9 +43,14 @@ public class RenderContextImpl implements RenderContext {
private final Bindings bindings;
private final ExtensionRegistryService extensionRegistryService;
- public RenderContextImpl(ScriptContext scriptContext) {
+ public RenderContextImpl(ExtensionRegistryService
extensionRegistryService, ScriptContext scriptContext) {
+ this.extensionRegistryService = extensionRegistryService;
bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
- extensionRegistryService =
BindingsUtils.getHelper(bindings).getService(ExtensionRegistryService.class);
+ Bundle scriptProvidingBundle = (Bundle)
scriptContext.getAttribute("org.apache.sling.scripting.resolver.provider.bundle",
+ SlingScriptConstants.SLING_SCOPE);
+ if (scriptProvidingBundle != null) {
+
bindings.put("org.apache.sling.scripting.sightly.render_unit.loader",
scriptProvidingBundle.adapt(BundleWiring.class).getClassLoader());
+ }
}
@Override
diff --git
a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerServiceTest.java
b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerServiceTest.java
deleted file mode 100644
index 98671d6..0000000
---
a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerServiceTest.java
+++ /dev/null
@@ -1,189 +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.compiler;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.commons.compiler.CompilationResult;
-import org.apache.sling.commons.compiler.CompilationUnit;
-import org.apache.sling.commons.compiler.CompilerMessage;
-import org.apache.sling.commons.compiler.JavaCompiler;
-import org.apache.sling.commons.compiler.Options;
-import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
-import
org.apache.sling.scripting.sightly.impl.engine.ResourceBackedPojoChangeMonitor;
-import
org.apache.sling.scripting.sightly.impl.engine.SightlyEngineConfiguration;
-import
org.apache.sling.scripting.sightly.impl.engine.SightlyJavaCompilerService;
-import
org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier;
-import
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.powermock.reflect.Whitebox;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.*;
-
-public class SightlyJavaCompilerServiceTest {
-
- private SightlyJavaCompilerService compiler;
- private ResourceBackedPojoChangeMonitor resourceBackedPojoChangeMonitor;
- private ClassLoaderWriter classLoaderWriter;
- private ScriptingResourceResolverProvider
scriptingResourceResolverProvider;
-
- @Before
- public void setUp() throws Exception {
- compiler = spy(new SightlyJavaCompilerService());
- resourceBackedPojoChangeMonitor = spy(new
ResourceBackedPojoChangeMonitor());
- SightlyEngineConfiguration sightlyEngineConfiguration =
mock(SightlyEngineConfiguration.class);
-
when(sightlyEngineConfiguration.getBundleSymbolicName()).thenReturn("org.apache.sling.scripting.sightly");
-
when(sightlyEngineConfiguration.getScratchFolder()).thenReturn("/org/apache/sling/scripting/sightly");
- Whitebox.setInternalState(compiler, "sightlyEngineConfiguration",
sightlyEngineConfiguration);
- Whitebox.setInternalState(compiler, "resourceBackedPojoChangeMonitor",
resourceBackedPojoChangeMonitor);
- classLoaderWriter = Mockito.mock(ClassLoaderWriter.class);
- ClassLoader classLoader = Mockito.mock(ClassLoader.class);
- when(classLoaderWriter.getClassLoader()).thenReturn(classLoader);
- }
-
- @After
- public void tearDown() throws Exception {
- compiler = null;
- resourceBackedPojoChangeMonitor = null;
- classLoaderWriter = null;
- }
-
- @Test
- public void testDiskCachedUseObject() throws Exception {
- String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
- String className = "apps.myproject.testcomponents.a.Pojo";
- scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
- ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
- Resource pojoResource = Mockito.mock(Resource.class);
- when(pojoResource.getPath()).thenReturn(pojoPath);
- ResourceMetadata mockMetadata = Mockito.mock(ResourceMetadata.class);
- when(mockMetadata.getModificationTime()).thenReturn(1l);
- when(pojoResource.getResourceMetadata()).thenReturn(mockMetadata);
-
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
- when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
-
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(2l);
- getInstancePojoTest(className);
- /*
- * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
- * object
- */
- verify(compiler, never()).compileSource(any(SourceIdentifier.class),
anyString());
- }
-
- @Test
- public void testObsoleteDiskCachedUseObject() throws Exception {
- String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
- String className = "apps.myproject.testcomponents.a.Pojo";
- scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
- ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
- Resource pojoResource = Mockito.mock(Resource.class);
- when(pojoResource.getPath()).thenReturn(pojoPath);
- ResourceMetadata mockMetadata = Mockito.mock(ResourceMetadata.class);
- when(mockMetadata.getModificationTime()).thenReturn(2l);
- when(pojoResource.getResourceMetadata()).thenReturn(mockMetadata);
-
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
- when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
-
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(1l);
- getInstancePojoTest(className);
- /*
- * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
- * object
- */
- verify(compiler).compileSource(any(SourceIdentifier.class),
anyString());
- }
-
- @Test
- public void testMemoryCachedUseObject() throws Exception {
- String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
- String className = "apps.myproject.testcomponents.a.Pojo";
- scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
- ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
- Resource pojoResource = Mockito.mock(Resource.class);
- when(pojoResource.getPath()).thenReturn(pojoPath);
-
when(resourceBackedPojoChangeMonitor.getLastModifiedDateForJavaUseObject(pojoPath)).thenReturn(1l);
-
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
- when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
-
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(2l);
- getInstancePojoTest(className);
- /*
- * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
- * object
- */
- verify(compiler, never()).compileSource(any(SourceIdentifier.class),
anyString());
- }
-
- @Test
- public void testObsoleteMemoryCachedUseObject() throws Exception {
- String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
- String className = "apps.myproject.testcomponents.a.Pojo";
- scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
- ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
- Resource pojoResource = Mockito.mock(Resource.class);
- when(pojoResource.getPath()).thenReturn(pojoPath);
-
when(resourceBackedPojoChangeMonitor.getLastModifiedDateForJavaUseObject(pojoPath)).thenReturn(2l);
-
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
- when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
-
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(1l);
- getInstancePojoTest(className);
- /*
- * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
- * object
- */
- verify(compiler).compileSource(any(SourceIdentifier.class),
anyString());
- }
-
- private void getInstancePojoTest(String className) throws Exception {
- RenderContextImpl renderContext =
Mockito.mock(RenderContextImpl.class);
-
-
- JavaCompiler javaCompiler = Mockito.mock(JavaCompiler.class);
- CompilationResult compilationResult =
Mockito.mock(CompilationResult.class);
- when(compilationResult.getErrors()).thenReturn(new
ArrayList<CompilerMessage>());
- when(javaCompiler.compile(Mockito.any(CompilationUnit[].class),
Mockito.any(Options.class))).thenReturn(compilationResult);
-
when(classLoaderWriter.getClassLoader().loadClass(className)).thenAnswer(new
Answer<Object>() {
- @Override
- public Object answer(InvocationOnMock invocation) throws Throwable
{
- return MockPojo.class;
- }
- });
- Whitebox.setInternalState(compiler, "classLoaderWriter",
classLoaderWriter);
- Whitebox.setInternalState(compiler, "javaCompiler", javaCompiler);
- Whitebox.setInternalState(compiler,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
- Object obj = compiler.getResourceBackedUseObject(renderContext,
className);
- assertTrue("Expected to obtain a " + MockPojo.class.getName() + "
object.", obj instanceof MockPojo);
- }
-}
diff --git
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScriptTest.java
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScriptTest.java
index 00cbf51..9fc3b03 100644
---
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScriptTest.java
+++
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyCompiledScriptTest.java
@@ -29,7 +29,7 @@ import javax.script.SimpleBindings;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.scripting.SlingBindings;
-import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
+import org.apache.sling.scripting.sightly.render.RenderUnit;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.sling.MockSling;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -55,8 +55,8 @@ public class SightlyCompiledScriptTest {
* @throws ScriptException
*/
@Test
- public void testEvalSlingBindings() throws ScriptException {
- ScriptEngine scriptEngine = mock(ScriptEngine.class);
+ public void testEvalSlingBindings() {
+ SightlyScriptEngine scriptEngine = mock(SightlyScriptEngine.class);
final RenderUnit renderUnit = mock(RenderUnit.class);
Whitebox.setInternalState(renderUnit, "subTemplates", new
HashMap<String, Object>());
final BundleContext bundleContext = MockOsgi.newBundleContext();
diff --git
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactoryTest.java
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactoryTest.java
deleted file mode 100644
index 79755ca..0000000
---
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactoryTest.java
+++ /dev/null
@@ -1,121 +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;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.powermock.reflect.Whitebox;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class SightlyScriptEngineFactoryTest {
-
- private SightlyEngineConfiguration sightlyEngineConfiguration;
- private ScriptingResourceResolverProvider
scriptingResourceResolverProvider;
-
- @Before
- public void setUp() {
- sightlyEngineConfiguration = mock(SightlyEngineConfiguration.class);
-
when(sightlyEngineConfiguration.getEngineVersion()).thenReturn("1.0.17-SNAPSHOT");
-
when(sightlyEngineConfiguration.getScratchFolder()).thenReturn("/org/apache/sling/scripting/sightly");
-
- ResourceResolver scriptingResourceResolver =
mock(ResourceResolver.class);
- scriptingResourceResolverProvider =
mock(ScriptingResourceResolverProvider.class);
-
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(scriptingResourceResolver);
- when(scriptingResourceResolver.getSearchPath()).thenReturn(new
String[] {"/apps", "/libs"});
- }
-
- @After
- public void tearDown() {
- sightlyEngineConfiguration = null;
- }
-
- @Test
- public void testActivateNoPreviousInfo() {
- SightlyScriptEngineFactory scriptEngineFactory = new
SightlyScriptEngineFactory();
- ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
when(classLoaderWriter.getOutputStream(SightlyScriptEngineFactory.SIGHTLY_CONFIG_FILE)).thenReturn(outputStream);
- Whitebox.setInternalState(scriptEngineFactory, "classLoaderWriter",
classLoaderWriter);
- Whitebox.setInternalState(scriptEngineFactory,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
- Whitebox.setInternalState(scriptEngineFactory,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
- scriptEngineFactory.activate();
-
verify(classLoaderWriter).delete(sightlyEngineConfiguration.getScratchFolder());
- assertEquals("1.0.17-SNAPSHOT", outputStream.toString());
- }
-
- @Test
- public void testActivateOverPreviousVersion() {
- SightlyScriptEngineFactory scriptEngineFactory = new
SightlyScriptEngineFactory();
- ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
- try {
-
when(classLoaderWriter.getInputStream(SightlyScriptEngineFactory.SIGHTLY_CONFIG_FILE))
- .thenReturn(IOUtils.toInputStream("1.0.16", "UTF-8"));
- } catch (IOException e) {
- fail("IOException while setting tests.");
- }
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
when(classLoaderWriter.getOutputStream(SightlyScriptEngineFactory.SIGHTLY_CONFIG_FILE)).thenReturn(outputStream);
-
when(classLoaderWriter.delete(sightlyEngineConfiguration.getScratchFolder())).thenReturn(true);
- Whitebox.setInternalState(scriptEngineFactory, "classLoaderWriter",
classLoaderWriter);
- Whitebox.setInternalState(scriptEngineFactory,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
- Whitebox.setInternalState(scriptEngineFactory,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
- scriptEngineFactory.activate();
-
verify(classLoaderWriter).delete(sightlyEngineConfiguration.getScratchFolder());
- assertEquals("1.0.17-SNAPSHOT", outputStream.toString());
- }
-
- @Test
- public void testActivateOverSameVersion() {
- SightlyScriptEngineFactory scriptEngineFactory = new
SightlyScriptEngineFactory();
- ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
- try {
-
when(classLoaderWriter.getInputStream(SightlyScriptEngineFactory.SIGHTLY_CONFIG_FILE))
- .thenReturn(IOUtils.toInputStream("1.0.17-SNAPSHOT",
"UTF-8"));
- } catch (IOException e) {
- fail("IOException while setting tests.");
- }
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- ByteArrayOutputStream spyOutputStream = spy(outputStream);
-
when(classLoaderWriter.getOutputStream(SightlyScriptEngineFactory.SIGHTLY_CONFIG_FILE)).thenReturn(spyOutputStream);
- Whitebox.setInternalState(scriptEngineFactory, "classLoaderWriter",
classLoaderWriter);
- Whitebox.setInternalState(scriptEngineFactory,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
- Whitebox.setInternalState(scriptEngineFactory,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
- scriptEngineFactory.activate();
- verify(classLoaderWriter,
never()).delete(sightlyEngineConfiguration.getScratchFolder());
- try {
- verify(spyOutputStream, never()).write(any(byte[].class));
- verify(spyOutputStream, never()).close();
- } catch (IOException e) {
- fail("IOException in test verification.");
- }
- }
-}
diff --git
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompilerTest.java
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompilerTest.java
new file mode 100644
index 0000000..ed85dca
--- /dev/null
+++
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SlingHTLMasterCompilerTest.java
@@ -0,0 +1,296 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.compiled;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
+import org.apache.sling.commons.compiler.CompilationResult;
+import org.apache.sling.commons.compiler.CompilationUnit;
+import org.apache.sling.commons.compiler.CompilerMessage;
+import org.apache.sling.commons.compiler.JavaCompiler;
+import org.apache.sling.commons.compiler.Options;
+import
org.apache.sling.scripting.api.resource.ScriptingResourceResolverProvider;
+import org.apache.sling.scripting.sightly.impl.compiler.MockPojo;
+import
org.apache.sling.scripting.sightly.impl.engine.ResourceBackedPojoChangeMonitor;
+import
org.apache.sling.scripting.sightly.impl.engine.SightlyEngineConfiguration;
+import
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.powermock.reflect.Whitebox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class SlingHTLMasterCompilerTest {
+
+ private SightlyEngineConfiguration sightlyEngineConfiguration;
+ private ScriptingResourceResolverProvider
scriptingResourceResolverProvider;
+ private SlingHTLMasterCompiler compiler;
+ private JavaCompiler javaCompiler;
+ private ResourceBackedPojoChangeMonitor resourceBackedPojoChangeMonitor;
+ private ClassLoaderWriter classLoaderWriter;
+
+ @Before
+ public void setUp() {
+ sightlyEngineConfiguration = mock(SightlyEngineConfiguration.class);
+
when(sightlyEngineConfiguration.getBundleSymbolicName()).thenReturn("org.apache.sling.scripting.sightly");
+
when(sightlyEngineConfiguration.getEngineVersion()).thenReturn("1.0.17-SNAPSHOT");
+
when(sightlyEngineConfiguration.getScratchFolder()).thenReturn("/org/apache/sling/scripting/sightly");
+
+ ResourceResolver scriptingResourceResolver =
mock(ResourceResolver.class);
+ scriptingResourceResolverProvider =
mock(ScriptingResourceResolverProvider.class);
+
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(scriptingResourceResolver);
+ when(scriptingResourceResolver.getSearchPath()).thenReturn(new
String[] {"/apps", "/libs"});
+
+ compiler = spy(new SlingHTLMasterCompiler());
+ javaCompiler = mock(JavaCompiler.class);
+
+ resourceBackedPojoChangeMonitor = spy(new
ResourceBackedPojoChangeMonitor());
+
+ Whitebox.setInternalState(compiler, "sightlyEngineConfiguration",
sightlyEngineConfiguration);
+ Whitebox.setInternalState(compiler, "resourceBackedPojoChangeMonitor",
resourceBackedPojoChangeMonitor);
+ Whitebox.setInternalState(compiler, "javaCompiler", javaCompiler);
+ classLoaderWriter = Mockito.mock(ClassLoaderWriter.class);
+ ClassLoader classLoader = Mockito.mock(ClassLoader.class);
+ when(classLoaderWriter.getClassLoader()).thenReturn(classLoader);
+ }
+
+ @After
+ public void tearDown() {
+ sightlyEngineConfiguration = null;
+ compiler = null;
+ resourceBackedPojoChangeMonitor = null;
+ classLoaderWriter = null;
+ }
+
+ @Test
+ public void testActivateNoPreviousInfo() {
+ SlingHTLMasterCompiler slingHTLMasterCompiler = new
SlingHTLMasterCompiler();
+ ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
when(classLoaderWriter.getOutputStream(SlingHTLMasterCompiler.SIGHTLY_CONFIG_FILE)).thenReturn(outputStream);
+ Whitebox.setInternalState(slingHTLMasterCompiler, "classLoaderWriter",
classLoaderWriter);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
+ slingHTLMasterCompiler.activate();
+
verify(classLoaderWriter).delete(sightlyEngineConfiguration.getScratchFolder());
+ assertEquals("1.0.17-SNAPSHOT", outputStream.toString());
+ }
+
+ @Test
+ public void testActivateOverPreviousVersion() {
+ SlingHTLMasterCompiler slingHTLMasterCompiler = new
SlingHTLMasterCompiler();
+ ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
+ try {
+
when(classLoaderWriter.getInputStream(SlingHTLMasterCompiler.SIGHTLY_CONFIG_FILE))
+ .thenReturn(IOUtils.toInputStream("1.0.16", "UTF-8"));
+ } catch (IOException e) {
+ fail("IOException while setting tests.");
+ }
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
when(classLoaderWriter.getOutputStream(SlingHTLMasterCompiler.SIGHTLY_CONFIG_FILE)).thenReturn(outputStream);
+
when(classLoaderWriter.delete(sightlyEngineConfiguration.getScratchFolder())).thenReturn(true);
+ Whitebox.setInternalState(slingHTLMasterCompiler, "classLoaderWriter",
classLoaderWriter);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
+ slingHTLMasterCompiler.activate();
+
verify(classLoaderWriter).delete(sightlyEngineConfiguration.getScratchFolder());
+ assertEquals("1.0.17-SNAPSHOT", outputStream.toString());
+ }
+
+ @Test
+ public void testActivateOverSameVersion() {
+ SlingHTLMasterCompiler slingHTLMasterCompiler = new
SlingHTLMasterCompiler();
+ ClassLoaderWriter classLoaderWriter = mock(ClassLoaderWriter.class);
+ try {
+
when(classLoaderWriter.getInputStream(SlingHTLMasterCompiler.SIGHTLY_CONFIG_FILE))
+ .thenReturn(IOUtils.toInputStream("1.0.17-SNAPSHOT",
"UTF-8"));
+ } catch (IOException e) {
+ fail("IOException while setting tests.");
+ }
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ ByteArrayOutputStream spyOutputStream = spy(outputStream);
+
when(classLoaderWriter.getOutputStream(SlingHTLMasterCompiler.SIGHTLY_CONFIG_FILE)).thenReturn(spyOutputStream);
+ Whitebox.setInternalState(slingHTLMasterCompiler, "classLoaderWriter",
classLoaderWriter);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"sightlyEngineConfiguration", sightlyEngineConfiguration);
+ Whitebox.setInternalState(slingHTLMasterCompiler,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
+ slingHTLMasterCompiler.activate();
+ verify(classLoaderWriter,
never()).delete(sightlyEngineConfiguration.getScratchFolder());
+ try {
+ verify(spyOutputStream, never()).write(any(byte[].class));
+ verify(spyOutputStream, never()).close();
+ } catch (IOException e) {
+ fail("IOException in test verification.");
+ }
+ }
+
+ @Test
+ public void testDiskCachedUseObject() throws Exception {
+ String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
+ String className = "apps.myproject.testcomponents.a.Pojo";
+ scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
+ ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
+ Resource pojoResource = Mockito.mock(Resource.class);
+ when(pojoResource.getPath()).thenReturn(pojoPath);
+ ResourceMetadata mockMetadata = Mockito.mock(ResourceMetadata.class);
+ when(mockMetadata.getModificationTime()).thenReturn(1L);
+ when(pojoResource.getResourceMetadata()).thenReturn(mockMetadata);
+
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
+ when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
+
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(2L);
+ getInstancePojoTest(className);
+ /*
+ * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
+ * object
+ */
+ verify(javaCompiler, never()).compile(any(CompilationUnit[].class),
any(Options.class));
+ }
+
+ @Test
+ public void testObsoleteDiskCachedUseObject() throws Exception {
+ String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
+ String className = "apps.myproject.testcomponents.a.Pojo";
+ scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
+ ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
+ Resource pojoResource = Mockito.mock(Resource.class);
+ when(pojoResource.getPath()).thenReturn(pojoPath);
+ ResourceMetadata mockMetadata = Mockito.mock(ResourceMetadata.class);
+ when(mockMetadata.getModificationTime()).thenReturn(2L);
+ when(pojoResource.getResourceMetadata()).thenReturn(mockMetadata);
+
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
+ when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
+
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(1L);
+ getInstancePojoTest(className);
+ /*
+ * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
+ * object
+ */
+ verify(compiler).getResourceBackedUseObject(any(RenderContext.class),
anyString());
+ }
+
+ @Test
+ public void testMemoryCachedUseObject() throws Exception {
+ String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
+ String className = "apps.myproject.testcomponents.a.Pojo";
+ scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
+ ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
+ Resource pojoResource = Mockito.mock(Resource.class);
+ when(pojoResource.getPath()).thenReturn(pojoPath);
+
when(resourceBackedPojoChangeMonitor.getLastModifiedDateForJavaUseObject(pojoPath)).thenReturn(1L);
+
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
+ when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
+
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(2L);
+ getInstancePojoTest(className);
+ /*
+ * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
+ * object
+ */
+ verify(javaCompiler, never()).compile(any(CompilationUnit[].class),
any(Options.class));
+ }
+
+ @Test
+ public void testObsoleteMemoryCachedUseObject() throws Exception {
+ String pojoPath = "/apps/myproject/testcomponents/a/Pojo.java";
+ String className = "apps.myproject.testcomponents.a.Pojo";
+ scriptingResourceResolverProvider =
Mockito.mock(ScriptingResourceResolverProvider.class);
+ ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+
when(scriptingResourceResolverProvider.getRequestScopedResourceResolver()).thenReturn(resolver);
+ Resource pojoResource = Mockito.mock(Resource.class);
+ when(pojoResource.getPath()).thenReturn(pojoPath);
+
when(resourceBackedPojoChangeMonitor.getLastModifiedDateForJavaUseObject(pojoPath)).thenReturn(2L);
+
when(pojoResource.adaptTo(InputStream.class)).thenReturn(IOUtils.toInputStream("DUMMY",
"UTF-8"));
+ when(resolver.getResource(pojoPath)).thenReturn(pojoResource);
+
when(classLoaderWriter.getLastModified("/apps/myproject/testcomponents/a/Pojo.class")).thenReturn(1L);
+ getInstancePojoTest(className);
+ /*
+ * assuming the compiled class has a last modified date greater than
the source, then the compiler should not recompile the Use
+ * object
+ */
+ verify(javaCompiler, times(1)).compile(any(CompilationUnit[].class),
any(Options.class));
+ }
+
+ @Test
+ public void testGetPOJOFromFQCN() {
+ Map<String, String> expectedScriptNames = new HashMap<String,
String>() {{
+ put("/apps/a_b_c/d_e_f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
+ put("/apps/a-b-c/d.e.f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
+ put("/apps/a-b-c/d-e.f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
+ put("/apps/a-b-c/d.e_f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
+ put("/apps/a-b-c/d-e-f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
+ put("/apps/a/b/c/Pojo.java", "apps.a.b.c.Pojo");
+ }};
+ for (Map.Entry<String, String> scriptEntry :
expectedScriptNames.entrySet()) {
+ ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
+ Resource resource = Mockito.mock(Resource.class);
+ when(resource.getPath()).thenReturn(scriptEntry.getKey());
+
when(resolver.getResource(scriptEntry.getKey())).thenReturn(resource);
+ Resource result = compiler.getPOJOFromFQCN(resolver,
scriptEntry.getValue());
+ assertNotNull(
+ String.format("ResourceResolver was expected to find
resource %s for POJO %s. Got null instead.", scriptEntry.getKey(),
+ scriptEntry.getValue()), result);
+ assertEquals(scriptEntry.getKey(), result.getPath());
+ }
+ }
+
+ private void getInstancePojoTest(String className) throws Exception {
+ RenderContextImpl renderContext =
Mockito.mock(RenderContextImpl.class);
+ CompilationResult compilationResult =
Mockito.mock(CompilationResult.class);
+ when(compilationResult.getErrors()).thenReturn(new
ArrayList<CompilerMessage>());
+ when(javaCompiler.compile(Mockito.any(CompilationUnit[].class),
Mockito.any(Options.class))).thenReturn(compilationResult);
+
when(classLoaderWriter.getClassLoader().loadClass(className)).thenAnswer(new
Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocation) {
+ return MockPojo.class;
+ }
+ });
+ Whitebox.setInternalState(compiler, "classLoaderWriter",
classLoaderWriter);
+ Whitebox.setInternalState(compiler, "javaCompiler", javaCompiler);
+ Whitebox.setInternalState(compiler,
"scriptingResourceResolverProvider", scriptingResourceResolverProvider);
+ Object obj = compiler.getResourceBackedUseObject(renderContext,
className);
+ assertTrue("Expected to obtain a " + MockPojo.class.getName() + "
object.", obj instanceof MockPojo);
+ }
+}
diff --git
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifierTest.java
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifierTest.java
index 15e46d2..870652e 100644
---
a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifierTest.java
+++
b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifierTest.java
@@ -35,48 +35,25 @@ public class SourceIdentifierTest {
private static final String BUNDLE_SYMBOLIC_NAME =
"org.apache.sling.scripting.sightly";
@Test
- public void testGetClassName() throws Exception {
+ public void testGetClassName() {
SourceIdentifier sourceIdentifier =
getSourceIdentifier("/apps/blah/static/foo/foo.html");
assertEquals("foo_html", sourceIdentifier.getSimpleClassName());
}
@Test
- public void testGetPackageName() throws Exception {
+ public void testGetPackageName() {
SourceIdentifier sourceIdentifier =
getSourceIdentifier("/apps/blah/static/foo/foo.html");
assertEquals(BUNDLE_SYMBOLIC_NAME + ".apps.blah.static_.foo",
sourceIdentifier.getPackageName());
}
@Test
- public void testGetFullyQualifiedName() throws Exception {
+ public void testGetFullyQualifiedName() {
SourceIdentifier sourceIdentifier =
getSourceIdentifier("/apps/blah/static/foo/foo.html");
assertEquals(BUNDLE_SYMBOLIC_NAME + ".apps.blah.static_.foo.foo_html",
sourceIdentifier.getPackageName() + "." +
sourceIdentifier.getSimpleClassName());
}
@Test
- public void testGetPOJOFromFQCN() {
- Map<String, String> expectedScriptNames = new HashMap<String,
String>() {{
- put("/apps/a_b_c/d_e_f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
- put("/apps/a-b-c/d.e.f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
- put("/apps/a-b-c/d-e.f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
- put("/apps/a-b-c/d.e_f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
- put("/apps/a-b-c/d-e-f/Pojo.java", "apps.a_b_c.d_e_f.Pojo");
- put("/apps/a/b/c/Pojo.java", "apps.a.b.c.Pojo");
- }};
- for (Map.Entry<String, String> scriptEntry :
expectedScriptNames.entrySet()) {
- ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
- Resource resource = Mockito.mock(Resource.class);
- when(resource.getPath()).thenReturn(scriptEntry.getKey());
-
when(resolver.getResource(scriptEntry.getKey())).thenReturn(resource);
- Resource result = SourceIdentifier.getPOJOFromFQCN(resolver,
BUNDLE_SYMBOLIC_NAME, scriptEntry.getValue());
- assertNotNull(
- String.format("ResourceResolver was expected to find
resource %s for POJO %s. Got null instead.", scriptEntry.getKey(),
- scriptEntry.getValue()), result);
- assertEquals(scriptEntry.getKey(), result.getPath());
- }
- }
-
- @Test
public void testPOJOMangling() {
Map<String, String> expectedMangling = new HashMap<String, String>(){{
put("/apps/test-static/Pojo.java", "apps.test_static.Pojo");