You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2019/12/18 15:59:57 UTC
[commons-jexl] branch master updated: JEXL-307: nitpicking on
options handling Task #JEXL-307 - Variable redeclaration option
This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new 676448c JEXL-307: nitpicking on options handling Task #JEXL-307 - Variable redeclaration option
676448c is described below
commit 676448c88b58ed49a97f7284d5dcee57258da08f
Author: henrib <he...@apache.org>
AuthorDate: Wed Dec 18 16:59:25 2019 +0100
JEXL-307: nitpicking on options handling
Task #JEXL-307 - Variable redeclaration option
---
.../java/org/apache/commons/jexl3/JexlContext.java | 2 +
.../org/apache/commons/jexl3/internal/Engine.java | 76 +++++++---------------
.../org/apache/commons/jexl3/internal/Script.java | 33 ++++++++--
.../java/org/apache/commons/jexl3/LexicalTest.java | 60 +++++++++++++++++
4 files changed, 113 insertions(+), 58 deletions(-)
diff --git a/src/main/java/org/apache/commons/jexl3/JexlContext.java b/src/main/java/org/apache/commons/jexl3/JexlContext.java
index 7a9c828..2f8371b 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlContext.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlContext.java
@@ -147,6 +147,7 @@ public interface JexlContext {
/**
* A marker interface of the JexlContext that exposes runtime evaluation options.
+ * @since 3.2
*/
interface OptionsHandle {
/**
@@ -183,6 +184,7 @@ public interface JexlContext {
* of its cancellation through the context. It uses the same interpreter logic
* that reacts to cancellation and is an alternative to using callable() and/or
* interrupting script interpreter threads.
+ * @since 3.2
*/
interface CancellationHandle {
/**
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Engine.java b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
index 2b96b98..d3ac4c3 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Engine.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
@@ -301,14 +301,25 @@ public class Engine extends JexlEngine {
}
/**
+ * Solves an optional option.
+ * @param conf the option as configured, may be null
+ * @param def the default value if null, shall not be null
+ * @param <T> the option type
+ * @return conf or def
+ */
+ private static <T> T option(T conf, T def) {
+ return conf == null? def : conf;
+ }
+
+ /**
* Extracts the engine evaluation options from context if available, the engine
* options otherwise.
- * <p>This creates a copy of the options so they are immutable during
- * execution.
+ * <p>If the context is a options handle and the handled options shared instance flag
+ * is false, this method creates a copy of the options making them immutable during execution.
* @param context the context
* @return the options if any
*/
- JexlOptions options(JexlContext context) {
+ protected JexlOptions options(JexlContext context) {
// Make a copy of the handled options if any
if (context instanceof JexlContext.OptionsHandle) {
JexlOptions jexlo = ((JexlContext.OptionsHandle) context).getEngineOptions();
@@ -333,14 +344,15 @@ public class Engine extends JexlEngine {
}
/**
- * Solves an optional option.
- * @param conf the option as configured, may be null
- * @param def the default value if null, shall not be null
- * @param <T> the option type
- * @return conf or def
+ * Sets options from this engine options.
+ * @param opts the options to set
+ * @return the options
*/
- private static <T> T option(T conf, T def) {
- return conf == null? def : conf;
+ public JexlOptions optionsSet(JexlOptions opts) {
+ if (opts != null) {
+ opts.set(options);
+ }
+ return opts;
}
@Override
@@ -356,50 +368,6 @@ public class Engine extends JexlEngine {
}
/**
- * Sets options from this engine options.
- * @param opts the options to set
- * @return the options
- */
- public JexlOptions optionsSet(JexlOptions opts) {
- if (opts != null) {
- opts.set(options);
- }
- return opts;
- }
-
- /**
- * Creates a script evaluation options.
- * <p>This also calls the pragma processor if any
- * @param script the script
- * @param context the context
- * @return the options
- */
- protected JexlOptions createOptions(Script script, JexlContext context) {
- JexlOptions opts = options(context);
- Map<String, Object> pragmas = script.getPragmas();
- if (pragmas != null) {
- JexlContext.PragmaProcessor processor =
- context instanceof JexlContext.PragmaProcessor
- ? (JexlContext.PragmaProcessor) context
- : null;
- for(Map.Entry<String, Object> pragma : pragmas.entrySet()) {
- String key = pragma.getKey();
- Object value = pragma.getValue();
- if (PRAGMA_OPTIONS.equals(key)) {
- if (value instanceof String) {
- String[] vs = ((String) value).split(" ");
- opts.setFlags(vs);
- }
- }
- if (processor != null) {
- processor.processPragma(key, value);
- }
- }
- }
- return opts;
- }
-
- /**
* Creates an interpreter.
* @param context a JexlContext; if null, the empty context is used instead.
* @param frame the interpreter frame
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Script.java b/src/main/java/org/apache/commons/jexl3/internal/Script.java
index 5b1f53d..2baa25c 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Script.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Script.java
@@ -50,6 +50,10 @@ public class Script implements JexlScript, JexlExpression {
* The engine version (as class loader change count) that last evaluated this script.
*/
protected int version;
+ /**
+ * The name of the options pragma.
+ */
+ protected static final String PRAGMA_OPTIONS = "jexl.options";
/**
* @return the script AST
@@ -101,13 +105,13 @@ public class Script implements JexlScript, JexlExpression {
}
/**
- * Creates this script options for evaluation.
+ * Compute this script options for evaluation.
* <p>This also calls the pragma processor
* @param context the context
* @return the options
*/
- protected JexlOptions createOptions(JexlContext context) {
- JexlOptions opts = jexl.createOptions(this, context);
+ protected JexlOptions options(JexlContext context) {
+ JexlOptions opts = jexl.options(context);
// when parsing lexical, try hard to run lexical
JexlFeatures features = script.getFeatures();
if (features != null) {
@@ -118,6 +122,27 @@ public class Script implements JexlScript, JexlExpression {
opts.setLexicalShade(true);
}
}
+ // process script pragmas if any
+ Map<String, Object> pragmas = script.getPragmas();
+ if (pragmas != null) {
+ JexlContext.PragmaProcessor processor =
+ context instanceof JexlContext.PragmaProcessor
+ ? (JexlContext.PragmaProcessor) context
+ : null;
+ for(Map.Entry<String, Object> pragma : pragmas.entrySet()) {
+ String key = pragma.getKey();
+ Object value = pragma.getValue();
+ if (PRAGMA_OPTIONS.equals(key)) {
+ if (value instanceof String) {
+ String[] vs = ((String) value).split(" ");
+ opts.setFlags(vs);
+ }
+ }
+ if (processor != null) {
+ processor.processPragma(key, value);
+ }
+ }
+ }
return opts;
}
@@ -128,7 +153,7 @@ public class Script implements JexlScript, JexlExpression {
* @return the interpreter
*/
protected Interpreter createInterpreter(JexlContext context, Frame frame) {
- return jexl.createInterpreter(context, frame, createOptions(context));
+ return jexl.createInterpreter(context, frame, options(context));
}
/**
diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
index cbdde4f..eac41eb 100644
--- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java
+++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
@@ -554,4 +554,64 @@ public class LexicalTest {
Object o = e.execute(ctxt);
Assert.assertEquals(0, o);
}
+
+ public static class VarContext extends MapContext implements JexlContext.PragmaProcessor, JexlContext.OptionsHandle {
+ private JexlOptions options = new JexlOptions();
+
+ JexlOptions snatchOptions() {
+ JexlOptions o = options;
+ options = new JexlOptions();
+ return o;
+}
+
+ @Override
+ public void processPragma(String key, Object value) {
+ if ("jexl.options".equals(key) && "canonical".equals(value)) {
+ options.setStrict(true);
+ options.setLexical(true);
+ options.setLexicalShade(true);
+ options.setSafe(false);
+ }
+ }
+
+ @Override
+ public JexlOptions getEngineOptions() {
+ return options;
+ }
+ }
+
+
+ @Test
+ public void testOptionsPragma() throws Exception {
+ try {
+ JexlOptions.setDefaultFlags("+safe", "-lexical", "-lexicalShade");
+ VarContext vars = new VarContext();
+ JexlEngine jexl = new JexlBuilder().create();
+ int n42;
+ JexlOptions o;
+
+ n42 = (Integer) jexl.createScript("#pragma jexl.options none\n-42").execute(vars);
+ Assert.assertEquals(-42, n42);
+ o = vars.snatchOptions();
+ Assert.assertNotNull(o);
+ Assert.assertTrue(o.isStrict());
+ Assert.assertTrue(o.isSafe());
+ Assert.assertTrue(o.isCancellable());
+ Assert.assertFalse(o.isLexical());
+ Assert.assertFalse(o.isLexicalShade());
+
+ n42 = (Integer) jexl.createScript("#pragma jexl.options canonical\n42").execute(vars);
+ Assert.assertEquals(42, n42);
+ o = vars.snatchOptions();
+ Assert.assertNotNull(o);
+ Assert.assertTrue(o.isStrict());
+ Assert.assertFalse(o.isSafe());
+ Assert.assertTrue(o.isCancellable());
+ Assert.assertTrue(o.isLexical());
+ Assert.assertTrue(o.isLexicalShade());
+ Assert.assertFalse(o.isSharedInstance());
+ } finally {
+ JexlOptions.setDefaultFlags("-safe", "+lexical");
+ }
+ }
}