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 e65235ba JEXL-379: updated new syntax;
     new 5e0f56b8 Merge remote-tracking branch 'origin/master'
e65235ba is described below

commit e65235ba16d0a32b2e2591a590798de7600d0cfd
Author: henrib <hen...@apache.org>
AuthorDate: Sun Aug 21 10:06:47 2022 +0200

    JEXL-379: updated new syntax;
---
 .../java/org/apache/commons/jexl3/JexlContext.java |  13 ++
 .../apache/commons/jexl3/internal/Debugger.java    |   6 +
 .../apache/commons/jexl3/internal/Interpreter.java |  13 ++
 .../commons/jexl3/internal/ScriptVisitor.java      |   5 +
 .../jexl3/internal/introspection/ClassTool.java    |  13 +-
 .../introspection/SimpleClassNameSolver.java       | 157 +++++++++++++++++++++
 .../jexl3/parser/ASTQualifiedIdentifier.java       |  50 +++++++
 .../apache/commons/jexl3/parser/JexlParser.java    |  14 +-
 .../org/apache/commons/jexl3/parser/Parser.jjt     |  11 +-
 .../apache/commons/jexl3/parser/ParserVisitor.java |   2 +
 .../org/apache/commons/jexl3/Issues300Test.java    |  10 ++
 .../java/org/apache/commons/jexl3/ScriptTest.java  | 129 ++++++++++++++---
 src/test/scripts/httpPost.jexl                     |  59 ++++----
 13 files changed, 428 insertions(+), 54 deletions(-)

diff --git a/src/main/java/org/apache/commons/jexl3/JexlContext.java 
b/src/main/java/org/apache/commons/jexl3/JexlContext.java
index 67dc118f..06d7704f 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlContext.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlContext.java
@@ -90,6 +90,19 @@ public interface JexlContext {
         Object resolveNamespace(String name);
     }
 
+    /**
+     * A marker interface that solves a simple class name into a 
fully-qualified one.
+     * @since 3.3
+     */
+    interface ClassNameResolver {
+        /**
+         * Resolves a class name.
+         * @param name the simple class name
+         * @return the fully qualified class name
+         */
+        String resolveClassName(String name);
+    }
+
     /**
      * A marker interface of the JexlContext, NamespaceFunctor allows creating 
an instance
      * to delegate namespace methods calls to.
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java 
b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
index 196c0fcf..5031607f 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
@@ -1020,6 +1020,12 @@ public class Debugger extends ParserVisitor implements 
JexlInfo.Detail {
         return data;
     }
 
+    @Override
+    protected Object visit(ASTQualifiedIdentifier node, Object data) {
+        String img = node.getName();
+        return this.check(node, img, data);
+    }
+
     @Override
     protected Object visit(ASTStringLiteral node, Object data) {
         String img = StringParser.escapeString(node.getLiteral(), '\'');
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java 
b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
index 4ba5113b..a9a6a4e3 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -1125,6 +1125,19 @@ public class Interpreter extends InterpreterBase {
         return object;
     }
 
+    @Override
+    protected Object visit(final ASTQualifiedIdentifier node, final Object 
data) {
+        String name = node.getName();
+        if (context instanceof JexlContext.ClassNameResolver) {
+            JexlContext.ClassNameResolver resolver = 
(JexlContext.ClassNameResolver) context;
+            String fqcn = resolver.resolveClassName(name);
+            if (fqcn != null) {
+                return fqcn;
+            }
+        }
+        return name;
+    }
+
     /**
      * Evaluates an access identifier based on the 2 main implementations;
      * static (name or numbered identifier) or dynamic (jxlt).
diff --git a/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java 
b/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
index 9da2182d..70f26f30 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
@@ -472,4 +472,9 @@ public class ScriptVisitor extends ParserVisitor {
     protected Object visit(final ASTAnnotatedStatement node, final Object 
data) {
         return visitNode(node, data);
     }
+
+    @Override
+    protected Object visit(final ASTQualifiedIdentifier node, final Object 
data) {
+        return visitNode(node, data);
+    }
 }
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassTool.java 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassTool.java
index fb531b35..b4f93233 100644
--- 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassTool.java
+++ 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassTool.java
@@ -30,8 +30,9 @@ class ClassTool {
     private static final MethodHandle GET_PKGNAME;
     /** The Module.isExported(String packageName) method. */
     private static final MethodHandle IS_EXPORTED;
