Author: cbrisson
Date: Fri Jul 15 15:19:57 2016
New Revision: 1752841

URL: http://svn.apache.org/viewvc?rev=1752841&view=rev
Log:
add a first JSR-223 scripting interface implematation (thanks to Dishara 
Wijewardana and to Google Summer of Code)

Added:
    velocity/engine/trunk/velocity-engine-scripting/
    velocity/engine/trunk/velocity-engine-scripting/pom.xml
    velocity/engine/trunk/velocity-engine-scripting/src/
    velocity/engine/trunk/velocity-engine-scripting/src/main/
    velocity/engine/trunk/velocity-engine-scripting/src/main/java/
    velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/
    velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityBindings.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompilable.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityInvocable.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptContext.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptException.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptResourceHolder.java
    
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptUtil.java
    velocity/engine/trunk/velocity-engine-scripting/src/test/
    velocity/engine/trunk/velocity-engine-scripting/src/test/java/
    velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/
    velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/AbstractScriptTest.java
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineFactoryTest.java
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineTest.java
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/VelocityScriptContextTest.java
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/eventtool.vm
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/velocity.properties
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/tools/
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/tools/CustomEvent.java
    
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/tools/EventToolTest.java
Modified:
    velocity/engine/trunk/pom.xml
    velocity/engine/trunk/src/changes/changes.xml
    velocity/engine/trunk/velocity-engine-assembly/pom.xml

Modified: velocity/engine/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/pom.xml?rev=1752841&r1=1752840&r2=1752841&view=diff
==============================================================================
--- velocity/engine/trunk/pom.xml (original)
+++ velocity/engine/trunk/pom.xml Fri Jul 15 15:19:57 2016
@@ -186,6 +186,7 @@
     <module>velocity-engine-core</module>
     <module>velocity-engine-examples</module>
     <module>velocity-engine-assembly</module>
+    <module>velocity-engine-scripting</module>
   </modules>
 
   <!-- This project is an effort by many people. If you feel that your name

Modified: velocity/engine/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/src/changes/changes.xml?rev=1752841&r1=1752840&r2=1752841&view=diff
==============================================================================
--- velocity/engine/trunk/src/changes/changes.xml (original)
+++ velocity/engine/trunk/src/changes/changes.xml Fri Jul 15 15:19:57 2016
@@ -27,6 +27,10 @@
   <body>
     <release version="2.0" date="In Subversion">
 
+      <action type="add" dev="cbrusson" issue="VELOCITY-735" due-to="Dishara 
Wijewardana">
+        Add a first implementation for the JSR 223 standard scripting 
interface.
+      </action>
+      
       <action type="fix" dev="cbrisson" issue="VELOCITY-809">
         Fix Template default encoding initialization problem.
       </action>

Modified: velocity/engine/trunk/velocity-engine-assembly/pom.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-assembly/pom.xml?rev=1752841&r1=1752840&r2=1752841&view=diff
==============================================================================
--- velocity/engine/trunk/velocity-engine-assembly/pom.xml (original)
+++ velocity/engine/trunk/velocity-engine-assembly/pom.xml Fri Jul 15 15:19:57 
2016
@@ -66,6 +66,11 @@
             <artifactId>velocity-engine-examples</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-scripting</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
     <profiles>
         <profile>

