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();
}
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);
}
}
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);
}
}
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);
}
Aggregations