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 (13 of 18352 files). Show all

Unified · Split

13 files
  1. java/pkg/com/sun/script/javascript/ExternalScriptable.java +467 −0
  2. java/pkg/com/sun/script/javascript/JSAdapter.java +338 −0
  3. java/pkg/com/sun/script/javascript/JavaAdapter.java +106 −0
  4. java/pkg/com/sun/script/javascript/META-INF/mkfile +6 −0
  5. java/pkg/com/sun/script/javascript/META-INF/services/javax.script.ScriptEngineFactory +5 −0
  6. java/pkg/com/sun/script/javascript/META-INF/services/mkfile +2 −0
  7. java/pkg/com/sun/script/javascript/RhinoClassShutter.java +75 −0
  8. java/pkg/com/sun/script/javascript/RhinoCompiledScript.java +78 −0
  9. java/pkg/com/sun/script/javascript/RhinoScriptEngine.java +398 −0
  10. java/pkg/com/sun/script/javascript/RhinoScriptEngineFactory.java +163 −0
  11. java/pkg/com/sun/script/javascript/RhinoTopLevel.java +156 −0
  12. java/pkg/com/sun/script/javascript/RhinoWrapFactory.java +148 −0
  13. java/pkg/com/sun/script/javascript/mkfile +20 −0
java/pkg/com/sun/script/javascript/ExternalScriptable.java+467−0
@@ -0,0 +1,467 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package com.sun.script.javascript;
27+import sun.org.mozilla.javascript.internal.*;
28+import javax.script.*;
29+import java.util.*;
30+
31+/**
32+ * ExternalScriptable is an implementation of Scriptable
33+ * backed by a JSR 223 ScriptContext instance.
34+ *
35+ * @author Mike Grogan
36+ * @author A. Sundararajan
37+ * @since 1.6
38+ */
39+
40+final class ExternalScriptable implements Scriptable {
41+ /* Underlying ScriptContext that we use to store
42+ * named variables of this scope.
43+ */
44+ private ScriptContext context;
45+
46+ /* JavaScript allows variables to be named as numbers (indexed
47+ * properties). This way arrays, objects (scopes) are treated uniformly.
48+ * Note that JSR 223 API supports only String named variables and
49+ * so we can't store these in Bindings. Also, JavaScript allows name
50+ * of the property name to be even empty String! Again, JSR 223 API
51+ * does not support empty name. So, we use the following fallback map
52+ * to store such variables of this scope. This map is not exposed to
53+ * JSR 223 API. We can just script objects "as is" and need not convert.
54+ */
55+ private Map<Object, Object> indexedProps;
56+
57+ // my prototype
58+ private Scriptable prototype;
59+ // my parent scope, if any
60+ private Scriptable parent;
61+
62+ ExternalScriptable(ScriptContext context) {
63+ this(context, new HashMap<Object, Object>());
64+ }
65+
66+ ExternalScriptable(ScriptContext context, Map<Object, Object> indexedProps) {
67+ if (context == null) {
68+ throw new NullPointerException("context is null");
69+ }
70+ this.context = context;
71+ this.indexedProps = indexedProps;
72+ }
73+
74+ ScriptContext getContext() {
75+ return context;
76+ }
77+
78+ private boolean isEmpty(String name) {
79+ return name.equals("");
80+ }
81+
82+ /**
83+ * Return the name of the class.
84+ */
85+ public String getClassName() {
86+ return "Global";
87+ }
88+
89+ /**
90+ * Returns the value of the named property or NOT_FOUND.
91+ *
92+ * If the property was created using defineProperty, the
93+ * appropriate getter method is called.
94+ *
95+ * @param name the name of the property
96+ * @param start the object in which the lookup began
97+ * @return the value of the property (may be null), or NOT_FOUND
98+ */
99+ public synchronized Object get(String name, Scriptable start) {
100+ if (isEmpty(name)) {
101+ if (indexedProps.containsKey(name)) {
102+ return indexedProps.get(name);
103+ } else {
104+ return NOT_FOUND;
105+ }
106+ } else {
107+ synchronized (context) {
108+ int scope = context.getAttributesScope(name);
109+ if (scope != -1) {
110+ Object value = context.getAttribute(name, scope);
111+ return Context.javaToJS(value, this);
112+ } else {
113+ return NOT_FOUND;
114+ }
115+ }
116+ }
117+ }
118+
119+ /**
120+ * Returns the value of the indexed property or NOT_FOUND.
121+ *
122+ * @param index the numeric index for the property
123+ * @param start the object in which the lookup began
124+ * @return the value of the property (may be null), or NOT_FOUND
125+ */
126+ public synchronized Object get(int index, Scriptable start) {
127+ Integer key = new Integer(index);
128+ if (indexedProps.containsKey(index)) {
129+ return indexedProps.get(key);
130+ } else {
131+ return NOT_FOUND;
132+ }
133+ }
134+
135+ /**
136+ * Returns true if the named property is defined.
137+ *
138+ * @param name the name of the property
139+ * @param start the object in which the lookup began
140+ * @return true if and only if the property was found in the object
141+ */
142+ public synchronized boolean has(String name, Scriptable start) {
143+ if (isEmpty(name)) {
144+ return indexedProps.containsKey(name);
145+ } else {
146+ synchronized (context) {
147+ return context.getAttributesScope(name) != -1;
148+ }
149+ }
150+ }
151+
152+ /**
153+ * Returns true if the property index is defined.
154+ *
155+ * @param index the numeric index for the property
156+ * @param start the object in which the lookup began
157+ * @return true if and only if the property was found in the object
158+ */
159+ public synchronized boolean has(int index, Scriptable start) {
160+ Integer key = new Integer(index);
161+ return indexedProps.containsKey(key);
162+ }
163+
164+ /**
165+ * Sets the value of the named property, creating it if need be.
166+ *
167+ * @param name the name of the property
168+ * @param start the object whose property is being set
169+ * @param value value to set the property to
170+ */
171+ public void put(String name, Scriptable start, Object value) {
172+ if (start == this) {
173+ synchronized (this) {
174+ if (isEmpty(name)) {
175+ indexedProps.put(name, value);
176+ } else {
177+ synchronized (context) {
178+ int scope = context.getAttributesScope(name);
179+ if (scope == -1) {
180+ scope = ScriptContext.ENGINE_SCOPE;
181+ }
182+ context.setAttribute(name, jsToJava(value), scope);
183+ }
184+ }
185+ }
186+ } else {
187+ start.put(name, start, value);
188+ }
189+ }
190+
191+ /**
192+ * Sets the value of the indexed property, creating it if need be.
193+ *
194+ * @param index the numeric index for the property
195+ * @param start the object whose property is being set
196+ * @param value value to set the property to
197+ */
198+ public void put(int index, Scriptable start, Object value) {
199+ if (start == this) {
200+ synchronized (this) {
201+ indexedProps.put(new Integer(index), value);
202+ }
203+ } else {
204+ start.put(index, start, value);
205+ }
206+ }
207+
208+ /**
209+ * Removes a named property from the object.
210+ *
211+ * If the property is not found, no action is taken.
212+ *
213+ * @param name the name of the property
214+ */
215+ public synchronized void delete(String name) {
216+ if (isEmpty(name)) {
217+ indexedProps.remove(name);
218+ } else {
219+ synchronized (context) {
220+ int scope = context.getAttributesScope(name);
221+ if (scope != -1) {
222+ context.removeAttribute(name, scope);
223+ }
224+ }
225+ }
226+ }
227+
228+ /**
229+ * Removes the indexed property from the object.
230+ *
231+ * If the property is not found, no action is taken.
232+ *
233+ * @param index the numeric index for the property
234+ */
235+ public void delete(int index) {
236+ indexedProps.remove(new Integer(index));
237+ }
238+
239+ /**
240+ * Get the prototype of the object.
241+ * @return the prototype
242+ */
243+ public Scriptable getPrototype() {
244+ return prototype;
245+ }
246+
247+ /**
248+ * Set the prototype of the object.
249+ * @param prototype the prototype to set
250+ */
251+ public void setPrototype(Scriptable prototype) {
252+ this.prototype = prototype;
253+ }
254+
255+ /**
256+ * Get the parent scope of the object.
257+ * @return the parent scope
258+ */
259+ public Scriptable getParentScope() {
260+ return parent;
261+ }
262+
263+ /**
264+ * Set the parent scope of the object.
265+ * @param parent the parent scope to set
266+ */
267+ public void setParentScope(Scriptable parent) {
268+ this.parent = parent;
269+ }
270+
271+ /**
272+ * Get an array of property ids.
273+ *
274+ * Not all property ids need be returned. Those properties
275+ * whose ids are not returned are considered non-enumerable.
276+ *
277+ * @return an array of Objects. Each entry in the array is either
278+ * a java.lang.String or a java.lang.Number
279+ */
280+ public synchronized Object[] getIds() {
281+ String[] keys = getAllKeys();
282+ int size = keys.length + indexedProps.size();
283+ Object[] res = new Object[size];
284+ System.arraycopy(keys, 0, res, 0, keys.length);
285+ int i = keys.length;
286+ // now add all indexed properties
287+ for (Object index : indexedProps.keySet()) {
288+ res[i++] = index;
289+ }
290+ return res;
291+ }
292+
293+ /**
294+ * Get the default value of the object with a given hint.
295+ * The hints are String.class for type String, Number.class for type
296+ * Number, Scriptable.class for type Object, and Boolean.class for
297+ * type Boolean. <p>
298+ *
299+ * A <code>hint</code> of null means "no hint".
300+ *
301+ * See ECMA 8.6.2.6.
302+ *
303+ * @param hint the type hint
304+ * @return the default value
305+ */
306+ public Object getDefaultValue(Class typeHint) {
307+ for (int i=0; i < 2; i++) {
308+ boolean tryToString;
309+ if (typeHint == ScriptRuntime.StringClass) {
310+ tryToString = (i == 0);
311+ } else {
312+ tryToString = (i == 1);
313+ }
314+
315+ String methodName;
316+ Object[] args;
317+ if (tryToString) {
318+ methodName = "toString";
319+ args = ScriptRuntime.emptyArgs;
320+ } else {
321+ methodName = "valueOf";
322+ args = new Object[1];
323+ String hint;
324+ if (typeHint == null) {
325+ hint = "undefined";
326+ } else if (typeHint == ScriptRuntime.StringClass) {
327+ hint = "string";
328+ } else if (typeHint == ScriptRuntime.ScriptableClass) {
329+ hint = "object";
330+ } else if (typeHint == ScriptRuntime.FunctionClass) {
331+ hint = "function";
332+ } else if (typeHint == ScriptRuntime.BooleanClass
333+ || typeHint == Boolean.TYPE)
334+ {
335+ hint = "boolean";
336+ } else if (typeHint == ScriptRuntime.NumberClass ||
337+ typeHint == ScriptRuntime.ByteClass ||
338+ typeHint == Byte.TYPE ||
339+ typeHint == ScriptRuntime.ShortClass ||
340+ typeHint == Short.TYPE ||
341+ typeHint == ScriptRuntime.IntegerClass ||
342+ typeHint == Integer.TYPE ||
343+ typeHint == ScriptRuntime.FloatClass ||
344+ typeHint == Float.TYPE ||
345+ typeHint == ScriptRuntime.DoubleClass ||
346+ typeHint == Double.TYPE)
347+ {
348+ hint = "number";
349+ } else {
350+ throw Context.reportRuntimeError(
351+ "Invalid JavaScript value of type " +
352+ typeHint.toString());
353+ }
354+ args[0] = hint;
355+ }
356+ Object v = ScriptableObject.getProperty(this, methodName);
357+ if (!(v instanceof Function))
358+ continue;
359+ Function fun = (Function) v;
360+ Context cx = RhinoScriptEngine.enterContext();
361+ try {
362+ v = fun.call(cx, fun.getParentScope(), this, args);
363+ } finally {
364+ cx.exit();
365+ }
366+ if (v != null) {
367+ if (!(v instanceof Scriptable)) {
368+ return v;
369+ }
370+ if (typeHint == ScriptRuntime.ScriptableClass
371+ || typeHint == ScriptRuntime.FunctionClass)
372+ {
373+ return v;
374+ }
375+ if (tryToString && v instanceof Wrapper) {
376+ // Let a wrapped java.lang.String pass for a primitive
377+ // string.
378+ Object u = ((Wrapper)v).unwrap();
379+ if (u instanceof String)
380+ return u;
381+ }
382+ }
383+ }
384+ // fall through to error
385+ String arg = (typeHint == null) ? "undefined" : typeHint.getName();
386+ throw Context.reportRuntimeError(
387+ "Cannot find default value for object " + arg);
388+ }
389+
390+ /**
391+ * Implements the instanceof operator.
392+ *
393+ * @param instance The value that appeared on the LHS of the instanceof
394+ * operator
395+ * @return true if "this" appears in value's prototype chain
396+ *
397+ */
398+ public boolean hasInstance(Scriptable instance) {
399+ // Default for JS objects (other than Function) is to do prototype
400+ // chasing.
401+ Scriptable proto = instance.getPrototype();
402+ while (proto != null) {
403+ if (proto.equals(this)) return true;
404+ proto = proto.getPrototype();
405+ }
406+ return false;
407+ }
408+
409+ private String[] getAllKeys() {
410+ ArrayList<String> list = new ArrayList<String>();
411+ synchronized (context) {
412+ for (int scope : context.getScopes()) {
413+ Bindings bindings = context.getBindings(scope);
414+ if (bindings != null) {
415+ list.ensureCapacity(bindings.size());
416+ for (String key : bindings.keySet()) {
417+ list.add(key);
418+ }
419+ }
420+ }
421+ }
422+ String[] res = new String[list.size()];
423+ list.toArray(res);
424+ return res;
425+ }
426+
427+ /**
428+ * We convert script values to the nearest Java value.
429+ * We unwrap wrapped Java objects so that access from
430+ * Bindings.get() would return "workable" value for Java.
431+ * But, at the same time, we need to make few special cases
432+ * and hence the following function is used.
433+ */
434+ private Object jsToJava(Object jsObj) {
435+ if (jsObj instanceof Wrapper) {
436+ Wrapper njb = (Wrapper) jsObj;
437+ /* importClass feature of ImporterTopLevel puts
438+ * NativeJavaClass in global scope. If we unwrap
439+ * it, importClass won't work.
440+ */
441+ if (njb instanceof NativeJavaClass) {
442+ return njb;
443+ }
444+
445+ /* script may use Java primitive wrapper type objects
446+ * (such as java.lang.Integer, java.lang.Boolean etc)
447+ * explicitly. If we unwrap, then these script objects
448+ * will become script primitive types. For example,
449+ *
450+ * var x = new java.lang.Double(3.0); print(typeof x);
451+ *
452+ * will print 'number'. We don't want that to happen.
453+ */
454+ Object obj = njb.unwrap();
455+ if (obj instanceof Number || obj instanceof String ||
456+ obj instanceof Boolean || obj instanceof Character) {
457+ // special type wrapped -- we just leave it as is.
458+ return njb;
459+ } else {
460+ // return unwrapped object for any other object.
461+ return obj;
462+ }
463+ } else { // not-a-Java-wrapper
464+ return jsObj;
465+ }
466+ }
467+}
java/pkg/com/sun/script/javascript/JSAdapter.java+338−0
@@ -0,0 +1,338 @@
1+/*
2+ * Copyright (c) 2005, 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+
26+package com.sun.script.javascript;
27+
28+import sun.org.mozilla.javascript.internal.*;
29+import java.util.*;
30+
31+/**
32+ * JSAdapter is java.lang.reflect.Proxy equivalent for JavaScript. JSAdapter
33+ * calls specially named JavaScript methods on an adaptee object when property
34+ * access is attempted on it.
35+ *
36+ * Example:
37+ *
38+ * var y = {
39+ * __get__ : function (name) { ... }
40+ * __has__ : function (name) { ... }
41+ * __put__ : function (name, value) {...}
42+ * __delete__ : function (name) { ... }
43+ * __getIds__ : function () { ... }
44+ * };
45+ *
46+ * var x = new JSAdapter(y);
47+ *
48+ * x.i; // calls y.__get__
49+ * i in x; // calls y.__has__
50+ * x.p = 10; // calls y.__put__
51+ * delete x.p; // calls y.__delete__
52+ * for (i in x) { print(i); } // calls y.__getIds__
53+ *
54+ * If a special JavaScript method is not found in the adaptee, then JSAdapter
55+ * forwards the property access to the adaptee itself.
56+ *
57+ * JavaScript caller of adapter object is isolated from the fact that
58+ * the property access/mutation/deletion are really calls to
59+ * JavaScript methods on adaptee. Use cases include 'smart'
60+ * properties, property access tracing/debugging, encaptulation with
61+ * easy client access - in short JavaScript becomes more "Self" like.
62+ *
63+ * Note that Rhino already supports special properties like __proto__
64+ * (to set, get prototype), __parent__ (to set, get parent scope). We
65+ * follow the same double underscore nameing convention here. Similarly
66+ * the name JSAdapter is derived from JavaAdapter -- which is a facility
67+ * to extend, implement Java classes/interfaces by JavaScript.
68+ *
69+ * @author A. Sundararajan
70+ * @since 1.6
71+ */
72+public final class JSAdapter implements Scriptable, Function {
73+ private JSAdapter(Scriptable obj) {
74+ setAdaptee(obj);
75+ }
76+
77+ // initializer to setup JSAdapter prototype in the given scope
78+ public static void init(Context cx, Scriptable scope, boolean sealed)
79+ throws RhinoException {
80+ JSAdapter obj = new JSAdapter(cx.newObject(scope));
81+ obj.setParentScope(scope);
82+ obj.setPrototype(getFunctionPrototype(scope));
83+ obj.isPrototype = true;
84+ ScriptableObject.defineProperty(scope, "JSAdapter", obj,
85+ ScriptableObject.DONTENUM);
86+ }
87+
88+ public String getClassName() {
89+ return "JSAdapter";
90+ }
91+
92+ public Object get(String name, Scriptable start) {
93+ Function func = getAdapteeFunction(GET_PROP);
94+ if (func != null) {
95+ return call(func, new Object[] { name });
96+ } else {
97+ start = getAdaptee();
98+ return start.get(name, start);
99+ }
100+ }
101+
102+ public Object get(int index, Scriptable start) {
103+ Function func = getAdapteeFunction(GET_PROP);
104+ if (func != null) {
105+ return call(func, new Object[] { new Integer(index) });
106+ } else {
107+ start = getAdaptee();
108+ return start.get(index, start);
109+ }
110+ }
111+
112+ public boolean has(String name, Scriptable start) {
113+ Function func = getAdapteeFunction(HAS_PROP);
114+ if (func != null) {
115+ Object res = call(func, new Object[] { name });
116+ return Context.toBoolean(res);
117+ } else {
118+ start = getAdaptee();
119+ return start.has(name, start);
120+ }
121+ }
122+
123+ public boolean has(int index, Scriptable start) {
124+ Function func = getAdapteeFunction(HAS_PROP);
125+ if (func != null) {
126+ Object res = call(func, new Object[] { new Integer(index) });
127+ return Context.toBoolean(res);
128+ } else {
129+ start = getAdaptee();
130+ return start.has(index, start);
131+ }
132+ }
133+
134+ public void put(String name, Scriptable start, Object value) {
135+ if (start == this) {
136+ Function func = getAdapteeFunction(PUT_PROP);
137+ if (func != null) {
138+ call(func, new Object[] { name, value });
139+ } else {
140+ start = getAdaptee();
141+ start.put(name, start, value);
142+ }
143+ } else {
144+ start.put(name, start, value);
145+ }
146+ }
147+
148+ public void put(int index, Scriptable start, Object value) {
149+ if (start == this) {
150+ Function func = getAdapteeFunction(PUT_PROP);
151+ if( func != null) {
152+ call(func, new Object[] { new Integer(index), value });
153+ } else {
154+ start = getAdaptee();
155+ start.put(index, start, value);
156+ }
157+ } else {
158+ start.put(index, start, value);
159+ }
160+ }
161+
162+ public void delete(String name) {
163+ Function func = getAdapteeFunction(DEL_PROP);
164+ if (func != null) {
165+ call(func, new Object[] { name });
166+ } else {
167+ getAdaptee().delete(name);
168+ }
169+ }
170+
171+ public void delete(int index) {
172+ Function func = getAdapteeFunction(DEL_PROP);
173+ if (func != null) {
174+ call(func, new Object[] { new Integer(index) });
175+ } else {
176+ getAdaptee().delete(index);
177+ }
178+ }
179+
180+ public Scriptable getPrototype() {
181+ return prototype;
182+ }
183+
184+ public void setPrototype(Scriptable prototype) {
185+ this.prototype = prototype;
186+ }
187+
188+ public Scriptable getParentScope() {
189+ return parent;
190+ }
191+
192+ public void setParentScope(Scriptable parent) {
193+ this.parent = parent;
194+ }
195+
196+ public Object[] getIds() {
197+ Function func = getAdapteeFunction(GET_PROPIDS);
198+ if (func != null) {
199+ Object val = call(func, new Object[0]);
200+ // in most cases, adaptee would return native JS array
201+ if (val instanceof NativeArray) {
202+ NativeArray array = (NativeArray) val;
203+ Object[] res = new Object[(int)array.getLength()];
204+ for (int index = 0; index < res.length; index++) {
205+ res[index] = mapToId(array.get(index, array));
206+ }
207+ return res;
208+ } else if (val instanceof NativeJavaArray) {
209+ // may be attempt wrapped Java array
210+ Object tmp = ((NativeJavaArray)val).unwrap();
211+ Object[] res;
212+ if (tmp.getClass() == Object[].class) {
213+ Object[] array = (Object[]) tmp;
214+ res = new Object[array.length];
215+ for (int index = 0; index < array.length; index++) {
216+ res[index] = mapToId(array[index]);
217+ }
218+ } else {
219+ // just return an empty array
220+ res = Context.emptyArgs;
221+ }
222+ return res;
223+ } else {
224+ // some other return type, just return empty array
225+ return Context.emptyArgs;
226+ }
227+ } else {
228+ return getAdaptee().getIds();
229+ }
230+ }
231+
232+ public boolean hasInstance(Scriptable scriptable) {
233+ if (scriptable instanceof JSAdapter) {
234+ return true;
235+ } else {
236+ Scriptable proto = scriptable.getPrototype();
237+ while (proto != null) {
238+ if (proto.equals(this)) return true;
239+ proto = proto.getPrototype();
240+ }
241+ return false;
242+ }
243+ }
244+
245+ public Object getDefaultValue(Class hint) {
246+ return getAdaptee().getDefaultValue(hint);
247+ }
248+
249+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
250+ Object[] args)
251+ throws RhinoException {
252+ if (isPrototype) {
253+ return construct(cx, scope, args);
254+ } else {
255+ Scriptable tmp = getAdaptee();
256+ if (tmp instanceof Function) {
257+ return ((Function)tmp).call(cx, scope, tmp, args);
258+ } else {
259+ throw Context.reportRuntimeError("TypeError: not a function");
260+ }
261+ }
262+ }
263+
264+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
265+ throws RhinoException {
266+ if (isPrototype) {
267+ Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
268+ JSAdapter newObj;
269+ if (args.length > 0) {
270+ newObj = new JSAdapter(Context.toObject(args[0], topLevel));
271+ } else {
272+ throw Context.reportRuntimeError("JSAdapter requires adaptee");
273+ }
274+ return newObj;
275+ } else {
276+ Scriptable tmp = getAdaptee();
277+ if (tmp instanceof Function) {
278+ return ((Function)tmp).construct(cx, scope, args);
279+ } else {
280+ throw Context.reportRuntimeError("TypeError: not a constructor");
281+ }
282+ }
283+ }
284+
285+ public Scriptable getAdaptee() {
286+ return adaptee;
287+ }
288+
289+ public void setAdaptee(Scriptable adaptee) {
290+ if (adaptee == null) {
291+ throw new NullPointerException("adaptee can not be null");
292+ }
293+ this.adaptee = adaptee;
294+ }
295+
296+ //-- internals only below this point
297+
298+ // map a property id. Property id can only be an Integer or String
299+ private Object mapToId(Object tmp) {
300+ if (tmp instanceof Double) {
301+ return new Integer(((Double)tmp).intValue());
302+ } else {
303+ return Context.toString(tmp);
304+ }
305+ }
306+
307+ private static Scriptable getFunctionPrototype(Scriptable scope) {
308+ return ScriptableObject.getFunctionPrototype(scope);
309+ }
310+
311+ private Function getAdapteeFunction(String name) {
312+ Object o = ScriptableObject.getProperty(getAdaptee(), name);
313+ return (o instanceof Function)? (Function)o : null;
314+ }
315+
316+ private Object call(Function func, Object[] args) {
317+ Context cx = Context.getCurrentContext();
318+ Scriptable thisObj = getAdaptee();
319+ Scriptable scope = func.getParentScope();
320+ try {
321+ return func.call(cx, scope, thisObj, args);
322+ } catch (RhinoException re) {
323+ throw Context.reportRuntimeError(re.getMessage());
324+ }
325+ }
326+
327+ private Scriptable prototype;
328+ private Scriptable parent;
329+ private Scriptable adaptee;
330+ private boolean isPrototype;
331+
332+ // names of adaptee JavaScript functions
333+ private static final String GET_PROP = "__get__";
334+ private static final String HAS_PROP = "__has__";
335+ private static final String PUT_PROP = "__put__";
336+ private static final String DEL_PROP = "__delete__";
337+ private static final String GET_PROPIDS = "__getIds__";
338+}
java/pkg/com/sun/script/javascript/JavaAdapter.java+106−0
@@ -0,0 +1,106 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package com.sun.script.javascript;
27+
28+import javax.script.Invocable;
29+import sun.org.mozilla.javascript.internal.*;
30+
31+/**
32+ * This class implements Rhino-like JavaAdapter to help implement a Java
33+ * interface in JavaScript. We support this using Invocable.getInterface.
34+ * Using this JavaAdapter, script author could write:
35+ *
36+ * var r = new java.lang.Runnable() {
37+ * run: function() { script... }
38+ * };
39+ *
40+ * r.run();
41+ * new java.lang.Thread(r).start();
42+ *
43+ * Note that Rhino's JavaAdapter support allows extending a Java class and/or
44+ * implementing one or more interfaces. This JavaAdapter implementation does
45+ * not support these.
46+ *
47+ * @author A. Sundararajan
48+ * @since 1.6
49+ */
50+final class JavaAdapter extends ScriptableObject implements Function {
51+ private JavaAdapter(Invocable engine) {
52+ this.engine = engine;
53+ }
54+
55+ static void init(Context cx, Scriptable scope, boolean sealed)
56+ throws RhinoException {
57+ RhinoTopLevel topLevel = (RhinoTopLevel) scope;
58+ Invocable engine = topLevel.getScriptEngine();
59+ JavaAdapter obj = new JavaAdapter(engine);
60+ obj.setParentScope(scope);
61+ obj.setPrototype(getFunctionPrototype(scope));
62+ /*
63+ * Note that we can't use defineProperty. A property of this
64+ * name is already defined in Context.initStandardObjects. We
65+ * simply overwrite the property value!
66+ */
67+ ScriptableObject.putProperty(topLevel, "JavaAdapter", obj);
68+ }
69+
70+ public String getClassName() {
71+ return "JavaAdapter";
72+ }
73+
74+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
75+ Object[] args) throws RhinoException {
76+ return construct(cx, scope, args);
77+ }
78+
79+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
80+ throws RhinoException {
81+ if (args.length == 2) {
82+ Class<?> clazz = null;
83+ Object obj1 = args[0];
84+ if (obj1 instanceof Wrapper) {
85+ Object o = ((Wrapper)obj1).unwrap();
86+ if (o instanceof Class && ((Class)o).isInterface()) {
87+ clazz = (Class) o;
88+ }
89+ } else if (obj1 instanceof Class) {
90+ if (((Class)obj1).isInterface()) {
91+ clazz = (Class) obj1;
92+ }
93+ }
94+ if (clazz == null) {
95+ throw Context.reportRuntimeError("JavaAdapter: first arg should be interface Class");
96+ }
97+
98+ Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
99+ return cx.toObject(engine.getInterface(args[1], clazz), topLevel);
100+ } else {
101+ throw Context.reportRuntimeError("JavaAdapter requires two arguments");
102+ }
103+ }
104+
105+ private Invocable engine;
106+}
java/pkg/com/sun/script/javascript/META-INF/mkfile+6−0
@@ -0,0 +1,6 @@
1+<../../../../../../../mkconfig
2+
3+DIRS=\
4+ services\
5+
6+<$ROOT/mkfiles/mksubdirs
java/pkg/com/sun/script/javascript/META-INF/services/javax.script.ScriptEngineFactory+5−0
@@ -0,0 +1,5 @@
1+
2+#script engines supported
3+
4+com.sun.script.javascript.RhinoScriptEngineFactory #javascript
5+
java/pkg/com/sun/script/javascript/META-INF/services/mkfile+2−0
@@ -0,0 +1,2 @@
1+<../../../../../../../../mkconfig
2+
java/pkg/com/sun/script/javascript/RhinoClassShutter.java+75−0
@@ -0,0 +1,75 @@
1+/*
2+ * Copyright (c) 2005, 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+
26+package com.sun.script.javascript;
27+
28+import java.util.*;
29+import sun.org.mozilla.javascript.internal.*;
30+
31+/**
32+ * This class prevents script access to certain sensitive classes.
33+ * Note that this class checks over and above SecurityManager. i.e., although
34+ * a SecurityManager would pass, class shutter may still prevent access.
35+ *
36+ * @author A. Sundararajan
37+ * @since 1.6
38+ */
39+final class RhinoClassShutter implements ClassShutter {
40+ private static Map<String, Boolean> protectedClasses;
41+ private static RhinoClassShutter theInstance;
42+
43+ private RhinoClassShutter() {
44+ }
45+
46+ static synchronized ClassShutter getInstance() {
47+ if (theInstance == null) {
48+ theInstance = new RhinoClassShutter();
49+ protectedClasses = new HashMap<String, Boolean>();
50+
51+ // For now, we just have AccessController. Allowing scripts
52+ // to this class will allow it to execute doPrivileged in
53+ // bootstrap context. We can add more classes for other reasons.
54+ protectedClasses.put("java.security.AccessController", Boolean.TRUE);
55+ }
56+ return theInstance;
57+ }
58+
59+ public boolean visibleToScripts(String fullClassName) {
60+ // first do the security check.
61+ SecurityManager sm = System.getSecurityManager();
62+ if (sm != null) {
63+ int i = fullClassName.lastIndexOf(".");
64+ if (i != -1) {
65+ try {
66+ sm.checkPackageAccess(fullClassName.substring(0, i));
67+ } catch (SecurityException se) {
68+ return false;
69+ }
70+ }
71+ }
72+ // now, check is it a protected class.
73+ return protectedClasses.get(fullClassName) == null;
74+ }
75+}
java/pkg/com/sun/script/javascript/RhinoCompiledScript.java+78−0
@@ -0,0 +1,78 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package com.sun.script.javascript;
27+import javax.script.*;
28+import sun.org.mozilla.javascript.internal.*;
29+
30+/**
31+ * Represents compiled JavaScript code.
32+ *
33+ * @author Mike Grogan
34+ * @since 1.6
35+ */
36+final class RhinoCompiledScript extends CompiledScript {
37+
38+ private RhinoScriptEngine engine;
39+ private Script script;
40+
41+
42+ RhinoCompiledScript(RhinoScriptEngine engine, Script script) {
43+ this.engine = engine;
44+ this.script = script;
45+ }
46+
47+ public Object eval(ScriptContext context) throws ScriptException {
48+
49+ Object result = null;
50+ Context cx = RhinoScriptEngine.enterContext();
51+ try {
52+
53+ Scriptable scope = engine.getRuntimeScope(context);
54+ Object ret = script.exec(cx, scope);
55+ result = engine.unwrapReturnValue(ret);
56+ } catch (RhinoException re) {
57+ int line = (line = re.lineNumber()) == 0 ? -1 : line;
58+ String msg;
59+ if (re instanceof JavaScriptException) {
60+ msg = String.valueOf(((JavaScriptException)re).getValue());
61+ } else {
62+ msg = re.toString();
63+ }
64+ ScriptException se = new ScriptException(msg, re.sourceName(), line);
65+ se.initCause(re);
66+ throw se;
67+ } finally {
68+ Context.exit();
69+ }
70+
71+ return result;
72+ }
73+
74+ public ScriptEngine getEngine() {
75+ return engine;
76+ }
77+
78+}
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+
26+package com.sun.script.javascript;
27+import com.sun.script.util.*;
28+import javax.script.*;
29+import sun.org.mozilla.javascript.internal.*;
30+import java.lang.reflect.Method;
31+import java.io.*;
32+import 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+ */
43+public 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+}
java/pkg/com/sun/script/javascript/RhinoScriptEngineFactory.java+163−0
@@ -0,0 +1,163 @@
1+/*
2+ * Copyright (c) 2005, 2010, 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+
26+package com.sun.script.javascript;
27+import javax.script.*;
28+import java.util.*;
29+import sun.org.mozilla.javascript.internal.*;
30+import com.sun.script.util.*;
31+
32+/**
33+ * Factory to create RhinoScriptEngine
34+ *
35+ * @author Mike Grogan
36+ * @since 1.6
37+ */
38+public class RhinoScriptEngineFactory extends ScriptEngineFactoryBase {
39+
40+ public RhinoScriptEngineFactory() {
41+ }
42+
43+ public List<String> getExtensions() {
44+ return extensions;
45+ }
46+
47+ public List<String> getMimeTypes() {
48+ return mimeTypes;
49+ }
50+
51+ public List<String> getNames() {
52+ return names;
53+ }
54+
55+ public Object getParameter(String key) {
56+ if (key.equals(ScriptEngine.NAME)) {
57+ return "javascript";
58+ } else if (key.equals(ScriptEngine.ENGINE)) {
59+ return "Mozilla Rhino";
60+ } else if (key.equals(ScriptEngine.ENGINE_VERSION)) {
61+ return "1.7 release 3 PRERELEASE";
62+ } else if (key.equals(ScriptEngine.LANGUAGE)) {
63+ return "ECMAScript";
64+ } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) {
65+ return "1.8";
66+ } else if (key.equals("THREADING")) {
67+ return "MULTITHREADED";
68+ } else {
69+ throw new IllegalArgumentException("Invalid key");
70+ }
71+ }
72+
73+ public ScriptEngine getScriptEngine() {
74+ RhinoScriptEngine ret = new RhinoScriptEngine();
75+ ret.setEngineFactory(this);
76+ return ret;
77+ }
78+
79+ public String getMethodCallSyntax(String obj, String method, String... args) {
80+
81+ String ret = obj + "." + method + "(";
82+ int len = args.length;
83+ if (len == 0) {
84+ ret += ")";
85+ return ret;
86+ }
87+
88+ for (int i = 0; i < len; i++) {
89+ ret += args[i];
90+ if (i != len - 1) {
91+ ret += ",";
92+ } else {
93+ ret += ")";
94+ }
95+ }
96+ return ret;
97+ }
98+
99+ public String getOutputStatement(String toDisplay) {
100+ StringBuffer buf = new StringBuffer();
101+ int len = toDisplay.length();
102+ buf.append("print(\"");
103+ for (int i = 0; i < len; i++) {
104+ char ch = toDisplay.charAt(i);
105+ switch (ch) {
106+ case '"':
107+ buf.append("\\\"");
108+ break;
109+ case '\\':
110+ buf.append("\\\\");
111+ break;
112+ default:
113+ buf.append(ch);
114+ break;
115+ }
116+ }
117+ buf.append("\")");
118+ return buf.toString();
119+ }
120+
121+ public String getProgram(String... statements) {
122+ int len = statements.length;
123+ String ret = "";
124+ for (int i = 0; i < len; i++) {
125+ ret += statements[i] + ";";
126+ }
127+
128+ return ret;
129+ }
130+
131+ /*
132+ public static void main(String[] args) {
133+ RhinoScriptEngineFactory fact = new RhinoScriptEngineFactory();
134+ System.out.println(fact.getParameter(ScriptEngine.ENGINE_VERSION));
135+ }
136+ */
137+
138+ private static List<String> names;
139+ private static List<String> mimeTypes;
140+ private static List<String> extensions;
141+
142+ static {
143+ names = new ArrayList<String>(6);
144+ names.add("js");
145+ names.add("rhino");
146+ names.add("JavaScript");
147+ names.add("javascript");
148+ names.add("ECMAScript");
149+ names.add("ecmascript");
150+ names = Collections.unmodifiableList(names);
151+
152+ mimeTypes = new ArrayList<String>(4);
153+ mimeTypes.add("application/javascript");
154+ mimeTypes.add("application/ecmascript");
155+ mimeTypes.add("text/javascript");
156+ mimeTypes.add("text/ecmascript");
157+ mimeTypes = Collections.unmodifiableList(mimeTypes);
158+
159+ extensions = new ArrayList<String>(1);
160+ extensions.add("js");
161+ extensions = Collections.unmodifiableList(extensions);
162+ }
163+}
java/pkg/com/sun/script/javascript/RhinoTopLevel.java+156−0
@@ -0,0 +1,156 @@
1+/*
2+ * Copyright (c) 2005, 2010, 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+
26+package com.sun.script.javascript;
27+
28+import sun.org.mozilla.javascript.internal.*;
29+import javax.script.*;
30+
31+/**
32+ * This class serves as top level scope for Rhino. This class adds
33+ * 3 top level functions (bindings, scope, sync) and two constructors
34+ * (JSAdapter, JavaAdapter).
35+ *
36+ * @author A. Sundararajan
37+ * @since 1.6
38+ */
39+public final class RhinoTopLevel extends ImporterTopLevel {
40+ RhinoTopLevel(Context cx, RhinoScriptEngine engine) {
41+ super(cx);
42+ this.engine = engine;
43+
44+
45+ // initialize JSAdapter lazily. Reduces footprint & startup time.
46+ new LazilyLoadedCtor(this, "JSAdapter",
47+ "com.sun.script.javascript.JSAdapter",
48+ false);
49+
50+ /*
51+ * initialize JavaAdapter. We can't lazy initialize this because
52+ * lazy initializer attempts to define a new property. But, JavaAdapter
53+ * is an exisiting property that we overwrite.
54+ */
55+ JavaAdapter.init(cx, this, false);
56+
57+ // add top level functions
58+ String names[] = { "bindings", "scope", "sync" };
59+ defineFunctionProperties(names, RhinoTopLevel.class,
60+ ScriptableObject.DONTENUM);
61+ }
62+
63+ /**
64+ * The bindings function takes a JavaScript scope object
65+ * of type ExternalScriptable and returns the underlying Bindings
66+ * instance.
67+ *
68+ * var page = scope(pageBindings);
69+ * with (page) {
70+ * // code that uses page scope
71+ * }
72+ * var b = bindings(page);
73+ * // operate on bindings here.
74+ */
75+ public static Object bindings(Context cx, Scriptable thisObj, Object[] args,
76+ Function funObj) {
77+ if (args.length == 1) {
78+ Object arg = args[0];
79+ if (arg instanceof Wrapper) {
80+ arg = ((Wrapper)arg).unwrap();
81+ }
82+ if (arg instanceof ExternalScriptable) {
83+ ScriptContext ctx = ((ExternalScriptable)arg).getContext();
84+ Bindings bind = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
85+ return Context.javaToJS(bind,
86+ ScriptableObject.getTopLevelScope(thisObj));
87+ }
88+ }
89+ return cx.getUndefinedValue();
90+ }
91+
92+ /**
93+ * The scope function creates a new JavaScript scope object
94+ * with given Bindings object as backing store. This can be used
95+ * to create a script scope based on arbitrary Bindings instance.
96+ * For example, in webapp scenario, a 'page' level Bindings instance
97+ * may be wrapped as a scope and code can be run in JavaScripe 'with'
98+ * statement:
99+ *
100+ * var page = scope(pageBindings);
101+ * with (page) {
102+ * // code that uses page scope
103+ * }
104+ */
105+ public static Object scope(Context cx, Scriptable thisObj, Object[] args,
106+ Function funObj) {
107+ if (args.length == 1) {
108+ Object arg = args[0];
109+ if (arg instanceof Wrapper) {
110+ arg = ((Wrapper)arg).unwrap();
111+ }
112+ if (arg instanceof Bindings) {
113+ ScriptContext ctx = new SimpleScriptContext();
114+ ctx.setBindings((Bindings)arg, ScriptContext.ENGINE_SCOPE);
115+ Scriptable res = new ExternalScriptable(ctx);
116+ res.setPrototype(ScriptableObject.getObjectPrototype(thisObj));
117+ res.setParentScope(ScriptableObject.getTopLevelScope(thisObj));
118+ return res;
119+ }
120+ }
121+ return cx.getUndefinedValue();
122+ }
123+
124+ /**
125+ * The sync function creates a synchronized function (in the sense
126+ * of a Java synchronized method) from an existing function. The
127+ * new function synchronizes on the <code>this</code> object of
128+ * its invocation.
129+ * js> var o = { f : sync(function(x) {
130+ * print("entry");
131+ * Packages.java.lang.Thread.sleep(x*1000);
132+ * print("exit");
133+ * })};
134+ * js> thread(function() {o.f(5);});
135+ * entry
136+ * js> thread(function() {o.f(5);});
137+ * js>
138+ * exit
139+ * entry
140+ * exit
141+ */
142+ public static Object sync(Context cx, Scriptable thisObj, Object[] args,
143+ Function funObj) {
144+ if (args.length == 1 && args[0] instanceof Function) {
145+ return new Synchronizer((Function)args[0]);
146+ } else {
147+ throw Context.reportRuntimeError("wrong argument(s) for sync");
148+ }
149+ }
150+
151+ RhinoScriptEngine getScriptEngine() {
152+ return engine;
153+ }
154+
155+ private RhinoScriptEngine engine;
156+}
java/pkg/com/sun/script/javascript/RhinoWrapFactory.java+148−0
@@ -0,0 +1,148 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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+
26+package com.sun.script.javascript;
27+
28+import java.lang.reflect.*;
29+import static sun.security.util.SecurityConstants.*;
30+import sun.org.mozilla.javascript.internal.*;
31+
32+/**
33+ * This wrap factory is used for security reasons. JSR 223 script
34+ * engine interface and JavaScript engine classes are run as bootstrap
35+ * classes. For example, java.lang.Class.forName method (when called without
36+ * class loader) uses caller's class loader. This may be exploited by script
37+ * authors to access classes otherwise not accessible. For example,
38+ * classes in sun.* namespace are normally not accessible to untrusted
39+ * code and hence should not be accessible to JavaScript run from
40+ * untrusted code.
41+ *
42+ * @author A. Sundararajan
43+ * @since 1.6
44+ */
45+final class RhinoWrapFactory extends WrapFactory {
46+ private RhinoWrapFactory() {}
47+ private static RhinoWrapFactory theInstance;
48+
49+ static synchronized WrapFactory getInstance() {
50+ if (theInstance == null) {
51+ theInstance = new RhinoWrapFactory();
52+ }
53+ return theInstance;
54+ }
55+
56+ // We use instance of this class to wrap security sensitive
57+ // Java object. Please refer below.
58+ private static class RhinoJavaObject extends NativeJavaObject {
59+ RhinoJavaObject(Scriptable scope, Object obj, Class type) {
60+ // we pass 'null' to object. NativeJavaObject uses
61+ // passed 'type' to reflect fields and methods when
62+ // object is null.
63+ super(scope, null, type);
64+
65+ // Now, we set actual object. 'javaObject' is protected
66+ // field of NativeJavaObject.
67+ javaObject = obj;
68+ }
69+ }
70+
71+ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
72+ Object javaObject, Class staticType) {
73+ SecurityManager sm = System.getSecurityManager();
74+ ClassShutter classShutter = RhinoClassShutter.getInstance();
75+ if (javaObject instanceof ClassLoader) {
76+ // Check with Security Manager whether we can expose a
77+ // ClassLoader...
78+ if (sm != null) {
79+ sm.checkPermission(GET_CLASSLOADER_PERMISSION);
80+ }
81+ // if we fall through here, check permission succeeded.
82+ return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
83+ } else {
84+ String name = null;
85+ if (javaObject instanceof Class) {
86+ name = ((Class)javaObject).getName();
87+ } else if (javaObject instanceof Member) {
88+ Member member = (Member) javaObject;
89+ // Check member access. Don't allow reflective access to
90+ // non-public members. Note that we can't call checkMemberAccess
91+ // because that expects exact stack depth!
92+ if (sm != null && !Modifier.isPublic(member.getModifiers())) {
93+ return null;
94+ }
95+ name = member.getDeclaringClass().getName();
96+ }
97+ // Now, make sure that no ClassShutter prevented Class or Member
98+ // of it is accessed reflectively. Note that ClassShutter may
99+ // prevent access to a class, even though SecurityManager permit.
100+ if (name != null) {
101+ if (!classShutter.visibleToScripts(name)) {
102+ return null;
103+ } else {
104+ return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
105+ }
106+ }
107+ }
108+
109+ // we have got some non-reflective object.
110+ Class dynamicType = javaObject.getClass();
111+ String name = dynamicType.getName();
112+ if (!classShutter.visibleToScripts(name)) {
113+ // Object of some sensitive class (such as sun.net.www.*
114+ // objects returned from public method of java.net.URL class.
115+ // We expose this object as though it is an object of some
116+ // super class that is safe for access.
117+
118+ Class type = null;
119+
120+ // Whenever a Java Object is wrapped, we are passed with a
121+ // staticType which is the type found from environment. For
122+ // example, method return type known from signature. The dynamic
123+ // type would be the actual Class of the actual returned object.
124+ // If the staticType is an interface, we just use that type.
125+ if (staticType != null && staticType.isInterface()) {
126+ type = staticType;
127+ } else {
128+ // dynamicType is always a class type and never an interface.
129+ // find an accessible super class of the dynamic type.
130+ while (dynamicType != null) {
131+ dynamicType = dynamicType.getSuperclass();
132+ name = dynamicType.getName();
133+ if (classShutter.visibleToScripts(name)) {
134+ type = dynamicType; break;
135+ }
136+ }
137+ // atleast java.lang.Object has to be accessible. So, when
138+ // we reach here, type variable should not be null.
139+ assert type != null:
140+ "even java.lang.Object is not accessible?";
141+ }
142+ // create custom wrapper with the 'safe' type.
143+ return new RhinoJavaObject(scope, javaObject, type);
144+ } else {
145+ return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
146+ }
147+ }
148+}
java/pkg/com/sun/script/javascript/mkfile+20−0
@@ -0,0 +1,20 @@
1+<../../../../../../mkconfig
2+
3+DIRS=\
4+ META-INF\
5+
6+TARG=\
7+ ExternalScriptable.dis\
8+ JavaAdapter.dis\
9+ JSAdapter.dis\
10+ RhinoClassShutter.dis\
11+ RhinoCompiledScript.dis\
12+ RhinoScriptEngine.dis\
13+ RhinoScriptEngineFactory.dis\
14+ RhinoTopLevel.dis\
15+ RhinoWrapFactory.dis\
16+
17+DISBIN=$ROOT/java/dis/java/java/com/sun/script/javascript
18+
19+<$ROOT/mkfiles/mkjava
20+<$ROOT/mkfiles/mksubdirs