Added: velocity/engine/trunk/velocity-engine-scripting/pom.xml
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/pom.xml?rev=1752841&view=auto
==============================================================================
--- velocity/engine/trunk/velocity-engine-scripting/pom.xml (added)
+++ velocity/engine/trunk/velocity-engine-scripting/pom.xml Fri Jul 15 15:19:57 
2016
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.velocity</groupId>
+        <artifactId>velocity-engine-parent</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>velocity-engine-scripting</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+    <name>Apache Velocity - JSR 223 Scripting</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+            <version>2.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityBindings.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityBindings.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityBindings.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityBindings.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,231 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.context.Context;
+import org.apache.velocity.script.util.ScriptUtil;
+
+import javax.script.Bindings;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A mapping of key/value pairs, all of whose keys are Strings.
+ * There are two fundamental ways to instantiate this.
+ * 1. By providing a pre enriched map as initial values which will override 
the default VelocityBindings values.
+ * 2. Default constructor which will adheres to the default setting with an 
starting empty map.
+ */
+public class VelocityBindings implements Bindings, Context {
+
+  /**
+     * Map which keeps the binding of names and associated values
+     */
+    private Map<String,Object> map;
+
+  /**
+     *
+     * @param map  pre created binding map passed to initialize.
+     */
+    public VelocityBindings(Map<String,Object> map) {
+        if(map == null) {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Cannot pass a null map to initialize VelocityBindings"));
+          throw new NullPointerException("Cannot pass a null map to initialize 
VelocityBindings");
+        }
+        this.map = map;
+    }
+
+  /**
+     * Default constructor which creates a new Map instance
+     */
+    public VelocityBindings(){
+        this.map = new HashMap<String, Object>();
+    }
+
+  /**
+     *   Set a named value.
+     * @param s The name associated with the value.
+     * @param o The value associated with the name.
+     * @return   The value previously associated with the given key/name. 
Returns null if no value was previously associated with the name.
+     */
+    public Object put(String s, Object o) {
+        validateKey(s);
+        return map.put(s,o);
+    }
+
+    /**
+     *   Inherits from org.apache.velocity.Context
+     * @param key The name of the desired value.
+     * @return  Returns the value associate with the given key
+     */
+    public Object get(String key) {
+        validateKey(key);
+        return map.get(key);
+    }
+
+    /**
+     *   Inherits from org.apache.velocity.Context
+     * @param key The name of the desired value.
+     * @return  Returns the value associate with the given key
+     */
+    public Object get(Object key) {
+        return get(String.valueOf(key));
+    }    
+    
+    /**
+     *  Inherits from org.apache.velocity.Context
+     * @return   All names added in the map
+     */
+    public String[] getKeys() {
+        return map.keySet().toArray(new String[map.size()]);
+    }
+
+  /**
+     *
+     * @param map , All the values in this map will be add in to the binding
+     */
+    public void putAll(Map<? extends String, ? extends Object> map) {
+         for (Map.Entry<? extends String, ? extends Object> entry : 
map.entrySet()) {
+             String key = entry.getKey();
+             validateKey(key);
+             put(key, entry.getValue());
+         }
+    }
+
+  /**
+     * Clears the map
+     */
+    public void clear() {
+     map.clear();
+    }
+
+  /**
+     *
+     * @return  returns the keys as a Set collection
+     */
+    public Set<String> keySet() {
+        return map.keySet();
+    }
+
+  /**
+     *
+     * @return  Returns all values associated win the map
+     */
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+  /**
+     *  EntrySet in interface java.util.Map<java.lang.String,java.lang.Object>
+     * @return   entrySet
+     */
+    public Set<Entry<String, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+  /**
+     *
+     * @return the size of the map
+     */
+    public int size() {
+        return map.size();
+    }
+
+  /**
+     *
+     * @return whether the map is empty
+     */
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+  /**
+     *  Check whether the given name is already binded to a value
+     * @param o  name
+     * @return  true if the given name contains a binding else false
+     */
+    public boolean containsKey(String k) {
+        validateKey(k);
+        return map.containsKey(k);
+    }
+
+  /**
+     *  Check whether the given name is already binded to a value
+     * @param o  name
+     * @return  true if the given name contains a binding else false
+     */
+    public boolean containsKey(Object k) {
+        return containsKey(String.valueOf(k));
+    }
+
+    
+  /**
+     *  Check whether the given value is already binded to a name in the map
+     * @param o  name
+     * @return  true if the given value contains a binding else false
+     */
+    public boolean containsValue(Object o) {
+        return map.containsValue(o);
+    }
+
+  /**
+     *   Removes the mapping for this key from this map if it is present 
(optional operation).
+     * @param o  name
+     * @return  Remove the value binded to the given name and the name itself 
from the mapping
+     */
+    public Object remove(String k) {
+        validateKey(k);
+        return map.remove(k);
+    }
+
+  /**
+     *   Removes the mapping for this key from this map if it is present 
(optional operation).
+     * @param o  name
+     * @return  Remove the value binded to the given name and the name itself 
from the mapping
+     */
+    public Object remove(Object k) {
+        return remove(String.valueOf(k));
+    }
+
+    
+ /**
+     *  Validates key and throw corresponding exceptions for JSR 223 compliance
+     * Throws: java.lang.NullPointerException - if key is null
+     *             java.lang.ClassCastException - if key is not String
+     *             java.lang.IllegalArgumentException - if key is empty String
+     * @param key   which used to validate the binding
+     */
+    private void validateKey(String key) {
+        if (key == null) {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Cannot pass a null map to initialize VelocityBindings"));
+            throw new NullPointerException("The key cannot be null..!!");
+        }
+        if (!(key instanceof String)) {
+            ScriptUtil.addExceptionToErrorWriter(new ClassCastException("The 
key must be of the type String..!!"));
+            throw new ClassCastException("The key must be of the type 
String..!!");
+        }
+        if (key.equals("")) {
+            ScriptUtil.addExceptionToErrorWriter(new 
IllegalArgumentException("The key cannot be empty..!!"));
+            throw new IllegalArgumentException("The key cannot be empty..!!");
+        }
+    }
+
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompilable.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompilable.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompilable.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompilable.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,35 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptException;
+import java.io.Reader;
+
+public class VelocityCompilable implements Compilable {
+    public CompiledScript compile(String s) throws ScriptException {
+        return null;
+    }
+
+    public CompiledScript compile(Reader reader) throws ScriptException {
+        return null;
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,46 @@
+package org.apache.velocity.script;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+/*
+* 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.
+*/
+public class VelocityCompiledScript extends CompiledScript {
+
+    private ScriptEngine scriptEngine;
+    private String script = "";
+
+    public VelocityCompiledScript(ScriptEngine scriptEngine,String script) {
+       this.scriptEngine = scriptEngine;
+       this.script = script;
+    }
+
+    @Override
+    public Object eval(ScriptContext context) throws ScriptException {
+        return scriptEngine.eval(script,context);
+    }
+
+    @Override
+    public ScriptEngine getEngine() {
+        return scriptEngine;
+    }
+
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityInvocable.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityInvocable.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityInvocable.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityInvocable.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,42 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import javax.script.Invocable;
+import javax.script.ScriptException;
+
+public class VelocityInvocable implements Invocable {
+
+    public Object invokeMethod(Object o, String s, Object... objects) throws 
ScriptException, NoSuchMethodException {
+        return null;
+    }
+
+    public Object invokeFunction(String s, Object... objects) throws 
ScriptException, NoSuchMethodException {
+        return null;
+    }
+
+    public <T> T getInterface(Class<T> tClass) {
+        return null;
+    }
+
+    public <T> T getInterface(Object o, Class<T> tClass) {
+        return null;
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptContext.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptContext.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptContext.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptContext.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,354 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.VelocityContext;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The class who used to connect Script Engines with objects, such as scoped 
Bindings, in hosting applications. Each scope is a set of named
+ * attributes whose values can be set and retrieved using the 
VelocityScriptContext methods. VelocityScriptContext also expose Readers and
+ * Writers that can be used by the VelocityScriptEngines for input and output.
+ *
+ * No additional params required to do instantiate this. Has only the default 
constructor.
+ */
+
+public class VelocityScriptContext implements ScriptContext {
+
+    /**
+     *    A binding reference dedicated to  cover engine scope
+     */
+    private Bindings engineScope;
+
+
+    /**
+     *   A binding reference dedicated to  cover global scope
+     */
+    private Bindings globalScope;
+
+
+    /**
+     *   Script context reader  for system in put. In other words Reader to be 
used by the script to read input.
+     */
+    private Reader reader;
+
+
+    /**
+     *   The Writer for scripts to use when displaying output. It defaults to 
system.out
+     */
+    private Writer writer = new PrintWriter(System.out);
+
+
+    /**
+     *  A dedicated Writer used to display error output.
+     */
+    private Writer errorWriter;
+
+
+    /**
+     *    List which stores the scopes supported by the scripting engine
+     */
+    private static List<Integer> scopes;
+
+
+    /**
+     *    Default constructor which init the scopes and readers and writers
+     */
+    public VelocityScriptContext() {
+         init();
+    }
+
+
+    /**
+     *   Instantiates the scopes(global and engine), readers and writers for 
the context
+     */
+    private void init() {
+        engineScope = new VelocityBindings();
+        globalScope = null;
+        reader = new InputStreamReader(System.in);
+        writer = new PrintWriter(System.out, true);
+        errorWriter = new PrintWriter(System.err, true);
+    }
+
+
+  /**
+     *  Associates a Bindings instance with a particular scope in this 
ScriptContext
+     * @param bindings  The Bindings to associate with the given scope
+     * @param i  scope
+     *  Throws:
+     * java.lang.IllegalArgumentException - If no Bindings is defined for the 
specified scope value in ScriptContexts of this type.
+     * java.lang.NullPointerException - if value of scope is ENGINE_SCOPE and 
the specified Bindings is null.
+     */
+    public void setBindings(Bindings bindings, int i)  {
+        switch (i){
+         case ENGINE_SCOPE:
+             if(bindings == null) {
+               throw new NullPointerException("Engine scope cannot be null");
+             }
+             engineScope = bindings;
+         break;
+
+         case GLOBAL_SCOPE:
+             globalScope = bindings;
+         break;
+
+         default:
+             throw new IllegalArgumentException("Invalid scope value");
+        }
+    }
+
+
+  /**
+     * @param i  scope
+     * @return   The associated Bindings. Returns null if it has not been set.
+     * throws java.lang.IllegalArgumentException - If no Bindings is defined 
for the specified scope value in ScriptContext of this type.
+     */
+    public Bindings getBindings(int i) {
+       switch (i) {
+         case ENGINE_SCOPE:
+              return engineScope;
+         case GLOBAL_SCOPE:
+              return globalScope;
+         default:
+             throw new IllegalArgumentException("Invalid scope value");
+        }
+    }
+
+
+
+  /**
+     *  Sets the value of an attribute in a given scope.
+     * @param s  attribute name
+     * @param o  attribute value
+     * @param i  scope
+     * Throws
+     * java.lang.IllegalArgumentException - if the name is empty or if the 
scope is invalid.
+     * java.lang.NullPointerException - if the name is null.
+     */
+    public void setAttribute(String s, Object o, int i) {
+
+         if(s == null) {
+             throw new NullPointerException("Name cannot be null .");
+         }
+
+         switch (i) {
+         case ENGINE_SCOPE:
+              engineScope.put(s,o);
+              return;
+         case GLOBAL_SCOPE:
+             if(globalScope != null) {
+              globalScope.put(s,o);
+             }
+              return;
+         default:
+             throw new IllegalArgumentException("Invalid scope value");
+        }
+    }
+
+
+
+  /**
+     *  Gets the value of an attribute in a given scope.
+     * @param s  name of the attribute
+     * @param i  scope
+     * @return  The value of the attribute. Returns null is the name does not 
exist in the given scope.
+     * Throws :
+     *  java.lang.IllegalArgumentException - if the name is empty or if the 
value of scope is invalid.
+     * java.lang.NullPointerException - if the name is null.
+     */
+    public Object getAttribute(String s, int i) {
+
+         if(s == null) {
+             throw new NullPointerException("Name cannot be null .");
+         }
+
+        switch (i) {
+        case ENGINE_SCOPE:
+             return engineScope.get(s);
+        case GLOBAL_SCOPE:
+            if(globalScope != null) {
+             return globalScope.get(s);
+            }
+            return null;
+        default:
+            throw new IllegalArgumentException("Invalid scope value");
+       }
+
+    }
+
+
+
+  /**
+     *   Remove an attribute in a given scope.
+     * @param s   The name of the attribute to remove
+     * @param i  The scope in which to remove the attribute
+     * @return   The removed value
+     * Throws:
+     * java.lang.IllegalArgumentException - if the name is empty or if the 
scope is invalid.
+     * java.lang.NullPointerException - if the name is null.
+     */
+    public Object removeAttribute(String s, int i) {
+
+         if(s == null) {
+             throw new NullPointerException("Name cannot be null .");
+         }
+
+        switch (i) {
+        case ENGINE_SCOPE:
+             return engineScope.remove(s);
+        case GLOBAL_SCOPE:
+            if(globalScope != null) {
+             return globalScope.remove(s);
+            }
+            return null;
+        default:
+            throw new IllegalArgumentException("Invalid scope value");
+       }
+
+    }
+
+
+  /**
+     * Retrieves the value of the attribute with the given name in the scope 
occurring earliest in the search order.
+     * The order is determined by the numeric value of the scope parameter 
(lowest scope values first.
+     * @param s   name of the attribute to return
+     * @return   The value of the attribute in the lowest scope for which an 
attribute with the given name is defined. Returns null
+     * if no attribute with the name exists in any scope.
+     * Throws:
+     * java.lang.NullPointerException - if the name is null.
+     * java.lang.IllegalArgumentException - if the name is empty.
+     */
+    public Object getAttribute(String s) {
+         if(s == null) {
+             throw new NullPointerException("Name cannot be null .");
+         }
+
+        if(engineScope.containsKey(s)) {
+           return getAttribute(s,ENGINE_SCOPE);
+        } else if (globalScope != null && (globalScope.containsKey(s))) {
+           return getAttribute(s,GLOBAL_SCOPE);
+        }
+        return null;
+    }
+
+
+  /**
+     *  Get the lowest scope in which an attribute is defined.
+     * @param s name of the attribute
+     * @return  The lowest scope. Returns -1 if no attribute with the given 
name is defined in any scope.
+     * Throws:
+     * java.lang.NullPointerException - if name is null.
+     * java.lang.IllegalArgumentException - if name is empty.
+     */
+    public int getAttributesScope(String s) {
+
+        if(s == null) {
+             throw new NullPointerException("Name cannot be null .");
+        }
+        if(engineScope.containsKey(s)) {
+           return ENGINE_SCOPE;
+        } else if(globalScope != null && globalScope.containsKey(s)) {
+           return GLOBAL_SCOPE;
+        } else {
+          return -1;
+        }
+    }
+
+
+  /**
+     *  Returns the Writer for scripts to use when displaying output.
+     * @return
+     */
+    public Writer getWriter() {
+        return writer;
+    }
+
+
+  /**
+     *  Returns the Writer used to display error output.
+     * @return
+     */
+    public Writer getErrorWriter() {
+        return errorWriter;
+    }
+
+
+  /**
+     *   Sets the Writer for scripts to use when displaying output.
+     * @param writer
+     */
+    public void setWriter(Writer writer) {
+        this.writer = writer;
+    }
+
+
+  /**
+     *  Sets the Writer used to display error output.
+     * @param writer
+     */
+    public void setErrorWriter(Writer writer) {
+        this.errorWriter = writer;
+    }
+
+
+  /**
+     *  Returns a Reader to be used by the script to read input.
+     * @return
+     */
+    public Reader getReader() {
+        return reader;
+    }
+
+
+  /**
+     *  Sets the Reader for scripts to read input .
+     * @param reader
+     */
+    public void setReader(Reader reader) {
+        this.reader = reader;
+    }
+
+
+  /**
+     *  Returns immutable List of all the valid values for scope in the 
ScriptContext.
+     * @return
+     */
+    public List<Integer> getScopes() {
+        return scopes;
+    }
+
+
+    //Adding the two scopes the api supports in to a unmodifiable list
+      static {
+        scopes = new ArrayList<Integer>(2);
+        scopes.add(ENGINE_SCOPE);
+        scopes.add(GLOBAL_SCOPE);
+        scopes = Collections.unmodifiableList(scopes);
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,489 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.script.util.ScriptResourceHolder;
+import org.apache.velocity.script.util.ScriptUtil;
+
+import javax.script.*;
+import java.io.*;
+import java.util.Properties;
+
+/**
+ *  VelocityScriptEngine is the fundamental class whose methods inherited from 
.javax.script.ScriptEngine interface
+ * These methods provide basic scripting functionality. This includes methods 
that execute scripts, and ones that set and get values.
+ * The values are key/value pairs of two types.
+ * This Provides a standard implementation for several of the variants of the 
eval method.
+ *  eval(Reader)
+ * eval(String)
+ * eval(String, Bindings)
+ * eval(Reader, Bindings)
+ *
+ * There are two ways to instantiate VelocityScriptEngine. One is directly 
using the script engine factory which was used to create this
+ * engine. Other one is by passing the factory and the pre defined bindings 
required for the engine.
+ */
+public class VelocityScriptEngine implements ScriptEngine {
+
+    /**
+     * ScriptEngineFactory reference from whom this engine got created
+     */
+    private ScriptEngineFactory scriptEngineFactory;
+
+
+    /**
+     * Velocity core engine reference
+     */
+    private VelocityEngine velocityEngine;
+
+
+    /**
+     * unmodifiable property name which is ued to obtain properties from 
context as well as from system to initialize velocity core engine
+     */
+    public static final String VELOCITY_PROPERTIES = 
"org.apache.velocity.engine.properties";
+
+
+    /**
+     * Default velocity log tag
+     */
+    public static final String DEFAULT_LOG_TAG = "default_log_tag";
+
+
+    /**
+     * script context reference which belongs to this engine instance
+     */
+    private ScriptContext scriptContext;
+
+
+    /**
+     * Constructor which gets created engine factory reference as input
+     *
+     * @param scriptEngineFactory ScriptEngineFactory reference from whom this 
engine got created
+     */
+    public VelocityScriptEngine(ScriptEngineFactory scriptEngineFactory) {
+        this.scriptEngineFactory = scriptEngineFactory;
+        this.scriptContext = new VelocityScriptContext();
+        ScriptUtil.setScriptContext(scriptContext);
+    }
+
+    /**
+     * @param scriptEngineFactory ScriptEngineFactory reference from whom this 
engine got created
+     * @param bindings            required binding needs to initialize this 
engine, unless it defaults to engine scope
+     */
+    public VelocityScriptEngine(ScriptEngineFactory scriptEngineFactory, 
Bindings bindings) {
+        this.scriptEngineFactory = scriptEngineFactory;
+        this.scriptContext = new VelocityScriptContext();
+        ScriptUtil.setScriptContext(scriptContext);
+        if (bindings != null) {
+            this.scriptContext.setBindings(bindings, 
ScriptContext.ENGINE_SCOPE);
+        } else {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Bindings cannot be null"));
+            throw new NullPointerException("Bindings cannot be null");
+        }
+    }
+
+
+    /**
+     * @return script engine factory who created this engine
+     */
+    public ScriptEngineFactory getFactory() {
+
+        //        if null return a newly created one
+        if (scriptEngineFactory == null) {
+            createNewFactory();
+        }
+        return scriptEngineFactory;
+    }
+
+    private void createNewFactory() {
+//          Added creation inside sync block to avoid creating two factories 
from a engine by two parallel threads at the same time.
+//          Also the additional null check out from sync block is to avoid 
every  thread to get blocked inside it even there is an already created factory.
+        synchronized (this) {
+            if (scriptEngineFactory == null) {
+                scriptEngineFactory = new VelocityScriptEngineFactory();
+            }
+        }
+    }
+
+    /**
+     * Creates the velocity core engine by initializing it from reading 
property file/system properties
+     *
+     * @param context
+     */
+    private void constructVelocityEngine(ScriptContext context) {
+
+        Properties props = getPropertiesFromContext(context);
+        //Check if property exists in context
+        if (props != null) {
+            initVelocityEngine(props);
+            return;
+        } else {
+            props = getPropertiesFromSystem();
+            //Check if properties exists in System
+            if (props != null) {
+                initVelocityEngine(props);
+                return;
+            }
+        }
+        //Init velocity engine with default settings
+        initVelocityEngine();
+    }
+
+    /**
+     * Init velocity engine without properties.
+     */
+    private void initVelocityEngine() {
+
+        if (velocityEngine != null) {
+
+//            Add sync block from a parallel thread creating two velocity 
engine instances
+            synchronized (this) {
+                velocityEngine = new VelocityEngine();
+                velocityEngine.init();
+            }
+        }
+    }
+
+    /**
+     * Initializes the velocity engine with pre defined properties
+     *
+     * @param props
+     */
+    private void initVelocityEngine(Properties props) {
+        if (velocityEngine == null) {
+            synchronized (this) {
+                velocityEngine = new VelocityEngine();
+                velocityEngine.init(props);
+            }
+        }
+    }
+
+    /**
+     * Obtain properties from a property file which is taken from a system 
property
+     *
+     * @return
+     */
+    private Properties getPropertiesFromSystem() {
+        String propFileName = System.getProperty(VELOCITY_PROPERTIES);
+        File propFile = new File(propFileName);
+        if (propFile.exists()) {
+            Properties properties = new Properties();
+            try {
+                properties.load(new FileInputStream(propFile));
+                return properties;
+            } catch (IOException e) {
+                ScriptUtil.addExceptionToErrorWriter(e);
+                return null;
+            }
+        }
+        //TODO log error msg saying no such property file
+        return null;
+    }
+
+    private Properties getPropertiesFromContext(ScriptContext context) {
+        Object props = context.getAttribute(VELOCITY_PROPERTIES);
+        if (props instanceof Properties) {
+            return (Properties) props;
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Causes the immediate execution of the script whose source is the String 
passed as the first argument. The script may be
+     * re-parsed or recompiled before execution. State left in the engine from 
previous executions, including variable values and
+     * compiled procedures may be visible during this execution.
+     *
+     * @param s             The script to be executed by the script engine.
+     * @param scriptContext A ScriptContext exposing sets of attributes in 
different scopes. The meanings of the
+     *                      scopes ScriptContext.GLOBAL_SCOPE, and 
ScriptContext.ENGINE_SCOPE are defined in the specification.
+     * @return The value returned from the execution of the script.
+     * @throws ScriptException
+     */
+    public Object eval(String s, ScriptContext scriptContext) throws 
ScriptException {
+            return eval(new StringReader(s),scriptContext);
+    }
+
+
+    /**
+     * Same as eval(String, ScriptContext) where the source of the script is 
read from a Reader.
+     *
+     * @param reader        The source of the script to be executed by the 
script engine.
+     * @param scriptContext The ScriptContext passed to the script engine.
+     * @return The value returned from the execution of the script.
+     * @throws ScriptException if an error occurrs in script.
+     *                         java.lang.NullPointerException - if either 
argument is null.
+     */
+    public Object eval(Reader reader, ScriptContext scriptContext) throws 
ScriptException {
+
+        if (reader == null) {
+            throw new NullPointerException("Reader passed cannot be null");
+        }
+        constructVelocityEngine(scriptContext);
+        VelocityContext velocityContext = getVelocityContext(scriptContext);
+
+        Writer outPut;
+        if (scriptContext.getWriter() != null) {
+            outPut = scriptContext.getWriter();
+        } else {
+            outPut = new StringWriter();
+        }
+        boolean result;
+
+        try {
+            //Check for velocity tools vm file
+            if (scriptContext.getAttribute(VelocityScriptEngine.FILENAME) != 
null) {
+                Template template = null;
+                String fileName = 
scriptContext.getAttribute(VelocityScriptEngine.FILENAME).toString();
+                //Cache hit
+                if (ScriptResourceHolder.hasTemplate(fileName)) {
+                    template = ScriptResourceHolder.getTemplate(fileName);
+                } else {
+                    try {
+                        template = velocityEngine.getTemplate(fileName);
+                        ScriptResourceHolder.putTemplate(fileName,template);
+                        template.merge(velocityContext, outPut);
+                    } catch(ResourceNotFoundException e1){
+                    }
+
+                }
+            }
+
+            result = velocityEngine.evaluate(velocityContext, outPut, 
VelocityScriptEngine.DEFAULT_LOG_TAG, reader);
+
+        } catch (Exception exp) {
+            ScriptUtil.addExceptionToErrorWriter(exp);
+            throw new ScriptException(exp);
+        }
+        return String.valueOf(result);
+    }
+
+    /**
+     * Executes the specified script. The default ScriptContext for the 
ScriptEngine is used.
+     *
+     * @param s The script language source to be executed.
+     * @return The value returned from the execution of the script.
+     * @throws ScriptException - if error occurrs in script.
+     *                         java.lang.NullPointerException - if either 
argument is null.
+     */
+    public Object eval(String s) throws ScriptException {
+        return eval(s, scriptContext);
+    }
+
+
+    /**
+     * Same as eval(String) except that the source of the script is provided 
as a Reader
+     *
+     * @param reader The source of the script.
+     * @return The value returned by the script.
+     * @throws ScriptException
+     */
+    public Object eval(Reader reader) throws ScriptException {
+        return eval(reader, scriptContext);
+    }
+
+
+    /**
+     * Executes the script using the Bindings argument as the ENGINE_SCOPE 
Bindings of the ScriptEngine during the script
+     * execution. The Reader, Writer and non-ENGINE_SCOPE Bindings of the 
default ScriptContext are used.
+     * The ENGINE_SCOPE Bindings of the ScriptEngine is not changed, and its 
mappings are unaltered by the script execution.
+     *
+     * @param s        The source for the script.
+     * @param bindings The Bindings of attributes to be used for script 
execution.
+     * @return The value returned by the script.
+     * @throws ScriptException
+     */
+    public Object eval(String s, Bindings bindings) throws ScriptException {
+        ScriptContext scriptContext = 
getGeneratedScriptContextFromBinding(bindings);
+        return eval(new StringReader(s), scriptContext);
+    }
+
+
+    /**
+     * Same as eval(String, Bindings) except that the source of the script is 
provided as a Reader.
+     *
+     * @param reader   The source of the script.
+     * @param bindings The Bindings of attributes to be used for script 
execution.
+     * @return The value returned by the script.
+     * @throws ScriptException
+     */
+    public Object eval(Reader reader, Bindings bindings) throws 
ScriptException {
+        ScriptContext scriptContext = 
getGeneratedScriptContextFromBinding(bindings);
+        return eval(reader, scriptContext);
+    }
+
+    private ScriptContext getGeneratedScriptContextFromBinding(Bindings 
bindings) {
+        ScriptContext tmpContext = new VelocityScriptContext();
+        Bindings globalScope = 
scriptContext.getBindings(ScriptContext.GLOBAL_SCOPE);
+
+        //Setting global and engine scopes to context
+        if (globalScope != null) {
+            tmpContext.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
+        }
+
+        if (bindings != null) {
+            tmpContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+        } else {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Engine scope Bindings cannot be null."));
+            throw new NullPointerException("Engine scope Bindings cannot be 
null.");
+        }
+
+        tmpContext.setReader(scriptContext.getReader());
+        tmpContext.setWriter(scriptContext.getWriter());
+        tmpContext.setErrorWriter(scriptContext.getErrorWriter());
+
+        return tmpContext;
+    }
+
+    /**
+     * Sets a key/value pair in the state of the ScriptEngine that may either 
create a Java Language Binding to be used in the
+     * execution of scripts or be used in some other way, depending on whether 
the key is reserved. Must have the same effect
+     * as getBindings(ScriptContext.ENGINE_SCOPE).put.
+     *
+     * @param s The name of named value to add
+     * @param o The value of named value to add.
+     *          Throws:
+     *          java.lang.NullPointerException - if key is null.
+     *          java.lang.IllegalArgumentException - if key is empty.
+     */
+    public void put(String s, Object o) {
+
+        if (s == null) {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Name cannot be null"));
+            throw new NullPointerException("Name cannot be null");
+        }
+
+        if ("".equals(s)) {
+            ScriptUtil.addExceptionToErrorWriter(new 
IllegalArgumentException("Name cannot be empty"));
+            throw new IllegalArgumentException("Name cannot be empty");
+        }
+
+        Bindings engineScope = 
scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+        engineScope.put(s, o);
+    }
+
+
+    /**
+     * Retrieves a value set in the state of this engine. The value might be 
one which was set using setValue or some other value in
+     * the state of the ScriptEngine, depending on the implementation. Must 
have the same effect as getBindings
+     * (ScriptContext.ENGINE_SCOPE).get
+     *
+     * @param s The key whose value is to be returned
+     * @return the value for the given key
+     *         Throws:
+     *         java.lang.NullPointerException - if key is null.
+     *         java.lang.IllegalArgumentException - if key is empty.
+     */
+    public Object get(String s) {
+
+        if (s == null) {
+            ScriptUtil.addExceptionToErrorWriter(new 
NullPointerException("Name cannot be null"));
+            throw new NullPointerException("Name cannot be null");
+        }
+
+        if ("".equals(s)) {
+            ScriptUtil.addExceptionToErrorWriter(new 
IllegalArgumentException("Name cannot be empty"));
+            throw new IllegalArgumentException("Name cannot be empty");
+        }
+
+        Bindings engineScope = 
scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
+        return engineScope.get(s);
+    }
+
+
+    /**
+     * The Bindings instances that are returned must be identical to those 
returned by the getBindings method of ScriptContext
+     * called with corresponding arguments on the default ScriptContext of the 
ScriptEngine.
+     *
+     * @param i scope
+     * @return The Bindings with the specified scope.
+     */
+    public Bindings getBindings(int i) {
+        return scriptContext.getBindings(i);
+    }
+
+
+    /**
+     * Sets a scope of named values to be used by scripts. The possible scopes 
are:
+     * ScriptContext.ENGINE_SCOPE - The specified Bindings replaces the engine 
scope of the ScriptEngine.
+     * ScriptContext.GLOBAL_SCOPE - The specified Bindings must be visible as 
the GLOBAL_SCOPE.
+     * Any other value of scope defined in the default ScriptContext of the 
ScriptEngine.
+     *
+     * @param bindings The Bindings for the specified scope.
+     * @param i        The specified scope. Either ScriptContext.ENGINE_SCOPE, 
ScriptContext.GLOBAL_SCOPE, or any other valid value of scope.
+     */
+    public void setBindings(Bindings bindings, int i) {
+        scriptContext.setBindings(bindings, i);
+    }
+
+
+    /**
+     * @return A Bindings that can be used to replace the state of this 
ScriptEngine.
+     */
+    public Bindings createBindings() {
+        return new VelocityBindings();
+    }
+
+    /**
+     * Returns the default ScriptContext of the ScriptEngine whose Bindings, 
Reader and Writers are used for script executions when no ScriptContext is 
specified.
+     *
+     * @return The default ScriptContext of the ScriptEngine.
+     */
+    public ScriptContext getContext() {
+        return scriptContext;
+    }
+
+
+    /**
+     * Sets the default ScriptContext of the ScriptEngine whose Bindings, 
Reader and Writers are used for script executions when no ScriptContext is 
specified.
+     *
+     * @param scriptContext A ScriptContext that will replace the default 
ScriptContext in the ScriptEngine.
+     *                      Throws: java.lang.NullPointerException - if 
context is null.
+     */
+    public void setContext(ScriptContext scriptContext) {
+        if (scriptContext == null) {
+            throw new NullPointerException("script context cannot be null");
+        }
+
+        this.scriptContext = scriptContext;
+    }
+
+    private VelocityContext getVelocityContext(ScriptContext ctx) {
+        Bindings engineScope = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
+        if (ctx.getBindings(ScriptContext.GLOBAL_SCOPE) == null) {
+            return new VelocityContext(engineScope);
+        } else {
+            return new VelocityContext(engineScope, new 
VelocityContext(ctx.getBindings(ScriptContext.GLOBAL_SCOPE)));
+        }
+    }
+
+    private String getTargetFilename(ScriptContext ctx) {
+        Object fileName = ctx.getAttribute(ScriptEngine.FILENAME);
+        if (fileName != null) {
+            return fileName.toString();
+        } else {
+            return "No-Such-File";
+        }
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,304 @@
+package org.apache.velocity.script;
+/*
+ * 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.
+ */
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * VelocityScriptEngineFactory is used to describe and instantiate 
ScriptEngines.
+ * There are two fundamental ways to instantiate this.
+ *
+ *   1. Create a factory by providing only name and version and allows to 
inherit default factory settings.
+ *   2. Create a factory by providing all required attributes i.e  
List<String> names, List<String> extensions
+ *       List<String> mimeTypes , String name,String version, String langName, 
String langVersion
+ */
+public class VelocityScriptEngineFactory implements ScriptEngineFactory {
+
+    /**
+     *  names of the script engine
+     */
+    private List<String> names;
+
+
+    /**
+     * List of  extensions for script engine
+     */
+    private List<String> extensions;
+
+
+    /**
+     *  List of mime types for script engine
+     */
+    private List<String> mimeTypes;
+
+    /**
+     *  Default name of the engine
+     */
+    private String name = "velocity";
+
+
+    /**
+     * Default version of the engine
+     */
+    private String version = "1.8";
+
+
+    /**
+     *  Default script language name
+     */
+    private String langName = "velocity";
+
+
+    /**
+     * Default  version of the script language
+     */
+    private String langVersion = "1.8";
+
+
+    /**
+     * Provides full capability to change default engine settings
+     *
+     * @param names       Override default names for script engine
+     * @param extensions  Override default extensions for script engine
+     * @param mimeTypes   Override default mime types for script engine
+     * @param name        Override default name for script engine
+     * @param version     Override default version for script engine
+     * @param langName    Override default language names for script engine
+     * @param langVersion Override default language version for script engine
+     */
+    public VelocityScriptEngineFactory(List<String> names, List<String> 
extensions
+            , List<String> mimeTypes
+            , String name
+            , String version
+            , String langName
+            , String langVersion
+    ) {
+        this.names = Collections.unmodifiableList(names);
+        this.extensions = Collections.unmodifiableList(extensions);
+        this.mimeTypes = Collections.unmodifiableList(mimeTypes);
+        this.name = name;
+        this.version = version;
+        this.langName = langName;
+        this.langVersion = langVersion;
+    }
+
+    /**
+     * @param name    Override default name for script engine
+     * @param version Override default version for script engine
+     */
+    public VelocityScriptEngineFactory(String name, String version) {
+        this.name = name;
+        this.version = version;
+        initDefaultSettings();
+    }
+
+    /**
+     * Simple Factory with all default settings
+     */
+    public VelocityScriptEngineFactory() {
+        initDefaultSettings();
+    }
+
+    private void initDefaultSettings() {
+        names = new ArrayList<String>(1);
+        names.add("Velocity");
+        names = Collections.unmodifiableList(names);
+        extensions = new ArrayList<String>(3);
+        extensions.add("vm");
+        extensions.add("vtl");
+        extensions.add("vhtml");
+        extensions = Collections.unmodifiableList(extensions);
+        mimeTypes = new ArrayList<String>(1);
+        mimeTypes.add("text/x-velocity");
+        mimeTypes = Collections.unmodifiableList(mimeTypes);
+    }
+
+  /**
+     *  Returns the full name of the ScriptEngine.
+     * @return
+     */
+    public String getEngineName() {
+        return name;
+    }
+
+
+  /**
+     *  Returns the version of the ScriptEngine.
+     * @return
+     */
+    public String getEngineVersion() {
+        return version;
+    }
+
+
+  /**
+     *  Returns an immutable list of filename extensions, which generally 
identify scripts written in the language
+     *  supported by this ScriptEngine.
+     * @return
+     */
+    public List<String> getExtensions() {
+        return extensions;
+    }
+
+
+  /**
+     *  Returns an immutable list of mimetypes, associated with scripts that 
can be executed by the engine.
+     * @return
+     */
+    public List<String> getMimeTypes() {
+        return mimeTypes;
+    }
+
+
+  /**
+     * Returns an immutable list of short names for the ScriptEngine, which 
may be used to identify the ScriptEngine by the ScriptEngineManager.
+     * @return
+     */
+    public List<String> getNames() {
+        return names;
+    }
+
+
+  /**
+     *  Returns the name of the scripting langauge supported by this 
ScriptEngine.
+     * @return
+     */
+    public String getLanguageName() {
+        return langName;
+    }
+
+
+  /**
+     *  Returns the version of the scripting language supported by this 
ScriptEngine.
+     * @return
+     */
+    public String getLanguageVersion() {
+        return langVersion;
+    }
+
+
+
+   /**
+     *   Returns the value of an attribute whose meaning may be 
implementation-specific.
+     * @param s
+     * @return
+     */
+    public Object getParameter(String s) {
+        if (s.equals(ScriptEngine.ENGINE)) {
+            return getEngineName();
+        } else if (s.equals(ScriptEngine.NAME)) {
+            return getNames().get(0);
+        } else if (s.equals(ScriptEngine.LANGUAGE)) {
+            return getLanguageName();
+        } else if (s.equals(ScriptEngine.ENGINE_VERSION)) {
+            return getEngineVersion();
+        } else if (s.equals(ScriptEngine.LANGUAGE_VERSION)) {
+            return getLanguageVersion();
+        } else if (s.equals("THREADING")) {
+            return "MULTITHREADED";
+        } else {
+            return null;
+        }
+    }
+
+
+
+    /**
+     *
+     * @param s   Name of the Object to whom the method belongs to
+     * @param s1  Name of the method
+     * @param strings method arguments to be passed
+     * @return  the method syntax for velocity script
+     */
+    public String getMethodCallSyntax(String s, String s1, String... strings) {
+        StringBuilder syntax = new StringBuilder();
+        syntax.append("$");
+        syntax.append("{");
+        syntax.append(s);
+        syntax.append(".");
+        syntax.append(s1);
+        syntax.append("(");
+        if (strings.length != 0) {
+            int i = 0;
+            for (; i < strings.length - 1; i++) {
+                syntax.append("$" + strings[i]);
+                syntax.append(", ");
+            }
+            syntax.append("$" + strings[i]);
+        }
+        syntax.append(")");
+        syntax.append("}");
+        return syntax.toString();
+    }
+
+
+
+    /**
+     *
+     * @param s  String to display
+     * @return     //TODO
+     */
+    public String getOutputStatement(String s) {
+        StringBuilder output = new StringBuilder();
+        output.append("${context.getWriter().write(\"");
+        for (int i = 0; i < s.length(); i++) {
+            char ch = s.charAt(i);
+            switch (ch) {
+            case '"':
+                output.append("\\\"");
+                break;
+            case '\\':
+                output.append("\\\\");
+                break;
+            default:
+                output.append(ch);
+                break;
+            }
+        }
+        output.append("\")}");
+        return output.toString();
+    }
+
+
+  /**
+     *   Returns A valid scripting language executable progam with given 
statements.
+     * @param strings  scripting statements provided
+     * @return the program from the statements given
+     */
+    public String getProgram(String... strings) {
+        StringBuilder program = new StringBuilder();
+        for (int i = 0; i < strings.length; i++) {
+            program.append(strings[i]);
+            program.append("\n");
+        }
+        return program.toString();
+    }
+
+    /**
+     *  Returns an instance of the ScriptEngine associated with this 
ScriptEngineFactory
+     * @return
+     */
+    public ScriptEngine getScriptEngine() {
+        return new VelocityScriptEngine(this);
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptException.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptException.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptException.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptException.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,33 @@
+package org.apache.velocity.script;
+
+/*
+ * 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.
+ */
+
+import javax.script.ScriptException;
+
+public class VelocityScriptException extends ScriptException {
+    public VelocityScriptException(String s) {
+        super(s);
+    }
+
+    public VelocityScriptException(Exception e) {
+        super(e);
+    }
+
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptResourceHolder.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptResourceHolder.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptResourceHolder.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptResourceHolder.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,47 @@
+package org.apache.velocity.script.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.Template;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ScriptResourceHolder {
+
+    /**
+     * Holds the template with their matching template file name
+      */
+private static Map<String,Template> templateCache = new HashMap<String, 
Template>();
+
+
+ public static void putTemplate(String fileName,Template template){
+    templateCache.put(fileName,template);
+ }
+
+ public static Template getTemplate(String fileName){
+     return  templateCache.get(fileName);
+ }
+
+ public static boolean hasTemplate(String fileName){
+     return templateCache.containsKey(fileName);
+ }
+
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptUtil.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptUtil.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptUtil.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/main/java/org/apache/velocity/script/util/ScriptUtil.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,43 @@
+package org.apache.velocity.script.util;
+
+
+import javax.script.ScriptContext;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/*
+* 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.
+*/
+public class ScriptUtil {
+
+    private static ScriptContext scriptContext;
+
+    public static void setScriptContext(ScriptContext scriptContext){
+        ScriptUtil.scriptContext = scriptContext;
+    }
+
+    public static void addExceptionToErrorWriter(Exception exc) {
+        StringWriter stringWriter = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(stringWriter);
+        exc.printStackTrace(printWriter);
+        scriptContext.setErrorWriter(stringWriter);
+    }
+}
+
+
+

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/AbstractScriptTest.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/AbstractScriptTest.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/AbstractScriptTest.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/AbstractScriptTest.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,31 @@
+package org.apache.velocity.script.test;
+
+
+import junit.framework.TestCase;
+import org.apache.velocity.script.VelocityScriptEngineFactory;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+
+public abstract class AbstractScriptTest  extends TestCase {
+   protected ScriptEngine engine;
+   protected  ScriptEngineFactory engineFactory;
+   protected  ScriptEngineManager manager;
+
+    @Override
+    public void setUp() {
+        manager = new ScriptEngineManager();
+    }
+
+    public void setupEngine(ScriptEngineFactory scriptEngineFactory){
+        manager.registerEngineName("velocity", scriptEngineFactory);
+        engine = manager.getEngineByName("velocity");
+    }
+
+    public void setupWithDefaultFactory() {
+        manager.registerEngineName("velocity", new 
VelocityScriptEngineFactory());
+        engine = manager.getEngineByName("velocity");
+        engineFactory = engine.getFactory();
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineFactoryTest.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineFactoryTest.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineFactoryTest.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineFactoryTest.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,90 @@
+package org.apache.velocity.script.test;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.script.VelocityScriptEngineFactory;
+import org.junit.Test;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScriptEngineFactoryTest extends AbstractScriptTest {
+
+    @Override
+    public void setUp() {
+        super.setUp();
+        super.setupEngine(constructFactory());
+    }
+    @Test
+    public void testCreateFactory() {
+
+        ScriptEngineFactory factory = engine.getFactory();
+
+        assertEquals(1, factory.getNames().size());
+        assertEquals("HelloWorld", factory.getNames().get(0));
+
+        assertEquals(1, factory.getExtensions().size());
+        assertEquals("hello-vm", factory.getExtensions().get(0));
+
+
+        assertEquals(1, factory.getMimeTypes().size());
+        assertEquals("mimetype1", factory.getMimeTypes().get(0));
+
+        assertEquals("test-engine",factory.getEngineName());
+        assertEquals("1.0.0",factory.getEngineVersion());
+        assertEquals("test-language",factory.getLanguageName());
+        assertEquals("2.0.0",factory.getLanguageVersion());
+
+    }
+
+    @Test
+    public void testParameters(){
+
+        ScriptEngineFactory factory = engine.getFactory();
+
+        assertEquals("test-engine",factory.getParameter(ScriptEngine.ENGINE));
+
+        
assertEquals("1.0.0",factory.getParameter(ScriptEngine.ENGINE_VERSION));
+
+        
assertEquals("test-language",factory.getParameter(ScriptEngine.LANGUAGE));
+
+        
assertEquals("2.0.0",factory.getParameter(ScriptEngine.LANGUAGE_VERSION));
+
+    }
+
+
+    private ScriptEngineFactory constructFactory() {
+        List<String> names = new ArrayList<String>();
+        names.add("HelloWorld");
+        List<String> extensions = new ArrayList<String>();
+        extensions.add("hello-vm");
+        List<String> mimeTypes = new ArrayList<String>();
+        mimeTypes.add("mimetype1");
+
+        return new VelocityScriptEngineFactory(names,
+                extensions,
+                mimeTypes,
+                "test-engine",
+                "1.0.0",
+                "test-language",
+                "2.0.0");
+    }
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineTest.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineTest.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineTest.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/ScriptEngineTest.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,93 @@
+package org.apache.velocity.script.test;
+/*
+ * 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.
+ */
+
+import org.apache.velocity.script.VelocityScriptEngine;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+public class ScriptEngineTest extends AbstractScriptTest {
+
+    @Override
+    public void setUp() {
+        super.setUp();
+        super.setupWithDefaultFactory();
+    }
+
+    public void testBasicOpe() {
+
+        engine.put("name1", "value1");
+        Bindings engineScope = 
engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+        assertEquals("Engine#put should have same effect as context.put ", 
engineScope.get("name1"), "value1");
+
+        String val = engine.get("name1").toString();
+        assertEquals("Engine#get should have same effect as context.get ", 
engineScope.get("name1"), val);
+
+
+    }
+
+
+    public void testJSR223tException(){
+       try {
+            engine.get("");
+            fail("Cannot pass empty name");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+
+        try {
+             engine.setContext(null);
+             fail("Cannot pass null to context");
+         } catch (NullPointerException n) {
+             //Success
+         }
+
+    }
+
+    public void testEngineEvals() throws ScriptException {
+        String path = 
ScriptEngineTest.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+        String propertyFile = 
path.substring(0,path.indexOf("target/test-classes")) +
+                
"src/test/java/org/apache/velocity/script/test/resources/velocity.properties";
+        System.setProperty(VelocityScriptEngine.VELOCITY_PROPERTIES,  
propertyFile) ;
+        //Comment test case
+
+        Writer writer = new StringWriter();
+        engine.getContext().setWriter(writer);
+        String script = "<html>\n" +
+                "<body>\n" +
+                "#set( $foo = \"Velocity\" )\n" +
+                "Hello $foo World!\n" +
+                "</body>\n" +
+                "<html>";
+//        String script = "## This is a comment ";
+        Object result = engine.eval(script);
+        assertTrue(Boolean.valueOf(result.toString()));
+        System.out.println(">>>"+writer);
+        //TODO add more engine script evaluation test cases
+
+    }
+
+
+
+
+}

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/VelocityScriptContextTest.java
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/VelocityScriptContextTest.java?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/VelocityScriptContextTest.java
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/VelocityScriptContextTest.java
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,160 @@
+package org.apache.velocity.script.test;
+
+/*
+* 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.
+*/
+
+import org.apache.velocity.script.VelocityBindings;
+import javax.script.ScriptContext;
+import java.util.List;
+
+
+public class VelocityScriptContextTest extends AbstractScriptTest {
+
+    @Override
+    public void setUp() {
+        super.setUp();
+        super.setupWithDefaultFactory();
+    }
+
+    public void testInitialScopes() {
+        List<Integer> defaultScopes = engine.getContext().getScopes();
+        assertEquals(defaultScopes.size(), 2);
+        assertTrue(defaultScopes.contains(ScriptContext.ENGINE_SCOPE));
+        assertTrue(defaultScopes.contains(ScriptContext.GLOBAL_SCOPE));
+    }
+
+    public void testScopes() {
+
+        VelocityBindings velocityBindings = new VelocityBindings();
+        engine.getContext().setBindings(velocityBindings, 
ScriptContext.ENGINE_SCOPE);
+        assertNotNull(engine.getBindings(ScriptContext.ENGINE_SCOPE));
+        assertNotNull("Engines Registered through manager sets the global 
scope", engine.getBindings(ScriptContext.GLOBAL_SCOPE));
+    }
+
+    public void testEngineScopeAttributes() {
+
+        ScriptContext context = engine.getContext();
+        context.setAttribute("engine-prop1", "engine-value1", 
ScriptContext.ENGINE_SCOPE);
+
+        assertEquals(context.getAttribute("engine-prop1", 
ScriptContext.ENGINE_SCOPE), "engine-value1");
+        assertNull(context.getAttribute("engine-prop1", 
ScriptContext.GLOBAL_SCOPE));
+
+        context.removeAttribute("engine-prop1", ScriptContext.ENGINE_SCOPE);
+        assertNull(context.getAttribute("engine-prop1", 
ScriptContext.ENGINE_SCOPE));
+
+
+    }
+
+    public void testGlobalScopeAttributes() {
+
+        ScriptContext context = engine.getContext();
+        context.setAttribute("global-prop1", "global-value1", 
ScriptContext.GLOBAL_SCOPE);
+
+        assertEquals(context.getAttribute("global-prop1", 
ScriptContext.GLOBAL_SCOPE), "global-value1");
+        assertNull(context.getAttribute("global-prop1", 
ScriptContext.ENGINE_SCOPE));
+
+        context.removeAttribute("global-prop1", ScriptContext.GLOBAL_SCOPE);
+        assertNull(context.getAttribute("global-prop1", 
ScriptContext.GLOBAL_SCOPE));
+
+    }
+
+    public void testJSRExceptions() {
+
+        ScriptContext context = engine.getContext();
+        context.setAttribute("global-prop", "global-value", 
ScriptContext.GLOBAL_SCOPE);
+        int invalidScope = 99;
+
+        try {
+            context.setBindings(null, ScriptContext.ENGINE_SCOPE);
+            fail("Cannot pass null binding for engine scope");
+        } catch (NullPointerException n) {
+            //Success
+        }
+
+        try {
+            context.setBindings(new VelocityBindings(), invalidScope);
+            fail("Cannot pass invalid scope");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+        try {
+            context.getBindings(invalidScope);
+            fail("Cannot pass invalid scope");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+
+
+        try {
+            context.setAttribute(null, "value", ScriptContext.ENGINE_SCOPE);
+
+            fail("Name cannot be null");
+        } catch (NullPointerException n) {
+            //Success
+        }
+        try {
+            context.setAttribute("name1", "value", invalidScope);
+
+            fail("Cannot pass invalid scope");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+
+
+
+        try {
+            context.getAttribute(null, ScriptContext.ENGINE_SCOPE);
+
+            fail("Name cannot be null");
+        } catch (NullPointerException n) {
+            //Success
+        }
+        try {
+            context.getAttribute("name1", invalidScope);
+
+            fail("Cannot pass invalid scope");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+
+
+         try {
+            context.removeAttribute(null, ScriptContext.ENGINE_SCOPE);
+
+            fail("Name cannot be null");
+        } catch (NullPointerException n) {
+            //Success
+        }
+        try {
+            context.removeAttribute("name1", invalidScope);
+
+            fail("Cannot pass invalid scope");
+        } catch (IllegalArgumentException n) {
+            //Success
+        }
+
+
+        
context.setAttribute("prop2","engine-value2",ScriptContext.ENGINE_SCOPE);
+        
context.setAttribute("prop2","global-value2",ScriptContext.GLOBAL_SCOPE);
+        assertEquals("Should return lowest scope value binded 
value",context.getAttribute("prop2"),"engine-value2");
+
+    }
+}
+
+

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/eventtool.vm
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/eventtool.vm?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/eventtool.vm
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/eventtool.vm
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,5 @@
+$event;
+
+Event Created by $event.getName()
+Event Created on $event.getDate()
+Event ID is $event.getID()

Added: 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/velocity.properties
URL: 
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/velocity.properties?rev=1752841&view=auto
==============================================================================
--- 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/velocity.properties
 (added)
+++ 
velocity/engine/trunk/velocity-engine-scripting/src/test/java/org/apache/velocity/script/test/resources/velocity.properties
 Fri Jul 15 15:19:57 2016
@@ -0,0 +1,18 @@
+# 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.    
+runtime.log = velocity_example.log
+


Reply via email to