On 31/07/2009, Rahul Akolkar <rahul.akol...@gmail.com> wrote: > On Thu, Jul 30, 2009 at 10:24 PM, <s...@apache.org> wrote: > > Author: sebb > > Date: Fri Jul 31 02:24:07 2009 > > New Revision: 799492 > > > > URL: http://svn.apache.org/viewvc?rev=799492&view=rev > > Log: > > Initial implementation of Jexl Script engine and simple unit test > > > > Added: > > > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > (with props) > > > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > (with props) > > > > Added: > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > > URL: > http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java?rev=799492&view=auto > > > ============================================================================== > > --- > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > (added) > > +++ > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > Fri Jul 31 02:24:07 2009 > > @@ -0,0 +1,202 @@ > > +/* > > + * Licensed to the Apache Software Foundation (ASF) under one or more > > + * contributor license agreements. See the NOTICE file distributed with > > + * this work for additional information regarding copyright ownership. > > + * The ASF licenses this file to You under the Apache License, Version 2.0 > > + * (the "License"); you may not use this file except in compliance with > > + * the License. You may obtain a copy of the License at > > + * > > + * http://www.apache.org/licenses/LICENSE-2.0 > > + * > > + * Unless required by applicable law or agreed to in writing, software > > + * distributed under the License is distributed on an "AS IS" BASIS, > > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > > + * See the License for the specific language governing permissions and > > + * limitations under the License. > > + * > > + */ > > + > > +package org.apache.commons.jexl.scripting; > > + > > +import java.io.BufferedReader; > > +import java.io.IOException; > > +import java.io.Reader; > > +import java.util.Collection; > > +import java.util.Map; > > +import java.util.Set; > > + > > +import javax.script.AbstractScriptEngine; > > +import javax.script.Bindings; > > +import javax.script.ScriptContext; > > +import javax.script.ScriptEngineFactory; > > +import javax.script.ScriptException; > > +import javax.script.SimpleBindings; > > + > > +import org.apache.commons.jexl.JexlContext; > > +import org.apache.commons.jexl.JexlEngine; > > +import org.apache.commons.jexl.Script; > > + > > +// Note: this is a generated class, so won't be present until JavaCC has > been run > > +import org.apache.commons.jexl.parser.ParseException; > > + > > +/** > > + * Implements the Jexl ScriptEngine for JSF-223. > > + * <p> > > + * See > > + * <a > href="http://java.sun.com/javase/6/docs/api/javax/script/package-summary.html">Java > Scripting API</a> > > + * Javadoc. > > + */ > > +public class JexlScriptEngine extends AbstractScriptEngine { > > + > > + private final ScriptEngineFactory factory; > > + > > + private final JexlEngine engine; > > + > > + public JexlScriptEngine() { > > + this(null); > > + } > > + > > + public JexlScriptEngine(final ScriptEngineFactory _factory) { > > + factory = _factory; > > + engine = new JexlEngine(); > > + } > > + > > + /** {...@inheritdoc} */ > > + public Bindings createBindings() { > > + return new SimpleBindings(); > > + } > > + > > + /** {...@inheritdoc} */ > > + public Object eval(Reader script, ScriptContext context) throws > ScriptException { > > + BufferedReader reader = new BufferedReader(script); > > + StringBuilder buffer = new StringBuilder(); > > + try { > > + String line; > > + try { > > + while ((line = reader.readLine()) != null) { > > + buffer.append(line).append('\n'); > > + } > > + } catch (IOException e) { > > + throw new ScriptException(e); > > + } > > + } finally { > > + try { > > + reader.close(); > > + } catch (IOException e) { > > + } > > + } > > + return eval(buffer.toString(), context); > > + } > > + > > + /** {...@inheritdoc} */ > > + @SuppressWarnings("unchecked") > > + public Object eval(String scriptText, final ScriptContext context) > throws ScriptException { > > + if (scriptText == null) { > > + return null; > > + } > > + context.setAttribute("context", context, > ScriptContext.ENGINE_SCOPE); > <snip/> > > Not sure what the above line is upto ... >
JSR-223 mandates that: >>> In all cases, the ScriptContext used during a script execution must be a value in the Engine Scope of the ScriptEngine whose key is the String “context”. <<< Will document. > > + try { > > + Script script = engine.createScript(scriptText); > > + JexlContext ctxt = new JexlContext(){ > > + public void setVars(Map vars) { > > + context.setBindings(new SimpleBindings(vars), > ScriptContext.ENGINE_SCOPE); > > + } > > + > > + public Map getVars() { > > + return new JexlContextWrapper(context); > > + } > > + }; > > + > > + ctxt.getVars().put("context", "value"); > <snap/> > > ... but it seems related to this other line above. Please elaborate. > Oops, the last line is a bug. Will fix. > > + > > + return script.execute(ctxt); > > + } catch (ParseException e) { > > + e.printStackTrace(); > > + throw new ScriptException(e); > > + } catch (Exception e) { > > + e.printStackTrace(); > > + throw new ScriptException(e.toString()); > > + } > > + } > > + > > + /** {...@inheritdoc} */ > > + public ScriptEngineFactory getFactory() { > > + return factory == null ? new JexlScriptEngineFactory() : factory; > > + } > > + > > + /** > > + * Wrapper to convert a JSR-223 ScriptContext into a JexlContext. > > + * > <snip/> > > The above statement (and perhaps the class name itself) is a bit > misleading. Its not that the ScriptContext is converted to a > JexlContext by this wrapper, but rather that it makes it easier to > complete the said conversion. However, given this is private, not the > most important. OK, will clarify. > -Rahul > > > > > + * Current implementation only gives access to ENGINE_SCOPE binding. > > + */ > > + @SuppressWarnings("unchecked") > > + private static class JexlContextWrapper implements Map { > > + > > + private final ScriptContext context; > > + > > + private JexlContextWrapper (final ScriptContext _context){ > > + context = _context; > > + } > > + > > + public void clear() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + bnd.clear(); > > + } > > + > > + public boolean containsKey(final Object key) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.containsKey(key); > > + } > > + > > + public boolean containsValue(final Object value) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.containsValue(value); > > + } > > + > > + public Set entrySet() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.entrySet(); > > + } > > + > > + public Object get(final Object key) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.get(key); > > + } > > + > > + public boolean isEmpty() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.isEmpty(); > > + } > > + > > + public Set keySet() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.keySet(); > > + } > > + > > + public Object put(final Object key, final Object value) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.put(key, value); > > + } > > + > > + public void putAll(Map t) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + bnd.putAll(t); // N.B. SimpleBindings checks for valid keys > > + } > > + > > + public Object remove(Object key) { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.remove(key); > > + } > > + > > + public int size() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.size(); > > + } > > + > > + public Collection values() { > > + Bindings bnd = > context.getBindings(ScriptContext.ENGINE_SCOPE); > > + return bnd.values(); > > + } > > + > > + } > > +} > > > > Propchange: > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > > > ------------------------------------------------------------------------------ > > svn:eol-style = native > > > > Propchange: > commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/scripting/JexlScriptEngine.java > > > ------------------------------------------------------------------------------ > > svn:keywords = Author Date Id Revision > > > > Added: > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > > URL: > http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java?rev=799492&view=auto > > > ============================================================================== > > --- > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > (added) > > +++ > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > Fri Jul 31 02:24:07 2009 > > @@ -0,0 +1,52 @@ > > +/* > > + * Licensed to the Apache Software Foundation (ASF) under one or more > > + * contributor license agreements. See the NOTICE file distributed with > > + * this work for additional information regarding copyright ownership. > > + * The ASF licenses this file to You under the Apache License, Version 2.0 > > + * (the "License"); you may not use this file except in compliance with > > + * the License. You may obtain a copy of the License at > > + * > > + * http://www.apache.org/licenses/LICENSE-2.0 > > + * > > + * Unless required by applicable law or agreed to in writing, software > > + * distributed under the License is distributed on an "AS IS" BASIS, > > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > > + * See the License for the specific language governing permissions and > > + * limitations under the License. > > + * > > + */ > > + > > +package org.apache.commons.jexl.scripting; > > + > > +import javax.script.ScriptEngine; > > +import javax.script.ScriptEngineManager; > > + > > +import junit.framework.TestCase; > > + > > +public class JexlScriptEngineTest extends TestCase { > > + > > + public void testScripting() throws Exception { > > + ScriptEngineManager manager = new ScriptEngineManager(); > > + assertNotNull("Manager should not be null", manager); > > + ScriptEngine engine = manager.getEngineByName("jexl"); > > + assertNotNull("Engine should not be null (name)", engine); > > + engine = manager.getEngineByExtension("jexl"); > > + assertNotNull("Engine should not be null (ext)", engine); > > + final Integer initialValue = Integer.valueOf(123); > > + assertEquals(initialValue,engine.eval("123")); > > + assertEquals(initialValue,engine.eval("0;123"));// multiple > statements > > + long time1 = System.currentTimeMillis(); > > + Long time2 = (Long) engine.eval("" + > > + "sys=context.class.forName(\"java.lang.System\");" > > + +"now=sys.currentTimeMillis();" > > + ); > > + assertTrue("Must take some time to process this",time1 <= > time2.longValue()); > > + engine.put("value", initialValue); > > + assertEquals(initialValue,engine.get("value")); > > + final Long newValue = Long.valueOf(124); > > + assertEquals(newValue,engine.eval("old=value;value=value+1")); > > + assertEquals(initialValue,engine.get("old")); > > + assertEquals(newValue,engine.get("value")); > > + } > > + > > +} > > > > Propchange: > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > > > ------------------------------------------------------------------------------ > > svn:eol-style = native > > > > Propchange: > commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/scripting/JexlScriptEngineTest.java > > > ------------------------------------------------------------------------------ > > svn:keywords = Author Date Id Revision > > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org