KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > js > Global


1 package org.openlaszlo.iv.flash.js;
2
3 import java.io.*;
4 import java.lang.reflect.*;
5 import org.mozilla.javascript.*;
6 import org.mozilla.javascript.serialize.*;
7 import org.mozilla.javascript.tools.shell.Environment;
8
9 /**
10  * This class provides for sharing functions across multiple threads.
11  * This is of particular interest to server applications.
12  *
13  * @author Norris Boyd
14  * @author Dmitry Skavish
15  */

16 public class Global extends ImporterTopLevel {
17
18     public Global( Context cx ) {
19         this(cx, null);
20     }
21
22     public Global( Context cx, org.openlaszlo.iv.flash.context.Context genContext ) {
23         // Define some global functions particular to the shell. Note
24
// that these functions are not part of ECMA.
25
super(cx);
26
27         this.genContext = genContext;
28
29         String JavaDoc[] names = { "print", "println", "version", "load",
30                            "loadClass", "defineClass", "spawn", "sync",
31                            "serialize", "deserialize", "getVar", "setVar" };
32         try {
33             defineFunctionProperties(names, Global.class, ScriptableObject.DONTENUM);
34         } catch (PropertyException e) {
35             throw new Error JavaDoc(); // shouldn't occur.
36
}
37         defineProperty(privateName, this, ScriptableObject.DONTENUM);
38
39         // Set up "environment" in the global scope to provide access to the
40
// System environment variables.
41
Environment.defineClass(this);
42         Environment environment = new Environment(this);
43         defineProperty("environment", environment,
44                        ScriptableObject.DONTENUM);
45
46         history = (NativeArray) cx.newArray(this, 0);
47         defineProperty("history", history, ScriptableObject.DONTENUM);
48     }
49
50     /**
51      * Print the string values of its arguments.
52      *
53      * This method is defined as a JavaScript function.
54      * Note that its arguments are of the "varargs" form, which
55      * allows it to handle an arbitrary number of arguments
56      * supplied to the JavaScript function.
57      *
58      */

59     public static Object JavaDoc print(Context cx, Scriptable thisObj,
60                                Object JavaDoc[] args, Function funObj)
61     {
62         PrintStream out = getInstance(thisObj).getOut();
63         for (int i=0; i < args.length; i++) {
64             // Convert the arbitrary JavaScript value into a string form.
65
String JavaDoc s = Context.toString(args[i]);
66             out.print(s);
67         }
68         return Context.getUndefinedValue();
69     }
70
71     /**
72      * Println the string values of its arguments.
73      *
74      * This method is defined as a JavaScript function.
75      * Note that its arguments are of the "varargs" form, which
76      * allows it to handle an arbitrary number of arguments
77      * supplied to the JavaScript function.
78      *
79      */

80     public static Object JavaDoc println(Context cx, Scriptable thisObj,
81                                Object JavaDoc[] args, Function funObj)
82     {
83         PrintStream out = getInstance(thisObj).getOut();
84         for (int i=0; i < args.length; i++) {
85             // Convert the arbitrary JavaScript value into a string form.
86
String JavaDoc s = Context.toString(args[i]);
87             out.print(s);
88         }
89         out.println();
90         return Context.getUndefinedValue();
91     }
92
93     /**
94      * Returns variable from associated generator context
95      */

96     public static Object JavaDoc getVar(Context cx, Scriptable thisObj, Object JavaDoc[] args, Function funObj) {
97         org.openlaszlo.iv.flash.context.Context myContext = (org.openlaszlo.iv.flash.context.Context) getInstance(thisObj).genContext;
98         //System.out.println("getVar: myContext="+myContext+", args.length="+args.length);
99
if( args.length > 0 && myContext != null ) {
100             String JavaDoc value = myContext.getValue(Context.toString(args[0]));
101             if( value == null ) {
102                 return Context.getUndefinedValue();
103             } else {
104                 return value;
105             }
106         } else {
107             return Context.getUndefinedValue();
108         }
109     }
110
111     /**
112      * Sets variable to associated standard generator context
113      */

114     public static Object JavaDoc setVar(Context cx, Scriptable thisObj, Object JavaDoc[] args, Function funObj) {
115         org.openlaszlo.iv.flash.context.Context myContext = (org.openlaszlo.iv.flash.context.Context) getInstance(thisObj).genContext;
116         if( args.length > 1 && myContext instanceof org.openlaszlo.iv.flash.context.StandardContext ) {
117             org.openlaszlo.iv.flash.context.StandardContext myContext1 = (org.openlaszlo.iv.flash.context.StandardContext) myContext;
118             String JavaDoc name = Context.toString(args[0]);
119             String JavaDoc value = Context.toString(args[1]);
120             myContext1.setValue(name, value);
121         }
122         return Context.getUndefinedValue();
123     }
124
125     /**
126      * Get and set the language version.
127      *
128      * This method is defined as a JavaScript function.
129      */

130     public static double version(Context cx, Scriptable thisObj,
131                                  Object JavaDoc[] args, Function funObj)
132     {
133         double result = (double) cx.getLanguageVersion();
134         if (args.length > 0) {
135             double d = cx.toNumber(args[0]);
136             cx.setLanguageVersion((int) d);
137         }
138         return result;
139     }
140
141     /**
142      * Load and execute a set of JavaScript source files.
143      *
144      * This method is defined as a JavaScript function.
145      *
146      */

147     public static void load(Context cx, Scriptable thisObj,
148                             Object JavaDoc[] args, Function funObj)
149     {
150         for (int i=0; i < args.length; i++) {
151             JSHelper.processFile(cx, thisObj, cx.toString(args[i]));
152         }
153     }
154
155     /**
156      * Load a Java class that defines a JavaScript object using the
157      * conventions outlined in ScriptableObject.defineClass.
158      * <p>
159      * This method is defined as a JavaScript function.
160      * @exception IllegalAccessException if access is not available
161      * to a reflected class member
162      * @exception InstantiationException if unable to instantiate
163      * the named class
164      * @exception InvocationTargetException if an exception is thrown
165      * during execution of methods of the named class
166      * @exception ClassDefinitionException if the format of the
167      * class causes this exception in ScriptableObject.defineClass
168      * @exception PropertyException if the format of the
169      * class causes this exception in ScriptableObject.defineClass
170      * @see org.mozilla.javascript.ScriptableObject#defineClass
171      */

172     public static void defineClass(Context cx, Scriptable thisObj,
173                                    Object JavaDoc[] args, Function funObj)
174         throws IllegalAccessException JavaDoc, InstantiationException JavaDoc,
175                InvocationTargetException, ClassDefinitionException,
176                PropertyException
177     {
178         Class JavaDoc clazz = getClass(args);
179         ScriptableObject.defineClass(thisObj, clazz);
180     }
181
182     /**
183      * Load and execute a script compiled to a class file.
184      * <p>
185      * This method is defined as a JavaScript function.
186      * When called as a JavaScript function, a single argument is
187      * expected. This argument should be the name of a class that
188      * implements the Script interface, as will any script
189      * compiled by jsc.
190      *
191      * @exception IllegalAccessException if access is not available
192      * to the class
193      * @exception InstantiationException if unable to instantiate
194      * the named class
195      * @exception InvocationTargetException if an exception is thrown
196      * during execution of methods of the named class
197      * @exception JavaScriptException if a JavaScript exception is thrown
198      * during execution of the compiled script
199      * @see org.mozilla.javascript.ScriptableObject#defineClass
200      */

201     public static void loadClass(Context cx, Scriptable thisObj,
202                                  Object JavaDoc[] args, Function funObj)
203         throws IllegalAccessException JavaDoc, InstantiationException JavaDoc,
204                InvocationTargetException, JavaScriptException
205     {
206         Class JavaDoc clazz = getClass(args);
207         if (!Script.class.isAssignableFrom(clazz)) {
208             throw Context.reportRuntimeError(IVErrorReporter.getMessage(
209                 "msg.must.implement.Script"));
210         }
211         Script script = (Script) clazz.newInstance();
212         script.exec(cx, thisObj);
213     }
214
215     private static Class JavaDoc getClass(Object JavaDoc[] args)
216         throws IllegalAccessException JavaDoc, InstantiationException JavaDoc,
217                InvocationTargetException
218     {
219         if (args.length == 0) {
220             throw Context.reportRuntimeError(IVErrorReporter.getMessage(
221                 "msg.expected.string.arg"));
222         }
223         String JavaDoc className = Context.toString(args[0]);
224         try {
225             return Class.forName(className);
226         }
227         catch (ClassNotFoundException JavaDoc cnfe) {
228             throw Context.reportRuntimeError(IVErrorReporter.getMessage(
229                 "msg.class.not.found",
230                 className));
231         }
232     }
233
234     public static void serialize(Context cx, Scriptable thisObj,
235                                  Object JavaDoc[] args, Function funObj)
236         throws IOException
237     {
238         if (args.length < 2) {
239             throw Context.reportRuntimeError(
240                 "Expected an object to serialize and a filename to write " +
241                 "the serialization to");
242         }
243         Object JavaDoc obj = args[0];
244         String JavaDoc filename = cx.toString(args[1]);
245         FileOutputStream fos = new FileOutputStream(filename);
246         Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
247         ScriptableOutputStream out = new ScriptableOutputStream(fos, scope);
248         out.writeObject(obj);
249         out.close();
250     }
251
252     public static Object JavaDoc deserialize(Context cx, Scriptable thisObj,
253                                      Object JavaDoc[] args, Function funObj)
254         throws IOException, ClassNotFoundException JavaDoc
255     {
256         if (args.length < 1) {
257             throw Context.reportRuntimeError(
258                 "Expected a filename to read the serialization from");
259         }
260         String JavaDoc filename = cx.toString(args[0]);
261         FileInputStream fis = new FileInputStream(filename);
262         Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
263         ObjectInputStream in = new ScriptableInputStream(fis, scope);
264         Object JavaDoc deserialized = in.readObject();
265         in.close();
266         return cx.toObject(deserialized, scope);
267     }
268
269     /**
270      * The spawn function runs a given function or script in a different
271      * thread.
272      *
273      * js> function g() { a = 7; }
274      * js> a = 3;
275      * 3
276      * js> spawn(g)
277      * Thread[Thread-1,5,main]
278      * js> a
279      * 3
280      */

281     public static Object JavaDoc spawn(Context cx, Scriptable thisObj, Object JavaDoc[] args,
282                                Function funObj)
283     {
284         Scriptable scope = funObj.getParentScope();
285         Runner runner;
286         if (args.length != 0 && args[0] instanceof Function) {
287             Object JavaDoc[] newArgs = null;
288             if (args.length > 1 && args[1] instanceof Scriptable) {
289                 newArgs = cx.getElements((Scriptable) args[1]);
290             }
291             runner = new Runner(scope, (Function) args[0], newArgs);
292         } else if (args.length != 0 && args[0] instanceof Script) {
293             runner = new Runner(scope, (Script) args[0]);
294         } else {
295             throw Context.reportRuntimeError(IVErrorReporter.getMessage(
296                 "msg.spawn.args"));
297         }
298         Thread JavaDoc thread = new Thread JavaDoc(runner);
299         thread.start();
300         return thread;
301     }
302
303     /**
304      * The sync function creates a synchronized function (in the sense
305      * of a Java synchronized method) from an existing function. The
306      * new function synchronizes on the <code>this</code> object of
307      * its invocation.
308      * js> var o = { f : sync(function(x) {
309      * print("entry");
310      * Packages.java.lang.Thread.sleep(x*1000);
311      * print("exit");
312      * })};
313      * js> spawn(function() {o.f(5);});
314      * Thread[Thread-0,5,main]
315      * entry
316      * js> spawn(function() {o.f(5);});
317      * Thread[Thread-1,5,main]
318      * js>
319      * exit
320      * entry
321      * exit
322      */

323     public static Object JavaDoc sync(Context cx, Scriptable thisObj, Object JavaDoc[] args,
324                                Function funObj)
325     {
326         if (args.length == 1 && args[0] instanceof Function) {
327             return new Synchronizer((Function)args[0]);
328         } else {
329             throw Context.reportRuntimeError(IVErrorReporter.getMessage(
330                 "msg.spawn.args"));
331         }
332     }
333
334     public InputStream getIn() {
335         return inStream == null ? System.in : inStream;
336     }
337
338     public void setIn(InputStream in) {
339         inStream = in;
340     }
341
342     public PrintStream getOut() {
343         return outStream == null ? System.out : outStream;
344     }
345
346     public void setOut(PrintStream out) {
347         outStream = out;
348     }
349
350     public PrintStream getErr() {
351         return errStream == null ? System.err : errStream;
352     }
353
354     public void setErr(PrintStream err) {
355         errStream = err;
356     }
357
358     static final String JavaDoc privateName = "org.openlaszlo.iv.flash.js.Global private";
359
360     public static Global getInstance(Scriptable scope) {
361         Object JavaDoc v = ScriptableObject.getProperty(scope,privateName);
362         if (v instanceof Global)
363             return (Global) v;
364         return null;
365     }
366
367     NativeArray history;
368     public InputStream inStream;
369     public PrintStream outStream;
370     public PrintStream errStream;
371     public org.openlaszlo.iv.flash.context.Context genContext;
372 }
373
374 class Runner implements Runnable JavaDoc {
375
376     Runner(Scriptable scope, Function func, Object JavaDoc[] args) {
377         this.scope = scope;
378         f = func;
379         this.args = args;
380     }
381
382     Runner(Scriptable scope, Script script) {
383         this.scope = scope;
384         s = script;
385     }
386
387     public void run() {
388         Context cx = Context.enter();
389
390         try {
391             if (f != null)
392                 f.call(cx, scope, scope, args);
393             else
394                 s.exec(cx, scope);
395         } catch (JavaScriptException e) {
396             Context.reportError(IVErrorReporter.getMessage(
397                 "msg.uncaughtJSException",
398                 e.getMessage()));
399         }
400
401         cx.exit();
402     }
403
404     private Scriptable scope;
405     private Function f;
406     private Script s;
407     private Object JavaDoc[] args;
408 }
409
410
Popular Tags