Search in sources :

Example 1 with RenderUnit

use of org.apache.sling.scripting.sightly.java.compiler.RenderUnit 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();
}
Also used : SightlyCompiledScript(org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript) CompiledScript(javax.script.CompiledScript) RenderUnit(org.apache.sling.scripting.sightly.java.compiler.RenderUnit) InputStreamReader(java.io.InputStreamReader) SlingScriptHelper(org.apache.sling.api.scripting.SlingScriptHelper) InputStream(java.io.InputStream) CachedScript(org.apache.sling.scripting.api.CachedScript) Resource(org.apache.sling.api.resource.Resource) SightlyScriptEngine(org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngine) Bindings(javax.script.Bindings) SlingHttpServletRequest(org.apache.sling.api.SlingHttpServletRequest) SightlyException(org.apache.sling.scripting.sightly.SightlyException) ScriptNameAwareReader(org.apache.sling.scripting.core.ScriptNameAwareReader) SightlyException(org.apache.sling.scripting.sightly.SightlyException) SightlyCompiledScript(org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript)

Example 2 with RenderUnit

use of org.apache.sling.scripting.sightly.java.compiler.RenderUnit in project sling by apache.

the class SightlyCompiledScriptTest method testEvalSlingBindings.

/**
     * Tests that SlingBindings are correctly handled by compiled scripts, by setting them from the script context to the request
     * attributes.
     * @throws ScriptException
     */
@Test
public void testEvalSlingBindings() throws ScriptException {
    ScriptEngine scriptEngine = mock(ScriptEngine.class);
    final RenderUnit renderUnit = mock(RenderUnit.class);
    Whitebox.setInternalState(renderUnit, "subTemplates", new HashMap<String, Object>());
    final BundleContext bundleContext = MockOsgi.newBundleContext();
    bundleContext.registerService(ExtensionRegistryService.class.getName(), mock(ExtensionRegistryService.class), new Hashtable<String, Object>());
    ResourceResolver resourceResolver = MockSling.newResourceResolver(bundleContext);
    final MockSlingHttpServletRequest request = spy(new MockSlingHttpServletRequest(resourceResolver, bundleContext));
    SightlyCompiledScript compiledScript = spy(new SightlyCompiledScript(scriptEngine, renderUnit));
    ScriptContext scriptContext = mock(ScriptContext.class);
    StringWriter writer = new StringWriter();
    when(scriptContext.getWriter()).thenReturn(writer);
    Bindings scriptContextBindings = new SimpleBindings() {

        {
            put("test", "testValue");
            put(SlingBindings.REQUEST, request);
            put(SlingBindings.SLING, MockSling.newSlingScriptHelper(bundleContext));
        }
    };
    SlingBindings oldBindings = new SlingBindings();
    oldBindings.put("old", "oldValue");
    request.setAttribute(SlingBindings.class.getName(), oldBindings);
    when(scriptContext.getBindings(ScriptContext.ENGINE_SCOPE)).thenReturn(scriptContextBindings);
    compiledScript.eval(scriptContext);
    ArgumentCaptor<SlingBindings> slingBindingsArgumentCaptor = ArgumentCaptor.forClass(SlingBindings.class);
    ArgumentCaptor<String> attributeNameArgumentCaptor = ArgumentCaptor.forClass(String.class);
    // request.setAttribute should have been invoked 3 times: once here, twice in the compiled script
    verify(request, times(3)).setAttribute(attributeNameArgumentCaptor.capture(), slingBindingsArgumentCaptor.capture());
    List<SlingBindings> slingBindingsValues = slingBindingsArgumentCaptor.getAllValues();
    int invocation = 1;
    for (SlingBindings bindings : slingBindingsValues) {
        switch(invocation) {
            case 1:
                assertEquals(oldBindings, bindings);
                break;
            case 2:
                assertEquals(3, bindings.size());
                for (Map.Entry<String, Object> entry : scriptContextBindings.entrySet()) {
                    assertEquals(entry.getValue(), bindings.get(entry.getKey()));
                }
                break;
            case 3:
                assertEquals(oldBindings, bindings);
        }
        invocation++;
    }
    for (String key : attributeNameArgumentCaptor.getAllValues()) {
        assertEquals(SlingBindings.class.getName(), key);
    }
}
Also used : SlingBindings(org.apache.sling.api.scripting.SlingBindings) RenderUnit(org.apache.sling.scripting.sightly.java.compiler.RenderUnit) ScriptContext(javax.script.ScriptContext) Bindings(javax.script.Bindings) SlingBindings(org.apache.sling.api.scripting.SlingBindings) SimpleBindings(javax.script.SimpleBindings) ScriptEngine(javax.script.ScriptEngine) StringWriter(java.io.StringWriter) MockSlingHttpServletRequest(org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest) SimpleBindings(javax.script.SimpleBindings) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) HashMap(java.util.HashMap) Map(java.util.Map) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Example 3 with RenderUnit

