001: package org.openlaszlo.iv.flash.js;
002:
003: import java.io.*;
004: import java.net.URL;
005: import java.net.MalformedURLException;
006: import java.util.*;
007: import java.lang.reflect.*;
008: import org.mozilla.javascript.*;
009: import org.mozilla.javascript.tools.ToolErrorReporter;
010:
011: import org.openlaszlo.iv.flash.util.*;
012:
013: /**
014: * @author Norris Boyd
015: */
016: public class JSHelper {
017:
018: private static Context init(String args[], PrintStream out,
019: org.openlaszlo.iv.flash.context.Context genContext) {
020: Context cx = Context.enter();
021: // Create the top-level scope object.
022: global = getGlobal(genContext);
023: global.setOut(out);
024: errorReporter = new IVErrorReporter(false);
025: cx.setErrorReporter(errorReporter);
026: cx.setLanguageVersion(Context.VERSION_1_5);
027: cx.setOptimizationLevel(-1);
028:
029: // define "arguments" array in the top-level object
030: if (args == null)
031: args = new String[0];
032: Object[] array = args;
033: Scriptable argsObj = cx.newArray(global, args);
034: global.defineProperty("arguments", argsObj,
035: ScriptableObject.DONTENUM);
036: return cx;
037: }
038:
039: /**
040: * Execute the given arguments
041: */
042: public static int execFile(String fileName, String args[],
043: PrintStream out) {
044:
045: Context cx = init(args, out, null);
046:
047: processFile(cx, global, fileName);
048:
049: cx.exit();
050:
051: return exitCode;
052: }
053:
054: /**
055: * Execute the given arguments
056: */
057: public static int execFile(String fileName, String args[],
058: PrintStream out,
059: org.openlaszlo.iv.flash.context.Context genContext) {
060:
061: Context cx = init(args, out, genContext);
062:
063: processFile(cx, global, fileName);
064:
065: cx.exit();
066:
067: return exitCode;
068: }
069:
070: /**
071: * Execute the given arguments
072: */
073: public static int execString(String js_text, String args[],
074: PrintStream out,
075: org.openlaszlo.iv.flash.context.Context genContext) {
076: Context cx = init(args, out, genContext);
077:
078: StringReader in = new StringReader(js_text);
079: String source = js_text.length() > 20 ? js_text
080: .substring(0, 20)
081: + "..." : js_text;
082: evaluateReader(cx, global, in, source, 1);
083:
084: cx.exit();
085: return exitCode;
086: }
087:
088: public static Global getGlobal() {
089: return getGlobal(null);
090: }
091:
092: public static Global getGlobal(
093: org.openlaszlo.iv.flash.context.Context genContext) {
094: if (global == null) {
095: try {
096: global = new Global(Context.enter(), genContext);
097: } finally {
098: Context.exit();
099: }
100: }
101: if (global != null) {
102: global.genContext = genContext;
103: }
104: return global;
105: }
106:
107: public static void processFile(Context cx, Scriptable scope,
108: String filename) {
109: Reader in = null;
110: // Try filename first as URL
111: try {
112: URL url = new URL(filename);
113: InputStream is = url.openStream();
114: in = new BufferedReader(new InputStreamReader(is));
115: } catch (MalformedURLException mfex) {
116: // fall through to try it as a file
117: in = null;
118: } catch (IOException ioex) {
119: Context.reportError(IVErrorReporter.getMessage(
120: "msg.couldnt.open.url", filename, ioex.toString()));
121: exitCode = EXITCODE_FILE_NOT_FOUND;
122: return;
123: }
124:
125: if (in == null) {
126: // Try filename as file
127: try {
128: in = new FileReader(filename);
129: filename = new java.io.File(filename)
130: .getCanonicalPath();
131: } catch (FileNotFoundException ex) {
132: Context.reportError(IVErrorReporter.getMessage(
133: "msg.couldnt.open", filename));
134: exitCode = EXITCODE_FILE_NOT_FOUND;
135: return;
136: } catch (IOException ioe) {
137: Log.logRB(Resource.JSERROR, ioe);
138: }
139: }
140: // Here we evalute the entire contents of the file as
141: // a script. Text is printed only if the print() function
142: // is called.
143: evaluateReader(cx, scope, in, filename, 1);
144: }
145:
146: public static Object evaluateReader(Context cx, Scriptable scope,
147: Reader in, String sourceName, int lineno) {
148: Object result = cx.getUndefinedValue();
149: try {
150: result = cx.evaluateReader(scope, in, sourceName, lineno,
151: null);
152: } catch (WrappedException we) {
153: Log.logRB(Resource.JSERROR, we);
154: } catch (EcmaError ee) {
155: String msg = IVErrorReporter.getMessage(
156: "msg.uncaughtJSException", ee.toString());
157: exitCode = EXITCODE_RUNTIME_ERROR;
158: if (ee.getSourceName() != null) {
159: Context.reportError(msg, ee.getSourceName(), ee
160: .getLineNumber(), ee.getLineSource(), ee
161: .getColumnNumber());
162: } else {
163: Context.reportError(msg);
164: }
165: } catch (EvaluatorException ee) {
166: // Already printed message.
167: exitCode = EXITCODE_RUNTIME_ERROR;
168: } catch (JavaScriptException jse) {
169: // Need to propagate ThreadDeath exceptions.
170: Object value = jse.getValue();
171: if (value instanceof ThreadDeath)
172: throw (ThreadDeath) value;
173: exitCode = EXITCODE_RUNTIME_ERROR;
174: Context.reportError(IVErrorReporter.getMessage(
175: "msg.uncaughtJSException", jse.getMessage()));
176: } catch (IOException ioe) {
177: Log.logRB(Resource.JSERROR, ioe);
178: } finally {
179: try {
180: in.close();
181: } catch (IOException ioe) {
182: Log.logRB(Resource.JSERROR, ioe);
183: }
184: }
185: return result;
186: }
187:
188: /* public static Node parseReader(Context cx, Scriptable scope, Reader in, String sourceName, int lineno) {
189: try {
190: TokenStream ts = new TokenStream(in, scope, sourceName, lineno);
191: IRFactory irf = new IRFactory(ts, scope);
192: Parser p = new Parser(irf);
193: Node tree = (Node) p.parse(ts);
194: if( tree == null ) {
195: System.out.println(tree.toStringTree());
196: return tree;
197: }
198: return null;
199: } catch (WrappedException we) {
200: Log.logRB(Resource.JSERROR, we);
201: } catch (EcmaError ee) {
202: String msg = IVErrorReporter.getMessage(
203: "msg.uncaughtJSException", ee.toString());
204: exitCode = EXITCODE_RUNTIME_ERROR;
205: if (ee.getSourceName() != null) {
206: Context.reportError(msg, ee.getSourceName(),
207: ee.getLineNumber(),
208: ee.getLineSource(),
209: ee.getColumnNumber());
210: } else {
211: Context.reportError(msg);
212: }
213: } catch (JavaScriptException jse) {
214: // Need to propagate ThreadDeath exceptions.
215: Object value = jse.getValue();
216: if (value instanceof ThreadDeath)
217: throw (ThreadDeath) value;
218: exitCode = EXITCODE_RUNTIME_ERROR;
219: Context.reportError(IVErrorReporter.getMessage(
220: "msg.uncaughtJSException",
221: jse.getMessage()));
222: } catch (IOException ioe) {
223: Log.logRB(Resource.JSERROR, ioe);
224: } finally {
225: try {
226: in.close();
227: } catch (IOException ioe) {
228: Log.logRB(Resource.JSERROR, ioe);
229: }
230: }
231: return null;
232: }
233: */
234: public static ScriptableObject getScope() {
235: return global;
236: }
237:
238: public static InputStream getIn() {
239: return Global.getInstance(getGlobal()).getIn();
240: }
241:
242: public static void setIn(InputStream in) {
243: Global.getInstance(getGlobal()).setIn(in);
244: }
245:
246: public static PrintStream getOut() {
247: return Global.getInstance(getGlobal()).getOut();
248: }
249:
250: public static void setOut(PrintStream out) {
251: Global.getInstance(getGlobal()).setOut(out);
252: }
253:
254: public static PrintStream getErr() {
255: return Global.getInstance(getGlobal()).getErr();
256: }
257:
258: public static void setErr(PrintStream err) {
259: Global.getInstance(getGlobal()).setErr(err);
260: }
261:
262: static protected IVErrorReporter errorReporter;
263: static protected Global global;
264: static protected int exitCode = 0;
265: static private final int EXITCODE_RUNTIME_ERROR = 3;
266: static private final int EXITCODE_FILE_NOT_FOUND = 4;
267: //static private DebugShell debugShell;
268: }
|