History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/script/javascript/RhinoScriptEngine.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/script/javascript/RhinoScriptEngine.java+398−0
@@ -0,0 +1,398 @@
1/*
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.script.javascript;
27import com.sun.script.util.*;
28import javax.script.*;
29import sun.org.mozilla.javascript.internal.*;
30import java.lang.reflect.Method;
31import java.io.*;
32import java.util.*;
33
34
35/**
36 * Implementation of <code>ScriptEngine</code> using the Mozilla Rhino
37 * interpreter.
38 *
39 * @author Mike Grogan
40 * @author A. Sundararajan
41 * @since 1.6
42 */
43public final class RhinoScriptEngine extends AbstractScriptEngine
44 implements Invocable, Compilable {
45
46 private static final boolean DEBUG = false;
47
48 /* Scope where standard JavaScript objects and our
49 * extensions to it are stored. Note that these are not
50 * user defined engine level global variables. These are
51 * variables have to be there on all compliant ECMAScript
52 * scopes. We put these standard objects in this top level.
53 */
54 private RhinoTopLevel topLevel;
55
56 /* map used to store indexed properties in engine scope
57 * refer to comment on 'indexedProps' in ExternalScriptable.java.
58 */
59 private Map<Object, Object> indexedProps;
60
61 private ScriptEngineFactory factory;
62 private InterfaceImplementor implementor;
63
64 private static final int languageVersion = getLanguageVersion();
65 private static final int optimizationLevel = getOptimizationLevel();
66 static {
67 ContextFactory.initGlobal(new ContextFactory() {
68 protected Context makeContext() {
69 Context cx = super.makeContext();
70 cx.setLanguageVersion(languageVersion);
71 cx.setOptimizationLevel(optimizationLevel);
72 cx.setClassShutter(RhinoClassShutter.getInstance());
73 cx.setWrapFactory(RhinoWrapFactory.getInstance());
74 return cx;
75 }
76 });
77 }
78
79 private static final String RHINO_JS_VERSION = "rhino.js.version";
80 private static int getLanguageVersion() {
81 int version;
82 String tmp = java.security.AccessController.doPrivileged(
83 new sun.security.action.GetPropertyAction(RHINO_JS_VERSION));
84 if (tmp != null) {
85 version = Integer.parseInt((String)tmp);
86 } else {
87 version = Context.VERSION_1_8;
88 }
89 return version;
90 }
91
92 private static final String RHINO_OPT_LEVEL = "rhino.opt.level";
93 private static int getOptimizationLevel() {
94 int optLevel = -1;
95 // disable optimizer under security manager, for now.
96 if (System.getSecurityManager() == null) {
97 optLevel = Integer.getInteger(RHINO_OPT_LEVEL, -1);
98 }
99 return optLevel;
100 }
101
102 /**
103 * Creates a new instance of RhinoScriptEngine
104 */
105 public RhinoScriptEngine() {
106
107 Context cx = enterContext();
108 try {
109 topLevel = new RhinoTopLevel(cx, this);
110 } finally {
111 cx.exit();
112 }
113
114 indexedProps = new HashMap<Object, Object>();
115
116 //construct object used to implement getInterface
117 implementor = new InterfaceImplementor(this) {
118 protected boolean isImplemented(Object thiz, Class<?> iface) {
119 Context cx = enterContext();
120 try {
121 if (thiz != null && !(thiz instanceof Scriptable)) {
122 thiz = cx.toObject(thiz, topLevel);
123 }
124 Scriptable engineScope = getRuntimeScope(context);
125 Scriptable localScope = (thiz != null)? (Scriptable) thiz :
126 engineScope;
127 for (Method method : iface.getMethods()) {
128 // ignore methods of java.lang.Object class
129 if (method.getDeclaringClass() == Object.class) {
130 continue;
131 }
132 Object obj = ScriptableObject.getProperty(localScope, method.getName());
133 if (! (obj instanceof Function)) {
134 return false;
135 }
136 }
137 return true;
138 } finally {
139 cx.exit();
140 }
141 }
142
143 protected Object convertResult(Method method, Object res)
144 throws ScriptException {
145 Class desiredType = method.getReturnType();
146 if (desiredType == Void.TYPE) {
147 return null;
148 } else {
149 return Context.jsToJava(res, desiredType);
150 }
151 }
152 };
153 }
154
155 public Object eval(Reader reader, ScriptContext ctxt)
156 throws ScriptException {
157 Object ret;
158
159 Context cx = enterContext();
160 try {
161 Scriptable scope = getRuntimeScope(ctxt);
162 String filename = (String) get(ScriptEngine.FILENAME);
163 filename = filename == null ? "<Unknown source>" : filename;
164
165 ret = cx.evaluateReader(scope, reader, filename , 1, null);
166 } catch (RhinoException re) {
167 if (DEBUG) re.printStackTrace();
168 int line = (line = re.lineNumber()) == 0 ? -1 : line;
169 String msg;
170 if (re instanceof JavaScriptException) {
171 msg = String.valueOf(((JavaScriptException)re).getValue());
172 } else {
173 msg = re.toString();
174 }
175 ScriptException se = new ScriptException(msg, re.sourceName(), line);
176 se.initCause(re);
177 throw se;
178 } catch (IOException ee) {
179 throw new ScriptException(ee);
180 } finally {
181 cx.exit();
182 }
183
184 return unwrapReturnValue(ret);
185 }
186
187 public Object eval(String script, ScriptContext ctxt) throws ScriptException {
188 if (script == null) {
189 throw new NullPointerException("null script");
190 }
191 return eval(new StringReader(script) , ctxt);
192 }
193
194 public ScriptEngineFactory getFactory() {
195 if (factory != null) {
196 return factory;
197 } else {
198 return new RhinoScriptEngineFactory();
199 }
200 }
201
202 public Bindings createBindings() {
203 return new SimpleBindings();
204 }
205
206 //Invocable methods
207 public Object invokeFunction(String name, Object... args)
208 throws ScriptException, NoSuchMethodException {
209 return invoke(null, name, args);
210 }
211
212 public Object invokeMethod(Object thiz, String name, Object... args)
213 throws ScriptException, NoSuchMethodException {
214 if (thiz == null) {
215 throw new IllegalArgumentException("script object can not be null");
216 }
217 return invoke(thiz, name, args);
218 }
219
220 private Object invoke(Object thiz, String name, Object... args)
221 throws ScriptException, NoSuchMethodException {
222 Context cx = enterContext();
223 try {
224 if (name == null) {
225 throw new NullPointerException("method name is null");
226 }
227
228 if (thiz != null && !(thiz instanceof Scriptable)) {
229 thiz = cx.toObject(thiz, topLevel);
230 }
231
232 Scriptable engineScope = getRuntimeScope(context);
233 Scriptable localScope = (thiz != null)? (Scriptable) thiz :
234 engineScope;
235 Object obj = ScriptableObject.getProperty(localScope, name);
236 if (! (obj instanceof Function)) {
237 throw new NoSuchMethodException("no such method: " + name);
238 }
239
240 Function func = (Function) obj;
241 Scriptable scope = func.getParentScope();
242 if (scope == null) {
243 scope = engineScope;
244 }
245 Object result = func.call(cx, scope, localScope,
246 wrapArguments(args));
247 return unwrapReturnValue(result);
248 } catch (RhinoException re) {
249 if (DEBUG) re.printStackTrace();
250 int line = (line = re.lineNumber()) == 0 ? -1 : line;
251 ScriptException se = new ScriptException(re.toString(), re.sourceName(), line);
252 se.initCause(re);
253 throw se;
254 } finally {
255 cx.exit();
256 }
257 }
258
259 public <T> T getInterface(Class<T> clasz) {
260 try {
261 return implementor.getInterface(null, clasz);
262 } catch (ScriptException e) {
263 return null;
264 }
265 }
266
267 public <T> T getInterface(Object thiz, Class<T> clasz) {
268 if (thiz == null) {
269 throw new IllegalArgumentException("script object can not be null");
270 }
271
272 try {
273 return implementor.getInterface(thiz, clasz);
274 } catch (ScriptException e) {
275 return null;
276 }
277 }
278
279 private static final String printSource =
280 "function print(str, newline) { \n" +
281 " if (typeof(str) == 'undefined') { \n" +
282 " str = 'undefined'; \n" +
283 " } else if (str == null) { \n" +
284 " str = 'null'; \n" +
285 " } \n" +
286 " var out = context.getWriter(); \n" +
287 " if (!(out instanceof java.io.PrintWriter))\n" +
288 " out = new java.io.PrintWriter(out); \n" +
289 " out.print(String(str)); \n" +
290 " if (newline) out.print('\\n'); \n" +
291 " out.flush(); \n" +
292 "}\n" +
293 "function println(str) { \n" +
294 " print(str, true); \n" +
295 "}";
296
297 Scriptable getRuntimeScope(ScriptContext ctxt) {
298 if (ctxt == null) {
299 throw new NullPointerException("null script context");
300 }
301
302 // we create a scope for the given ScriptContext
303 Scriptable newScope = new ExternalScriptable(ctxt, indexedProps);
304
305 // Set the prototype of newScope to be 'topLevel' so that
306 // JavaScript standard objects are visible from the scope.
307 newScope.setPrototype(topLevel);
308
309 // define "context" variable in the new scope
310 newScope.put("context", newScope, ctxt);
311
312 // define "print", "println" functions in the new scope
313 Context cx = enterContext();
314 try {
315 cx.evaluateString(newScope, printSource, "print", 1, null);
316 } finally {
317 cx.exit();
318 }
319 return newScope;
320 }
321
322
323 //Compilable methods
324 public CompiledScript compile(String script) throws ScriptException {
325 return compile(new StringReader(script));
326 }
327
328 public CompiledScript compile(java.io.Reader script) throws ScriptException {
329 CompiledScript ret = null;
330 Context cx = enterContext();
331
332 try {
333 String fileName = (String) get(ScriptEngine.FILENAME);
334 if (fileName == null) {
335 fileName = "<Unknown Source>";
336 }
337
338 Scriptable scope = getRuntimeScope(context);
339 Script scr = cx.compileReader(scope, script, fileName, 1, null);
340 ret = new RhinoCompiledScript(this, scr);
341 } catch (Exception e) {
342 if (DEBUG) e.printStackTrace();
343 throw new ScriptException(e);
344 } finally {
345 cx.exit();
346 }
347 return ret;
348 }
349
350
351 //package-private helpers
352
353 static Context enterContext() {
354 // call this always so that initializer of this class runs
355 // and initializes custom wrap factory and class shutter.
356 return Context.enter();
357 }
358
359 void setEngineFactory(ScriptEngineFactory fac) {
360 factory = fac;
361 }
362
363 Object[] wrapArguments(Object[] args) {
364 if (args == null) {
365 return Context.emptyArgs;
366 }
367 Object[] res = new Object[args.length];
368 for (int i = 0; i < res.length; i++) {
369 res[i] = Context.javaToJS(args[i], topLevel);
370 }
371 return res;
372 }
373
374 Object unwrapReturnValue(Object result) {
375 if (result instanceof Wrapper) {
376 result = ( (Wrapper) result).unwrap();
377 }
378
379 return result instanceof Undefined ? null : result;
380 }
381
382 /*
383 public static void main(String[] args) throws Exception {
384 if (args.length == 0) {
385 System.out.println("No file specified");
386 return;
387 }
388
389 InputStreamReader r = new InputStreamReader(new FileInputStream(args[0]));
390 ScriptEngine engine = new RhinoScriptEngine();
391
392 engine.put("x", "y");
393 engine.put(ScriptEngine.FILENAME, args[0]);
394 engine.eval(r);
395 System.out.println(engine.get("x"));
396 }
397 */
398}