1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jexl3.scripting;
19
20 import java.io.Reader;
21 import java.util.Arrays;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.script.CompiledScript;
26 import javax.script.ScriptContext;
27 import javax.script.ScriptEngine;
28 import javax.script.ScriptEngineManager;
29 import javax.script.ScriptException;
30
31 import org.apache.commons.jexl3.JexlBuilder;
32 import org.apache.commons.jexl3.JexlException;
33 import org.apache.commons.jexl3.introspection.JexlPermissions;
34 import org.apache.commons.logging.LogFactory;
35 import org.junit.After;
36 import org.junit.Assert;
37 import org.junit.Before;
38 import org.junit.Test;
39
40 public class JexlScriptEngineTest {
41 private static final List<String> NAMES = Arrays.asList("JEXL", "Jexl", "jexl",
42 "JEXL2", "Jexl2", "jexl2",
43 "JEXL3", "Jexl3", "jexl3");
44 private static final List<String> EXTENSIONS = Arrays.asList("jexl", "jexl2", "jexl3");
45 private static final List<String> MIMES = Arrays.asList("application/x-jexl",
46 "application/x-jexl2",
47 "application/x-jexl3");
48
49 @Before
50 public void setUp() {
51 }
52
53 @After
54 public void tearDown() {
55 JexlBuilder.setDefaultPermissions(null);
56 JexlScriptEngine.setInstance(null);
57 JexlScriptEngine.setPermissions(null);
58 }
59
60 @Test
61 public void testScriptEngineFactory() throws Exception {
62 final JexlScriptEngineFactory factory = new JexlScriptEngineFactory();
63 Assert.assertEquals("JEXL Engine", factory.getParameter(ScriptEngine.ENGINE));
64 Assert.assertEquals("3.3", factory.getParameter(ScriptEngine.ENGINE_VERSION));
65 Assert.assertEquals("JEXL", factory.getParameter(ScriptEngine.LANGUAGE));
66 Assert.assertEquals("3.3", factory.getParameter(ScriptEngine.LANGUAGE_VERSION));
67 Assert.assertNull(factory.getParameter("THREADING"));
68 Assert.assertEquals(NAMES, factory.getParameter(ScriptEngine.NAME));
69 Assert.assertEquals(EXTENSIONS, factory.getExtensions());
70 Assert.assertEquals(MIMES, factory.getMimeTypes());
71
72 Assert.assertEquals("42;", factory.getProgram("42"));
73 Assert.assertEquals("str.substring(3,4)", factory.getMethodCallSyntax("str", "substring", "3", "4"));
74 }
75
76 @Test
77 public void testScriptingGetBy() throws Exception {
78 final ScriptEngineManager manager = new ScriptEngineManager();
79 Assert.assertNotNull("Manager should not be null", manager);
80 for (final String name : NAMES) {
81 final ScriptEngine engine = manager.getEngineByName(name);
82 Assert.assertNotNull("Engine should not be null (name)", engine);
83 }
84 for (final String extension : EXTENSIONS) {
85 final ScriptEngine engine = manager.getEngineByExtension(extension);
86 Assert.assertNotNull("Engine should not be null (extension)", engine);
87 }
88 for (final String mime : MIMES) {
89 final ScriptEngine engine = manager.getEngineByMimeType(mime);
90 Assert.assertNotNull("Engine should not be null (mime)", engine);
91 }
92 }
93
94 @Test
95 public void testScripting() throws Exception {
96 final ScriptEngineManager manager = new ScriptEngineManager();
97 Assert.assertNotNull("Manager should not be null", manager);
98 final ScriptEngine engine = manager.getEngineByName("jexl3");
99 final Integer initialValue = 123;
100 Assert.assertEquals(initialValue,engine.eval("123"));
101 Assert.assertEquals(initialValue,engine.eval("0;123"));
102 try {
103 final Long time2 = (Long) engine.eval(
104 "sys=context.class.forName(\"java.lang.System\");"
105 + "now=sys.currentTimeMillis();"
106 );
107 Assert.fail("default engine no longer accesses System classes");
108 } catch(ScriptException xscript) {
109 JexlException.Method xjexl = (JexlException.Method) xscript.getCause();
110 Assert.assertEquals("forName", xjexl.getMethod());
111 }
112 engine.put("value", initialValue);
113 Assert.assertEquals(initialValue,engine.get("value"));
114 final Integer newValue = 124;
115 Assert.assertEquals(newValue,engine.eval("old=value;value=value+1"));
116 Assert.assertEquals(initialValue,engine.get("old"));
117 Assert.assertEquals(newValue,engine.get("value"));
118 Assert.assertEquals(engine.getContext(),engine.get(JexlScriptEngine.CONTEXT_KEY));
119
120 Assert.assertEquals(engine.getContext().getReader(),engine.eval("JEXL.in"));
121 Assert.assertEquals(engine.getContext().getWriter(),engine.eval("JEXL.out"));
122 Assert.assertEquals(engine.getContext().getErrorWriter(),engine.eval("JEXL.err"));
123 Assert.assertEquals(System.class,engine.eval("JEXL.System"));
124 }
125
126 @Test
127 public void testScriptingInstance0() throws Exception {
128 JexlScriptEngine.setPermissions(JexlPermissions.UNRESTRICTED);
129 final ScriptEngineManager manager = new ScriptEngineManager();
130 final ScriptEngine engine = manager.getEngineByName("jexl3");
131 Long time2 = (Long) engine.eval(
132 "sys=context.class.forName(\"java.lang.System\");"
133 + "now=sys.currentTimeMillis();");
134 Assert.assertTrue(time2 <= System.currentTimeMillis());
135 }
136
137 @Test
138 public void testScriptingPermissions1() throws Exception {
139 JexlBuilder.setDefaultPermissions(JexlPermissions.UNRESTRICTED);
140 JexlScriptEngine.setPermissions(null);
141 final ScriptEngineManager manager = new ScriptEngineManager();
142 final ScriptEngine engine = manager.getEngineByName("jexl3");
143 Long time2 = (Long) engine.eval(
144 "sys=context.class.forName(\"java.lang.System\");"
145 + "now=sys.currentTimeMillis();");
146 Assert.assertTrue(time2 <= System.currentTimeMillis());
147 }
148
149 @Test
150 public void testNulls() throws Exception {
151 final ScriptEngineManager manager = new ScriptEngineManager();
152 Assert.assertNotNull("Manager should not be null", manager);
153 final ScriptEngine engine = manager.getEngineByName("jexl3");
154 Assert.assertNotNull("Engine should not be null (name)", engine);
155 Assert.assertNotNull(engine.getFactory());
156 try {
157 engine.eval((String) null);
158 Assert.fail("Should have caused NPE");
159 } catch (final NullPointerException e) {
160
161 }
162 try {
163 engine.eval((Reader) null);
164 Assert.fail("Should have caused NPE");
165 } catch (final NullPointerException e) {
166
167 }
168 ScriptContext ctxt = null;
169 try {
170 engine.eval((String) null, ctxt);
171 Assert.fail("Should have caused NPE");
172 } catch (final NullPointerException e) {
173
174 }
175 try {
176 engine.eval((Reader) null, ctxt);
177 Assert.fail("Should have caused NPE");
178 } catch (final NullPointerException e) {
179
180 }
181 }
182
183 @Test
184 public void testScopes() throws Exception {
185 final ScriptEngineManager manager = new ScriptEngineManager();
186 Assert.assertNotNull("Manager should not be null", manager);
187 final ScriptEngine engine = manager.getEngineByName("JEXL");
188 Assert.assertNotNull("Engine should not be null (JEXL)", engine);
189 manager.put("global", 1);
190 engine.put("local", 10);
191 manager.put("both", 7);
192 engine.put("both", 7);
193 engine.eval("local=local+1");
194 engine.eval("global=global+1");
195 engine.eval("both=both+1");
196 engine.eval("newvar=42;");
197 Assert.assertEquals(2,manager.get("global"));
198 Assert.assertEquals(11,engine.get("local"));
199 Assert.assertEquals(7,manager.get("both"));
200 Assert.assertEquals(8,engine.get("both"));
201 Assert.assertEquals(42,engine.get("newvar"));
202 Assert.assertNull(manager.get("newvar"));
203 }
204
205 public static class Errors {
206 public int npe() {
207 throw new NullPointerException("jexl");
208 }
209 public int illegal() {
210 throw new IllegalArgumentException("jexl");
211 }
212 }
213
214 @Test
215 public void testErrors() throws Exception {
216 final ScriptEngineManager manager = new ScriptEngineManager();
217 final JexlScriptEngine engine = (JexlScriptEngine) manager.getEngineByName("JEXL");
218 ScriptContext ctxt = engine.getContext();
219 engine.put("errors", new Errors());
220 try {
221 engine.eval("errors.npe()");
222 } catch(ScriptException xscript) {
223 Assert.assertTrue(xscript.getCause() instanceof NullPointerException);
224 }
225 try {
226 engine.eval("errors.illegal()", ctxt);
227 } catch(ScriptException xscript) {
228 Assert.assertTrue(xscript.getCause() instanceof IllegalArgumentException);
229 }
230 CompiledScript script0 = engine.compile("errors.npe()");
231 try {
232 script0.eval();
233 } catch(ScriptException xscript) {
234 Assert.assertTrue(xscript.getCause() instanceof NullPointerException);
235 }
236 CompiledScript script1 = engine.compile("errors.illegal()");
237 try {
238 script1.eval(ctxt);
239 } catch(ScriptException xscript) {
240 Assert.assertTrue(xscript.getCause() instanceof IllegalArgumentException);
241 }
242 }
243
244
245 @Test
246 public void testCompile() throws Exception {
247 final ScriptEngineManager manager = new ScriptEngineManager();
248 final JexlScriptEngine engine = (JexlScriptEngine) manager.getEngineByName("JEXL");
249 ScriptContext ctxt = engine.getContext();
250 String str = null;
251 String reader = null;
252 try {
253 CompiledScript script0 = engine.compile(str);
254 Assert.fail("should have thrown npe");
255 } catch(NullPointerException npe) {
256 Assert.assertNotNull(npe);
257 }
258 try {
259 CompiledScript script0 = engine.compile(reader);
260 Assert.fail("should have thrown npe");
261 } catch(NullPointerException npe) {
262 Assert.assertNotNull(npe);
263 }
264 try {
265 CompiledScript script0 = engine.compile("3 + 4");
266 Assert.assertEquals(engine, script0.getEngine());
267 Object result = script0.eval();
268 Assert.assertEquals(7, result);
269 result = script0.eval();
270 Assert.assertEquals(7, result);
271 } catch(ScriptException xscript) {
272 Assert.assertTrue(xscript.getCause() instanceof NullPointerException);
273 }
274 try {
275 ctxt.setAttribute("x", 20, ScriptContext.ENGINE_SCOPE);
276 ctxt.setAttribute("y", 22, ScriptContext.ENGINE_SCOPE);
277 CompiledScript script0 = engine.compile("x + y");
278 Object result = script0.eval();
279 Assert.assertEquals(42, result);
280 ctxt.setAttribute("x", -20, ScriptContext.ENGINE_SCOPE);
281 ctxt.setAttribute("y", -22, ScriptContext.ENGINE_SCOPE);
282 result = script0.eval();
283 Assert.assertEquals(-42, result);
284 } catch(ScriptException xscript) {
285 Assert.assertTrue(xscript.getCause() instanceof NullPointerException);
286 }
287
288 }
289 @Test
290 public void testDottedNames() throws Exception {
291 final ScriptEngineManager manager = new ScriptEngineManager();
292 Assert.assertNotNull("Manager should not be null", manager);
293 final ScriptEngine engine = manager.getEngineByName("JEXL");
294 Assert.assertNotNull("Engine should not be null (JEXL)", engine);
295 engine.eval("this.is.a.test=null");
296 Assert.assertNull(engine.get("this.is.a.test"));
297 Assert.assertEquals(Boolean.TRUE, engine.eval("empty(this.is.a.test)"));
298 final Object mymap = engine.eval("testmap={ 'key1' : 'value1', 'key2' : 'value2' }");
299 Assert.assertTrue(mymap instanceof Map<?, ?>);
300 Assert.assertEquals(2,((Map<?, ?>)mymap).size());
301 }
302
303 @Test
304 public void testDirectNew() throws Exception {
305 final ScriptEngine engine = new JexlScriptEngine();
306 final Integer initialValue = 123;
307 Assert.assertEquals(initialValue,engine.eval("123"));
308 }
309 }