+
     static {
-        final MethodHandles.Lookup LOOKUP= MethodHandles.lookup();
+        final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
         MethodHandle getModule = null;
         MethodHandle getPackageName = null;
         MethodHandle isExported = null;
@@ -64,11 +65,12 @@ class ClassTool {
      * </code>
      * This is required since some classes and methods may not be exported 
thus not callable through
      * reflection.
+     *
      * @param declarator the class
      * @return true if class is exported or no module support exists
      */
     static boolean isExported(Class<?> declarator) {
-        if (IS_EXPORTED != null)  {
+        if (IS_EXPORTED != null) {
             try {
                 final Object module = GET_MODULE.invoke(declarator);
                 if (module != null) {
@@ -84,6 +86,7 @@ class ClassTool {
 
     /**
      * Gets the package name of a class (class.getPackage() may return null).
+     *
      * @param clz the class
      * @return the class package name
      */
@@ -94,13 +97,13 @@ class ClassTool {
             if (GET_PKGNAME != null) {
                 try {
                     return (String) GET_PKGNAME.invoke(clz);
-                } catch(Throwable xany) {
+                } catch (Throwable xany) {
                     return "";
                 }
             }
             // remove array
             Class<?> clazz = clz;
-            while(clazz.isArray()) {
+            while (clazz.isArray()) {
                 clazz = clazz.getComponentType();
             }
             // mimic getPackageName()
@@ -109,7 +112,7 @@ class ClassTool {
             }
             // remove enclosing
             Class<?> walk = clazz.getEnclosingClass();
-            while(walk != null) {
+            while (walk != null) {
                 clazz = walk;
                 walk = walk.getEnclosingClass();
             }
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/SimpleClassNameSolver.java
 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/SimpleClassNameSolver.java
new file mode 100644
index 00000000..918ae4d7
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/SimpleClassNameSolver.java
@@ -0,0 +1,157 @@
+/*
+ * 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.commons.jexl3.internal.introspection;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Helper solving a simple class name into a fully-qualified class name using 
packages.
+ */
+public class SimpleClassNameSolver {
+    /**
+     * The class loader.
+     */
+    private final ClassLoader loader;
+    /**
+     * A lock for RW concurrent ops.
+     */
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+    /**
+     * The set of packages to be used as import.
+     */
+    private final Set<String> imports = new LinkedHashSet<>();
+    /**
+     * The set of solved fqcns based on imports.
+     */
+    private final Map<String, String> fqcns = new HashMap<>();
+    /**
+     * Optional parent solver.
+     */
+    private final SimpleClassNameSolver parent;
+
+    /**
+     * Creates a class name solver.
+     *
+     * @param loader   the optional class loader
+     * @param packages the optional package names
+     */
+    public SimpleClassNameSolver(ClassLoader loader, List<String> packages) {
+        this.loader = loader == null ? 
SimpleClassNameSolver.class.getClassLoader() : loader;
+        if (packages != null) {
+            imports.addAll(packages);
+        }
+        this.parent = null;
+    }
+
+    /**
+     * Creates a class name solver.
+     * @param solver the parent solver
+     * @throws NullPointerException if parent solver is null
+     */
+    public SimpleClassNameSolver(SimpleClassNameSolver solver) {
+        if (solver == null) {
+            throw new NullPointerException("parent solver can not be null");
+        }
+        this.parent = solver;
+        this.loader = solver.loader;
+    }
+
+    /**
+     * Checks is a package is imported by this solver of one of its ascendants.
+     * @param pkg the package name
+     * @return true if an import exists for this package, false otherwise
+     */
+    boolean isImporting(String pkg) {
+        if (parent != null && parent.isImporting(pkg)) {
+            return true;
+        }
+        lock.readLock().lock();
+        try {
+            return imports.contains(pkg);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    /**
+     * Adds a list of packages as solving roots.
+     *
+     * @param packages the packages
+     */
+    public void addPackages(Collection<String> packages) {
+        if (packages != null) {
+            lock.writeLock().lock();
+            try {
+                if (parent == null) {
+                    imports.addAll(packages);
+                } else {
+                    for(String pkg : packages) {
+                        if (!parent.isImporting(pkg)) {
+                            imports.add(pkg);
+                        }
+                    }
+                }
+            } finally {
+                lock.writeLock().unlock();
+            }
+        }
+    }
+
+    /**
+     * Gets a fully qualified class name from a simple class name and imports.
+     *
+     * @param name the simple name
+     * @return the fqcn
+     */
+    public String getQualifiedName(String name) {
+        String fqcn;
+        if (parent != null && (fqcn = parent.getQualifiedName(name)) != null) {
+            return  fqcn;
+        }
+        lock.readLock().lock();
+        try {
+            fqcn = fqcns.get(name);
+        } finally {
+            lock.readLock().unlock();
+        }
+        if (fqcn == null) {
+            Class<?> clazz;
+            for (String pkg : imports) {
+                try {
+                    clazz = loader.loadClass(pkg + "." + name);
+                    lock.writeLock().lock();
+                    try {
+                        fqcns.put(name, fqcn = clazz.getName());
+                        break;
+                    } finally {
+                        lock.writeLock().unlock();
+                    }
+                } catch (ClassNotFoundException e) {
+                    // nope
+                }
+            }
+        }
+        return fqcn;
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/jexl3/parser/ASTQualifiedIdentifier.java 
b/src/main/java/org/apache/commons/jexl3/parser/ASTQualifiedIdentifier.java
new file mode 100644
index 00000000..a5610b4c
--- /dev/null
+++ b/src/main/java/org/apache/commons/jexl3/parser/ASTQualifiedIdentifier.java
@@ -0,0 +1,50 @@
+/*
+ * 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.commons.jexl3.parser;
+
+/**
+ * Identifiers, variables, ie symbols.
+ */
+public class ASTQualifiedIdentifier extends JexlNode {
+    protected String name = null;
+
+    ASTQualifiedIdentifier(final int id) {
+        super(id);
+    }
+
+    ASTQualifiedIdentifier(final Parser p, final int id) {
+        super(p, id);
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public void setName(String qualified) {
+        this.name = qualified;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Object jjtAccept(final ParserVisitor visitor, final Object data) {
+        return visitor.visit(this, data);
+    }
+}
diff --git a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java 
b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
index 2edef122..5ade580d 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
@@ -30,6 +30,7 @@ import java.util.ArrayDeque;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -517,7 +518,18 @@ public abstract class JexlParser extends StringParser {
                 namespaces.add(nsname);
             }
         }
-        pragmas.put(key, value);
+        Object previous = pragmas.put(key, value);
+        if (previous != null) {
+            Set<Object> values;
+            if (previous instanceof Set<?>) {
+                values = (Set<Object>) previous;
+            } else {
+                values = new LinkedHashSet<Object>();
+                pragmas.put(key, values);
+                values.add(previous);
+            }
+            values.add(value);
+        }
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt 
b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
index 074c8471..763ef4a5 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
+++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
@@ -916,9 +916,18 @@ void FunctionCall() #void : {}
     LOOKAHEAD(<IDENTIFIER> <LPAREN>) Identifier(true) Arguments() 
#FunctionNode(2)
 }
 
+void QualifiedIdentifier() #QualifiedIdentifier : {
+    LinkedList<String> lstr = new LinkedList<String>();
+}
+{
+    pragmaKey(lstr) { jjtThis.setName(stringify(lstr));}
+}
+
 void Constructor() #ConstructorNode : {}
 {
-  <NEW> <LPAREN> Expression() ( <COMMA> Expression() )* <RPAREN>
+  LOOKAHEAD(2) <NEW> <LPAREN> Expression() ( <COMMA> Expression() )* <RPAREN>
+  |
+  <NEW> QualifiedIdentifier()  <LPAREN> [ Expression() ( <COMMA> Expression() 
)* ] <RPAREN>
 }
 
 void Parameter() #void :
diff --git a/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java 
b/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
index e457c417..66479e23 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
@@ -207,4 +207,6 @@ public abstract class ParserVisitor {
     protected abstract Object visit(ASTAnnotation node, Object data);
 
     protected abstract Object visit(ASTAnnotatedStatement node, Object data);
+
+    protected abstract Object visit(final ASTQualifiedIdentifier node, final 
Object data);
 }
diff --git a/src/test/java/org/apache/commons/jexl3/Issues300Test.java 
b/src/test/java/org/apache/commons/jexl3/Issues300Test.java
index 12187785..e223080d 100644
--- a/src/test/java/org/apache/commons/jexl3/Issues300Test.java
+++ b/src/test/java/org/apache/commons/jexl3/Issues300Test.java
@@ -874,4 +874,14 @@ public class Issues300Test {
         DOMICILE
     }
 
+
+    @Test
+    public void test377() {
+        String text = "function add(x, y) { x + y } add(a, b)";
+        JexlEngine jexl = new JexlBuilder().safe(true).create();
+        JexlScript script = jexl.createScript(text, "a", "b");
+        Object result = script.execute(null, 20, 22);
+        Assert.assertEquals(42, result);
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/jexl3/ScriptTest.java 
b/src/test/java/org/apache/commons/jexl3/ScriptTest.java
index fb9f0e65..0cc79c75 100644
--- a/src/test/java/org/apache/commons/jexl3/ScriptTest.java
+++ b/src/test/java/org/apache/commons/jexl3/ScriptTest.java
@@ -16,16 +16,27 @@
  */
 package org.apache.commons.jexl3;
 
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import org.apache.commons.jexl3.internal.introspection.SimpleClassNameSolver;
+import org.junit.Assert;
+import org.junit.Test;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
 import java.net.URL;
-
-import org.junit.Assert;
-import org.junit.Test;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.function.Function;
 
 /**
  * Tests for JexlScript
@@ -83,26 +94,81 @@ public class ScriptTest extends JexlTestCase {
         Assert.assertEquals("getText is wrong", code, s.getSourceText());
     }
 
+    static class ImportContext extends MapContext implements 
JexlContext.ClassNameResolver, JexlContext.PragmaProcessor {
+        private final SimpleClassNameSolver solver;
+        ImportContext(SimpleClassNameSolver parent) {
+            solver = new SimpleClassNameSolver(parent);
+        }
+
+        @Override
+        public String resolveClassName(String name) {
+            return name.indexOf('.') < 0 ? solver.getQualifiedName(name) : 
name;
+        }
+
+        @Override
+        public void processPragma(String key, Object value) {
+            processPragma(null, key, value);
+        }
+
+        @Override
+        public void processPragma(JexlOptions opts, String key, Object value) {
+            if ("jexl.import".equals(key)) {
+                if (value instanceof Collection<?>) {
+                    for(Object pkg : ((Collection<?>) value)) {
+                        
solver.addPackages(Collections.singletonList(pkg.toString()));
+                    }
+                } else {
+                    
solver.addPackages(Collections.singletonList(value.toString()));
+                }
+            }
+        }
+    }
+
     @Test
     public void testScriptJsonFromFileJexl() {
-        final File testScript = new File(TEST_JSON);
-        final JexlScript s = JEXL.createScript(testScript);
-        final JexlContext jc = new MapContext();
-        jc.set("httpr", new HttpPostRequest());
-        Object result = s.execute(jc);
-        Assert.assertNotNull(result);
-        Assert.assertEquals("{  \"id\": 101}", result);
+        SimpleClassNameSolver baseSolver = new SimpleClassNameSolver(null, 
Arrays.asList("java.lang"));
+        HttpServer server = null;
+        try {
+            final String response = "{  \"id\": 101}";
+            server = createJsonServer(h -> response);
+            final File httprFile = new File(TEST_JSON);
+            final JexlScript httprScript = JEXL.createScript(httprFile);
+            final JexlContext jc = new ImportContext(baseSolver);
+            Object httpr = httprScript.execute(jc);
+            final JexlScript s = 
JEXL.createScript("(httpr,url)->httpr.execute(url, null)");
+            //jc.set("httpr", new HttpPostRequest());
+            Object result = s.execute(jc, httpr, "http://localhost:8001/test";);
+            Assert.assertNotNull(result);
+            Assert.assertEquals(response, result);
+        } catch(IOException xio) {
+            Assert.fail(xio.getMessage());
+        } finally {
+            if (server != null) {
+                server.stop(0);
+            }
+        }
     }
 
     @Test
     public void testScriptJsonFromFileJava() {
-        final String testScript 
="httpr.execute('https://jsonplaceholder.typicode.com/posts', null)";
-        final JexlScript s = JEXL.createScript(testScript);
-        final JexlContext jc = new MapContext();
-        jc.set("httpr", new HttpPostRequest());
-        Object result = s.execute(jc);
-        Assert.assertNotNull(result);
-        Assert.assertEquals("{  \"id\": 101}", result);
+        HttpServer server = null;
+        try {
+            final String response = "{  \"id\": 101}";
+            server = createJsonServer(h -> response);
+            final String testScript = 
"httpr.execute('http://localhost:8001/test', null)";
+            final JexlScript s = JEXL.createScript(testScript);
+            final JexlContext jc = new MapContext();
+            jc.set("httpr", new HttpPostRequest());
+            Object result = s.execute(jc);
+            Assert.assertNotNull(result);
+            Assert.assertEquals(response, result);
+        } catch(IOException xio) {
+            Assert.fail(xio.getMessage());
+        } finally {
+            if (server != null) {
+                server.stop(0);
+            }
+        }
     }
 
     /**
@@ -151,6 +217,35 @@ public class ScriptTest extends JexlTestCase {
         return response.toString();
     }
 
+    /**
+     * Creates a simple local http server.
+     * <p>Only handles POST request on /test</p>
+     * @return the server
+     * @throws IOException
+     */
+    static HttpServer createJsonServer(final Function<HttpExchange, String> 
responder) throws IOException {
+        HttpServer server = HttpServer.create(new 
InetSocketAddress("localhost", 8001), 0);
+        ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) 
Executors.newFixedThreadPool(1);
+        server.createContext("/test", new HttpHandler() {
+            @Override
+            public void handle(HttpExchange httpExchange) throws IOException {
+                if ("POST".equals(httpExchange.getRequestMethod())) {
+                    OutputStream outputStream = httpExchange.getResponseBody();
+                    String json = responder.apply(httpExchange);
+                    httpExchange.sendResponseHeaders(200, json.length());
+                    outputStream.write(json.toString().getBytes());
+                    outputStream.flush();
+                    outputStream.close();
+                } else {
+                    // error
+                    httpExchange.sendResponseHeaders(500, 0);
+                }
+            }
+        });
+        server.setExecutor(threadPoolExecutor);
+        server.start();
+        return server;
+    }
 
     @Test
     public void testScriptFromFile() {
diff --git a/src/test/scripts/httpPost.jexl b/src/test/scripts/httpPost.jexl
index 5f106203..7c6bbe6b 100644
--- a/src/test/scripts/httpPost.jexl
+++ b/src/test/scripts/httpPost.jexl
@@ -17,37 +17,36 @@
 //-------------------------------------------------------------------
 // send a POST Request
 //-------------------------------------------------------------------
+#pragma jexl.import  java.net
+#pragma jexl.import  java.io
+{
+    "execute" : (sURL, jsonData) -> {
+        let url = new URL(sURL);
+        let con = url.openConnection();
+        con.setRequestMethod("POST");
+        con.setRequestProperty("Accept", "application/json");
 
-var httpPostRequest = (sURL, jsonData) -> {
-  var url = new("java.net.URL", sURL);
-  var con = url.openConnection();
-  con.setRequestMethod("POST");
-  con.setRequestProperty("Accept", "application/json");
+        // send data
+        if (jsonData != null) {
+            con.setRequestProperty("Content-Type", "application/json; utf-8");
+            con.setDoOutput(true);
+            let outputStream = con.getOutputStream();
+            let input = jsonData.getBytes("utf-8");
+            outputStream.write(input, 0, size(input));
+        }
 
-  // send data
-  if ( jsonData != null ) {
-    con.setRequestProperty("Content-Type", "application/json; utf-8");
-    con.setDoOutput(true);
-
-    var outputStream = con.getOutputStream();
-    var input = jsonData.getBytes("utf-8");
-    outputStream.write(input, 0, size(input));
-  }
-
-  // read response
-  var responseCode = con.getResponseCode();
-  var inputStream = null;
-  inputStream =  con.getInputStream();
-  var response = new("java.lang.StringBuffer");
-  if (inputStream != null) {
-    var in = new("java.io.BufferedReader", new("java.io.InputStreamReader", 
inputStream));
-    var inputLine = "";
-    while ((inputLine = in.readLine()) != null) {
-      response.append(inputLine);
+        // read response
+        let responseCode = con.getResponseCode();
+        let inputStream = con.getInputStream();
+        let response = new StringBuffer();
+        if (inputStream != null) {
+            let in = new BufferedReader(new InputStreamReader(inputStream));
+            var inputLine = "";
+            while ((inputLine = in.readLine()) != null) {
+                response.append(inputLine);
+            }
+            in.close();
+        }
+        response.toString();
     }
-    in.close();
-  }
-  response.toString();
 }
-
-httpPostRequest("https://jsonplaceholder.typicode.com/posts";);

Reply via email to