You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2016/06/16 16:08:00 UTC
svn commit: r1748750 [8/12] - in /sling/trunk/bundles/scripting/sightly: ./
compiler/ compiler/src/ compiler/src/main/ compiler/src/main/antlr4/
compiler/src/main/antlr4/org/ compiler/src/main/antlr4/org/apache/
compiler/src/main/antlr4/org/apache/slin...
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngineFactory.java Thu Jun 16 16:07:57 2016
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
-
package org.apache.sling.scripting.sightly.impl.engine;
import java.io.IOException;
@@ -36,6 +35,7 @@ import org.apache.felix.scr.annotations.
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.sightly.compiler.SightlyCompiler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,19 +53,19 @@ public class SightlyScriptEngineFactory
private static final Logger LOGGER = LoggerFactory.getLogger(SightlyScriptEngineFactory.class);
@Reference
- private UnitLoader unitLoader;
+ private DynamicClassLoaderManager dynamicClassLoaderManager;
@Reference
- private ExtensionRegistryService extensionRegistryService;
+ private SightlyEngineConfiguration sightlyEngineConfiguration;
@Reference
- private DynamicClassLoaderManager dynamicClassLoaderManager;
+ private ClassLoaderWriter classLoaderWriter;
@Reference
- private SightlyEngineConfiguration sightlyEngineConfiguration;
+ private SightlyCompiler sightlyCompiler;
@Reference
- private ClassLoaderWriter classLoaderWriter;
+ private SightlyJavaCompilerService sightlyJavaCompilerService;
public final static String SHORT_NAME = "sightly";
@@ -94,7 +94,7 @@ public class SightlyScriptEngineFactory
@Override
public ScriptEngine getScriptEngine() {
- return new SightlyScriptEngine(this, unitLoader, extensionRegistryService);
+ return new SightlyScriptEngine(this, sightlyCompiler, sightlyJavaCompilerService, sightlyEngineConfiguration);
}
protected ClassLoader getClassLoader() {
@@ -102,7 +102,6 @@ public class SightlyScriptEngineFactory
}
@Activate
- @SuppressWarnings("unused")
protected void activate() {
InputStream is;
boolean newVersion = true;
Added: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java?rev=1748750&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java (added)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java Thu Jun 16 16:07:57 2016
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * 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.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+@Service(UnitChangeMonitor.class)
+public class UnitChangeMonitor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UnitChangeMonitor.class);
+
+ private Map<String, Long> slyJavaUseMap = new ConcurrentHashMap<String, Long>();
+ private ServiceRegistration eventHandlerServiceRegistration;
+
+ @Reference
+ private ResourceResolverFactory rrf = null;
+
+ @Reference
+ private SightlyEngineConfiguration sightlyEngineConfiguration = null;
+
+ /**
+ * Returns the last modified date for a Java Use-API object stored in the repository.
+ *
+ * @param className the fully qualified class name
+ * @return the Java Use-API file's last modified date or 0 if there's no information about this file
+ */
+ public long getLastModifiedDateForJavaUseObject(String className) {
+ if (className == null) {
+ return 0;
+ }
+ Long date = slyJavaUseMap.get(className);
+ return date != null ? date : 0;
+ }
+
+ public void clearJavaUseObject(String className) {
+ if (StringUtils.isNotEmpty(className)) {
+ slyJavaUseMap.remove(className);
+ }
+ }
+
+ @Activate
+ protected void activate(ComponentContext componentContext) {
+ ResourceResolver adminResolver = null;
+ try {
+ adminResolver = rrf.getAdministrativeResourceResolver(null);
+ StringBuilder eventHandlerFilteredPaths = new StringBuilder("(|");
+ String[] searchPaths = adminResolver.getSearchPath();
+ for (String sp : searchPaths) {
+ // Sightly Java Use-API objects
+ eventHandlerFilteredPaths.append("(path=").append(sp).append("**/*.java").append(")");
+ }
+ eventHandlerFilteredPaths.append(")");
+ Dictionary eventHandlerProperties = new Hashtable();
+ eventHandlerProperties.put(EventConstants.EVENT_FILTER, eventHandlerFilteredPaths.toString());
+ eventHandlerProperties.put(EventConstants.EVENT_TOPIC, new String[]{SlingConstants.TOPIC_RESOURCE_ADDED, SlingConstants
+ .TOPIC_RESOURCE_CHANGED, SlingConstants.TOPIC_RESOURCE_REMOVED});
+ eventHandlerServiceRegistration = componentContext.getBundleContext().registerService(
+ EventHandler.class.getName(),
+ new EventHandler() {
+ @Override
+ public void handleEvent(Event event) {
+ processEvent(event);
+ }
+ },
+ eventHandlerProperties
+ );
+ } catch (LoginException e) {
+ LOG.error("Unable to listen for change events.", e);
+ } finally {
+ if (adminResolver != null) {
+ adminResolver.close();
+ }
+ }
+
+ }
+
+ @Deactivate
+ protected void deactivate(ComponentContext componentContext) {
+ if (eventHandlerServiceRegistration != null) {
+ eventHandlerServiceRegistration.unregister();
+ }
+ }
+
+ private void processEvent(Event event) {
+ String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
+ String topic = event.getTopic();
+ LOG.debug("Received event {} for path {}.", topic, path);
+ if (path.endsWith(".java")) {
+ SourceIdentifier sourceIdentifier = new SourceIdentifier(sightlyEngineConfiguration, path);
+ if (SlingConstants.TOPIC_RESOURCE_ADDED.equals(topic) || SlingConstants.TOPIC_RESOURCE_CHANGED.equals(topic)) {
+ LOG.debug("Java Use Object {} was {}.", path, topic);
+ slyJavaUseMap.put(sourceIdentifier.getFullyQualifiedClassName(), System.currentTimeMillis());
+ } else if (SlingConstants.TOPIC_RESOURCE_REMOVED.equals(topic)) {
+ LOG.debug("Removed Java Use Object {} from UnitChangeMonitor cache.", path);
+ slyJavaUseMap.remove(sourceIdentifier.getFullyQualifiedClassName());
+ }
+ }
+ }
+}
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/compiled/SourceIdentifier.java Thu Jun 16 16:07:57 2016
@@ -16,118 +16,242 @@
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
-
package org.apache.sling.scripting.sightly.impl.engine.compiled;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.scripting.sightly.impl.compiler.UnitChangeMonitor;
import org.apache.sling.scripting.sightly.impl.engine.SightlyEngineConfiguration;
-import org.apache.sling.scripting.sightly.impl.utils.JavaEscapeUtils;
+import org.apache.sling.scripting.sightly.java.compiler.ClassInfo;
/**
* Identifies a Java source file based on a {@link Resource}. Depending on the used constructor this class might provide the abstraction
* for either a Java source file generated for a Sightly HTML script or for a Sightly {@link Resource}-based Java Use-API Object.
*/
-public class SourceIdentifier {
-
- private final String className;
- private final Resource resource;
- private final String packageName;
- private final String fullyQualifiedName;
- private SightlyEngineConfiguration configuration;
- private UnitChangeMonitor unitChangeMonitor;
- private ClassLoaderWriter writer;
- private boolean scriptSource = false;
-
- public SourceIdentifier(SightlyEngineConfiguration configuration, UnitChangeMonitor unitChangeMonitor, ClassLoaderWriter writer,
- Resource resource) {
- this(configuration, unitChangeMonitor, writer, resource, null);
- }
-
- public SourceIdentifier(SightlyEngineConfiguration configuration, UnitChangeMonitor unitChangeMonitor, ClassLoaderWriter writer,
- Resource resource, String classNamePrefix) {
- this.resource = resource;
- this.configuration = configuration;
- this.unitChangeMonitor = unitChangeMonitor;
- this.writer = writer;
- if (StringUtils.isNotEmpty(classNamePrefix)) {
- scriptSource = true;
- }
- this.className = buildClassName(resource, classNamePrefix);
- this.packageName = buildPackageName(resource);
- this.fullyQualifiedName = buildFullyQualifiedName(packageName, className);
- }
+public class SourceIdentifier implements ClassInfo {
- public String getClassName() {
- return className;
+ private static final Set<String> javaKeywords = new HashSet<String>() {{
+ add("abstract");
+ add("assert");
+ add("boolean");
+ add("break");
+ add("byte");
+ add("case");
+ add("catch");
+ add("char");
+ add("class");
+ add("const");
+ add("continue");
+ add("default");
+ add("do");
+ add("double");
+ add("else");
+ add("enum");
+ add("extends");
+ add("final");
+ add("finally");
+ add("float");
+ add("for");
+ add("goto");
+ add("if");
+ add("implements");
+ add("import");
+ add("instanceof");
+ add("int");
+ add("interface");
+ add("long");
+ add("native");
+ add("new");
+ add("package");
+ add("private");
+ add("protected");
+ add("public");
+ add("return");
+ add("short");
+ add("static");
+ add("strictfp");
+ add("super");
+ add("switch");
+ add("synchronized");
+ add("this");
+ add("throws");
+ add("transient");
+ add("try");
+ add("void");
+ add("volatile");
+ add("while");
+ }};
+
+ public static final Pattern MANGLED_CHAR_PATTER = 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 scriptName) {
+ this.engineConfiguration = engineConfiguration;
+ this.scriptName = scriptName;
}
- public Resource getResource() {
- return resource;
+ @Override
+ public String getSimpleClassName() {
+ if (simpleClassName == null) {
+ int lastSlashIndex = scriptName.lastIndexOf("/");
+ String processingScriptName = scriptName;
+ if (scriptName.endsWith(".java")) {
+ processingScriptName = scriptName.substring(0, scriptName.length() - 5);
+ }
+ if (lastSlashIndex != -1) {
+ simpleClassName = makeJavaPackage(processingScriptName.substring(lastSlashIndex));
+ } else {
+ simpleClassName = makeJavaPackage(processingScriptName);
+ }
+ }
+ return simpleClassName;
}
+ @Override
public String getPackageName() {
+ if (packageName == null) {
+ int lastSlashIndex = scriptName.lastIndexOf("/");
+ String processingScriptName = scriptName;
+ boolean javaFile = scriptName.endsWith(".java");
+ if (javaFile) {
+ processingScriptName = scriptName.substring(0, scriptName.length() - 5);
+ }
+ if (lastSlashIndex != -1) {
+ packageName = makeJavaPackage(processingScriptName.substring(0, lastSlashIndex));
+ } else {
+ packageName = makeJavaPackage(processingScriptName);
+ }
+ if (!javaFile) {
+ packageName = engineConfiguration.getBundleSymbolicName() + "." + packageName;
+ }
+ }
return packageName;
}
- public String getFullyQualifiedName() {
- return fullyQualifiedName;
- }
-
- public boolean needsUpdate() {
- if (configuration.isDevMode()) {
- return true;
+ @Override
+ public String getFullyQualifiedClassName() {
+ if (fullyQualifiedClassName == null) {
+ fullyQualifiedClassName = getPackageName() + "." + getSimpleClassName();
}
- String slyPath = getResource().getPath();
- long slyScriptChangeDate = unitChangeMonitor.getLastModifiedDateForScript(slyPath);
- String javaCompilerPath = "/" + getFullyQualifiedName().replaceAll("\\.", "/") + ".class";
- long javaFileDate = writer.getLastModified(javaCompilerPath);
- return ((slyScriptChangeDate == 0 && javaFileDate > -1) || (slyScriptChangeDate > javaFileDate));
- }
-
- private String buildFullyQualifiedName(String packageName, String className) {
- return packageName + "." + className;
+ return fullyQualifiedClassName;
}
- private String buildClassName(Resource resource, String classNamePrefix) {
- String scriptName = ResourceUtil.getName(resource.getPath());
- scriptName = scriptName.substring(0, scriptName.lastIndexOf(getExtension(scriptName)));
- String className;
- if (StringUtils.isNotEmpty(classNamePrefix)) {
- className = classNamePrefix + scriptName;
- } else {
- className = scriptName;
+ /**
+ * Converts the given identifier to a legal Java identifier
+ *
+ * @param identifier the identifier to convert
+ * @return legal Java identifier corresponding to the given identifier
+ */
+ public static String makeJavaIdentifier(String identifier) {
+ StringBuilder modifiedIdentifier = new StringBuilder(identifier.length());
+ if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
+ modifiedIdentifier.append('_');
+ }
+ for (int i = 0; i < identifier.length(); i++) {
+ char ch = identifier.charAt(i);
+ if (Character.isJavaIdentifierPart(ch) && ch != '_') {
+ modifiedIdentifier.append(ch);
+ } else if (ch == '.') {
+ modifiedIdentifier.append('_');
+ } else {
+ modifiedIdentifier.append(mangleChar(ch));
+ }
+ }
+ if (isJavaKeyword(modifiedIdentifier.toString())) {
+ modifiedIdentifier.append('_');
}
- return className.replaceAll("-", "_").replaceAll("\\.", "_");
+ return modifiedIdentifier.toString();
}
- private String buildPackageName(Resource resource) {
- String packageName = ResourceUtil.getParent(resource.getPath()).replaceAll("/", ".").substring(1).replaceAll("-", "_");
- String[] packageNameElements = packageName.split("\\.");
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < packageNameElements.length; i++) {
- String subPackage = packageNameElements[i];
- sb.append(JavaEscapeUtils.getEscapedToken(subPackage));
- if (i != packageNameElements.length - 1) {
- sb.append(".");
+ /**
+ * Converts the given scriptName to a Java package or fully-qualified class name
+ *
+ * @param scriptName the scriptName to convert
+ * @return Java package corresponding to the given scriptName
+ */
+ public static String makeJavaPackage(String scriptName) {
+ String classNameComponents[] = StringUtils.split(scriptName, '/');
+ StringBuilder legalClassNames = new StringBuilder();
+ for (int i = 0; i < classNameComponents.length; i++) {
+ legalClassNames.append(makeJavaIdentifier(classNameComponents[i]));
+ if (i < classNameComponents.length - 1) {
+ legalClassNames.append('.');
}
}
- if (!scriptSource) {
- return sb.toString();
- }
- return configuration.getBundleSymbolicName() + "." + sb.toString();
+ return legalClassNames.toString();
}
- private String getExtension(String scriptName) {
- int lastDotIndex = scriptName.lastIndexOf('.');
- return scriptName.substring(lastDotIndex);
+ public static String getScriptName(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_PATTER.matcher(classElem);
+ if (matcher.matches()) {
+ String group = matcher.group(2);
+ char unmangled = unmangle(group);
+ classElem = classElem.replaceAll(group, Character.toString(unmangled));
+ while (matcher.find()) {
+ group = matcher.group(2);
+ unmangled = 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 {
+ classElem = classElem.replaceAll("_", ".");
+ }
+ }
+ }
+ pathElements.append(classElem);
+ if (i < classElements.length - 1) {
+ pathElements.append("/");
+ }
+ }
+ return pathElements.toString();
}
- @Override
- public String toString() {
- return "SourceIdentifier { resourcePath=" + resource.getPath() + ", fqcn=" + fullyQualifiedName + " }";
+ /**
+ * Mangle the specified character to create a legal Java class name.
+ *
+ * @param ch the character to mangle
+ * @return the mangled
+ */
+ public static String mangleChar(char ch) {
+ return String.format("__%04x__", (int) ch);
+ }
+
+ /**
+ * Provided a mangled string (obtained by calling {@link #mangleChar(char)}) it will will return the character that was mangled.
+ *
+ * @param mangled the mangled string
+ * @return the original character
+ */
+ public static char unmangle(String mangled) {
+ String toProcess = mangled.replaceAll("__", "");
+ return (char) Integer.parseInt(toProcess, 16);
+ }
+
+ /**
+ * Test whether the argument is a Java keyword
+ */
+ public static boolean isJavaKeyword(String key) {
+ return javaKeywords.contains(key);
}
}
Added: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java?rev=1748750&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java (added)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/FormatFilterExtension.java Thu Jun 16 16:07:57 2016
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.extension;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+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;
+
+@Component
+@Service(RuntimeExtension.class)
+@Properties({
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.FORMAT)
+})
+public class FormatFilterExtension implements RuntimeExtension {
+
+ private static final Pattern PLACEHOLDER_REGEX = Pattern.compile("\\{\\d+}");
+
+ @Override
+ public Object call(final RenderContext renderContext, Object... arguments) {
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.FORMAT, arguments, 2);
+ RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
+ String source = runtimeObjectModel.toString(arguments[0]);
+ Object[] params = decodeParams(runtimeObjectModel, arguments[1]);
+ return replace(runtimeObjectModel, source, params);
+ }
+
+ private Object[] decodeParams(RuntimeObjectModel runtimeObjectModel, Object paramObj) {
+ if (runtimeObjectModel.isCollection(paramObj)) {
+ return runtimeObjectModel.toCollection(paramObj).toArray();
+ }
+ return new Object[] {paramObj};
+ }
+
+ private String replace(RuntimeObjectModel runtimeObjectModel, String source, Object[] params) {
+ Matcher matcher = PLACEHOLDER_REGEX.matcher(source);
+ StringBuilder builder = new StringBuilder();
+ int lastPos = 0;
+ boolean matched = true;
+ while (matched) {
+ matched = matcher.find();
+ if (matched) {
+ String group = matcher.group();
+ int paramIndex = Integer.parseInt(group.substring(1, group.length() - 1));
+ String replacement = param(runtimeObjectModel, params, paramIndex);
+ int matchStart = matcher.start();
+ int matchEnd = matcher.end();
+ builder.append(source, lastPos, matchStart).append(replacement);
+ lastPos = matchEnd;
+ }
+ }
+ builder.append(source, lastPos, source.length());
+ return builder.toString();
+ }
+
+ private String param(RuntimeObjectModel runtimeObjectModel, Object[] params, int index) {
+ if (index >= 0 && index < params.length) {
+ return runtimeObjectModel.toString(params[index]);
+ }
+ return "";
+ }
+}
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/I18nRuntimeExtension.java Thu Jun 16 16:07:57 2016
@@ -31,20 +31,20 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.scripting.SlingBindings;
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.filter.I18nFilter;
-import org.apache.sling.scripting.sightly.impl.utils.RenderUtils;
+import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component
@Service(RuntimeExtension.class)
@Properties({
- @Property(name = RuntimeExtension.NAME, value = I18nFilter.FUNCTION)
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.I18N)
})
public class I18nRuntimeExtension implements RuntimeExtension {
@@ -52,19 +52,20 @@ public class I18nRuntimeExtension implem
@Override
public Object call(final RenderContext renderContext, Object... arguments) {
- ExtensionUtils.checkArgumentCount(I18nFilter.FUNCTION, arguments, 2);
- String text = RenderUtils.toString(arguments[0]);
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.I18N, arguments, 2);
+ RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
+ String text = runtimeObjectModel.toString(arguments[0]);
Map<String, Object> options = (Map<String, Object>) arguments[1];
- String locale = RenderUtils.toString(options.get(I18nFilter.LOCALE_OPTION));
- String hint = RenderUtils.toString(options.get(I18nFilter.HINT_OPTION));
+ String locale = runtimeObjectModel.toString(options.get("locale"));
+ String hint = runtimeObjectModel.toString(options.get("hint"));
final Bindings bindings = renderContext.getBindings();
return get(bindings, text, locale, hint);
}
private String get(final Bindings bindings, String text, String locale, String hint) {
- final SlingScriptHelper slingScriptHelper = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
- final SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
+ final SlingScriptHelper slingScriptHelper = BindingsUtils.getHelper(bindings);
+ final SlingHttpServletRequest request = BindingsUtils.getRequest(bindings);
final ResourceBundleProvider resourceBundleProvider = slingScriptHelper.getService(ResourceBundleProvider.class);
if (resourceBundleProvider != null) {
String key = text;
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/IncludeRuntimeExtension.java Thu Jun 16 16:07:57 2016
@@ -31,26 +31,25 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.scripting.SlingBindings;
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.plugin.IncludePlugin;
-import org.apache.sling.scripting.sightly.impl.utils.RenderUtils;
+import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Runtime support for including resources in a Sightly script through {@code data-sly-include}.
+ */
@Component
@Service(RuntimeExtension.class)
@Properties({
- @Property(name = RuntimeExtension.NAME, value = IncludePlugin.FUNCTION)
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.INCLUDE)
})
-/**
- * Runtime support for including resources in a Sightly script through {@code data-sly-include}. For more details check the implementation
- * of the {@link org.apache.sling.scripting.sightly.impl.plugin.IncludePlugin}.
- */
public class IncludeRuntimeExtension implements RuntimeExtension {
private static final Logger LOG = LoggerFactory.getLogger(IncludeRuntimeExtension.class);
@@ -61,8 +60,9 @@ public class IncludeRuntimeExtension imp
@Override
public Object call(final RenderContext renderContext, Object... arguments) {
- ExtensionUtils.checkArgumentCount(IncludePlugin.FUNCTION, arguments, 2);
- String originalPath = RenderUtils.toString(arguments[0]);
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.INCLUDE, arguments, 2);
+ RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
+ String originalPath = runtimeObjectModel.toString(arguments[0]);
Map options = (Map) arguments[1];
String path = buildPath(originalPath, options);
StringWriter output = new StringWriter();
@@ -95,14 +95,14 @@ public class IncludeRuntimeExtension imp
throw new SightlyException("Path for data-sly-include is empty");
} else {
LOG.debug("Attempting to include script {}.", script);
- SlingScriptHelper slingScriptHelper = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
+ SlingScriptHelper slingScriptHelper = BindingsUtils.getHelper(bindings);
ServletResolver servletResolver = slingScriptHelper.getService(ServletResolver.class);
if (servletResolver != null) {
- SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
+ SlingHttpServletRequest request = BindingsUtils.getRequest(bindings);
Servlet servlet = servletResolver.resolveServlet(request.getResource(), script);
if (servlet != null) {
try {
- SlingHttpServletResponse response = (SlingHttpServletResponse) bindings.get(SlingBindings.RESPONSE);
+ SlingHttpServletResponse response = BindingsUtils.getResponse(bindings);
PrintWriterResponseWrapper resWrapper = new PrintWriterResponseWrapper(out, response);
servlet.service(request, resWrapper);
} catch (Exception e) {
Added: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java?rev=1748750&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java (added)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/JoinFilterExtension.java Thu Jun 16 16:07:57 2016
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.extension;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+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;
+
+@Component
+@Service(RuntimeExtension.class)
+@Properties({
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.JOIN)
+})
+public class JoinFilterExtension implements RuntimeExtension {
+
+ @Override
+ public Object call(final RenderContext renderContext, Object... arguments) {
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.JOIN, arguments, 2);
+ Object joinArgument = arguments[0];
+ RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
+ Collection<?> collection = runtimeObjectModel.toCollection(joinArgument);
+ String joinString = runtimeObjectModel.toString(arguments[1]);
+ return join(runtimeObjectModel, collection, joinString);
+ }
+
+ private String join(RuntimeObjectModel runtimeObjectModel, Collection<?> collection, String joinString) {
+ StringBuilder sb = new StringBuilder();
+ Iterator<?> iterator = collection.iterator();
+ while (iterator.hasNext()) {
+ String element = runtimeObjectModel.toString(iterator.next());
+ sb.append(element);
+ if (iterator.hasNext()) {
+ sb.append(joinString);
+ }
+ }
+ return sb.toString();
+ }
+
+}
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/ResourceRuntimeExtension.java Thu Jun 16 16:07:57 2016
@@ -26,7 +26,6 @@ import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
-
import javax.script.Bindings;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
@@ -43,24 +42,22 @@ import org.apache.sling.api.resource.Non
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.api.scripting.SlingBindings;
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.plugin.ResourcePlugin;
+import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Runtime support for including resources in a Sightly script through {@code data-sly-resource}. For more details check the implementation
- * of the {@link org.apache.sling.scripting.sightly.impl.plugin.ResourcePlugin}.
+ * Runtime support for including resources in a Sightly script through {@code data-sly-resource}.
*/
@Component
@Service(RuntimeExtension.class)
@Properties(
- @Property(name = RuntimeExtension.NAME, value = ResourcePlugin.FUNCTION)
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.RESOURCE)
)
-@SuppressWarnings("unused")
public class ResourceRuntimeExtension implements RuntimeExtension {
private static final Logger LOG = LoggerFactory.getLogger(ResourceRuntimeExtension.class);
@@ -74,18 +71,17 @@ public class ResourceRuntimeExtension im
private static final String OPTION_REPLACE_SELECTORS = "replaceSelectors";
@Override
- @SuppressWarnings("unchecked")
public Object call(final RenderContext renderContext, Object... arguments) {
- ExtensionUtils.checkArgumentCount(ResourcePlugin.FUNCTION, arguments, 2);
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.RESOURCE, arguments, 2);
return provideResource(renderContext, arguments[0], (Map<String, Object>) arguments[1]);
}
private String provideResource(final RenderContext renderContext, Object pathObj, Map<String, Object> options) {
- Map<String, Object> opts = new HashMap<String, Object>(options);
+ Map<String, Object> opts = new HashMap<>(options);
PathInfo pathInfo = new PathInfo(coerceString(pathObj));
String path = pathInfo.path;
final Bindings bindings = renderContext.getBindings();
- String finalPath = buildPath(path, opts, (Resource) bindings.get(SlingBindings.RESOURCE));
+ String finalPath = buildPath(path, opts, BindingsUtils.getResource(bindings));
String resourceType = coerceString(getAndRemoveOption(opts, OPTION_RESOURCE_TYPE));
Map<String, String> dispatcherOptionsMap = handleSelectors(bindings, pathInfo.selectors, opts);
String dispatcherOptions = createDispatcherOptions(dispatcherOptionsMap);
@@ -97,46 +93,22 @@ public class ResourceRuntimeExtension im
private Map<String, String> handleSelectors(Bindings bindings, Set<String> selectors, Map<String, Object> options) {
if (selectors.isEmpty()) {
- SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
+ SlingHttpServletRequest request = BindingsUtils.getRequest(bindings);
selectors.addAll(Arrays.asList(request.getRequestPathInfo().getSelectors()));
}
- Map<String, String> dispatcherOptionsMap = new HashMap<String, String>();
+ Map<String, String> dispatcherOptionsMap = new HashMap<>();
dispatcherOptionsMap.put(OPTION_ADD_SELECTORS, getSelectorString(selectors));
dispatcherOptionsMap.put(OPTION_REPLACE_SELECTORS, " ");
if (options.containsKey(OPTION_SELECTORS)) {
Object selectorsObject = getAndRemoveOption(options, OPTION_SELECTORS);
selectors.clear();
- if (selectorsObject instanceof String) {
- String selectorString = (String) selectorsObject;
- String[] parts = selectorString.split("\\.");
- selectors.addAll(Arrays.asList(parts));
- } else if (selectorsObject instanceof Object[]) {
- for (Object s : (Object[]) selectorsObject) {
- String selector = coerceString(s);
- if (StringUtils.isNotEmpty(selector)) {
- selectors.add(selector);
- }
- }
- }
+ addSelectors(selectors, selectorsObject);
dispatcherOptionsMap.put(OPTION_ADD_SELECTORS, getSelectorString(selectors));
dispatcherOptionsMap.put(OPTION_REPLACE_SELECTORS, " ");
}
if (options.containsKey(OPTION_ADD_SELECTORS)) {
Object selectorsObject = getAndRemoveOption(options, OPTION_ADD_SELECTORS);
- if (selectorsObject instanceof String) {
- String selectorString = (String) selectorsObject;
- String[] parts = selectorString.split("\\.");
- for (String s : parts) {
- selectors.add(s);
- }
- } else if (selectorsObject instanceof Object[]) {
- for (Object s : (Object[]) selectorsObject) {
- String selector = coerceString(s);
- if (StringUtils.isNotEmpty(selector)) {
- selectors.add(selector);
- }
- }
- }
+ addSelectors(selectors, selectorsObject);
dispatcherOptionsMap.put(OPTION_ADD_SELECTORS, getSelectorString(selectors));
dispatcherOptionsMap.put(OPTION_REPLACE_SELECTORS, " ");
}
@@ -169,6 +141,21 @@ public class ResourceRuntimeExtension im
return dispatcherOptionsMap;
}
+ private void addSelectors(Set<String> selectors, Object selectorsObject) {
+ if (selectorsObject instanceof String) {
+ String selectorString = (String) selectorsObject;
+ String[] parts = selectorString.split("\\.");
+ selectors.addAll(Arrays.asList(parts));
+ } else if (selectorsObject instanceof Object[]) {
+ for (Object s : (Object[]) selectorsObject) {
+ String selector = coerceString(s);
+ if (StringUtils.isNotEmpty(selector)) {
+ selectors.add(selector);
+ }
+ }
+ }
+ }
+
private String buildPath(Object pathObj, Map<String, Object> options, Resource currentResource) {
String prependPath = getOption(OPTION_PREPEND_PATH, options, StringUtils.EMPTY);
if (prependPath == null) {
@@ -244,9 +231,8 @@ public class ResourceRuntimeExtension im
if (StringUtils.isEmpty(script)) {
LOG.error("Script path cannot be empty");
} else {
- SlingHttpServletResponse customResponse = new PrintWriterResponseWrapper(out,
- (SlingHttpServletResponse) bindings.get(SlingBindings.RESPONSE));
- SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST);
+ SlingHttpServletResponse customResponse = new PrintWriterResponseWrapper(out, BindingsUtils.getResponse(bindings));
+ SlingHttpServletRequest request = BindingsUtils.getRequest(bindings);
script = normalizePath(request, script);
Resource includeRes = request.getResourceResolver().resolve(script);
@@ -291,7 +277,7 @@ public class ResourceRuntimeExtension im
}
private Set<String> getSelectorsFromPath(String path) {
- Set<String> selectors = new LinkedHashSet<String>();
+ Set<String> selectors = new LinkedHashSet<>();
if (path != null) {
String processingPath = path;
int lastSlashPos = path.lastIndexOf('/');
Copied: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java (from r1748726, sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java)
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java?p2=sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java&p1=sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java&r1=1748726&r2=1748750&rev=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java Thu Jun 16 16:07:57 2016
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,44 +16,36 @@
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
-package org.apache.sling.scripting.sightly.impl.filter;
+package org.apache.sling.scripting.sightly.impl.engine.extension;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.resource.ResourceUtil;
+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.compiler.expression.Expression;
-import org.apache.sling.scripting.sightly.impl.compiler.expression.ExpressionNode;
-import org.apache.sling.scripting.sightly.impl.compiler.expression.node.MapLiteral;
-import org.apache.sling.scripting.sightly.impl.compiler.expression.node.RuntimeCall;
-import org.apache.sling.scripting.sightly.impl.engine.extension.ExtensionUtils;
-import org.apache.sling.scripting.sightly.impl.utils.PathInfo;
-import org.apache.sling.scripting.sightly.impl.utils.RenderUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
-/**
- * The {@code URIManipulationFilter} provides support for Sightly's URI Manipulation options according to the
- * <a href="https://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/1.1/SPECIFICATION.md">language specification</a>
- */
@Component
-@Service({Filter.class, RuntimeExtension.class})
+@Service(RuntimeExtension.class)
@Properties({
- @Property(name = RuntimeExtension.NAME, value = URIManipulationFilter.URI_MANIPULATION_FUNCTION)
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.URI_MANIPULATION)
})
-public class URIManipulationFilter extends FilterComponent implements RuntimeExtension {
-
- public static final String URI_MANIPULATION_FUNCTION = "uriManipulation";
+public class URIManipulationFilterExtension implements RuntimeExtension {
public static final String SCHEME = "scheme";
public static final String DOMAIN = "domain";
@@ -72,34 +64,14 @@ public class URIManipulationFilter exten
public static final String ADD_QUERY = "addQuery";
public static final String REMOVE_QUERY = "removeQuery";
- @Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if ((expression.containsOption(SCHEME) || expression.containsOption(DOMAIN) || expression.containsOption(PATH) || expression
- .containsOption(APPEND_PATH) || expression.containsOption(PREPEND_PATH) || expression.containsOption(SELECTORS) ||
- expression.containsOption(ADD_SELECTORS) || expression.containsOption(REMOVE_SELECTORS) || expression.containsOption
- (EXTENSION) || expression.containsOption(SUFFIX) || expression.containsOption(PREPEND_SUFFIX) || expression
- .containsOption(APPEND_SUFFIX) || expression.containsOption(FRAGMENT) || expression.containsOption(QUERY) || expression
- .containsOption(ADD_QUERY) || expression.containsOption(REMOVE_QUERY)) && expressionContext != ExpressionContext
- .PLUGIN_DATA_SLY_USE && expressionContext
- != ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE && expressionContext != ExpressionContext.PLUGIN_DATA_SLY_CALL &&
- expressionContext != ExpressionContext.PLUGIN_DATA_SLY_RESOURCE) {
- Map<String, ExpressionNode> uriOptions = getFilterOptions(expression, SCHEME, DOMAIN, PATH, APPEND_PATH, PREPEND_PATH,
- SELECTORS, ADD_SELECTORS, REMOVE_SELECTORS, EXTENSION, SUFFIX, PREPEND_SUFFIX, APPEND_SUFFIX, FRAGMENT, QUERY,
- ADD_QUERY, REMOVE_QUERY);
- if (uriOptions.size() > 0) {
- ExpressionNode translation = new RuntimeCall(URI_MANIPULATION_FUNCTION, expression.getRoot(), new MapLiteral(uriOptions));
- return expression.withNode(translation);
- }
- }
- return expression;
- }
@Override
@SuppressWarnings("unchecked")
public Object call(RenderContext renderContext, Object... arguments) {
- ExtensionUtils.checkArgumentCount(URI_MANIPULATION_FUNCTION, arguments, 2);
- String uriString = RenderUtils.toString(arguments[0]);
- Map<String, Object> options = RenderUtils.toMap(arguments[1]);
+ ExtensionUtils.checkArgumentCount(RuntimeFunction.URI_MANIPULATION, arguments, 2);
+ RuntimeObjectModel runtimeObjectModel = renderContext.getObjectModel();
+ String uriString = runtimeObjectModel.toString(arguments[0]);
+ Map<String, Object> options = runtimeObjectModel.toMap(arguments[1]);
StringBuilder sb = new StringBuilder();
PathInfo pathInfo = new PathInfo(uriString);
uriAppender(sb, SCHEME, options, pathInfo.getScheme());
@@ -155,7 +127,7 @@ public class URIManipulationFilter exten
}
sb.append(newPath);
Set<String> selectors = pathInfo.getSelectors();
- handleSelectors(selectors, options);
+ handleSelectors(runtimeObjectModel, selectors, options);
for (String selector : selectors) {
if (StringUtils.isNotBlank(selector) && !selector.contains(" ")) {
// make sure not to append empty or invalid selectors
@@ -185,7 +157,7 @@ public class URIManipulationFilter exten
if (StringUtils.isNotEmpty(appendSuffix)) {
appendSuffix = "/" + appendSuffix;
}
- String newSuffix = ResourceUtil.normalize(prependSuffix + suffix + appendSuffix);
+ String newSuffix = FilenameUtils.normalize(prependSuffix + suffix + appendSuffix, true);
if (StringUtils.isNotEmpty(newSuffix)) {
if (!newSuffix.startsWith("/")) {
sb.append("/");
@@ -193,7 +165,7 @@ public class URIManipulationFilter exten
sb.append(newSuffix);
}
Map<String, Collection<String>> parameters = pathInfo.getParameters();
- handleParameters(parameters, options);
+ handleParameters(runtimeObjectModel, parameters, options);
if (!parameters.isEmpty()) {
sb.append("?");
for (Map.Entry<String, Collection<String>> entry : parameters.entrySet()) {
@@ -230,7 +202,7 @@ public class URIManipulationFilter exten
return defaultValue;
}
- private void handleSelectors(Set<String> selectors, Map<String, Object> options) {
+ private void handleSelectors(RuntimeObjectModel runtimeObjectModel, Set<String> selectors, Map<String, Object> options) {
if (options.containsKey(SELECTORS)) {
Object selectorsOption = options.get(SELECTORS);
if (selectorsOption == null) {
@@ -245,7 +217,7 @@ public class URIManipulationFilter exten
String[] selectorsArray = new String[selectorsURIArray.length];
int index = 0;
for (Object selector : selectorsURIArray) {
- selectorsArray[index++] = RenderUtils.toString(selector);
+ selectorsArray[index++] = runtimeObjectModel.toString(selector);
}
replaceSelectors(selectors, selectorsArray);
}
@@ -260,7 +232,7 @@ public class URIManipulationFilter exten
String[] selectorsArray = new String[selectorsURIArray.length];
int index = 0;
for (Object selector : selectorsURIArray) {
- selectorsArray[index++] = RenderUtils.toString(selector);
+ selectorsArray[index++] = runtimeObjectModel.toString(selector);
}
addSelectors(selectors, selectorsArray);
}
@@ -274,7 +246,7 @@ public class URIManipulationFilter exten
String[] selectorsArray = new String[selectorsURIArray.length];
int index = 0;
for (Object selector : selectorsURIArray) {
- selectorsArray[index++] = RenderUtils.toString(selector);
+ selectorsArray[index++] = runtimeObjectModel.toString(selector);
}
removeSelectors(selectors, selectorsArray);
}
@@ -295,45 +267,18 @@ public class URIManipulationFilter exten
}
@SuppressWarnings("unchecked")
- private void handleParameters(Map<String, Collection<String>> parameters, Map<String, Object> options) {
+ private void handleParameters(RuntimeObjectModel runtimeObjectModel, Map<String, Collection<String>> parameters, Map<String, Object>
+ options) {
if (options.containsKey(QUERY)) {
Object queryOption = options.get(QUERY);
parameters.clear();
- Map<String, Object> queryParameters = RenderUtils.toMap(queryOption);
- for (Map.Entry<String, Object> entry : queryParameters.entrySet()) {
- Object entryValue = entry.getValue();
- if (RenderUtils.isCollection(entryValue)) {
- Collection<Object> collection = RenderUtils.toCollection(entryValue);
- Collection<String> values = new ArrayList<String>(collection.size());
- for (Object o : collection) {
- values.add(RenderUtils.toString(o));
- }
- parameters.put(entry.getKey(), values);
- } else {
- Collection<String> values = new ArrayList<String>(1);
- values.add(RenderUtils.toString(entryValue));
- parameters.put(entry.getKey(), values);
- }
- }
+ Map<String, Object> queryParameters = runtimeObjectModel.toMap(queryOption);
+ addQueryParameters(runtimeObjectModel, parameters, queryParameters);
}
Object addQueryOption = options.get(ADD_QUERY);
if (addQueryOption != null) {
- Map<String, Object> addParams = RenderUtils.toMap(addQueryOption);
- for (Map.Entry<String, Object> entry : addParams.entrySet()) {
- Object entryValue = entry.getValue();
- if (RenderUtils.isCollection(entryValue)) {
- Collection<Object> collection = RenderUtils.toCollection(entryValue);
- Collection<String> values = new ArrayList<String>(collection.size());
- for (Object o : collection) {
- values.add(RenderUtils.toString(o));
- }
- parameters.put(entry.getKey(), values);
- } else {
- Collection<String> values = new ArrayList<String>(1);
- values.add(RenderUtils.toString(entryValue));
- parameters.put(entry.getKey(), values);
- }
- }
+ Map<String, Object> addParams = runtimeObjectModel.toMap(addQueryOption);
+ addQueryParameters(runtimeObjectModel, parameters, addParams);
}
Object removeQueryOption = options.get(REMOVE_QUERY);
if (removeQueryOption != null) {
@@ -342,7 +287,7 @@ public class URIManipulationFilter exten
} else if (removeQueryOption instanceof Object[]) {
Object[] removeQueryParamArray = (Object[]) removeQueryOption;
for (Object param : removeQueryParamArray) {
- String paramString = RenderUtils.toString(param);
+ String paramString = runtimeObjectModel.toString(param);
if (paramString != null) {
parameters.remove(paramString);
}
@@ -350,4 +295,216 @@ public class URIManipulationFilter exten
}
}
}
+
+ private void addQueryParameters(RuntimeObjectModel runtimeObjectModel, Map<String, Collection<String>> parameters, Map<String, Object>
+ queryParameters) {
+ for (Map.Entry<String, Object> entry : queryParameters.entrySet()) {
+ Object entryValue = entry.getValue();
+ if (runtimeObjectModel.isCollection(entryValue)) {
+ Collection<Object> collection = runtimeObjectModel.toCollection(entryValue);
+ Collection<String> values = new ArrayList<>(collection.size());
+ for (Object o : collection) {
+ values.add(runtimeObjectModel.toString(o));
+ }
+ parameters.put(entry.getKey(), values);
+ } else {
+ Collection<String> values = new ArrayList<>(1);
+ values.add(runtimeObjectModel.toString(entryValue));
+ parameters.put(entry.getKey(), values);
+ }
+ }
+ }
+
+ public static class PathInfo {
+
+ private URI uri;
+ private String path;
+ private Set<String> selectors;
+ private String selectorString;
+ private String extension;
+ private String suffix;
+ private Map<String, Collection<String>> parameters = new LinkedHashMap<>();
+
+ /**
+ * Creates a {@code PathInfo} object based on a request path.
+ *
+ * @param path the full normalized path (no '.', '..', or double slashes8) of the request, including the query parameters
+ * @throws NullPointerException if the supplied {@code path} is null
+ */
+ public PathInfo(String path) {
+ if (path == null) {
+ throw new NullPointerException("The path parameter cannot be null.");
+ }
+ try {
+ uri = new URI(path);
+ } catch (URISyntaxException e) {
+ throw new SightlyException("The provided path does not represent a valid URI: " + path);
+ }
+ selectors = new LinkedHashSet<>();
+ String processingPath = path;
+ if (uri.getPath() != null) {
+ processingPath = uri.getPath();
+ }
+ int lastDot = processingPath.lastIndexOf('.');
+ if (lastDot > -1) {
+ String afterLastDot = processingPath.substring(lastDot + 1);
+ String[] parts = afterLastDot.split("/");
+ extension = parts[0];
+ if (parts.length > 1) {
+ // we have a suffix
+ StringBuilder suffixSB = new StringBuilder();
+ for (int i = 1; i < parts.length; i++) {
+ suffixSB.append("/").append(parts[i]);
+ }
+ int hashIndex = suffixSB.indexOf("#");
+ if (hashIndex > -1) {
+ suffix = suffixSB.substring(0, hashIndex);
+ } else {
+ suffix = suffixSB.toString();
+ }
+ }
+ }
+ int firstDot = processingPath.indexOf('.');
+ if (firstDot < lastDot) {
+ selectorString = processingPath.substring(firstDot + 1, lastDot);
+ String[] selectorsArray = selectorString.split("\\.");
+ selectors.addAll(Arrays.asList(selectorsArray));
+ }
+ int pathLength = processingPath.length() - (selectorString == null ? 0 : selectorString.length() + 1) - (extension == null ? 0:
+ extension.length() + 1) - (suffix == null ? 0 : suffix.length());
+ if (pathLength == processingPath.length()) {
+ this.path = processingPath;
+ } else {
+ this.path = processingPath.substring(0, pathLength);
+ }
+ String query = uri.getQuery();
+ if (StringUtils.isNotEmpty(query)) {
+ String[] keyValuePairs = query.split("&");
+ for (int i = 0; i < keyValuePairs.length; i++) {
+ String[] pair = keyValuePairs[i].split("=");
+ if (pair.length == 2) {
+ String param = pair[0];
+ String value = pair[1];
+ Collection<String> values = parameters.get(param);
+ if (values == null) {
+ values = new ArrayList<>();
+ parameters.put(param, values);
+ }
+ values.add(value);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the scheme of this path if the path corresponds to a URI and if the URI provides scheme information.
+ *
+ * @return the scheme or {@code null} if the path does not contain a scheme
+ */
+ public String getScheme() {
+ return uri.getScheme();
+ }
+
+ /**
+ * Returns the path separator ("//") if the path defines an absolute URI.
+ *
+ * @return the path separator if the path is an absolute URI, {@code null} otherwise
+ */
+ public String getBeginPathSeparator() {
+ if (uri.isAbsolute()) {
+ return "//";
+ }
+ return null;
+ }
+
+ /**
+ * Returns the host part of the path, if the path defines a URI.
+ *
+ * @return the host if the path defines a URI, {@code null} otherwise
+ */
+ public String getHost() {
+ return uri.getHost();
+ }
+
+ /**
+ * Returns the port if the path defines a URI and if it contains port information.
+ *
+ * @return the port or -1 if no port is defined
+ */
+ public int getPort() {
+ return uri.getPort();
+ }
+
+ /**
+ * Returns the path from which <i>{@code this}</i> object was built.
+ *
+ * @return the original path
+ */
+ public String getFullPath() {
+ return uri.toString();
+ }
+
+ /**
+ * Returns the path identifying the resource, without any selectors, extension or query parameters.
+ *
+ * @return the path of the resource
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Returns the selectors set.
+ *
+ * @return the selectors set; if there are no selectors the set will be empty
+ */
+ public Set<String> getSelectors() {
+ return selectors;
+ }
+
+ /**
+ * Returns the extension.
+ *
+ * @return the extension, if one exists, otherwise {@code null}
+ */
+ public String getExtension() {
+ return extension;
+ }
+
+ /**
+ * Returns the selector string.
+ *
+ * @return the selector string, if the path has selectors, otherwise {@code null}
+ */
+ public String getSelectorString() {
+ return selectorString;
+ }
+
+ /**
+ * Returns the suffix appended to the path. The suffix represents the path segment between the path's extension and the path's fragment.
+ *
+ * @return the suffix if the path contains one, {@code null} otherwise
+ */
+ public String getSuffix() {
+ return suffix;
+ }
+
+ /**
+ * Returns the fragment is this path defines a URI and it contains a fragment.
+ *
+ * @return the fragment, or {@code null} if one doesn't exist
+ */
+ public String getFragment() {
+ return uri.getFragment();
+ }
+
+ /**
+ * Returns the URI parameters if the provided path defines a URI.
+ * @return the parameters map; can be empty if there are no parameters of if the path doesn't identify a URI
+ */
+ public Map<String, Collection<String>> getParameters() {
+ return parameters;
+ }
+ }
+
}
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/XSSRuntimeExtension.java Thu Jun 16 16:07:57 2016
@@ -16,13 +16,11 @@
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
-
package org.apache.sling.scripting.sightly.impl.engine.extension;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
-
import javax.script.Bindings;
import org.apache.felix.scr.annotations.Component;
@@ -31,12 +29,10 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
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.impl.compiler.CompilerException;
-import org.apache.sling.scripting.sightly.impl.filter.XSSFilter;
-import org.apache.sling.scripting.sightly.impl.html.MarkupUtils;
-import org.apache.sling.scripting.sightly.impl.plugin.MarkupContext;
-import org.apache.sling.scripting.sightly.impl.utils.RenderUtils;
+import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.xss.XSSAPI;
import org.slf4j.Logger;
@@ -48,19 +44,20 @@ import org.slf4j.LoggerFactory;
@Component
@Service(RuntimeExtension.class)
@Properties(
- @Property(name = RuntimeExtension.NAME, value = XSSFilter.FUNCTION_NAME)
+ @Property(name = RuntimeExtension.NAME, value = RuntimeFunction.XSS)
)
public class XSSRuntimeExtension implements RuntimeExtension {
private static final Set<String> elementNameWhiteList = new HashSet<String>();
private static final Logger LOG = LoggerFactory.getLogger(XSSRuntimeExtension.class);
private static final Pattern VALID_ATTRIBUTE = Pattern.compile("^[a-zA-Z_:][\\-a-zA-Z0-9_:\\.]*$");
+ private static final Pattern ATTRIBUTE_BLACKLIST = Pattern.compile("^(style|(on.*))$", Pattern.CASE_INSENSITIVE);
@Override
public Object call(final RenderContext renderContext, Object... arguments) {
if (arguments.length < 2) {
throw new SightlyException(
- String.format("Extension %s requires at least %d arguments", XSSFilter.FUNCTION_NAME, 2));
+ String.format("Extension %s requires at least %d arguments", RuntimeFunction.XSS, 2));
}
Object original = arguments[0];
Object option = arguments[1];
@@ -80,7 +77,7 @@ public class XSSRuntimeExtension impleme
LOG.warn("Expression context {} is invalid, expression will be replaced by the empty string", option);
return "";
}
- String text = RenderUtils.toString(original);
+ String text = renderContext.getObjectModel().toString(original);
final XSSAPI xssapi = obtainAPI(renderContext.getBindings());
return applyXSSFilter(xssapi, text, hint, markupContext);
}
@@ -104,7 +101,10 @@ public class XSSRuntimeExtension impleme
case ATTRIBUTE_NAME:
return escapeAttributeName(text);
case NUMBER:
- return xssapi.getValidLong(text, 0).toString();
+ Long result = xssapi.getValidLong(text, 0);
+ if (result != null) {
+ return result.toString();
+ }
case URI:
return xssapi.getValidHref(text);
case SCRIPT_TOKEN:
@@ -135,9 +135,9 @@ public class XSSRuntimeExtension impleme
}
private XSSAPI obtainAPI(Bindings bindings) {
- SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get("request");
+ SlingHttpServletRequest request = BindingsUtils.getRequest(bindings);
if (request == null) {
- throw new CompilerException("Cannot obtain request from bindings");
+ throw new SightlyException("Cannot obtain request from bindings");
}
return request.adaptTo(XSSAPI.class);
}
@@ -154,7 +154,7 @@ public class XSSRuntimeExtension impleme
return null;
}
attributeName = attributeName.trim();
- if (matchPattern(VALID_ATTRIBUTE, attributeName) && !MarkupUtils.isSensitiveAttribute(attributeName)) {
+ if (matchPattern(VALID_ATTRIBUTE, attributeName) && !isSensitiveAttribute(attributeName)) {
return attributeName;
}
return null;
@@ -234,4 +234,7 @@ public class XSSRuntimeExtension impleme
elementNameWhiteList.add("th");
}
+ private boolean isSensitiveAttribute(String name) {
+ return ATTRIBUTE_BLACKLIST.matcher(name).matches();
+ }
}
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java Thu Jun 16 16:07:57 2016
@@ -31,11 +31,10 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.commons.classloader.ClassLoaderWriter;
-import org.apache.sling.scripting.sightly.impl.compiler.SightlyJavaCompilerService;
-import org.apache.sling.scripting.sightly.impl.compiler.UnitChangeMonitor;
+import org.apache.sling.scripting.sightly.impl.engine.SightlyJavaCompilerService;
+import org.apache.sling.scripting.sightly.impl.engine.UnitChangeMonitor;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.pojo.Use;
import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -83,7 +82,7 @@ public class JavaUseProvider implements
}
Bindings globalBindings = renderContext.getBindings();
SlingScriptHelper sling = BindingsUtils.getHelper(globalBindings);
- SlingHttpServletRequest request = (SlingHttpServletRequest) globalBindings.get(SlingBindings.REQUEST);
+ SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
Map<String, Object> overrides = setRequestAttributes(request, arguments);
Object result;
@@ -106,7 +105,7 @@ public class JavaUseProvider implements
}
result = request.adaptTo(cls);
if (result == null) {
- Resource resource = (Resource) globalBindings.get(SlingBindings.RESOURCE);
+ Resource resource = BindingsUtils.getResource(globalBindings);
result = resource.adaptTo(cls);
}
if (result != null) {
@@ -141,7 +140,7 @@ public class JavaUseProvider implements
}
private Map<String, Object> setRequestAttributes(ServletRequest request, Bindings arguments) {
- Map<String, Object> overrides = new HashMap<String, Object>();
+ Map<String, Object> overrides = new HashMap<>();
for (Map.Entry<String, Object> entry : arguments.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java Thu Jun 16 16:07:57 2016
@@ -19,7 +19,11 @@
package org.apache.sling.scripting.sightly.impl.engine.extension.use;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import javax.script.Bindings;
+import javax.script.CompiledScript;
+import javax.script.ScriptEngineManager;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
@@ -27,14 +31,19 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.api.CachedScript;
+import org.apache.sling.scripting.api.ScriptCache;
import org.apache.sling.scripting.sightly.ResourceResolution;
import org.apache.sling.scripting.sightly.SightlyException;
+import org.apache.sling.scripting.sightly.impl.engine.SightlyCompiledScript;
+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.engine.UnitLoader;
-import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
+import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.use.ProviderOutcome;
import org.apache.sling.scripting.sightly.use.UseProvider;
@@ -62,17 +71,21 @@ import org.osgi.framework.Constants;
public class RenderUnitProvider implements UseProvider {
@Reference
- private UnitLoader unitLoader;
+ private ScriptCache scriptCache;
+
+ @Reference
+ private ScriptEngineManager scriptEngineManager;
@Override
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
+ RenderContextImpl rci = (RenderContextImpl) renderContext;
Bindings globalBindings = renderContext.getBindings();
SlingScriptHelper sling = BindingsUtils.getHelper(globalBindings);
- Resource renderUnitResource = UseProviderUtils.locateScriptResource(renderContext, identifier);
+ SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
+ final Resource renderUnitResource = rci.resolveScript(identifier);
if (renderUnitResource == null) {
- Resource caller = ResourceResolution.getResourceForRequest(sling.getRequest().getResourceResolver(), sling
- .getRequest());
+ Resource caller = ResourceResolution.getResourceForRequest(request.getResourceResolver(), request);
if (caller != null) {
String resourceSuperType = caller.getResourceSuperType();
StringBuilder errorMessage = new StringBuilder("Cannot find resource ");
@@ -87,8 +100,35 @@ public class RenderUnitProvider implemen
.getScript().getScriptResource().getPath()));
}
}
+ RenderUnit renderUnit;
try {
- RenderUnit renderUnit = unitLoader.createUnit(renderUnitResource, renderContext);
+ 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);
+ InputStream inputStream = renderUnitResource.adaptTo(InputStream.class);
+ String encoding = renderUnitResource.getResourceMetadata().getCharacterEncoding();
+ if (StringUtils.isEmpty(encoding)) {
+ encoding = "UTF-8";
+ }
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream, encoding);
+ compiledScript = (SightlyCompiledScript) sightlyScriptEngine.compile(inputStreamReader);
+ 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);
Modified: sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java?rev=1748750&r1=1748749&r2=1748750&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java (original)
+++ sling/trunk/bundles/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java Thu Jun 16 16:07:57 2016
@@ -30,6 +30,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScript;
import org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
import org.apache.sling.scripting.sightly.impl.utils.BindingsUtils;
import org.apache.sling.scripting.sightly.render.RenderContext;
import org.apache.sling.scripting.sightly.use.ProviderOutcome;
@@ -68,13 +69,14 @@ public class ScriptUseProvider implement
@Override
public ProviderOutcome provide(String scriptName, RenderContext renderContext, Bindings arguments) {
- Bindings globalBindings = renderContext.getBindings();
+ RenderContextImpl rci = (RenderContextImpl) renderContext;
+ Bindings globalBindings = rci.getBindings();
Bindings bindings = BindingsUtils.merge(globalBindings, arguments);
String extension = scriptExtension(scriptName);
if (extension == null || extension.equals(SightlyScriptEngineFactory.EXTENSION)) {
return ProviderOutcome.failure();
}
- Resource scriptResource = UseProviderUtils.locateScriptResource(renderContext, scriptName);
+ Resource scriptResource = rci.resolveScript(scriptName);
if (scriptResource == null) {
log.debug("Path does not match an existing resource: {}", scriptName);
return ProviderOutcome.failure();