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 2019/06/05 11:45:04 UTC
[sling-org-apache-sling-scripting-sightly-compiler] branch master
updated: SLING-6779 - The HTL compiler and Maven Plugin should warn when
using potentially invalid options
This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler.git
The following commit(s) were added to refs/heads/master by this push:
new eb8891e SLING-6779 - The HTL compiler and Maven Plugin should warn when using potentially invalid options
eb8891e is described below
commit eb8891e89caef2993f4cdab0fbe764a7695ec0e8
Author: Radu Cotescu <17...@users.noreply.github.com>
AuthorDate: Wed Jun 5 13:44:58 2019 +0200
SLING-6779 - The HTL compiler and Maven Plugin should warn when using potentially invalid options
* collected all known options from filters and plugins
* added a warn message in the compiler if a certain expression option is not handled by
any of the filters and the expression context doesn't allow arbitrary options
* added the possibility to configure the compiler to ignore certain additional options
* removed unused imports
* removed unneeded powermock instrumentation for the SightlyCompiler since it messed up code
coverage reports
---
bnd.bnd | 2 +
pom.xml | 61 ++++++----------------
.../sightly/compiler/SightlyCompiler.java | 55 ++++++++++++++++---
.../scripting/sightly/compiler/package-info.java | 2 +-
.../sightly/impl/compiler/CompilerFrontend.java | 33 ------------
.../impl/compiler/frontend/CompilerContext.java | 6 +--
.../impl/compiler/frontend/ExpressionWrapper.java | 21 ++++++--
.../impl/compiler/frontend/SimpleFrontend.java | 11 ++--
.../sightly/impl/filter/AbstractFilter.java | 50 +++++++++++++++++-
.../sightly/impl/filter/ExpressionContext.java | 49 +++++++++++------
.../scripting/sightly/impl/filter/Filter.java | 32 ++++++++++++
.../sightly/impl/filter/FormatFilter.java | 23 +++-----
.../scripting/sightly/impl/filter/I18nFilter.java | 21 ++++----
.../scripting/sightly/impl/filter/JoinFilter.java | 17 +++---
.../sightly/impl/filter/URIManipulationFilter.java | 46 ++++++++--------
.../scripting/sightly/impl/filter/XSSFilter.java | 14 ++---
.../sightly/impl/html/dom/MarkupHandler.java | 4 +-
.../sightly/impl/compiler/SightlyCompilerTest.java | 22 +++++---
.../impl/frontend/ExpressionWrapperTest.java | 9 ++--
19 files changed, 280 insertions(+), 198 deletions(-)
diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..b036455
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,2 @@
+Provide-Capability: io.sightly.compiler; version:Version="1.0", io.sightly.compiler; version:Version="1.1", io.sightly.compiler; version:Version="1.2", io.sightly.compiler; version:Version="1.3", io.sightly.compiler; version:Version="1.3.1", io.sightly.compiler; version:Version="1.4",
+Require-Capability: io.sightly.runtime; filter:="(&(version>=1.0)(!(version>=2.0)))"
diff --git a/pom.xml b/pom.xml
index 8797fb0..3e5f0d1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,8 +24,8 @@
<!-- ======================================================================= -->
<parent>
<groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>34</version>
+ <artifactId>sling-bundle-parent</artifactId>
+ <version>35</version>
<relativePath />
</parent>
@@ -37,8 +37,7 @@
The versioning scheme defined here corresponds to SLING-7406 (<module_version>-<htl_specification_version>). Take care when
releasing to only increase the first part, unless the module provides support for a newer version of the HTL specification.
-->
- <version>1.1.3-1.4.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
+ <version>1.2.0-1.4.0-SNAPSHOT</version>
<name>Apache Sling Scripting HTL Compiler</name>
@@ -56,7 +55,7 @@
<properties>
<antlr.version>4.7.1</antlr.version>
- <jacoco.maven.plugin.version>0.7.9</jacoco.maven.plugin.version>
+ <jacoco.maven.plugin.version>0.8.3</jacoco.maven.plugin.version>
</properties>
<!-- ======================================================================= -->
@@ -65,35 +64,6 @@
<build>
<plugins>
<plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <executions>
- <execution>
- <id>scr-metadata</id>
- <goals>
- <goal>manifest</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <exportScr>true</exportScr>
- <instructions>
- <Provide-Capability>
- io.sightly.compiler; version:Version=1.0,
- io.sightly.compiler; version:Version=1.1,
- io.sightly.compiler; version:Version=1.2,
- io.sightly.compiler; version:Version=1.3,
- io.sightly.compiler; version:Version=1.3.1,
- io.sightly.compiler; version:Version=1.4
- </Provide-Capability>
- <Require-Capability>
- io.sightly.runtime; filter:="(&(version>=1.0)(!(version>=2.0)))"
- </Require-Capability>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${antlr.version}</version>
@@ -126,9 +96,9 @@
</executions>
</plugin>
<plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <version>3.0.5</version>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>3.1.11</version>
<configuration>
<effort>Max</effort>
<xmlOutput>true</xmlOutput>
@@ -249,6 +219,11 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.jetbrains</groupId>
+ <artifactId>annotations</artifactId>
+ </dependency>
+
<!-- testing -->
<dependency>
<groupId>junit</groupId>
@@ -257,20 +232,14 @@
</dependency>
<dependency>
<groupId>org.powermock</groupId>
- <artifactId>powermock-reflect</artifactId>
- <version>1.6.5</version>
+ <artifactId>powermock-api-mockito2</artifactId>
+ <version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
- <version>1.6.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-mockito</artifactId>
- <version>1.6.5</version>
+ <version>2.0.2</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
index 3216b7c..bd16d85 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/SightlyCompiler.java
@@ -21,16 +21,18 @@ package org.apache.sling.scripting.sightly.compiler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.scripting.sightly.compiler.backend.BackendCompiler;
import org.apache.sling.scripting.sightly.compiler.commands.CommandStream;
import org.apache.sling.scripting.sightly.impl.compiler.CompilationResultImpl;
-import org.apache.sling.scripting.sightly.impl.compiler.CompilerFrontend;
import org.apache.sling.scripting.sightly.impl.compiler.CompilerMessageImpl;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
+import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
import org.apache.sling.scripting.sightly.impl.compiler.debug.SanityChecker;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.SimpleFrontend;
import org.apache.sling.scripting.sightly.impl.compiler.optimization.CoalescingWrites;
@@ -40,6 +42,7 @@ import org.apache.sling.scripting.sightly.impl.compiler.optimization.StreamTrans
import org.apache.sling.scripting.sightly.impl.compiler.optimization.SyntheticMapRemoval;
import org.apache.sling.scripting.sightly.impl.compiler.optimization.UnusedVariableRemoval;
import org.apache.sling.scripting.sightly.impl.compiler.optimization.reduce.ConstantFolding;
+import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
import org.apache.sling.scripting.sightly.impl.filter.Filter;
import org.apache.sling.scripting.sightly.impl.filter.FormatFilter;
import org.apache.sling.scripting.sightly.impl.filter.I18nFilter;
@@ -60,6 +63,7 @@ import org.apache.sling.scripting.sightly.impl.plugin.TestPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.TextPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.UnwrapPlugin;
import org.apache.sling.scripting.sightly.impl.plugin.UsePlugin;
+import org.jetbrains.annotations.NotNull;
import org.osgi.service.component.annotations.Component;
/**
@@ -74,10 +78,17 @@ import org.osgi.service.component.annotations.Component;
)
public final class SightlyCompiler {
- private StreamTransformer optimizer;
- private CompilerFrontend frontend;
+ private final StreamTransformer optimizer;
+ private final SimpleFrontend frontend;
+ private final Set<String> knownExpressionOptions;
+ private final List<Plugin> plugins;
+ private final List<Filter> filters;
public SightlyCompiler() {
+ this(Collections.emptySet());
+ }
+
+ private SightlyCompiler(Set<String> additionalExpresionOptions) {
ArrayList<StreamTransformer> transformers = new ArrayList<>(5);
transformers.add(ConstantFolding.transformer());
transformers.add(DeadCodeRemoval.transformer());
@@ -87,7 +98,7 @@ public final class SightlyCompiler {
optimizer = new SequenceStreamTransformer(transformers);
// register plugins
- final List<Plugin> plugins = new ArrayList<>(12);
+ plugins = new ArrayList<>(12);
plugins.add(new AttributePlugin());
plugins.add(new CallPlugin());
plugins.add(new ElementPlugin());
@@ -104,15 +115,43 @@ public final class SightlyCompiler {
Collections.sort(plugins);
// register filters
- final List<Filter> filters = new ArrayList<>(5);
+ filters = new ArrayList<>(5);
filters.add(I18nFilter.getInstance());
filters.add(FormatFilter.getInstance());
filters.add(JoinFilter.getInstance());
filters.add(URIManipulationFilter.getInstance());
filters.add(XSSFilter.getInstance());
Collections.sort(filters);
+ knownExpressionOptions = new HashSet<>(additionalExpresionOptions);
+ for (Filter filter : filters) {
+ knownExpressionOptions.addAll(filter.getOptions());
+ }
+ knownExpressionOptions.add(Syntax.CONTEXT_OPTION);
+ for (ExpressionContext context : ExpressionContext.values()) {
+ knownExpressionOptions.addAll(context.getOptions());
+ }
+ frontend = new SimpleFrontend(plugins, filters, knownExpressionOptions);
+ }
- frontend = new SimpleFrontend(plugins, filters);
+ /**
+ * <p>
+ * Returns an instance of the {@code SightlyCompiler} with the provided {@code options} added to the list of known expression options.
+ * </p>
+ * <p>
+ * The compiler builds internally a set of allowed options from the options permitted by the expressions or plugins. As soon as an
+ * expression contains an unknown option the compiler logs a warning. Since the compiler works with dynamically registered
+ * {@link org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall}s, some of them can work with additional expression
+ * options, not known to the compiler.
+ * </p>
+ * <p>
+ * <strong>NOTE</strong>: The {@code data-sly-template, data-sly-call, data-sly-use} plugins allow arbitrary options which define
+ * parameters and do not generate warnings.
+ * </p>
+ *
+ * @param options the options to add to the compiler's set of known expression options
+ */
+ public static SightlyCompiler withKnownExpressionOptions(@NotNull Set<String> options) {
+ return new SightlyCompiler(options);
}
/**
@@ -176,7 +215,7 @@ public final class SightlyCompiler {
String textBeforeError = documentFragment.substring(0, offendingInputIndex);
int line = lineOffset;
int lastNewLineIndex = 0;
- for (String s : new String[] {"\r\n", "\r", "\n"}) {
+ for (String s : new String[]{"\r\n", "\r", "\n"}) {
int l = textBeforeError.split(s, -1).length - 1;
if (l + lineOffset > line) {
line = l + lineOffset;
@@ -188,7 +227,7 @@ public final class SightlyCompiler {
}
int column = textBeforeError.substring(lastNewLineIndex).length();
if (column != columnOffset) {
- column +=columnOffset;
+ column += columnOffset;
}
return new ScriptError(line, column, longestContiguousOffendingSequence + ": " + message);
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/compiler/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/compiler/package-info.java
index 6ffe873..6272741 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/compiler/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/compiler/package-info.java
@@ -21,7 +21,7 @@
* The {@code org.apache.sling.scripting.sightly.compiler} package defines the API exposed by the
* {@link org.apache.sling.scripting.sightly.compiler.SightlyCompiler}.
*/
-@Version("1.0.1")
+@Version("1.1.0")
package org.apache.sling.scripting.sightly.compiler;
import org.osgi.annotation.versioning.Version;
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerFrontend.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerFrontend.java
deleted file mode 100644
index d3cfd52..0000000
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerFrontend.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * 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.compiler;
-
-/**
- * HTL compiler frontend.
- */
-public interface CompilerFrontend {
-
- /**
- * Compile the source code to a stream of commands
- * @param stream the output stream
- * @param source the source code
- */
- void compile(PushStream stream, String source);
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
index 60b4247..6096c20 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/CompilerContext.java
@@ -19,7 +19,6 @@
package org.apache.sling.scripting.sightly.impl.compiler.frontend;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
-import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
@@ -47,10 +46,7 @@ public class CompilerContext {
}
public Expression adjustToContext(Expression expression, MarkupContext context, ExpressionContext expressionContext) {
- if (!expression.getOptions().containsKey(Syntax.CONTEXT_OPTION)) {
- return expressionWrapper.adjustToContext(expression, context, expressionContext);
- }
- return expression;
+ return expressionWrapper.adjustToContext(expression, context, expressionContext);
}
public PushStream getPushStream() {
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
index cf26b1c..78f03ff 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/ExpressionWrapper.java
@@ -21,16 +21,19 @@ package org.apache.sling.scripting.sightly.impl.compiler.frontend;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
+import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.compiler.Syntax;
+import org.apache.sling.scripting.sightly.impl.filter.AbstractFilter;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
import org.apache.sling.scripting.sightly.impl.filter.Filter;
-import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
/**
* This object wraps expressions in filter applications depending on options.
@@ -38,9 +41,13 @@ import org.apache.sling.scripting.sightly.compiler.expression.MarkupContext;
public class ExpressionWrapper {
private final List<Filter> filters;
+ private final Set<String> knownOptions;
+ private final PushStream stream;
- public ExpressionWrapper(List<Filter> filters) {
+ public ExpressionWrapper(PushStream stream, List<Filter> filters, Set<String> knownExpressionOptions) {
+ this.stream = stream;
this.filters = filters;
+ this.knownOptions = knownExpressionOptions;
}
public Expression transform(Interpolation interpolation, MarkupContext markupContext, ExpressionContext expressionContext) {
@@ -51,13 +58,21 @@ public class ExpressionWrapper {
nodes.add(new StringConstant(fragment.getText()));
} else {
Expression expression = fragment.getExpression();
+ if (AbstractFilter.NON_PARAMETRIZABLE_CONTEXTS.contains(expressionContext)) {
+ expression.getOptions().keySet().stream().filter(option -> !knownOptions.contains(option)).forEach(
+ unknownOption ->
+ stream.warn(
+ new PushStream.StreamMessage(String.format("Unknown option '%s'.", unknownOption), expression.getRawText())
+ )
+ );
+ }
Expression transformed = adjustToContext(expression, markupContext, expressionContext);
nodes.add(transformed.getRoot());
options.putAll(transformed.getOptions());
}
}
ExpressionNode root = join(nodes);
- if (interpolation.size() > 1 && options.containsKey(Syntax.CONTEXT_OPTION)) {
+ if (interpolation.size() > 1) {
//context must not be calculated by merging
options.remove(Syntax.CONTEXT_OPTION);
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java
index 9de45da..6759893 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/frontend/SimpleFrontend.java
@@ -21,8 +21,8 @@ package org.apache.sling.scripting.sightly.impl.compiler.frontend;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
-import org.apache.sling.scripting.sightly.impl.compiler.CompilerFrontend;
import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.filter.Filter;
import org.apache.sling.scripting.sightly.impl.html.dom.DocumentParser;
@@ -32,22 +32,23 @@ import org.apache.sling.scripting.sightly.impl.plugin.Plugin;
/**
* DOM-based compiler implementation
*/
-public class SimpleFrontend implements CompilerFrontend {
+public class SimpleFrontend {
private final Map<String, Plugin> plugins;
private final List<Filter> filters;
+ private final Set<String> knownExpressionOptions;
- public SimpleFrontend(List<Plugin> plugins, List<Filter> filters) {
+ public SimpleFrontend(List<Plugin> plugins, List<Filter> filters, Set<String> knownExpressionOptions) {
this.plugins = new HashMap<>();
this.filters = filters;
+ this.knownExpressionOptions = knownExpressionOptions;
for (Plugin plugin : plugins) {
this.plugins.put(plugin.name(), plugin);
}
}
- @Override
public void compile(PushStream stream, String source) {
- MarkupHandler markupHandler = new MarkupHandler(stream, plugins, filters);
+ MarkupHandler markupHandler = new MarkupHandler(stream, plugins, filters, knownExpressionOptions);
DocumentParser.parse(source, markupHandler);
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
index f72ded7..7bb94c7 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/AbstractFilter.java
@@ -18,8 +18,12 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
@@ -27,6 +31,24 @@ import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
public abstract class AbstractFilter implements Filter {
protected int priority = 100;
+ public static final Set<ExpressionContext> NON_PARAMETRIZABLE_CONTEXTS;
+ static {
+ Set<ExpressionContext> contexts = new HashSet<>(Arrays.asList(ExpressionContext.values()));
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_USE);
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE);
+ contexts.remove(ExpressionContext.PLUGIN_DATA_SLY_CALL);
+ NON_PARAMETRIZABLE_CONTEXTS = Collections.unmodifiableSet(contexts);
+ }
+
+ private final Set<ExpressionContext> applicableContexts;
+ private final Set<String> options;
+ private final Set<String> requiredOptions;
+
+ AbstractFilter(Set<ExpressionContext> applicableContexts, Set<String> options, Set<String> requiredOptions) {
+ this.applicableContexts = applicableContexts;
+ this.options = options;
+ this.requiredOptions = requiredOptions;
+ }
@Override
public int priority() {
@@ -43,6 +65,17 @@ public abstract class AbstractFilter implements Filter {
return 1;
}
+ @Override
+ public Expression apply(Expression expression, ExpressionContext expressionContext) {
+ Set<String> expressionOptions = expression.getOptions().keySet();
+ if (getApplicableContexts().contains(expressionContext) && expressionOptions.containsAll(getRequiredOptions())) {
+ return apply(expression, getFilterOptions(expression, getOptions()));
+ }
+ return expression;
+ }
+
+ protected abstract Expression apply(Expression expression, Map<String, ExpressionNode> options);
+
/**
* Collects the options passed in the {@code options} array into a new map while removing them from the original expression.
*
@@ -50,7 +83,7 @@ public abstract class AbstractFilter implements Filter {
* @param options the options of interest for the {@link Filter}
* @return a map with the retrieved options; the map can be empty if none of the options were found
*/
- protected Map<String, ExpressionNode> getFilterOptions(Expression expression, String... options) {
+ private Map<String, ExpressionNode> getFilterOptions(Expression expression, Set<String> options) {
Map<String, ExpressionNode> collector = new HashMap<>();
for (String option : options) {
ExpressionNode optionNode = expression.removeOption(option);
@@ -70,4 +103,19 @@ public abstract class AbstractFilter implements Filter {
public boolean equals(Object obj) {
return obj != null && this.getClass().equals(obj.getClass());
}
+
+ @Override
+ public Set<String> getOptions() {
+ return options;
+ }
+
+ @Override
+ public Set<String> getRequiredOptions() {
+ return requiredOptions;
+ }
+
+ @Override
+ public Set<ExpressionContext> getApplicableContexts() {
+ return applicableContexts;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
index 531e813..2c3e5fa 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/ExpressionContext.java
@@ -18,6 +18,13 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.sling.scripting.sightly.compiler.expression.Expression;
+
/**
* Defines a context for the {@link Expression} that will be processed by a {@link Filter}. The context can then be used by filters to
* further enhance the decision mechanism for their processing.
@@ -25,27 +32,34 @@ package org.apache.sling.scripting.sightly.impl.filter;
public enum ExpressionContext {
// Plugin contexts
- PLUGIN_DATA_SLY_USE,
- PLUGIN_DATA_SLY_TEXT,
- PLUGIN_DATA_SLY_ATTRIBUTE,
- PLUGIN_DATA_SLY_ELEMENT,
- PLUGIN_DATA_SLY_TEST,
- PLUGIN_DATA_SLY_SET,
- PLUGIN_DATA_SLY_LIST,
- PLUGIN_DATA_SLY_REPEAT,
- PLUGIN_DATA_SLY_INCLUDE,
- PLUGIN_DATA_SLY_RESOURCE,
- PLUGIN_DATA_SLY_TEMPLATE,
- PLUGIN_DATA_SLY_CALL,
- PLUGIN_DATA_SLY_UNWRAP,
+ PLUGIN_DATA_SLY_USE(Collections.emptySet()),
+ PLUGIN_DATA_SLY_TEXT(Collections.emptySet()),
+ PLUGIN_DATA_SLY_ATTRIBUTE(Collections.emptySet()),
+ PLUGIN_DATA_SLY_ELEMENT(Collections.emptySet()),
+ PLUGIN_DATA_SLY_TEST(Collections.emptySet()),
+ PLUGIN_DATA_SLY_SET(Collections.emptySet()),
+ PLUGIN_DATA_SLY_LIST(new HashSet<>(Arrays.asList("begin", "step", "end"))),
+ PLUGIN_DATA_SLY_REPEAT(new HashSet<>(Arrays.asList("begin", "step", "end"))),
+ PLUGIN_DATA_SLY_INCLUDE(new HashSet<>(Arrays.asList("appendPath", "prependPath", "file"))),
+ PLUGIN_DATA_SLY_RESOURCE(new HashSet<>(Arrays.asList("appendPath", "prependPath", "file", "selectors", "addSelectors",
+ "removeSelectors", "resourceType"))),
+ PLUGIN_DATA_SLY_TEMPLATE(Collections.emptySet()),
+ PLUGIN_DATA_SLY_CALL(Collections.emptySet()),
+ PLUGIN_DATA_SLY_UNWRAP(Collections.emptySet()),
// Markup contexts
- ELEMENT,
- TEXT,
- ATTRIBUTE;
+ ELEMENT(Collections.emptySet()),
+ TEXT(Collections.emptySet()),
+ ATTRIBUTE(Collections.emptySet());
private static final String PLUGIN_PREFIX = "PLUGIN_DATA_SLY_";
+ private final Set<String> options;
+
+ ExpressionContext(Set<String> options) {
+ this.options = options;
+ }
+
/**
* Retrieves the context for the plugin specified by {@code pluginName}.
*
@@ -57,4 +71,7 @@ public enum ExpressionContext {
return valueOf(PLUGIN_PREFIX + pluginName.toUpperCase());
}
+ public Set<String> getOptions() {
+ return options;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
index be239ef..4607df1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/Filter.java
@@ -18,6 +18,11 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
/**
@@ -45,4 +50,31 @@ public interface Filter extends Comparable<Filter> {
*/
int priority();
+ /**
+ * Provides the option names this {@code Filter} will process.
+ *
+ * @return a set of option names
+ */
+ default Set<String> getOptions() {
+ return Collections.emptySet();
+ }
+
+ /**
+ * Provides the option names that will trigger a filter's execution.
+ *
+ * @return the required options from an expression in order to trigger the filter
+ */
+ default Set<String> getRequiredOptions() {
+ return Collections.emptySet();
+ }
+
+ /**
+ * Provides the applicable contexts for this filter.
+ *
+ * @return the applicable contexts for this filter
+ */
+ default Set<ExpressionContext> getApplicableContexts() {
+ return new HashSet<>(Arrays.asList(ExpressionContext.values()));
+ }
+
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
index 1962dc1..21ab92a 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/FormatFilter.java
@@ -18,6 +18,11 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.MapLiteral;
@@ -30,7 +35,6 @@ public class FormatFilter extends AbstractFilter {
public static final String FORMAT_OPTION = "format";
public static final String TYPE_OPTION = "type";
- public static final String FORMAT_LOCALE_OPTION = "formatLocale";
public static final String TIMEZONE_OPTION = "timezone";
private static final class FormatFilterLoader {
@@ -38,6 +42,7 @@ public class FormatFilter extends AbstractFilter {
}
private FormatFilter() {
+ super(NON_PARAMETRIZABLE_CONTEXTS, new HashSet<>(Arrays.asList(FORMAT_OPTION, TYPE_OPTION, I18nFilter.LOCALE_OPTION, TIMEZONE_OPTION)), Collections.singleton(FORMAT_OPTION));
}
public static FormatFilter getInstance() {
@@ -45,21 +50,9 @@ public class FormatFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- //todo: if the expression is a string constant, we can produce the transformation at
- //compile time, with no need of a runtime function
- if (!expression.containsOption(FORMAT_OPTION) || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext
- == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode translation =
- new RuntimeCall(RuntimeCall.FORMAT, expression.getRoot(),
- new MapLiteral(getFilterOptions(expression,
- FORMAT_OPTION,
- TYPE_OPTION,
- I18nFilter.LOCALE_OPTION,
- FORMAT_LOCALE_OPTION,
- TIMEZONE_OPTION)));
+ new RuntimeCall(RuntimeCall.FORMAT, expression.getRoot(), new MapLiteral(options));
return expression.withNode(translation);
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
index 5275b13..9b2134f 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/I18nFilter.java
@@ -18,6 +18,9 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Map;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
@@ -40,9 +43,7 @@ public final class I18nFilter extends AbstractFilter {
}
private I18nFilter() {
- if (I18nFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
+ super(NON_PARAMETRIZABLE_CONTEXTS, new HashSet<>(Arrays.asList(I18N_OPTION, HINT_OPTION, LOCALE_OPTION, BASENAME_OPTION)), Collections.singleton(I18N_OPTION));
priority = 90;
}
@@ -51,16 +52,12 @@ public final class I18nFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if (!expression.containsOption(I18N_OPTION) || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext
- == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
+ ExpressionNode translation = new RuntimeCall(RuntimeCall.I18N, expression.getRoot(), new MapLiteral(options));
+ if (options.containsKey(LOCALE_OPTION)) {
+ // put back the locale option, in case it will be used by the FormatFilter
+ expression.getOptions().put(LOCALE_OPTION, options.get(LOCALE_OPTION));
}
- Map <String, ExpressionNode> options = getFilterOptions(expression, HINT_OPTION, LOCALE_OPTION, BASENAME_OPTION);
- ExpressionNode translation = new RuntimeCall(RuntimeCall.I18N, expression.getRoot(), new MapLiteral
- (options));
- expression.removeOption(I18N_OPTION);
- expression.getOptions().put(FormatFilter.FORMAT_LOCALE_OPTION, options.get(LOCALE_OPTION));
return expression.withNode(translation);
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
index 113b3f5..b84c8a2 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/JoinFilter.java
@@ -18,6 +18,10 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
@@ -28,15 +32,14 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
public class JoinFilter extends AbstractFilter {
public static final String JOIN_OPTION = "join";
+ private static final Set<String> OPTIONS = Collections.singleton(JOIN_OPTION);
private static final class JoinFilterLoader {
private static final JoinFilter INSTANCE = new JoinFilter();
}
private JoinFilter() {
- if (JoinFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
+ super(NON_PARAMETRIZABLE_CONTEXTS, OPTIONS, OPTIONS);
}
public static JoinFilter getInstance() {
@@ -44,13 +47,9 @@ public class JoinFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if (!expression.containsOption(JOIN_OPTION) || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext
- == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode translation =
- new RuntimeCall(RuntimeCall.JOIN, expression.getRoot(), expression.removeOption(JOIN_OPTION));
+ new RuntimeCall(RuntimeCall.JOIN, expression.getRoot(), options.get(JOIN_OPTION));
return expression.withNode(translation);
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
index 8ba4b22..028d795 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/URIManipulationFilter.java
@@ -18,7 +18,11 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
@@ -48,15 +52,26 @@ public class URIManipulationFilter extends AbstractFilter {
public static final String ADD_QUERY = "addQuery";
public static final String REMOVE_QUERY = "removeQuery";
+ private static final Set<ExpressionContext> APPLICABLE_CONTEXTS;
+
+ static {
+ Set<ExpressionContext> applicableContexts = new HashSet<>(Arrays.asList(ExpressionContext.values()));
+ applicableContexts.remove(ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE);
+ applicableContexts.remove(ExpressionContext.PLUGIN_DATA_SLY_CALL);
+ applicableContexts.remove(ExpressionContext.PLUGIN_DATA_SLY_RESOURCE);
+ applicableContexts.remove(ExpressionContext.PLUGIN_DATA_SLY_INCLUDE);
+ APPLICABLE_CONTEXTS = Collections.unmodifiableSet(applicableContexts);
+ }
+
private static final class URIManipulationFilterLoader {
private static final URIManipulationFilter INSTANCE = new URIManipulationFilter();
}
private URIManipulationFilter() {
- if (URIManipulationFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
+ super(APPLICABLE_CONTEXTS, new HashSet<>(Arrays.asList(SCHEME, DOMAIN, PATH, APPEND_PATH, PREPEND_PATH, SELECTORS,
+ ADD_SELECTORS, REMOVE_SELECTORS, EXTENSION, SUFFIX, PREPEND_SUFFIX, APPEND_SUFFIX, FRAGMENT, QUERY, ADD_QUERY,
+ REMOVE_QUERY)), Collections.emptySet());
}
public static URIManipulationFilter getInstance() {
@@ -64,27 +79,12 @@ public class URIManipulationFilter extends AbstractFilter {
}
@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(RuntimeCall.URI_MANIPULATION, expression.getRoot(), new MapLiteral(uriOptions));
- return expression.withNode(translation);
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
+ if (options.size() > 0) {
+ ExpressionNode translation =
+ new RuntimeCall(RuntimeCall.URI_MANIPULATION, expression.getRoot(), new MapLiteral(options));
+ return expression.withNode(translation);
}
return expression;
}
-
-
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
index f693102..a809300 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/filter/XSSFilter.java
@@ -18,6 +18,9 @@
******************************************************************************/
package org.apache.sling.scripting.sightly.impl.filter;
+import java.util.Collections;
+import java.util.Map;
+
import org.apache.sling.scripting.sightly.compiler.expression.Expression;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
@@ -33,9 +36,7 @@ public class XSSFilter extends AbstractFilter {
}
private XSSFilter() {
- if (XSSFilterLoader.INSTANCE != null) {
- throw new IllegalStateException("INSTANCE was already defined.");
- }
+ super(NON_PARAMETRIZABLE_CONTEXTS, Collections.emptySet(), Collections.emptySet());
priority = 110;
}
@@ -44,16 +45,11 @@ public class XSSFilter extends AbstractFilter {
}
@Override
- public Expression apply(Expression expression, ExpressionContext expressionContext) {
- if (expressionContext == ExpressionContext.PLUGIN_DATA_SLY_USE || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_TEMPLATE
- || expressionContext == ExpressionContext.PLUGIN_DATA_SLY_CALL) {
- return expression;
- }
+ protected Expression apply(Expression expression, Map<String, ExpressionNode> options) {
ExpressionNode context = expression.removeOption(Syntax.CONTEXT_OPTION);
if (context != null) {
return expression.withNode(new RuntimeCall(RuntimeCall.XSS, expression.getRoot(), context));
}
return expression;
}
-
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
index c8c4966..2a58176 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java
@@ -75,10 +75,10 @@ public class MarkupHandler {
private static final Set<String> URI_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("action", "cite",
"data", "formaction", "href", "manifest", "poster", "src")));
- public MarkupHandler(PushStream stream, Map<String, Plugin> pluginRegistry, List<Filter> filters) {
+ public MarkupHandler(PushStream stream, Map<String, Plugin> pluginRegistry, List<Filter> filters, Set<String> knownExpressionOptions) {
this.stream = stream;
this.pluginRegistry = pluginRegistry;
- this.expressionWrapper = new ExpressionWrapper(filters);
+ this.expressionWrapper = new ExpressionWrapper(stream, filters, knownExpressionOptions);
this.compilerContext = new CompilerContext(symbolGenerator, expressionWrapper, stream);
}
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
index 7d95e1d..902649c 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyCompilerTest.java
@@ -38,7 +38,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(PowerMockRunner.class)
-@PrepareForTest(SightlyCompiler.class)
public class SightlyCompilerTest {
private SightlyCompiler compiler = new SightlyCompiler();
@@ -51,7 +50,7 @@ public class SightlyCompilerTest {
@Test
public void testMissingExplicitContext() {
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -74,7 +73,7 @@ public class SightlyCompilerTest {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.lineSeparator()).thenReturn("\r\n");
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -85,7 +84,7 @@ public class SightlyCompilerTest {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.lineSeparator()).thenReturn("\r");
- for (String s : new String[] {"", "-win", "-mac"}) {
+ for (String s : new String[]{"", "-win", "-mac"}) {
String script = "/missing-explicit-context" + s + ".html";
testMissingExplicitContext(script);
}
@@ -129,8 +128,8 @@ public class SightlyCompilerTest {
}
// doubles
- double doubleTestRange = 20.00;
- for (double i = -1.00 * doubleTestRange; i < doubleTestRange; i+= 0.1) {
+ double doubleTestRange = 20.00;
+ for (double i = -1.00 * doubleTestRange; i < doubleTestRange; i += 0.1) {
assertEquals(0, compileSource("${" + i + "}").getErrors().size());
}
@@ -150,6 +149,17 @@ public class SightlyCompilerTest {
assertEquals(0, compileSource("${1e+2}").getErrors().size());
}
+ @Test
+ public void testUnknownExpressionOptions() {
+ assertEquals(0, compileSource("<sly data-sly-use.a=\"${com.example.Pojo @ param1=1, param2=2}\"></sly>").getWarnings().size());
+ assertEquals(0, compileSource("<sly data-sly-call=\"${myTemplate @ param1=1, param2=2}\"></sly>").getWarnings().size());
+ assertEquals(0, compileSource("<template data-sly-template.myTemplate=\"${@ param1, param2}\"></template>").getWarnings().size());
+ assertEquals(1, compileSource("${currentPage.title @ contex = 'scriptString'}").getWarnings().size());
+ assertEquals(1, compileSource("${a @ unknownOption}").getWarnings().size());
+ assertEquals(2, compileSource("${a @ unknownOption1, unknownOption2}").getWarnings().size());
+ assertEquals(1, compileSource("<div data-sly-text='${\"text\" @ i18nn}'>Replaced</div>").getWarnings().size());
+ }
+
private CompilationResult compileFile(final String file) {
InputStream stream = this.getClass().getResourceAsStream(file);
final Reader reader = new InputStreamReader(stream);
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
index 4eea958..ebeafa9 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/frontend/ExpressionWrapperTest.java
@@ -33,6 +33,7 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.NullLiteral;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.NumericConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
+import org.apache.sling.scripting.sightly.impl.compiler.PushStream;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.ExpressionWrapper;
import org.apache.sling.scripting.sightly.impl.compiler.frontend.Interpolation;
import org.apache.sling.scripting.sightly.impl.filter.ExpressionContext;
@@ -70,7 +71,7 @@ public class ExpressionWrapperTest {
options.put(I18nFilter.LOCALE_OPTION, new StringConstant("de"));
options.put(I18nFilter.I18N_OPTION, NullLiteral.INSTANCE);
interpolation.addExpression(new Expression(new StringConstant("hello"), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters, Collections.emptySet());
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 1);
RuntimeCall i18n = (RuntimeCall) xssArguments.get(0);
@@ -86,7 +87,7 @@ public class ExpressionWrapperTest {
formatArray.add(new StringConstant("Doe"));
options.put(FormatFilter.FORMAT_OPTION, new ArrayLiteral(formatArray));
interpolation.addExpression(new Expression(new StringConstant("Hello {0} {1}"), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters, Collections.emptySet());
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall format = (RuntimeCall) xssArguments.get(0);
@@ -102,7 +103,7 @@ public class ExpressionWrapperTest {
array.add(new NumericConstant(0));
array.add(new NumericConstant(1));
interpolation.addExpression(new Expression(new ArrayLiteral(array), options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters, Collections.emptySet());
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall join = (RuntimeCall) xssArguments.get(0);
@@ -138,7 +139,7 @@ public class ExpressionWrapperTest {
interpolation.addExpression(
new Expression(new StringConstant("http://www.example.com/resource.selector.extension/suffix#fragment?param=value"),
options));
- ExpressionWrapper wrapper = new ExpressionWrapper(filters);
+ ExpressionWrapper wrapper = new ExpressionWrapper(new PushStream(), filters, Collections.emptySet());
Expression result = wrapper.transform(interpolation, MarkupContext.TEXT, ExpressionContext.TEXT);
List<ExpressionNode> xssArguments = runOptionsAndXSSAssertions(result, 0);
RuntimeCall join = (RuntimeCall) xssArguments.get(0);