| @@ -188,10 +188,15 @@ public class ScriptDef extends DefBase { | |||||
| } | } | ||||
| if (helper.getLanguage() == null) { | if (helper.getLanguage() == null) { | ||||
| throw new BuildException("<scriptdef> requires a language attribute " | |||||
| throw new BuildException("scriptdef requires a language attribute " | |||||
| + "to specify the script language"); | + "to specify the script language"); | ||||
| } | } | ||||
| if (helper.getSrc() == null && helper.getEncoding() != null) { | |||||
| throw new BuildException("scriptdef requires a src attribute " | |||||
| + "if the encoding is set"); | |||||
| } | |||||
| // Check if need to set the loader | // Check if need to set the loader | ||||
| if (getAntlibClassLoader() != null || hasCpDelegate()) { | if (getAntlibClassLoader() != null || hasCpDelegate()) { | ||||
| helper.setClassLoader(createLoader()); | helper.setClassLoader(createLoader()); | ||||
| @@ -367,9 +372,9 @@ public class ScriptDef extends DefBase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Defines the language (required). | |||||
| * Defines the compilation feature (optional). | |||||
| * | * | ||||
| * @param language the scripting language name for the script. | |||||
| * @param compiled enables the script compilation if available. | |||||
| */ | */ | ||||
| public void setCompiled(boolean compiled) { | public void setCompiled(boolean compiled) { | ||||
| helper.setCompiled(compiled); | helper.setCompiled(compiled); | ||||
| @@ -25,7 +25,7 @@ import java.io.IOException; | |||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
| import java.io.Reader; | import java.io.Reader; | ||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.nio.charset.Charset; | |||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -223,7 +223,6 @@ public abstract class ScriptRunnerBase { | |||||
| /** | /** | ||||
| * Load the script from an external file; optional. | * Load the script from an external file; optional. | ||||
| * @since Ant 1.10.1 | |||||
| * @param file the file containing the script source. | * @param file the file containing the script source. | ||||
| */ | */ | ||||
| public void setSrc(File file) { | public void setSrc(File file) { | ||||
| @@ -231,6 +230,7 @@ public abstract class ScriptRunnerBase { | |||||
| if (!file.exists()) { | if (!file.exists()) { | ||||
| throw new BuildException("file " + filename + " not found."); | throw new BuildException("file " + filename + " not found."); | ||||
| } | } | ||||
| InputStream in = null; | InputStream in = null; | ||||
| try { | try { | ||||
| in = new FileInputStream(file); | in = new FileInputStream(file); | ||||
| @@ -239,8 +239,15 @@ public abstract class ScriptRunnerBase { | |||||
| throw new BuildException("file " + filename + " not found."); | throw new BuildException("file " + filename + " not found."); | ||||
| } | } | ||||
| final Charset charset; | |||||
| if (null == encoding) { | |||||
| charset = null; | |||||
| } else { | |||||
| charset = Charset.forName(encoding); | |||||
| } | |||||
| try { | try { | ||||
| readSource(in, filename); | |||||
| readSource(in, filename, charset); | |||||
| } finally { | } finally { | ||||
| FileUtils.close(in); | FileUtils.close(in); | ||||
| } | } | ||||
| @@ -250,19 +257,18 @@ public abstract class ScriptRunnerBase { | |||||
| * Read some source in from the given reader | * Read some source in from the given reader | ||||
| * @param reader the reader; this is closed afterwards. | * @param reader the reader; this is closed afterwards. | ||||
| * @param name the name to use in error messages | * @param name the name to use in error messages | ||||
| * @param charset the encoding for the reader, may be null. | |||||
| */ | */ | ||||
| private void readSource(InputStream in, String name) { | |||||
| private void readSource(InputStream in, String name, Charset charset) { | |||||
| Reader reader = null; | Reader reader = null; | ||||
| try { | try { | ||||
| if (null == encoding) { | |||||
| if (null == charset) { | |||||
| reader = new InputStreamReader(in); | reader = new InputStreamReader(in); | ||||
| } else { | } else { | ||||
| reader = new InputStreamReader(in, encoding); | |||||
| reader = new InputStreamReader(in, charset); | |||||
| } | } | ||||
| reader = new BufferedReader(reader); | reader = new BufferedReader(reader); | ||||
| script += FileUtils.safeReadFully(reader); | script += FileUtils.safeReadFully(reader); | ||||
| } catch(UnsupportedEncodingException e) { | |||||
| throw new BuildException("Failed to decode " + name + " with encoding " + encoding, e); | |||||
| } catch (IOException ex) { | } catch (IOException ex) { | ||||
| throw new BuildException("Failed to read " + name, ex); | throw new BuildException("Failed to read " + name, ex); | ||||
| } finally { | } finally { | ||||
| @@ -278,7 +284,6 @@ public abstract class ScriptRunnerBase { | |||||
| */ | */ | ||||
| public void loadResource(Resource sourceResource) { | public void loadResource(Resource sourceResource) { | ||||
| if(sourceResource instanceof StringResource) { | if(sourceResource instanceof StringResource) { | ||||
| // Note: StringResource uses UTF-8 by default to encode/decode, not the default platform encoding | |||||
| script += ((StringResource) sourceResource).getValue(); | script += ((StringResource) sourceResource).getValue(); | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -287,10 +292,6 @@ public abstract class ScriptRunnerBase { | |||||
| return; | return; | ||||
| } | } | ||||
| // Concat resource | |||||
| // FileResource : OK for default encoding | |||||
| String name = sourceResource.toLongString(); | String name = sourceResource.toLongString(); | ||||
| InputStream in = null; | InputStream in = null; | ||||
| try { | try { | ||||
| @@ -299,11 +300,11 @@ public abstract class ScriptRunnerBase { | |||||
| throw new BuildException("Failed to open " + name, e); | throw new BuildException("Failed to open " + name, e); | ||||
| } catch (UnsupportedOperationException e) { | } catch (UnsupportedOperationException e) { | ||||
| throw new BuildException( | throw new BuildException( | ||||
| "Failed to open " + name + " -it is not readable", e); | |||||
| "Failed to open " + name + " - it is not readable", e); | |||||
| } | } | ||||
| try { | try { | ||||
| readSource(in, name); | |||||
| readSource(in, name, (Charset) null); | |||||
| } finally { | } finally { | ||||
| FileUtils.close(in); | FileUtils.close(in); | ||||
| } | } | ||||
| @@ -58,7 +58,7 @@ public class ScriptRunnerHelper { | |||||
| runner.setCompiled(compiled); | runner.setCompiled(compiled); | ||||
| if (encoding != null) { | if (encoding != null) { | ||||
| // set it first, because runner.setSrc() loads immediately the file | |||||
| // set it first, because runner.setSrc() loads immediately the file | |||||
| runner.setEncoding(encoding); | runner.setEncoding(encoding); | ||||
| } | } | ||||
| if (srcFile != null) { | if (srcFile != null) { | ||||
| @@ -115,15 +115,33 @@ public class ScriptRunnerHelper { | |||||
| this.srcFile = file; | this.srcFile = file; | ||||
| } | } | ||||
| /** | |||||
| * Get the external script file ; optional. | |||||
| * @return the file containing the script source. | |||||
| * @since Ant 1.10.1 | |||||
| */ | |||||
| public File getSrc() { | |||||
| return srcFile; | |||||
| } | |||||
| /** | /** | ||||
| * Set the encoding of the script from an external file ; optional. | * Set the encoding of the script from an external file ; optional. | ||||
| * | * | ||||
| * @param encoding the encoding of the file containing the script source. | * @param encoding the encoding of the file containing the script source. | ||||
| * @since Ant 1.10.1 | * @since Ant 1.10.1 | ||||
| */ | */ | ||||
| public void setEncoding(String encoding) { | |||||
| this.encoding = encoding; | |||||
| } | |||||
| public void setEncoding(String encoding) { | |||||
| this.encoding = encoding; | |||||
| } | |||||
| /** | |||||
| * Get the external file encoding. | |||||
| * @return the encoding of the file containing the script source. | |||||
| * @since Ant 1.10.1 | |||||
| */ | |||||
| public String getEncoding() { | |||||
| return encoding; | |||||
| } | |||||
| /** | /** | ||||
| * Add script text. | * Add script text. | ||||
| @@ -31,11 +31,7 @@ import org.apache.tools.ant.util.ScriptRunnerBase; | |||||
| */ | */ | ||||
| public class JavaxScriptRunner extends ScriptRunnerBase { | public class JavaxScriptRunner extends ScriptRunnerBase { | ||||
| private ReflectWrapper engine; | private ReflectWrapper engine; | ||||
| /** Debug constant */ | |||||
| private static final boolean DEBUG = Boolean.getBoolean("JavaxScriptRunner.DEBUG"); | |||||
| private String compiledScriptRefName; | |||||
| private ReflectWrapper compiledScript; | |||||
| /** | /** | ||||
| * Get the name of the manager prefix. | * Get the name of the manager prefix. | ||||
| @@ -86,16 +82,14 @@ public class JavaxScriptRunner extends ScriptRunnerBase { | |||||
| ClassLoader origLoader = replaceContextLoader(); | ClassLoader origLoader = replaceContextLoader(); | ||||
| try { | try { | ||||
| if(DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : compile enabled [" + getCompiled() + "]"); | |||||
| if (getCompiled()) { | if (getCompiled()) { | ||||
| if (null == compiledScriptRefName) { | |||||
| compiledScriptRefName = execName + ".compiledScript.0123456789"; | |||||
| } | |||||
| ReflectWrapper scriptRefObj = getProject().getReference(compiledScriptRefName); | |||||
| final String compiledScriptRefName = execName + ".compiledScript.0123456789"; | |||||
| if (null == compiledScript) { | |||||
| compiledScript = getProject().getReference(compiledScriptRefName); | |||||
| } | |||||
| if (null == scriptRefObj) { | |||||
| if (null == compiledScript) { | |||||
| ReflectWrapper engine = createEngine(); | ReflectWrapper engine = createEngine(); | ||||
| if (engine == null) { | if (engine == null) { | ||||
| @@ -104,51 +98,36 @@ public class JavaxScriptRunner extends ScriptRunnerBase { | |||||
| + getLanguage()); | + getLanguage()); | ||||
| } | } | ||||
| final Class engineClass = Class.forName("javax.script.ScriptEngine"); | |||||
| final Class compilableClass = Class.forName("javax.script.Compilable"); | |||||
| final Class engineClass = Class.forName("javax.script.ScriptEngine", true, getClass().getClassLoader()); | |||||
| final Class compilableClass = Class.forName("javax.script.Compilable", true, getClass().getClassLoader()); | |||||
| final Object wrappedObject = engine.getObject(); | 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() + "]"); | |||||
| if (engineClass.isAssignableFrom(wrappedObject.getClass()) && | |||||
| compilableClass.isAssignableFrom(wrappedObject.getClass())) { | |||||
| { | |||||
| getProject().log("compile script" + compiledScriptRefName, Project.MSG_VERBOSE); | |||||
| getProject().log("compile script " + execName, 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); | |||||
| final Object compiled = engine.invoke("compile", String.class, getScript()); | |||||
| compiledScript = new ReflectWrapper(compiled); | |||||
| } else { | } else { | ||||
| getProject().log("script compilation not available", Project.MSG_DEBUG); | |||||
| scriptRefObj = new ReflectWrapper(null); | |||||
| getProject().log("script compilation not available", Project.MSG_VERBOSE); | |||||
| compiledScript = new ReflectWrapper(null); | |||||
| } | } | ||||
| getProject().addReference(compiledScriptRefName, scriptRefObj); | |||||
| getProject().addReference(compiledScriptRefName, compiledScript); | |||||
| } | } | ||||
| if (null != scriptRefObj.getObject()) { | |||||
| if (null != compiledScript.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(); | |||||
| } | |||||
| final ReflectWrapper simpleBindings = new ReflectWrapper(getClass().getClassLoader(), "javax.script.SimpleBindings"); | |||||
| applyBindings(new ReflectWrapper(simpleBindings)); | |||||
| if (DEBUG) System.out.println("-- JavaxScriptRunner.evaluateScript : bindings applied"); | |||||
| applyBindings(simpleBindings); | |||||
| getProject().log("run compiled script, ref " + compiledScriptRefName, Project.MSG_DEBUG); | |||||
| getProject().log("run compiled script " + execName, Project.MSG_DEBUG); | |||||
| final Class bindingsClass = Class.forName("javax.script.Bindings"); | |||||
| final Class bindingsClass = Class.forName("javax.script.Bindings", true, getClass().getClassLoader()); | |||||
| return scriptRefObj.invoke("eval", bindingsClass, simpleBindings); | |||||
| return compiledScript.invoke("eval", bindingsClass, simpleBindings.getObject()); | |||||
| } | } | ||||
| } | } | ||||