You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2017/02/20 16:58:54 UTC
[04/12] ant git commit: Scriptdef task new options : 'compiled' (if
javax.script engine implements Compilable), 'encoding' to load resources
Scriptdef task new options : 'compiled' (if javax.script engine implements Compilable), 'encoding' to load resources
Project: http://git-wip-us.apache.org/repos/asf/ant/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant/commit/4bd9b4a6
Tree: http://git-wip-us.apache.org/repos/asf/ant/tree/4bd9b4a6
Diff: http://git-wip-us.apache.org/repos/asf/ant/diff/4bd9b4a6
Branch: refs/heads/master
Commit: 4bd9b4a6e473a9188124989315f75b778ad2a363
Parents: 526df1e
Author: pyxide <op...@gmail.com>
Authored: Fri Jan 13 17:16:50 2017 +0100
Committer: Stefan Bodewig <bo...@apache.org>
Committed: Mon Feb 20 17:41:37 2017 +0100
----------------------------------------------------------------------
.../ant/taskdefs/optional/script/ScriptDef.java | 22 +++-
.../apache/tools/ant/util/ScriptRunnerBase.java | 87 +++++++++++++--
.../tools/ant/util/ScriptRunnerHelper.java | 40 +++++++
.../ant/util/optional/JavaxScriptRunner.java | 108 ++++++++++++++++---
4 files changed, 230 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ant/blob/4bd9b4a6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
index ac9eb88..3f40a14 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
@@ -67,7 +67,7 @@ public class ScriptDef extends DefBase {
/**
* Set the project.
- * @param project the project that this def belows to.
+ * @param project the project that this definition belongs to.
*/
public void setProject(Project project) {
super.setProject(project);
@@ -237,7 +237,6 @@ public class ScriptDef extends DefBase {
+ "attributes");
}
-
nestedElementMap.put(nestedElement.name, nestedElement);
}
@@ -368,6 +367,15 @@ public class ScriptDef extends DefBase {
}
/**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setCompiled(boolean compiled) {
+ helper.setCompiled(compiled);
+ }
+
+ /**
* Load the script from an external file ; optional.
*
* @param file the file containing the script source.
@@ -377,6 +385,15 @@ public class ScriptDef extends DefBase {
}
/**
+ * Set the encoding of the script from an external file ; optional.
+ *
+ * @param encoding the encoding of the file containing the script source.
+ */
+ public void setEncoding(String encoding) {
+ helper.setEncoding(encoding);
+ }
+
+ /**
* Set the script text.
*
* @param text a component of the script text to be added.
@@ -394,4 +411,3 @@ public class ScriptDef extends DefBase {
helper.add(resource);
}
}
-
http://git-wip-us.apache.org/repos/asf/ant/blob/4bd9b4a6/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java b/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
index b8aa01a..ac08f98 100644
--- a/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
+++ b/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
@@ -19,12 +19,13 @@ package org.apache.tools.ant.util;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -34,6 +35,8 @@ import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.PropertyResource;
+import org.apache.tools.ant.types.resources.StringResource;
/**
* This is a common abstract base case for script runners.
@@ -51,6 +54,11 @@ public abstract class ScriptRunnerBase {
/** Script content */
private String script = "";
+ private String encoding;
+
+ /** Enable script compilation. */
+ private boolean compiled;
+
/** Project this runner is used in */
private Project project;
@@ -187,7 +195,35 @@ public abstract class ScriptRunnerBase {
}
/**
+ * Whether to use script compilation if available.
+ * @since Ant 1.10.1
+ * @param compiled if true, compile the script if possible.
+ */
+ public final void setCompiled(boolean compiled) {
+ this.compiled = compiled;
+ }
+
+ /**
+ * Get the compiled attribute.
+ * @since Ant 1.10.1
+ * @return the attribute.
+ */
+ public final boolean getCompiled() {
+ return compiled;
+ }
+
+ /**
+ * Set encoding of the script from an external file; optional.
+ * @since Ant 1.10.1
+ * @param encoding encoding of the external file containing the script source.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
* Load the script from an external file; optional.
+ * @since Ant 1.10.1
* @param file the file containing the script source.
*/
public void setSrc(File file) {
@@ -195,12 +231,19 @@ public abstract class ScriptRunnerBase {
if (!file.exists()) {
throw new BuildException("file " + filename + " not found.");
}
+ InputStream in = null;
try {
- readSource(new FileReader(file), filename);
+ in = new FileInputStream(file);
} catch (FileNotFoundException e) {
//this can only happen if the file got deleted a short moment ago
throw new BuildException("file " + filename + " not found.");
}
+
+ try {
+ readSource(in, filename);
+ } finally {
+ FileUtils.close(in);
+ }
}
/**
@@ -208,19 +251,25 @@ public abstract class ScriptRunnerBase {
* @param reader the reader; this is closed afterwards.
* @param name the name to use in error messages
*/
- private void readSource(Reader reader, String name) {
- BufferedReader in = null;
+ private void readSource(InputStream in, String name) {
+ Reader reader = null;
try {
- in = new BufferedReader(reader);
- script += FileUtils.safeReadFully(in);
+ if (null == encoding) {
+ reader = new InputStreamReader(in);
+ } else {
+ reader = new InputStreamReader(in, encoding);
+ }
+ reader = new BufferedReader(reader);
+ script += FileUtils.safeReadFully(reader);
+ } catch(UnsupportedEncodingException e) {
+ throw new BuildException("Failed to decode " + name + " with encoding " + encoding, e);
} catch (IOException ex) {
throw new BuildException("Failed to read " + name, ex);
} finally {
- FileUtils.close(in);
+ FileUtils.close(reader);
}
}
-
/**
* Add a resource to the source list.
* @since Ant 1.7.1
@@ -228,6 +277,20 @@ public abstract class ScriptRunnerBase {
* @throws BuildException if the resource cannot be read
*/
public void loadResource(Resource sourceResource) {
+ if(sourceResource instanceof StringResource) {
+ // Note: StringResource uses UTF-8 by default to encode/decode, not the default platform encoding
+ script += ((StringResource) sourceResource).getValue();
+ return;
+ }
+ if(sourceResource instanceof PropertyResource) {
+ script += ((PropertyResource) sourceResource).getValue();
+ return;
+ }
+
+ // Concat resource
+
+ // FileResource : OK for default encoding
+
String name = sourceResource.toLongString();
InputStream in = null;
try {
@@ -238,7 +301,12 @@ public abstract class ScriptRunnerBase {
throw new BuildException(
"Failed to open " + name + " -it is not readable", e);
}
- readSource(new InputStreamReader(in), name);
+
+ try {
+ readSource(in, name);
+ } finally {
+ FileUtils.close(in);
+ }
}
/**
@@ -356,5 +424,4 @@ public abstract class ScriptRunnerBase {
Thread.currentThread().setContextClassLoader(
origLoader);
}
-
}
http://git-wip-us.apache.org/repos/asf/ant/blob/4bd9b4a6/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java b/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
index 9e814d9..5cc23ab 100644
--- a/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
+++ b/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
@@ -31,9 +31,11 @@ import org.apache.tools.ant.types.resources.Union;
public class ScriptRunnerHelper {
private ClasspathUtils.Delegate cpDelegate = null;
private File srcFile;
+ private String encoding;
private String manager = "auto";
private String language;
private String text;
+ private boolean compiled = false;
private boolean setBeans = true;
private ProjectComponent projectComponent;
private ClassLoader scriptLoader = null;
@@ -53,6 +55,12 @@ public class ScriptRunnerHelper {
*/
public ScriptRunnerBase getScriptRunner() {
ScriptRunnerBase runner = getRunner();
+ runner.setCompiled(compiled);
+
+ if (encoding != null) {
+ // set it first, because runner.setSrc() loads immediately the file
+ runner.setEncoding(encoding);
+ }
if (srcFile != null) {
runner.setSrc(srcFile);
}
@@ -108,6 +116,16 @@ public class ScriptRunnerHelper {
}
/**
+ * Set the encoding of the script from an external file ; optional.
+ *
+ * @param encoding the encoding of the file containing the script source.
+ * @since Ant 1.10.1
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
* Add script text.
*
* @param text a component of the script text to be added.
@@ -143,6 +161,28 @@ public class ScriptRunnerHelper {
}
/**
+ * Enable the compilation of the script if possible.
+ * If this is true and the compilation feature is available in
+ * the script engine, the script is compiled before the first
+ * evaluation, and should be cached for future evaluations.
+ * Otherwise, a script is evaluated is used.
+ * The default is false.
+ *
+ * @param compiled the value to set.
+ */
+ public void setCompiled(boolean compiled) {
+ this.compiled = compiled;
+ }
+
+ /**
+ * Get the compilation feature.
+ * @return the compilation feature.
+ */
+ public boolean getCompiled() {
+ return this.compiled;
+ }
+
+ /**
* Set the setbeans attribute.
* If this is true, <script> will create variables in the
* script instance for all
http://git-wip-us.apache.org/repos/asf/ant/blob/4bd9b4a6/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
index 7a5cfa4..2670b09 100644
--- a/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
+++ b/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -21,6 +21,7 @@ package org.apache.tools.ant.util.optional;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.ReflectWrapper;
import org.apache.tools.ant.util.ScriptRunnerBase;
@@ -31,6 +32,11 @@ import org.apache.tools.ant.util.ScriptRunnerBase;
public class JavaxScriptRunner extends ScriptRunnerBase {
private ReflectWrapper engine;
+ /** Debug constant */
+ private static final boolean DEBUG = Boolean.getBoolean("JavaxScriptRunner.DEBUG");
+
+ private String compiledScriptRefName;
+
/**
* Get the name of the manager prefix.
* @return "javax"
@@ -79,28 +85,85 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
checkLanguage();
ClassLoader origLoader = replaceContextLoader();
try {
+
+ if(DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : compile enabled [" + getCompiled() + "]");
+
+ if (getCompiled()) {
+
+ if (null == compiledScriptRefName) {
+ compiledScriptRefName = execName + ".compiledScript.0123456789";
+ }
+ ReflectWrapper scriptRefObj = getProject().getReference(compiledScriptRefName);
+
+ if (null == scriptRefObj) {
+
+ ReflectWrapper engine = createEngine();
+ if (engine == null) {
+ throw new BuildException(
+ "Unable to create javax script engine for "
+ + getLanguage());
+ }
+
+ final Class engineClass = Class.forName("javax.script.ScriptEngine");
+ final Class compilableClass = Class.forName("javax.script.Compilable");
+ final Object wrappedObject = engine.getObject();
+
+ if (DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : wrappedObject [" + wrappedObject.getClass().getName() + "]");
+ if (engineClass.isAssignableFrom(wrappedObject.getClass()) && compilableClass.isAssignableFrom(wrappedObject.getClass())) {
+
+ if(DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : compilable [" + wrappedObject.getClass().getName() + "]");
+
+ {
+ getProject().log("compile script" + compiledScriptRefName, Project.MSG_VERBOSE);
+
+ // compilable engine
+ final Object compiledScript = engine.invoke("compile", String.class, getScript());
+ scriptRefObj = new ReflectWrapper(compiledScript);
+ }
+
+ getProject().log("store compiled script, ref " + compiledScriptRefName, Project.MSG_DEBUG);
+
+ } else {
+ getProject().log("script compilation not available", Project.MSG_DEBUG);
+ scriptRefObj = new ReflectWrapper(null);
+ }
+
+ getProject().addReference(compiledScriptRefName, scriptRefObj);
+ }
+
+ if (null != scriptRefObj.getObject()) {
+
+ if (DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : execute compiled script");
+
+ final Object simpleBindings;
+ {
+ final Class simpleBindingsClass = Class.forName("javax.script.SimpleBindings");
+ simpleBindings = simpleBindingsClass.newInstance();
+ }
+
+ applyBindings(new ReflectWrapper(simpleBindings));
+ if (DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : bindings applied");
+
+ getProject().log("run compiled script, ref " + compiledScriptRefName, Project.MSG_DEBUG);
+
+ final Class bindingsClass = Class.forName("javax.script.Bindings");
+
+ return scriptRefObj.invoke("eval", bindingsClass, simpleBindings);
+ }
+ }
+
ReflectWrapper engine = createEngine();
if (engine == null) {
throw new BuildException(
"Unable to create javax script engine for "
+ getLanguage());
}
- for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
- String key = (String) i.next();
- Object value = getBeans().get(key);
- if ("FX".equalsIgnoreCase(getLanguage())) {
- engine.invoke(
- "put", String.class, key
- + ":" + value.getClass().getName(),
- Object.class, value);
- } else {
- engine.invoke(
- "put", String.class, key,
- Object.class, value);
- }
- }
+
+ applyBindings(engine);
+
// execute the script
return engine.invoke("eval", String.class, getScript());
+
} catch (BuildException be) {
//catch and rethrow build exceptions
@@ -126,6 +189,23 @@ public class JavaxScriptRunner extends ScriptRunnerBase {
}
}
+ private void applyBindings(ReflectWrapper engine) {
+ for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ Object value = getBeans().get(key);
+ if ("FX".equalsIgnoreCase(getLanguage())) {
+ engine.invoke(
+ "put", String.class, key
+ + ":" + value.getClass().getName(),
+ Object.class, value);
+ } else {
+ engine.invoke(
+ "put", String.class, key,
+ Object.class, value);
+ }
+ }
+ }
+
private ReflectWrapper createEngine() {
if (engine != null) {
return engine;