use of org.apache.sling.scripting.api.CachedScript in project sling by apache.
the class ScriptCacheImpl method activate.
@Activate
protected void activate(ScriptCacheImplConfiguration configuration, BundleContext bundleCtx) {
threadPool = threadPoolManager.get("Script Cache Thread Pool");
bundleContext = bundleCtx;
additionalExtensions = configuration.org_apache_sling_scripting_cache_additional__extensions();
int newMaxCacheSize = configuration.org_apache_sling_scripting_cache_size();
if (newMaxCacheSize != DEFAULT_CACHE_SIZE) {
// change the map only if there's a configuration change regarding the cache's max size
CachingMap<CachedScript> newMap = new CachingMap<>(newMaxCacheSize);
newMap.putAll(internalMap);
internalMap = newMap;
}
ResourceResolver resolver = null;
try {
resolver = rrf.getServiceResourceResolver(null);
searchPaths = resolver.getSearchPath();
} catch (LoginException e) {
LOGGER.error("Unable to retrieve a ResourceResolver for determining the search paths.", e);
} finally {
if (resolver != null) {
resolver.close();
}
}
configureCache();
active = true;
}
use of org.apache.sling.scripting.api.CachedScript in project sling by apache.
the class RenderUnitProvider method provide.
@Override
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
Bindings globalBindings = renderContext.getBindings();
SlingScriptHelper sling = BindingsUtils.getHelper(globalBindings);
SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
final Resource renderUnitResource = ScriptUtils.resolveScript(scriptingResourceResolverProvider.getRequestScopedResourceResolver(), renderContext, identifier);
if (renderUnitResource == null) {
Resource caller = ResourceResolution.getResourceForRequest(request.getResourceResolver(), request);
if (caller != null) {
String resourceSuperType = caller.getResourceSuperType();
StringBuilder errorMessage = new StringBuilder("Cannot find resource ");
errorMessage.append(identifier).append(" for base path ").append(caller.getPath());
if (StringUtils.isNotEmpty(resourceSuperType)) {
errorMessage.append(" with resource super type ").append(resourceSuperType);
}
errorMessage.append(".");
return ProviderOutcome.failure(new SightlyException(errorMessage.toString()));
} else {
return ProviderOutcome.failure(new SightlyException("Cannot resolve template " + identifier + " for script " + sling.getScript().getScriptResource().getPath()));
}
}
RenderUnit renderUnit;
try {
CachedScript cachedScript = scriptCache.getScript(renderUnitResource.getPath());
final SightlyCompiledScript compiledScript;
if (cachedScript != null) {
compiledScript = (SightlyCompiledScript) cachedScript.getCompiledScript();
} else {
SightlyScriptEngine sightlyScriptEngine = (SightlyScriptEngine) scriptEngineManager.getEngineByName(SightlyScriptEngineFactory.SHORT_NAME);
String encoding = renderUnitResource.getResourceMetadata().getCharacterEncoding();
if (StringUtils.isEmpty(encoding)) {
encoding = "UTF-8";
}
InputStream inputStream = renderUnitResource.adaptTo(InputStream.class);
if (inputStream == null) {
return ProviderOutcome.failure();
}
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, encoding);
ScriptNameAwareReader reader = new ScriptNameAwareReader(inputStreamReader, renderUnitResource.getPath());
compiledScript = (SightlyCompiledScript) sightlyScriptEngine.compile(reader);
scriptCache.putScript(new CachedScript() {
@Override
public String getScriptPath() {
return renderUnitResource.getPath();
}
@Override
public CompiledScript getCompiledScript() {
return compiledScript;
}
});
}
renderUnit = compiledScript.getRenderUnit();
return ProviderOutcome.success(renderUnit);
} catch (Exception e) {
return ProviderOutcome.failure(e);
}
}
return ProviderOutcome.failure();
}
use of org.apache.sling.scripting.api.CachedScript in project sling by apache.
the class DefaultSlingScript method call.
/**
* @see org.apache.sling.api.scripting.SlingScript#call(org.apache.sling.api.scripting.SlingBindings, java.lang.String, java.lang.Object[])
* @throws ScriptEvaluationException
*/
public Object call(SlingBindings props, String method, Object... args) {
Bindings bindings = null;
Reader reader = null;
boolean disposeScriptHelper = !props.containsKey(SLING);
ResourceResolver oldResolver = null;
try {
bindings = verifySlingBindings(props);
// use final variable for inner class!
final Bindings b = bindings;
// create script context
final ScriptContext ctx = new ScriptContext() {
private Bindings globalScope;
private Bindings engineScope = b;
private Writer writer = (Writer) b.get(OUT);
private Writer errorWriter = new LogWriter((Logger) b.get(LOG));
private Reader reader = (Reader) b.get(READER);
private Bindings slingScope = new SimpleBindings();
/**
* @see javax.script.ScriptContext#setBindings(javax.script.Bindings, int)
*/
public void setBindings(final Bindings bindings, final int scope) {
switch(scope) {
case SlingScriptConstants.SLING_SCOPE:
this.slingScope = bindings;
break;
case 100:
if (bindings == null)
throw new NullPointerException("Bindings for ENGINE scope is null");
this.engineScope = bindings;
break;
case 200:
this.globalScope = bindings;
break;
default:
throw new IllegalArgumentException("Invalid scope");
}
}
/**
* @see javax.script.ScriptContext#getBindings(int)
*/
public Bindings getBindings(final int scope) {
switch(scope) {
case SlingScriptConstants.SLING_SCOPE:
return slingScope;
case 100:
return this.engineScope;
case 200:
return this.globalScope;
}
throw new IllegalArgumentException("Invalid scope");
}
/**
* @see javax.script.ScriptContext#setAttribute(java.lang.String, java.lang.Object, int)
*/
public void setAttribute(final String name, final Object value, final int scope) {
if (name == null)
throw new IllegalArgumentException("Name is null");
final Bindings bindings = getBindings(scope);
if (bindings != null) {
bindings.put(name, value);
}
}
/**
* @see javax.script.ScriptContext#getAttribute(java.lang.String, int)
*/
public Object getAttribute(final String name, final int scope) {
if (name == null)
throw new IllegalArgumentException("Name is null");
final Bindings bindings = getBindings(scope);
if (bindings != null) {
return bindings.get(name);
}
return null;
}
/**
* @see javax.script.ScriptContext#removeAttribute(java.lang.String, int)
*/
public Object removeAttribute(final String name, final int scope) {
if (name == null)
throw new IllegalArgumentException("Name is null");
final Bindings bindings = getBindings(scope);
if (bindings != null) {
return bindings.remove(name);
}
return null;
}
/**
* @see javax.script.ScriptContext#getAttribute(java.lang.String)
*/
public Object getAttribute(String name) {
if (name == null)
throw new IllegalArgumentException("Name is null");
for (final int scope : SCOPES) {
final Bindings bindings = getBindings(scope);
if (bindings != null) {
final Object o = bindings.get(name);
if (o != null) {
return o;
}
}
}
return null;
}
/**
* @see javax.script.ScriptContext#getAttributesScope(java.lang.String)
*/
public int getAttributesScope(String name) {
if (name == null)
throw new IllegalArgumentException("Name is null");
for (final int scope : SCOPES) {
if ((getBindings(scope) != null) && (getBindings(scope).containsKey(name))) {
return scope;
}
}
return -1;
}
/**
* @see javax.script.ScriptContext#getScopes()
*/
public List<Integer> getScopes() {
return Arrays.asList(SCOPES);
}
/**
* @see javax.script.ScriptContext#getWriter()
*/
public Writer getWriter() {
return this.writer;
}
/**
* @see javax.script.ScriptContext#getErrorWriter()
*/
public Writer getErrorWriter() {
return this.errorWriter;
}
/**
* @see javax.script.ScriptContext#setWriter(java.io.Writer)
*/
public void setWriter(Writer writer) {
this.writer = writer;
}
/**
* @see javax.script.ScriptContext#setErrorWriter(java.io.Writer)
*/
public void setErrorWriter(Writer writer) {
this.errorWriter = writer;
}
/**
* @see javax.script.ScriptContext#getReader()
*/
public Reader getReader() {
return this.reader;
}
/**
* @see javax.script.ScriptContext#setReader(java.io.Reader)
*/
public void setReader(Reader reader) {
this.reader = reader;
}
};
// set the current resource resolver if a request is available from the bindings
if (props.getRequest() != null) {
oldResolver = requestResourceResolver.get();
requestResourceResolver.set(props.getRequest().getResourceResolver());
}
// set the script resource resolver as an attribute
ctx.setAttribute(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, this.scriptResource.getResourceResolver(), SlingScriptConstants.SLING_SCOPE);
reader = getScriptReader();
if (method != null && !(this.scriptEngine instanceof Invocable)) {
reader = getWrapperReader(reader, method, args);
}
// evaluate the script
final Object result;
if (method == null && this.scriptEngine instanceof Compilable) {
CachedScript cachedScript = scriptCache.getScript(scriptName);
if (cachedScript == null) {
ScriptNameAwareReader snReader = new ScriptNameAwareReader(reader, scriptName);
CompiledScript compiledScript = ((Compilable) scriptEngine).compile(snReader);
cachedScript = new CachedScriptImpl(scriptName, compiledScript);
scriptCache.putScript(cachedScript);
LOGGER.debug("Adding {} to the script cache.", scriptName);
} else {
LOGGER.debug("Script {} was already cached.", scriptName);
}
result = cachedScript.getCompiledScript().eval(ctx);
} else {
result = scriptEngine.eval(reader, ctx);
}
// call method - if supplied and script engine supports direct invocation
if (method != null && (this.scriptEngine instanceof Invocable)) {
try {
((Invocable) scriptEngine).invokeFunction(method, Arrays.asList(args).toArray());
} catch (NoSuchMethodException e) {
throw new ScriptEvaluationException(this.scriptName, "Method " + method + " not found in script.", e);
}
}
// optionall flush the output channel
Object flushObject = bindings.get(FLUSH);
if (flushObject instanceof Boolean && (Boolean) flushObject) {
ctx.getWriter().flush();
}
// allways flush the error channel
ctx.getErrorWriter().flush();
return result;
} catch (IOException ioe) {
throw new ScriptEvaluationException(this.scriptName, ioe.getMessage(), ioe);
} catch (ScriptException se) {
Throwable cause = (se.getCause() == null) ? se : se.getCause();
throw new ScriptEvaluationException(this.scriptName, se.getMessage(), cause);
} finally {
if (props.getRequest() != null) {
requestResourceResolver.set(oldResolver);
}
// close the script reader (SLING-380)
if (reader != null) {
try {
reader.close();
} catch (IOException ignore) {
// don't care
}
}
// dispose of the SlingScriptHelper
if (bindings != null && disposeScriptHelper) {
final InternalScriptHelper helper = (InternalScriptHelper) bindings.get(SLING);
if (helper != null) {
helper.cleanup();
}
}
}
}
use of org.apache.sling.scripting.api.CachedScript in project sling by apache.
the class RhinoJavaScriptEngine method compile.
public CompiledScript compile(Reader scriptReader) throws ScriptException {
final String scriptName = getScriptName(scriptReader);
CachedScript cachedScript = scriptCache.getScript(scriptName);
if (cachedScript != null) {
LOGGER.debug("Detected cached script for {}.", scriptName);
return cachedScript.getCompiledScript();
} else {
scriptReader = wrapReaderIfEspScript(scriptReader, scriptName);
try {
final Context rhinoContext = Context.enter();
rhinoContext.setOptimizationLevel(optimizationLevel());
if (!ScriptRuntime.hasTopCall(rhinoContext)) {
// setup the context for use
WrapFactory wrapFactory = ((RhinoJavaScriptEngineFactory) getFactory()).getWrapFactory();
rhinoContext.setWrapFactory(wrapFactory);
}
final int lineNumber = 1;
final Object securityDomain = null;
final Script script = rhinoContext.compileReader(scriptReader, scriptName, lineNumber, securityDomain);
final SlingCompiledScript slingCompiledScript = new SlingCompiledScript(script, this);
cachedScript = new CachedScript() {
@Override
public String getScriptPath() {
return scriptName;
}
@Override
public CompiledScript getCompiledScript() {
return slingCompiledScript;
}
};
// SLING-4935 avoid caching scripts for which we cannot determine a name
if (!scriptName.equals(NO_SCRIPT_NAME)) {
scriptCache.putScript(cachedScript);
}
LOGGER.debug("Added {} script to Script Cache.", scriptName);
return slingCompiledScript;
} catch (IOException e) {
final ScriptException se = new ScriptException("Failure running script " + scriptName + ": " + e.getMessage());
se.initCause(e);
throw se;
} finally {
Context.exit();
}
}
}
Aggregations