Search in sources :

Example 1 with CachedScriptImpl

use of org.apache.sling.scripting.core.impl.helper.CachedScriptImpl 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();
            }
        }
    }
}
Also used : CompiledScript(javax.script.CompiledScript) ScriptEvaluationException(org.apache.sling.api.scripting.ScriptEvaluationException) CachedScript(org.apache.sling.scripting.api.CachedScript) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) ScriptNameAwareReader(org.apache.sling.scripting.core.ScriptNameAwareReader) StringReader(java.io.StringReader) BufferedReader(java.io.BufferedReader) ScriptContext(javax.script.ScriptContext) Logger(org.slf4j.Logger) SlingBindings(org.apache.sling.api.scripting.SlingBindings) SimpleBindings(javax.script.SimpleBindings) Bindings(javax.script.Bindings) ProtectedBindings(org.apache.sling.scripting.core.impl.helper.ProtectedBindings) Invocable(javax.script.Invocable) ScriptException(javax.script.ScriptException) Compilable(javax.script.Compilable) IOException(java.io.IOException) ScriptNameAwareReader(org.apache.sling.scripting.core.ScriptNameAwareReader) SimpleBindings(javax.script.SimpleBindings) CachedScriptImpl(org.apache.sling.scripting.core.impl.helper.CachedScriptImpl) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer)

Aggregations

BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 PrintWriter (java.io.PrintWriter)1 Reader (java.io.Reader)1 StringReader (java.io.StringReader)1 Writer (java.io.Writer)1 Bindings (javax.script.Bindings)1 Compilable (javax.script.Compilable)1 CompiledScript (javax.script.CompiledScript)1 Invocable (javax.script.Invocable)1 ScriptContext (javax.script.ScriptContext)1 ScriptException (javax.script.ScriptException)1 SimpleBindings (javax.script.SimpleBindings)1 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)1 ScriptEvaluationException (org.apache.sling.api.scripting.ScriptEvaluationException)1 SlingBindings (org.apache.sling.api.scripting.SlingBindings)1 CachedScript (org.apache.sling.scripting.api.CachedScript)1 ScriptNameAwareReader (org.apache.sling.scripting.core.ScriptNameAwareReader)1 CachedScriptImpl (org.apache.sling.scripting.core.impl.helper.CachedScriptImpl)1