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 2020/08/30 14:45:03 UTC
[commons-jexl] branch master updated: JEXL-333: fixed namespace
resolution on static only (private ctor) classes Task #JEXL-333 - Allow
declaration of namespace within script
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 89a8d63 JEXL-333: fixed namespace resolution on static only (private ctor) classes Task #JEXL-333 - Allow declaration of namespace within script
89a8d63 is described below
commit 89a8d635a946edc111c7e57c18009ffc0ccdae6d
Author: henrib <he...@apache.org>
AuthorDate: Sun Aug 30 16:44:29 2020 +0200
JEXL-333: fixed namespace resolution on static only (private ctor) classes
Task #JEXL-333 - Allow declaration of namespace within script
---
.../java/org/apache/commons/jexl3/JexlOptions.java | 2 +-
.../org/apache/commons/jexl3/internal/Engine.java | 8 ++-
.../commons/jexl3/internal/InterpreterBase.java | 28 +++++++-
.../java/org/apache/commons/jexl3/PragmaTest.java | 84 ++++++++++++++++++++++
4 files changed, 118 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/apache/commons/jexl3/JexlOptions.java b/src/main/java/org/apache/commons/jexl3/JexlOptions.java
index 78e274c..e54985e 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlOptions.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlOptions.java
@@ -40,7 +40,7 @@ import org.apache.commons.jexl3.internal.Engine;
* @since 3.2
*/
public final class JexlOptions {
- /** The shared isntance bit. */
+ /** The shared instance bit. */
private static final int SHARED = 7;
/** The local shade bit. */
private static final int SHADE = 6;
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 ec8484f..ec2e58b 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Engine.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
@@ -398,11 +398,15 @@ public class Engine extends JexlEngine {
// jexl.namespace.***
String nsname = key.substring(PRAGMA_JEXLNS.length());
if (nsname != null && !nsname.isEmpty()) {
- String nsclass = value.toString();
if (ns == null) {
ns = new HashMap<>(functions);
}
- ns.put(nsname, nsclass);
+ String nsclass = value.toString();
+ try {
+ ns.put(nsname, uberspect.getClassLoader().loadClass(nsclass));
+ } catch (ClassNotFoundException e) {
+ ns.put(nsname, nsclass);
+ }
}
}
}
diff --git a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
index b56245a..557ca19 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
@@ -200,6 +200,7 @@ public abstract class InterpreterBase extends ParserVisitor {
}
}
if (functor == null) {
+ // find a ctor with that context class
JexlMethod ctor = uberspect.getConstructor(namespace, context);
if (ctor != null) {
try {
@@ -211,13 +212,38 @@ public abstract class InterpreterBase extends ParserVisitor {
throw new JexlException(node, "unable to instantiate namespace " + prefix, xinst);
}
}
+ // find a ctor with no arg
+ if (functor == null) {
+ ctor = uberspect.getConstructor(namespace);
+ if (ctor != null) {
+ try {
+ functor = ctor.invoke(namespace);
+ } catch (Exception xinst) {
+ throw new JexlException(node, "unable to instantiate namespace " + prefix, xinst);
+ }
+ }
+ // use a class, namespace of static methods
+ if (functor == null) {
+ // try to find a class with that name
+ if (namespace instanceof String) {
+ try {
+ functor = uberspect.getClassLoader().loadClass((String) namespace);
+ } catch (ClassNotFoundException xignore) {
+ // not a class
+ namespace = null;
+ }
+ } else { // we know its a class
+ functor = (Class<?>) namespace;
+ }
+ }
+ }
}
}
// got a functor, store it and return it
if (functor != null) {
synchronized (this) {
if (functors == null) {
- functors = new HashMap<String, Object>();
+ functors = new HashMap<>();
}
functors.put(prefix, functor);
}
diff --git a/src/test/java/org/apache/commons/jexl3/PragmaTest.java b/src/test/java/org/apache/commons/jexl3/PragmaTest.java
index 713acf7..03a8bd2 100644
--- a/src/test/java/org/apache/commons/jexl3/PragmaTest.java
+++ b/src/test/java/org/apache/commons/jexl3/PragmaTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.jexl3;
+import java.util.Collections;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
@@ -77,6 +78,14 @@ public class PragmaTest extends JexlTestCase {
}
}
}
+
+ public void sleep(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
}
@Test
@@ -98,4 +107,79 @@ public class PragmaTest extends JexlTestCase {
// ok, expected
}
}
+
+
+ public static class StaticSleeper {
+ // precludes instantiation
+ private StaticSleeper() {}
+
+ public static void sleep(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ }
+
+ public static class Sleeper {
+ public void sleep(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ }
+
+ @Test
+ @SuppressWarnings("AssertEqualsBetweenInconvertibleTypes")
+ public void testStaticNamespacePragma() throws Exception {
+ SafeContext jc = new SafeContext();
+ JexlScript script = JEXL.createScript(
+ "#pragma jexl.namespace.sleeper " + StaticSleeper.class.getName() + "\n"
+ + "sleeper:sleep(100);"
+ + "42");
+ Object result = script.execute(jc);
+ Assert.assertEquals(42, result);
+ }
+
+ @Test
+ @SuppressWarnings("AssertEqualsBetweenInconvertibleTypes")
+ public void testStatictNamespacePragmaCtl() throws Exception {
+ Map<String, Object> ns = Collections.singletonMap("sleeper", StaticSleeper.class.getName());
+ JexlEngine jexl = new JexlBuilder().namespaces(ns).create();
+ SafeContext jc = new SafeContext();
+ JexlScript script = jexl.createScript(
+ "sleeper:sleep(100);"
+ + "42");
+ Object result = script.execute(jc);
+ Assert.assertEquals(42, result);
+ }
+
+ @Test
+ @SuppressWarnings("AssertEqualsBetweenInconvertibleTypes")
+ public void testNamespacePragma() throws Exception {
+ SafeContext jc = new SafeContext();
+ JexlScript script = JEXL.createScript(
+ "#pragma jexl.namespace.sleeper " + Sleeper.class.getName() + "\n"
+ + "sleeper:sleep(100);"
+ + "42");
+ Object result = script.execute(jc);
+ Assert.assertEquals(42, result);
+ }
+
+ @Test
+ @SuppressWarnings("AssertEqualsBetweenInconvertibleTypes")
+ public void testNamespacePragmaCtl() throws Exception {
+ Map<String, Object> ns = Collections.singletonMap("sleeper", Sleeper.class.getName());
+ JexlEngine jexl = new JexlBuilder().namespaces(ns).create();
+ SafeContext jc = new SafeContext();
+ JexlScript script = jexl.createScript(
+ "sleeper:sleep(100);"
+ + "42");
+ Object result = script.execute(jc);
+ Assert.assertEquals(42, result);
+ }
+
}