use of org.apache.sling.scripting.sightly.java.compiler.RenderUnit in project sling by apache.

the class SightlyScriptEngine method internalCompile.

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();
        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 {} {}:{}: {}", new Object[] { 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);
    }
}
Also used : CompilationUnit(org.apache.sling.scripting.sightly.compiler.CompilationUnit) ScriptNameAware(org.apache.sling.scripting.api.ScriptNameAware) CompilerMessage(org.apache.sling.scripting.sightly.compiler.CompilerMessage) JavaClassBackendCompiler(org.apache.sling.scripting.sightly.java.compiler.JavaClassBackendCompiler) RenderUnit(org.apache.sling.scripting.sightly.java.compiler.RenderUnit) GlobalShadowCheckBackendCompiler(org.apache.sling.scripting.sightly.java.compiler.GlobalShadowCheckBackendCompiler) SourceIdentifier(org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier) Bindings(javax.script.Bindings) SlingBindings(org.apache.sling.api.scripting.SlingBindings) ScriptException(javax.script.ScriptException) SightlyException(org.apache.sling.scripting.sightly.SightlyException) CompilationResult(org.apache.sling.scripting.sightly.compiler.CompilationResult)

Example 4 with RenderUnit

use of org.apache.sling.scripting.sightly.java.compiler.RenderUnit in project sling by apache.

the class JavaClassBackendCompilerTest method render.

private void render(StringWriter writer, ClassInfo classInfo, String source, RenderContext renderContext, Bindings arguments) throws Exception {
    ClassLoader classLoader = JavaClassBackendCompilerTest.class.getClassLoader();
    CharSequenceJavaCompiler<RenderUnit> compiler = new CharSequenceJavaCompiler<>(classLoader, null);
    Class<RenderUnit> newClass = compiler.compile(classInfo.getFullyQualifiedClassName(), source);
    RenderUnit renderUnit = newClass.newInstance();
    PrintWriter printWriter = new PrintWriter(writer);
    renderUnit.render(printWriter, renderContext, arguments);
}
Also used : RenderUnit(org.apache.sling.scripting.sightly.java.compiler.RenderUnit) CharSequenceJavaCompiler(org.apache.sling.scripting.sightly.compiler.java.utils.CharSequenceJavaCompiler) PrintWriter(java.io.PrintWriter)

Aggregations

RenderUnit (org.apache.sling.scripting.sightly.java.compiler.RenderUnit)4 Bindings (javax.script.Bindings)3 SlingBindings (org.apache.sling.api.scripting.SlingBindings)2 SightlyException (org.apache.sling.scripting.sightly.SightlyException)2 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 CompiledScript (javax.script.CompiledScript)1 ScriptContext (javax.script.ScriptContext)1 ScriptEngine (javax.script.ScriptEngine)1 ScriptException (javax.script.ScriptException)1 SimpleBindings (javax.script.SimpleBindings)1 SlingHttpServletRequest (org.apache.sling.api.SlingHttpServletRequest)1 Resource (org.apache.sling.api.resource.Resource)1 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)1 SlingScriptHelper (org.apache.sling.api.scripting.SlingScriptHelper)1 CachedScript (org.apache.sling.scripting.api.CachedScript)1