From: megacz Date: Fri, 30 Jan 2004 07:00:31 +0000 (+0000) Subject: 2003/05/12 05:31:50 X-Git-Tag: RC3~967 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=e58686eae8a823ed64ed0ec92c2274c41d90ec93 2003/05/12 05:31:50 darcs-hash:20040130070031-2ba56-095195c2b586fe6262fc970cfcfa9d208cb7eada.gz --- diff --git a/src/org/xwt/ByteStream.java b/src/org/xwt/ByteStream.java index 2211d7d..5aa8526 100644 --- a/src/org/xwt/ByteStream.java +++ b/src/org/xwt/ByteStream.java @@ -1,98 +1,82 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] + package org.xwt; import java.io.*; import java.util.*; +import org.xwt.js.*; import org.xwt.util.*; -import org.mozilla.javascript.*; /** A ByteStream encapsulates a source of a stream of bytes -- * currently either a local file or a Base64-encoded XMLRPC/SOAP element */ - -public class ByteStream extends JSObject { +public class ByteStream extends JS.Obj { private byte[] bytes = null; private File file = null; private ByteStream() { setSeal(true); } + ByteStream(String filename) { this(); this.file = new File(filename); } + ByteStream(byte[] bytes) { this(); this.bytes = bytes; } public String toString() { return "ByteStream, source=" + (file == null ? "memory" : file.getAbsolutePath()); } - public String getClassName() { return "ByteStream"; } - - ByteStream(String filename) { - this(); - this.file = new File(filename); - } - ByteStream(byte[] bytes) { - this(); - this.bytes = bytes; - } - - public Object get(String name, Scriptable start) { - if (name == null) return null; - else if (name.equals("getUTF")) return getUTF; + public Object get(Object name) { + if (name.equals("getUTF")) return getUTF; else if (name.equals("getDOM")) return getDOM; else if (name.equals("fileName")) return file == null ? null : file.getAbsolutePath(); else return null; } - /** Helper class for defining functions. */ - private abstract class JSFunction extends JSObject implements Function { - JSFunction() { this.setSeal(true); } - public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; } - } - private class XMLHelper extends XML { Vector obStack = new Vector(); public XMLHelper() { super(BUFFER_SIZE); } public void startElement(XML.Element c) throws XML.SchemaException { - JSObject o = new JSObject(); - o.put("$name", null, c.localName); - for(int i=0; i= 1 ? (Scriptable)obStack.elementAt(0) : null; + return obStack.size() >= 1 ? (JS)obStack.elementAt(0) : null; } } @@ -117,16 +101,16 @@ public class ByteStream extends JSObject { os.close(); } - private final JSFunction getDOM = new JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 0) return null; + private final JS.Function getDOM = new JS.Function() { + public Object _call(JS.Array args) throws JS.Exn { + if (args.length() != 0) return null; return new XMLHelper().doParse(); } }; - private final JSFunction getUTF = new JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 0) return null; + private final JS.Function getUTF = new JS.Function() { + public Object _call(JS.Array args) throws JS.Exn { + if (args.length() != 0) return null; try { CharArrayWriter caw = new CharArrayWriter(); InputStream is = getInputStream(); @@ -141,7 +125,7 @@ public class ByteStream extends JSObject { } catch (IOException e) { if (Log.on) Log.log(ByteStream.class, "IO Exception while reading from file"); if (Log.on) Log.log(ByteStream.class, e); - throw new JavaScriptException("error while reading from ByteStream"); + throw new JS.Exn("error while reading from ByteStream"); } } }; diff --git a/src/org/xwt/HTML.java b/src/org/xwt/HTML.java index 8d36a10..022e7a0 100644 --- a/src/org/xwt/HTML.java +++ b/src/org/xwt/HTML.java @@ -1,26 +1,27 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; -import org.xwt.util.*; import java.util.*; import java.net.*; import java.io.*; +import org.xwt.js.*; +import org.xwt.util.*; /* - While entities are limited to a subset of Unicode characters , - numeric character references can specify any character. Numeric - character references may be given in decimal or hexadecimal, though - browser support is stronger for decimal references. Decimal - references are of the form &#number; while hexadecimal references - take the case-insensitive form &#xnumber;. Examples of numeric - character references include © or © for the copyright - symbol, Α or Α for the Greek capital letter alpha, and - ا or ا for the Arabic letter ALEF. - - http://www.htmlhelp.com/reference/html40/entities/special.html - http://www.htmlhelp.com/reference/html40/entities/symbols.html - http://www.htmlhelp.com/reference/html40/entities/latin1.html -*/ + * While entities are limited to a subset of Unicode characters , + * numeric character references can specify any character. Numeric + * character references may be given in decimal or hexadecimal, though + * browser support is stronger for decimal references. Decimal + * references are of the form &#number; while hexadecimal references + * take the case-insensitive form &#xnumber;. Examples of numeric + * character references include © or © for the copyright + * symbol, Α or Α for the Greek capital letter alpha, and + * ا or ا for the Arabic letter ALEF. + * + * http://www.htmlhelp.com/reference/html40/entities/special.html + * http://www.htmlhelp.com/reference/html40/entities/symbols.html + * http://www.htmlhelp.com/reference/html40/entities/latin1.html + */ /** * This class parses an InputStream containing HTML and returns it @@ -48,9 +49,9 @@ public class HTML { /** true iff we have encountered an LI more recently than the last OL/UL */ private static boolean withinLI = false; - public static synchronized JSObject parseReader(Reader r) throws IOException { + public static synchronized JS parseReader(Reader r) throws IOException { CharStream cs = new CharStream(r); - JSObject h = new JSObject(); + JS.Obj h = new JS.Obj(); withinLI = false; h.put("$name", "html"); @@ -61,11 +62,11 @@ public class HTML { // continue until we get an EOFException } - Object[] ids = h.getIds(); + Object[] ids = h.keys(); for(int i=0; io to sb */ - void appendObject(String name, Object o, StringBuffer sb) throws JavaScriptException { + void appendObject(String name, Object o, StringBuffer sb) throws JS.Exn { if (o instanceof Number) { if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) { sb.append(" <" + name + " xsi:type=\"xsd:int\">"); @@ -199,7 +199,7 @@ class SOAP extends XMLRPC { } catch (IOException e) { if (Log.on) Log.log(this, "caught IOException while attempting to send a ByteStream via SOAP"); if (Log.on) Log.log(this, e); - throw new JavaScriptException("caught IOException while attempting to send a ByteStream via SOAP"); + throw new JS.Exn("caught IOException while attempting to send a ByteStream via SOAP"); } } else if (o instanceof String) { @@ -221,24 +221,22 @@ class SOAP extends XMLRPC { } sb.append("\r\n"); - } else if (o instanceof NativeArray) { - NativeArray na = (NativeArray)o; - sb.append(" <" + name + " SOAP-ENC:arrayType=\"xsd:ur-type[" + na.jsGet_length() + "]\">"); - for(int i=0; i"); + for(int i=0; i\r\n"); - } else if (o instanceof Scriptable && !(o instanceof Undefined)) { - Scriptable s = (Scriptable)o; + } else if (o instanceof JS) { + JS j = (JS)o; sb.append(" <" + name + ">"); - Object[] ids = s.getIds(); - for(int i=0; i\r\n"); } } - protected String send(Object[] args, HTTP http) throws JavaScriptException, IOException { + protected String send(JS.Array args, HTTP http) throws JS.Exn, IOException { // build up the request StringBuffer content = new StringBuffer(); content.append("SOAPAction: " + action + "\r\n\r\n"); @@ -253,10 +251,10 @@ class SOAP extends XMLRPC { content.append(methodname); content.append(nameSpace != null ? " xmlns=\"" + nameSpace + "\"" : ""); content.append(">\r\n"); - if (args.length > 0) { - Object[] o = ((Scriptable)args[0]).getIds(); + if (args.length() > 0) { + Object[] o = ((JS)args.elementAt(0)).keys(); for(int i=0; i\r\n"); return content.toString(); diff --git a/src/org/xwt/SpecialBoxProperty.java b/src/org/xwt/SpecialBoxProperty.java index 095cc6f..bc9b9d4 100644 --- a/src/org/xwt/SpecialBoxProperty.java +++ b/src/org/xwt/SpecialBoxProperty.java @@ -1,11 +1,11 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; -import org.mozilla.javascript.*; -import org.xwt.util.*; import java.util.*; import java.net.*; import java.text.*; +import org.xwt.js.*; +import org.xwt.util.*; /** * A helper class for properties of Box which require special @@ -101,8 +101,7 @@ class SpecialBoxProperty { else if (s.equals("pink")) newcolor = pink; else if (s.equals("yellow")) newcolor = yellow; else if (s.equals("white")) newcolor = white; - else if (Log.on) Log.log(this, "invalid color \"" + s + "\" at " + - Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine); + else if (Log.on) Log.log(this, "invalid color \"" + s + "\" at " + JS.getCurrentFunctionSourceName()); if (newcolor == b.color) return; b.color = newcolor; b.dirty(); @@ -145,9 +144,7 @@ class SpecialBoxProperty { else if (s.equals("pink")) newtextcolor = pink; else if (s.equals("yellow")) newtextcolor = yellow; else if (s.equals("white")) newtextcolor = white; - else if (Log.on) Log.log(this, "invalid color \"" + s + "\" at " + - Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine); - + else if (Log.on) Log.log(this, "invalid color \"" + s + "\" at " + JS.getCurrentFunctionSourceName()); if (newtextcolor == b.textcolor) return; b.textcolor = newtextcolor; b.dirty(); @@ -164,14 +161,11 @@ class SpecialBoxProperty { if (Log.on) Log.log(this, "ISO Control characters are not permitted in box text strings; offending character is ASCII " + ((int)t.charAt(i))); - /* FIXME: reinstate return; - */ } - // FIXME: don't know why this is needed + // FEATURE: try removing the following line; it appears to be redundant b.dirty(); - b.text = t; b.textupdate(); b.dirty(); @@ -220,7 +214,7 @@ class SpecialBoxProperty { specialBoxProperties.put("static", new SpecialBoxProperty() { public Object get(Box b) { - String cfsn = JSObject.getCurrentFunctionSourceName(); + String cfsn = JS.getCurrentFunction().getSourceName(); for(int i=0; ichange as needed */ @@ -368,20 +363,25 @@ public class Template { private void link(boolean force) { if (staticscript != null) try { - Scriptable s = Static.createStatic(nodeName, false); + JS.Scope s = Static.createStatic(nodeName, false); if (staticscript != null) { - Script temp = staticscript; - ((InterpretedScript)temp).setParentScope(s); // so we know how to handle Static.get("xwt") + JS.Script temp = staticscript; staticscript = null; - temp.exec(Context.enter(), s); + + // we layer a transparent scope over the Static so that we can catch requests for the xwt object + // yet not screw up paths that include a package called xwt (ie xwt.static.org.xwt.foo) + JS.Scope varScope = new JS.Scope(s) { + public boolean isTransparent() { return true; } + public Object get(Object key) { + if ("xwt".equals(key)) return XWT.singleton; else return super.get(key); + } }; + + JS.Array args = new JS.Array(); + args.addElement(varScope); + temp.call(args); } - } catch (EcmaError e) { - if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown while executing block for " + nodeName + - " at " + e.getSourceName() + ":" + e.getLineNumber()); - } catch (JavaScriptException e) { + } catch (JS.Exn e) { if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown while executing block for " + nodeName + " at " + e.sourceFile + ":" + e.line); } if (!(force || (preapply != null && _preapply == null) || (postapply != null && _postapply == null))) return; @@ -654,17 +654,11 @@ public class Template { } } - private Script genscript(boolean isstatic) { - Script thisscript = null; - Context cx = Context.enter(); - cx.setOptimizationLevel(-1); - + private JS.Script genscript(boolean isstatic) { + JS.Script thisscript = null; try { - thisscript = cx.compileReader(null, new StringReader(t.content.toString()), t.nodeName + (isstatic ? "._" : ""), t.content_start, null); - } catch (EcmaError ee) { - if (Log.on) Log.log(this, ee.getMessage() + " at " + ee.getSourceName() + ":" + ee.getLineNumber()); - thisscript = null; - } catch (EvaluatorException ee) { + thisscript = JS.Script.parse(new StringReader(t.content.toString()), t.nodeName + (isstatic ? "._" : ""), t.content_start); + } catch (JS.Exn ee) { if (Log.on) Log.log(this, " ERROR: " + ee.getMessage()); thisscript = null; } catch (IOException ioe) { diff --git a/src/org/xwt/ThreadMessage.java b/src/org/xwt/ThreadMessage.java index bbd1f24..f4f95a9 100644 --- a/src/org/xwt/ThreadMessage.java +++ b/src/org/xwt/ThreadMessage.java @@ -1,9 +1,9 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; -import org.xwt.util.*; import java.util.*; -import org.mozilla.javascript.*; +import org.xwt.util.*; +import org.xwt.js.*; /** * A background thread. All threads created with xwt.thread @@ -20,7 +20,7 @@ public class ThreadMessage extends Thread implements Message { private volatile static int threadcount = 0; /** the JavaScript function that we are executing */ - volatile Function f; + volatile JS.Function f; /** the ThreadMessage thread blocks on this before executing any JavaScript */ Semaphore go = new Semaphore(); @@ -38,7 +38,7 @@ public class ThreadMessage extends Thread implements Message { private static Object[] emptyobj = new Object[] { }; /** creates a new thread to execute function f */ - public static synchronized void newthread(Function f) { + public static synchronized void newthread(JS.Function f) { ThreadMessage ret = (ThreadMessage)spare.remove(false); if (ret == null) { if (threadcount < Platform.maxThreads()) ret = new ThreadMessage(); @@ -56,9 +56,7 @@ public class ThreadMessage extends Thread implements Message { // put ourselves in the background Thread thread = Thread.currentThread(); if (!(thread instanceof ThreadMessage)) { - Context cx = Context.enter(); - if (Log.on) Log.log(ThreadMessage.class, "attempt to perform background-only operation in a foreground thread at " + - cx.interpreterSourceFile + ":" + cx.interpreterLine); + if (Log.on) Log.log(ThreadMessage.class, "attempt to perform background-only operation in a foreground thread at " + JS.getCurrentFunctionSourceName()); return false; } ThreadMessage mythread = (ThreadMessage)thread; @@ -78,22 +76,17 @@ public class ThreadMessage extends Thread implements Message { public void run() { try { threadcount++; - Context cx = Context.enter(); while (true) { try { go.block(); - f.call(cx, f.getParentScope(), f.getParentScope(), emptyobj); - } catch (EcmaError e) { - if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown from background thread at " + e.getSourceName() + ":" + e.getLineNumber()); - } catch (JavaScriptException e) { - if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown from background thread at " + e.sourceFile + ":" + e.line); + f.call(new JS.Array()); + } catch (JS.Exn e) { + if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e); } done.release(); synchronized(waiting) { if (waiting.size() > 0) { - f = (Function)waiting.remove(false); + f = (JS.Function)waiting.remove(false); MessageQueue.add(this); } else if (spare.size() < 10) { spare.append(this); diff --git a/src/org/xwt/Trap.java b/src/org/xwt/Trap.java index aee4625..8d9404e 100644 --- a/src/org/xwt/Trap.java +++ b/src/org/xwt/Trap.java @@ -1,9 +1,9 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; -import org.xwt.util.*; import java.util.*; -import org.mozilla.javascript.*; +import org.xwt.js.*; +import org.xwt.util.*; /** * This class encapsulates a single trap placed on a given node. The @@ -41,10 +41,10 @@ public class Trap { private Box trapee = null; /** If this trap was actually placed on a root proxy, this is a reference to the proxy */ - private Scriptable rp = null; + private JS rp = null; /** the function for this trap */ - Function f = null; + JS.Function f = null; /** the name of the property that this trap was placed on */ private String name = null; @@ -72,7 +72,7 @@ public class Trap { * @param isreadtrap true iff this is a read (double-underscore) trap * @param rp if this trap is being placed via a rootproxy, this is that proxy object. */ - static void addTrap(Box trapee, String name, Function f, boolean isreadtrap, Scriptable rp) { + static void addTrap(Box trapee, String name, JS.Function f, boolean isreadtrap, JS rp) { if (PROHIBITED.get(name) != null || name.startsWith("xwt_")) { Log.log(Trap.class, "Error: you cannot place traps on special property \"" + name + "\""); @@ -80,7 +80,7 @@ public class Trap { } // find out what script is currently running - String placerNodeName = JSObject.getCurrentFunctionSourceName(); + String placerNodeName = JS.getCurrentFunctionSourceName(); // check if this script has already placed a trap on this property if (trapee.traps == null) trapee.traps = new Hash(10, 3); @@ -108,7 +108,7 @@ public class Trap { public static Trap getTrap(Box b, String name) { if (b.traps == null) return null; - String currentFunctionNodeName = JSObject.getCurrentFunctionSourceName(); + String currentFunctionNodeName = JS.getCurrentFunctionSourceName(); for(Trap cur = (Trap)b.traps.get(name); cur != null; cur = cur.next) if (cur.placerNodeName.equals(currentFunctionNodeName)) return cur; @@ -117,23 +117,27 @@ public class Trap { } /** Called by Rhino's arguments.cascade. Note: cx will be null if this was invoked from perform() rather than from a script. */ - public static final Function cascadeFunction = new CascadeFunction(); - private static class CascadeFunction extends JSObject implements Function { + public static final CascadeFunction cascadeFunction = new CascadeFunction(); + private static class CascadeFunction extends JS.Function { CascadeFunction() { setSeal(true); } - public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; } - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) { + public Object _call(JS.Array args) { return _call(args, JS.getCurrentFunction()); } + public Object _call(JS.Array args, Function currentFunction) { Trap currentTrap = TrapContext.get().currentTrap; - if (currentTrap == null || (cx != null && Context.getCurrentContext().currentFunction != currentTrap.f)) { + /* + if (currentTrap == null || (currentFunction != currentTrap.f)) { if (Log.on) Log.log(this, "attempt to cascade() by a function that was not invoked as a trap at " + - cx.interpreterSourceFile + ":" + cx.interpreterLine); + currentFunction.getSourceName()); + if (Log.on) Log.log(this, "currentfunction == " + currentFunction); + if (Log.on) Log.log(this, "currentTrap.f == " + currentTrap.f); return null; } - if (args.length != 0) TrapContext.get().putCascadeHappened = true; + */ + if (args.length() != 0) TrapContext.get().putCascadeHappened = true; Trap t = currentTrap.next; // if we've hit the end of the trap stack, just do a put(,,,true) if (t == null) { - if (args.length == 0) return currentTrap.trapee.get(currentTrap.name, currentTrap.trapee, true); - currentTrap.trapee.put(currentTrap.name, currentTrap.trapee, args[0], true); + if (args.length() == 0) return currentTrap.trapee.get(currentTrap.name, true); + currentTrap.trapee.put(currentTrap.name, args.elementAt(0), true); return null; } return t.perform(args); @@ -155,32 +159,13 @@ public class Trap { else return current.name; } - /** removes all traps whose function's ultimate parent scope is b. Used for retheming */ - public static void removeAllTrapsByBox(Box b) { - Enumeration e = allTraps.keys(); - while(e.hasMoreElements()) { - Weak w = (Weak)e.nextElement(); - Trap t = (Trap)w.get(); - if (t == null) { - allTraps.remove(w); - continue; - } - for(Scriptable cur = t.f; cur != null; cur = cur.getParentScope()) { - if (cur == b) { - t.delete(); - break; - } - } - } - } - // Instance Methods ////////////////////////////////////////////////////////////////////////// private Trap() { allTraps.put(myWeak, dummy); } /** perform this trap -- arg.length == 0 if this is a get; otherwise it contains a single element to be put */ - public Object perform(Object[] arg) { + public Object perform(JS.Array args) { TrapContext tc = TrapContext.get(); // save both thread-locals on the stack and update their values @@ -192,28 +177,25 @@ public class Trap { // invoke the trap function try { - if (!isreadtrap && arg.length == 0) return cascadeFunction.call(null, null, null, arg); + if (!isreadtrap && args.length() == 0) return cascadeFunction._call(args, f); if (f == null) { if (Log.verbose) Log.log(this, "debug: reclaimed a dangling trap on property " + name); - Object ret = cascadeFunction.call(null, null, null, arg); + Object ret = cascadeFunction._call(args, f); delete(); return ret; } - Object ret = f.call(Context.enter(), f.getParentScope(), f.getParentScope(), arg); + Object ret = f._call(args); // autocascade if required - if (arg.length > 0 && !isreadtrap && !tc.putCascadeHappened) cascadeFunction.call(null, null, null, arg); + if (args.length() > 0 && !isreadtrap && !tc.putCascadeHappened) cascadeFunction._call(args, f); return ret; - } catch (EcmaError e) { - if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown from within trap '" + name + "' at " + e.getSourceName() + ":" + e.getLineNumber()); - } catch (JavaScriptException e) { - if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage()); - if (Log.on) Log.log(this, " thrown from within trap '" + name + "' at " + e.sourceFile + ":" + e.line); + } catch (JS.Exn e) { + if (Log.on) Log.log(this, e); + } finally { // restore the thread-locals tc.putCascadeHappened = save_putCascadeHappened; diff --git a/src/org/xwt/XMLRPC.java b/src/org/xwt/XMLRPC.java index ebea2a6..27bfcc5 100644 --- a/src/org/xwt/XMLRPC.java +++ b/src/org/xwt/XMLRPC.java @@ -4,13 +4,13 @@ package org.xwt; import java.io.*; import java.net.*; import java.util.*; -import org.mozilla.javascript.*; +import org.xwt.js.*; import org.xwt.util.*; import org.bouncycastle.util.encoders.Base64; /** - * An XML-RPC client implemented as a Rhino JavaScript Host - * Object. See the XWT spec for information on its behavior. + * An XML-RPC client implemented as a JavaScript Host Object. See the + * XWT spec for information on its behavior. * * NOTE: this client is EXTREMELY lenient in the responses it will * accept; there are many, many invalid responses that it will @@ -30,7 +30,9 @@ import org.bouncycastle.util.encoders.Base64; * convert. * */ -class XMLRPC extends XML implements Function { +class XMLRPC extends JS.Function { + + public Object[] keys() { throw new Error("not implemented"); } /** the url to connect to */ protected String url = null; @@ -76,100 +78,107 @@ class XMLRPC extends XML implements Function { // Methods to Recieve and parse XML-RPC Response //////////////////////////////////////////////////// - public void startElement(XML.Element c) { - content.reset(); - if (c.localName.equals("fault")) fault = true; - else if (c.localName.equals("struct")) objects.setElementAt(new JSObject(false), objects.size() - 1); - else if (c.localName.equals("array")) objects.setElementAt(null, objects.size() - 1); - else if (c.localName.equals("value")) objects.addElement(""); + private class Helper extends XML { + public Helper() { super(BUFFER_SIZE); } + + public void startElement(XML.Element c) { + content.reset(); + if (c.localName.equals("fault")) fault = true; + else if (c.localName.equals("struct")) objects.setElementAt(new JS.Obj(), objects.size() - 1); + else if (c.localName.equals("array")) objects.setElementAt(null, objects.size() - 1); + else if (c.localName.equals("value")) objects.addElement(""); + } + + public void endElement(XML.Element c) { + + if (c.localName.equals("int") || c.localName.equals("i4")) + objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1); + + else if (c.localName.equals("boolean")) + objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1); + + else if (c.localName.equals("string")) + objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1); + + else if (c.localName.equals("double")) + objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1); + + else if (c.localName.equals("base64")) + objects.setElementAt(new ByteStream(Base64.decode(new String(content.getBuf(), 0, content.size()))), objects.size() - 1); + + else if (c.localName.equals("name")) + objects.addElement(new String(content.getBuf(), 0, content.size())); + + else if (c.localName.equals("value") && "".equals(objects.lastElement())) + objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1); + + else if (c.localName.equals("dateTime.iso8601")) { + throw new Error("not implemented"); + /* + String s = new String(content.getBuf(), 0, content.size()); + + // strip whitespace + int i=0; + while(Character.isWhitespace(s.charAt(i))) i++; + if (i > 0) s = s.substring(i); + + try { + NativeDate nd = (NativeDate)Context.enter().newObject(org.xwt.util.JS.Obj.defaultObjects, "Date"); + double date = NativeDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(), + Double.valueOf(s.substring(4, 6)).doubleValue() - 1, + Double.valueOf(s.substring(6, 8)).doubleValue(), + Double.valueOf(s.substring(9, 11)).doubleValue(), + Double.valueOf(s.substring(12, 14)).doubleValue(), + Double.valueOf(s.substring(15, 17)).doubleValue(), + (double)0 + ); + nd.jsFunction_setTime(NativeDate.internalUTC(date)); + objects.setElementAt(nd, objects.size() - 1); + + } catch (Exception e) { + if (Log.on) Log.log(this, "error parsing date : " + s); + if (Log.on) Log.log(this, e); + } + */ + + } else if (c.localName.equals("member")) { + Object memberValue = objects.elementAt(objects.size() - 1); + String memberName = (String)objects.elementAt(objects.size() - 2); + JS struct = (JS)objects.elementAt(objects.size() - 3); + struct.put(memberName, memberValue); + objects.setSize(objects.size() - 2); + + } else if (c.localName.equals("data")) { + int i; + for(i=objects.size() - 1; objects.elementAt(i) != null; i--); + JS.Array arr = new JS.Array(); + for(int j = i + 1; j 0) s = s.substring(i); - - try { - NativeDate nd = (NativeDate)Context.enter().newObject(org.xwt.util.JSObject.defaultObjects, "Date"); - double date = NativeDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(), - Double.valueOf(s.substring(4, 6)).doubleValue() - 1, - Double.valueOf(s.substring(6, 8)).doubleValue(), - Double.valueOf(s.substring(9, 11)).doubleValue(), - Double.valueOf(s.substring(12, 14)).doubleValue(), - Double.valueOf(s.substring(15, 17)).doubleValue(), - (double)0 - ); - nd.jsFunction_setTime(NativeDate.internalUTC(date)); - objects.setElementAt(nd, objects.size() - 1); - - } catch (Exception e) { - if (Log.on) Log.log(this, "error parsing date : " + s); - if (Log.on) Log.log(this, e); - } - - } else if (c.localName.equals("member")) { - Object memberValue = objects.elementAt(objects.size() - 1); - String memberName = (String)objects.elementAt(objects.size() - 2); - Scriptable struct = (Scriptable)objects.elementAt(objects.size() - 3); - struct.put(memberName, struct, memberValue); - objects.setSize(objects.size() - 2); - - } else if (c.localName.equals("data")) { - int i; - for(i=objects.size() - 1; objects.elementAt(i) != null; i--); - Object[] arr = new Object[objects.size() - i - 1]; - for(int j = i + 1; jo to sb */ - void appendObject(Object o, StringBuffer sb) throws JavaScriptException { + void appendObject(Object o, StringBuffer sb) throws JS.Exn { if (o == null) { - throw new JavaScriptException("attempted to send a null value via XML-RPC"); + throw new JS.Exn("attempted to send a null value via XML-RPC"); } else if (o instanceof Number) { if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) { @@ -208,7 +217,7 @@ class XMLRPC extends XML implements Function { } catch (IOException e) { if (Log.on) Log.log(this, "caught IOException while attempting to send a ByteStream via XML-RPC"); if (Log.on) Log.log(this, e); - throw new JavaScriptException("caught IOException while attempting to send a ByteStream via XML-RPC"); + throw new JS.Exn("caught IOException while attempting to send a ByteStream via XML-RPC"); } } else if (o instanceof String) { @@ -231,9 +240,11 @@ class XMLRPC extends XML implements Function { } sb.append("\n"); - } else if (o instanceof NativeDate) { + /* + } else if (o instanceof org.xwt.js.Date) { sb.append(" "); - NativeDate nd = (NativeDate)o; + FIXME + org.xwt.js.Date d = (org.xwt.js.Date)o; Date d = new Date(nd.getRawTime()); sb.append(d.getYear() + 1900); if (d.getMonth() + 1 < 10) sb.append('0'); @@ -250,38 +261,38 @@ class XMLRPC extends XML implements Function { if (d.getSeconds() < 10) sb.append('0'); sb.append(d.getSeconds()); sb.append("\n"); + */ - } else if (o instanceof NativeArray) { - if (tracker.get(o) != null) throw new JavaScriptException("attempted to send multi-ref data structure via XML-RPC"); + } else if (o instanceof JS.Array) { + if (tracker.get(o) != null) throw new JS.Exn("attempted to send multi-ref data structure via XML-RPC"); tracker.put(o, Boolean.TRUE); sb.append(" \n"); - NativeArray na = (NativeArray)o; - for(int i=0; i\n"); - } else if (o instanceof Scriptable && !(o instanceof Undefined)) { - if (tracker.get(o) != null) throw new JavaScriptException("attempted to send multi-ref data structure via XML-RPC"); + } else if (o instanceof JS) { + if (tracker.get(o) != null) throw new JS.Exn("attempted to send multi-ref data structure via XML-RPC"); tracker.put(o, Boolean.TRUE); - Scriptable s = (Scriptable)o; + JS j = (JS)o; sb.append(" \n"); - Object[] ids = s.getIds(); + Object[] ids = j.keys(); for(int i=0; i" + ids[i] + "\n"); - appendObject(s.get(ids[i].toString(), s), sb); + appendObject(j.get(ids[i].toString()), sb); sb.append(" \n"); } sb.append(" \n"); } else { - throw new JavaScriptException("attempt to send object of type " + o.getClass().getName() + " via XML-RPC"); + throw new JS.Exn("attempt to send object of type " + o.getClass().getName() + " via XML-RPC"); } } // this is synchronized in case multiple threads try to make a call on the same object... in the future, change this // behavior to use pipelining. - public synchronized Object call(Object[] args) throws JavaScriptException, IOException { + public synchronized Object call2(JS.Array args) throws JS.Exn, IOException { if (Log.verbose) Log.log(this, "call to " + url + " : " + methodname); if (tracker == null) tracker = new Hash(); @@ -322,7 +333,7 @@ class XMLRPC extends XML implements Function { } } - protected String send(Object[] args, HTTP http) throws JavaScriptException, IOException { + protected String send(JS.Array args, HTTP http) throws JS.Exn, IOException { StringBuffer content = new StringBuffer(); content.append("\r\n"); content.append("\n"); @@ -331,9 +342,9 @@ class XMLRPC extends XML implements Function { content.append(methodname); content.append("\n"); content.append(" \n"); - for(int i=0; i\n"); - appendObject(args[i], content); + appendObject(args.elementAt(i), content); content.append(" \n"); } content.append(" \n"); @@ -341,37 +352,32 @@ class XMLRPC extends XML implements Function { return content.toString(); } - protected Object recieve(BufferedReader br) throws JavaScriptException, IOException { + protected Object recieve(BufferedReader br) throws JS.Exn, IOException { // parse XML reply try { - parse(br); + new Helper().parse(br); } catch (XML.XMLException e) { if (Log.on) Log.log(this, "reply from server was not well-formed XML: " + e); - throw new JavaScriptException("reply from server was not well-formed XML: " + e); + throw new JS.Exn("reply from server was not well-formed XML: " + e); } - if (fault) throw new JavaScriptException(objects.elementAt(0)); + if (fault) throw new JS.Exn(objects.elementAt(0)); if (objects.size() == 0) return null; return objects.elementAt(0); } - public final Object call(Context cx, Scriptable scope, Scriptable thisObj, java.lang.Object[] args) throws JavaScriptException { + public final Object _call(JS.Array args) throws JS.Exn { if (!ThreadMessage.suspendThread()) return null; try { - return call(args); + return call2(args); } catch (IOException se) { if (Log.on) Log.log(this, se); - if (Log.on) Log.log(this, " at " + cx.interpreterSourceFile + ":" + cx.interpreterLine); - throw new JavaScriptException("socket exception: " + se); - - } catch (JavaScriptException jse) { - Object val = jse.getValue(); - if (val instanceof String) { - if (Log.on) Log.log(this, val.toString()); - if (Log.on) Log.log(this, " at " + cx.interpreterSourceFile + ":" + cx.interpreterLine); - } + throw new JS.Exn("socket exception: " + se); + + } catch (JS.Exn jse) { + if (Log.on) Log.log(this, jse.toString()); throw jse; } finally { ThreadMessage.resumeThread(); @@ -380,7 +386,7 @@ class XMLRPC extends XML implements Function { } /** When you get a property from an XMLRPC, it just returns another XMLRPC with the property name tacked onto methodname. */ - public Object get(String name, Scriptable start) { + public Object get(String name) { return new XMLRPC(url, (methodname.equals("") ? "" : methodname + ".") + name, http); } @@ -389,8 +395,6 @@ class XMLRPC extends XML implements Function { } public XMLRPC(String url, String methodname, HTTP http) { - super(BUFFER_SIZE); - this.http = http; this.url = url; this.methodname = methodname; @@ -425,24 +429,4 @@ class XMLRPC extends XML implements Function { } } - - // Methods Required by Rhino //////////////////////////////////////////////////////// - - public String getClassName() { return "XMLRPC"; } - public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; } - public void delete(String name) { } - public Scriptable getParentScope() { return null; } - public void setParentScope(Scriptable p) { } - public boolean hasInstance(Scriptable value) { return false; } - public Scriptable getPrototype() { return null; } - public void setPrototype(Scriptable p) { } - public void delete(int i) { } - public Object getDefaultValue(Class hint) { return "XML-RPC"; } - public void put(int i, Scriptable start, Object value) { } - public Object get(int i, Scriptable start) { return null; } - public void put(String name, Scriptable start, Object value) { } - public boolean has(String name, Scriptable start) { return true; } - public boolean has(int i, Scriptable start) { return false; } - public Object[] getIds() { return new Object[] { }; } - } diff --git a/src/org/xwt/XWT.java b/src/org/xwt/XWT.java index 7d73e9c..dd6edc2 100644 --- a/src/org/xwt/XWT.java +++ b/src/org/xwt/XWT.java @@ -5,463 +5,286 @@ import java.io.*; import java.net.*; import java.text.*; import java.util.*; +import org.xwt.js.*; import org.xwt.util.*; -import org.mozilla.javascript.*; import org.bouncycastle.util.encoders.Base64; /** Singleton class that provides all functionality in the xwt.* namespace */ -public final class XWT extends JSObject { +public final class XWT extends JS.Obj { public static final XWT singleton = new XWT(); /** each key is a string representing a filename which the user has already given XWT permission to write to */ private static Hashtable safeFiles = new Hashtable(); - public String getClassName() { return "XWT"; } - private XWT() { setSeal(true); } - - public Object get(String name, Scriptable start) { - if (name == null) return null; - else if (name.equals("maxdim")) return new Integer(Short.MAX_VALUE); - else if (name.equals("parseFloat")) return JSObject.defaultObjects.get("parseFloat", null); - else if (name.equals("parseInt")) return JSObject.defaultObjects.get("parseInt", null); + public Object get(Object name) { + if (name.equals("parseFloat")) throw new Error("not implemented"); + else if (name.equals("parseInt")) throw new Error("not implemented"); else if (name.equals("alt")) return Surface.alt ? Boolean.TRUE : Boolean.FALSE; else if (name.equals("control")) return Surface.control ? Boolean.TRUE : Boolean.FALSE; else if (name.equals("shift")) return Surface.shift ? Boolean.TRUE : Boolean.FALSE; - else if (name.equals("date")) return date; - else if (name.equals("listfonts")) return listfonts; - else if (name.equals("regexp")) return regexp; - else if (name.equals("sleep")) return sleep; - else if (name.equals("yield")) return yield; - else if (name.equals("newBrowserWindow")) return newBrowserWindow; - else if (name.equals("textwidth")) return textwidth; - else if (name.equals("textheight")) return textheight; - else if (name.equals("newBox")) return newBox; - else if (name.equals("soap")) return soap; - else if (name.equals("xmlrpc")) return xmlrpc; - else if (name.equals("origin")) return Main.origin; else if (name.equals("clipboard")) return Platform.getClipBoard(); - else if (name.equals("altKeyName")) return Platform.altKeyName(); - else if (name.equals("screenWidth")) return new Integer(Platform.getScreenWidth()); - else if (name.equals("screenHeight")) return new Integer(Platform.getScreenHeight()); - else if (name.equals("static")) return Static.getStatic(""); - else if (name.equals("theme")) return theme; - else if (name.equals("openFile")) return openFile; - else if (name.equals("saveFile")) return saveFile; - else if (name.equals("saveFileAs")) return saveFileAs; - else if (name.equals("utfEncode")) return utfEncode; - else if (name.equals("fileSeparator")) return File.separator; - else if (name.equals("homeDir")) return System.getProperty("user.home"); - else if (name.equals("tempDir")) return System.getProperty("java.io.tempdir"); - else if (name.equals("recursivePrintObject")) return recursivePrintObject; - else if (name.equals("parseHTML")) return parseHTML; + else if (name.equals("static")) return Static.getStatic(""); else if (name.equals("button")) { if (Surface.button1 && !Surface.button2 && !Surface.button3) return new Integer(1); else if (!Surface.button1 && Surface.button2 && !Surface.button3) return new Integer(1); else if (!Surface.button1 && !Surface.button2 && Surface.button3) return new Integer(1); else return new Integer(0); - } - else if (name.equals("println")) return println; - else if (name.equals("math")) return org.xwt.util.JSObject.defaultObjects.get("Math", null); - else if (name.equals("loadArchive")) return loadArchive; - else if (name.equals("prefetchImage")) return prefetchImage; - else if (name.equals("prefs")) return prefs; - else if (name.equals("encodeURI")) return JSObject.defaultObjects.get("encodeURI", null); - else if (name.equals("encodeURIComponent")) return JSObject.defaultObjects.get("encodeURIComponent", null); - else if (name.equals("decodeURI")) return JSObject.defaultObjects.get("decodeURI", null); - else if (name.equals("decodeURIComponent")) return JSObject.defaultObjects.get("decodeURIComponent", null); - else return super.get(name, start); + } + else if (name.equals("encodeURI")) throw new Error("not implemented"); + else if (name.equals("encodeURIComponent")) throw new Error("not implemented"); + else if (name.equals("decodeURI")) throw new Error("not implemented"); + else if (name.equals("decodeURIComponent")) throw new Error("not implemented"); + else return super.get(name); } - public void put(String name, Scriptable start, Object value) { - if (name == null) return; - else if (name.equals("thread") && value != null && value instanceof Function) ThreadMessage.newthread((Function)value); + public void put(Object name, Object value) { + if (name.equals("thread") && value != null && value instanceof JS.Function) ThreadMessage.newthread((JS.Function)value); else if (name.equals("clipboard")) Platform.setClipBoard(value.toString()); - - // FIXME: undocumented, possibly insecure else if (name.equals("proxyAuthorization")) { + // FIXME: undocumented, possibly insecure Proxy.Authorization.authorization = value.toString(); Proxy.Authorization.waitingForUser.release(); - } - - else super.put(name, start, value); + } else super.put(name, value); } - - // Prefs Object ////////////////////////////////////////////////////////////////////////// - - static Scriptable prefsRPC = new XMLRPC("http://megacz:mypassword@localhost/RPC2", "prefs"); - - private static final JSObject prefs = new JSObject(false, true) { - public Object get(String name, Scriptable start) { - if (name.equals("get")) return prefsGet; - else if (name.equals("list")) return prefsList; - else if (name.equals("put")) return prefsPut; - else return null; - } - }; - - private static final JSObject.JSFunction prefsGet = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 1 || args[0] == null) return null; + private XWT() { + put("maxdim", new Integer(Short.MAX_VALUE)); + put("origin", Main.origin); + put("altKeyName", Platform.altKeyName()); + put("screenWidth", new Integer(Platform.getScreenWidth())); + put("screenHeight", new Integer(Platform.getScreenHeight())); + put("fileSeparator", File.separator); + put("homeDir", System.getProperty("user.home")); + put("tempDir", System.getProperty("java.io.tempdir")); + + put("math", new JS.Obj() { public Object get(Object name) { + if ("ceil".equals(name)) return new JS.Function() { public Object _call(JS.Array args) + { if (args.elementAt(0) == null) return null; + return new Long((long)Math.ceil(Double.parseDouble(args.elementAt(0).toString()))); } }; + else if ("floor".equals(name)) return new JS.Function() { public Object _call(JS.Array args) + { if (args.elementAt(0) == null) return null; + return new Long((long)Math.floor(Double.parseDouble(args.elementAt(0).toString()))); } }; + else if ("round".equals(name)) return new JS.Function() { public Object _call(JS.Array args) + { if (args.elementAt(0) == null) return null; + return new Long((long)Math.round(Double.parseDouble(args.elementAt(0).toString()))); } }; + else if ("abs".equals(name)) return new JS.Function() { public Object _call(JS.Array args) + { if (args.elementAt(0) == null) return null; + return new Long((long)Math.abs(Double.parseDouble(args.elementAt(0).toString()))); } }; + else if ("min".equals(name)) return new JS.Function() { public Object _call(JS.Array args) { + if (args.length() < 2 || args.elementAt(0) == null || args.elementAt(1) == null) return args.elementAt(0); + return new Double(Math.min(((Number)args.elementAt(0)).doubleValue(), + ((Number)args.elementAt(1)).doubleValue())); } }; + else if ("max".equals(name)) return new JS.Function() { public Object _call(JS.Array args) { + if (args.length() < 2) return args.elementAt(0); + return new Double(Math.max(((Number)args.elementAt(0)).doubleValue(), + ((Number)args.elementAt(1)).doubleValue())); } }; + return null; + }}); + + put("newBrowserWindow", new JS.Function() { public Object _call(JS.Array args) throws JS.Exn { + if (args.length() != 1 || args.elementAt(0) == null) return null; + Platform.newBrowserWindow(args.elementAt(0).toString()); + return null; + }}); + + put("yield", new JS.Function() { public Object _call(JS.Array args) throws JS.Exn { + sleep(0); + return null; + }}); + + put("theme", new JS.Function() { public Object _call(JS.Array args) throws JS.Exn { + if (args.length() != 2) return null; + if (args.elementAt(0) == null || args.elementAt(1) == null) return null; + for(int i=1; i 2) return null; + if (args.elementAt(0) == null || (args.length() == 2 && args.elementAt(1) == null)) return null; + String font = args.length() == 1 ? Platform.getDefaultFont() : args.elementAt(0).toString(); + String text = args.length() == 1 ? args.elementAt(0).toString() : args.elementAt(1).toString(); + XWF xwf = XWF.getXWF(font); + if (xwf == null) return new Integer(Platform.stringWidth(font, text)); + else return new Integer(xwf.stringWidth(text)); + }}); + + put("textheight", new JS.Function() { public Object _call(JS.Array args) throws JS.Exn { + if (args.length() > 1) return null; + if (args.length() == 1 && args.elementAt(0) == null) return null; + String font = args.length() == 0 || args.elementAt(0) == null ? Platform.getDefaultFont() : args.elementAt(0).toString(); + XWF xwf = XWF.getXWF(font); + if (xwf == null) return new Integer(Platform.getMaxAscent(font) + Platform.getMaxDescent(font)); + else return new Integer(xwf.getMaxAscent() + xwf.getMaxDescent()); + }}); + + put("newBox", new JS.Function() { public Object _call(JS.Array args) throws JS.Exn { + if (args.length() > 0) Log.log(XWT.class, "DEPRECATED: xwt.newBox() with multiple arguments is deprecated; use xwt.newBox().apply()"); + JS.Function callback = null; + for(int i=1; i 2) return null; - if (args[0] == null || (args.length == 2 && args[1] == null)) return null; - String font = args.length == 1 ? Platform.getDefaultFont() : args[0].toString(); - String text = args.length == 1 ? args[0].toString() : args[1].toString(); - XWF xwf = XWF.getXWF(font); - if (xwf == null) return new Integer(Platform.stringWidth(font, text)); - else return new Integer(xwf.stringWidth(text)); - } - }; - - - private static final JSObject.JSFunction textheight = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length > 1) return null; - if (args.length == 1 && args[0] == null) return null; - String font = args.length == 0 || args[0] == null ? Platform.getDefaultFont() : args[0].toString(); - XWF xwf = XWF.getXWF(font); - if (xwf == null) return new Integer(Platform.getMaxAscent(font) + Platform.getMaxDescent(font)); - else return new Integer(xwf.getMaxAscent() + xwf.getMaxDescent()); - } - }; - - private static final JSObject.JSFunction newBox = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - - if (args.length > 0) - if (Log.on) Log.log(XWT.class, "DEPRECATED: xwt.newBox() with multiple arguments is deprecated; use xwt.newBox().apply() " + - Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine); - - Function callback = null; - for(int i=1; i 0) try { Thread.sleep(i); } catch (Exception e) { } - - MessageQueue.add(mythread); - mythread.go.block(); - return null; - } - }; - - private static final JSObject.JSFunction openFile = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 1) return null; - String file = Platform.fileDialog(args[0].toString(), false); - return file == null ? null : new ByteStream(file); - } - }; - - private static final JSObject.JSFunction saveFile = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 2) return null; - if (!(args[1] instanceof ByteStream)) return null; - String file = args[0].toString(); - if (safeFiles.get(Platform.isCaseSensitive() ? file : file.toLowerCase()) == null) { - file = Platform.fileDialog(file, true); - if (file == null) return null; - safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object()); - } - try { - ((ByteStream)args[1]).writeTo(new FileOutputStream(file)); - return null; - } catch (IOException e) { - if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file"); - if (Log.on) Log.log(ByteStream.class, e); - throw new JavaScriptException("error while writing a ByteStream to a file"); - } - } - }; - - private static final JSObject.JSFunction saveFileAs = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args.length != 2) return null; - if (!(args[1] instanceof ByteStream)) return null; - String file = args[0].toString(); - file = Platform.fileDialog(file, true); - if (file == null) return null; - safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object()); - try { - ((ByteStream)args[1]).writeTo(new FileOutputStream(file)); - return null; - } catch (IOException e) { - if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file"); - if (Log.on) Log.log(ByteStream.class, e); - throw new JavaScriptException("error while writing a ByteStream to a file"); - } - } - }; - - private static final JSObject.JSFunction utfEncode = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args == null || args.length != 1) return null; - return new ByteStream(args[0].toString().getBytes()); - } - }; - - - private static final JSObject.JSFunction parseHTML = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args == null || args.length != 1 || args[0] == null) return null; - try { - if (args[0] instanceof ByteStream) { - return HTML.parseReader(new InputStreamReader(((ByteStream)args[0]).getInputStream())); + if (args.elementAt(0) instanceof ByteStream) { + return HTML.parseReader(new InputStreamReader(((ByteStream)args.elementAt(0)).getInputStream())); } else { - return HTML.parseReader(new StringReader(args[0].toString())); + return HTML.parseReader(new StringReader(args.elementAt(0).toString())); } } catch (IOException e) { if (Log.on) Log.log(HTML.class, "IO Exception while parsing HTML"); if (Log.on) Log.log(HTML.class, e); - throw new JavaScriptException("error while parsing HTML"); + throw new JS.Exn("error while parsing HTML"); } } - }; + }); - private static void recurse(String indent, String name, Object o, Context cx) { - if (!name.equals("")) name += " : "; + put("recursivePrintObject", new JS.Function() { public Object _call(JS.Array args) { + if (args.length() != 1) return null; + recurse("", "", args.elementAt(0)); + return null; + }}); - if (o == null) { - Log.log(cx.interpreterSourceFile, indent + name + ""); - - } else if (o instanceof NativeArray) { - Log.log(cx.interpreterSourceFile, indent + name + ""); - NativeArray na = (NativeArray)o; - for(int i=0; i"); - Scriptable s = (Scriptable)o; - Object[] keys = s.getIds(); - for(int i=0; i 1 && args.elementAt(1) instanceof JS.Function ? (JS.Function)args.elementAt(1) : null); + return null; + }}); + } - private static final JSObject.JSFunction prefetchImage = new JSObject.JSFunction() { - public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException { - if (args == null || args.length < 1 || args[0] == null) return null; - Box.getImage(args[0].toString(), args.length > 1 && args[1] instanceof Function ? (Function)args[1] : null); - return null; - } - }; + private static void recurse(String indent, String name, Object o) { + if (!name.equals("")) name += " : "; + if (o == null) { + Log.log(JS.getCurrentFunction().getSourceName(), indent + name + ""); + + } else if (o instanceof JS.Array) { + Log.log(JS.getCurrentFunction().getSourceName(), indent + name + ""); + JS.Array na = (JS.Array)o; + for(int i=0; i"); + JS s = (JS)o; + Object[] keys = s.keys(); + for(int i=0; i 0) try { Thread.sleep(i); } catch (Exception e) { } + MessageQueue.add(mythread); + mythread.go.block(); + } + } } + + + diff --git a/src/org/xwt/plat/AWT.java b/src/org/xwt/plat/AWT.java index 81edee0..43f2fba 100644 --- a/src/org/xwt/plat/AWT.java +++ b/src/org/xwt/plat/AWT.java @@ -3,7 +3,6 @@ package org.xwt.plat; import org.xwt.*; import org.xwt.util.*; -import org.mozilla.javascript.*; import java.net.*; import java.io.*; import java.util.*; @@ -28,8 +27,7 @@ public class AWT extends Platform { protected boolean _supressDirtyOnResize() { return true; } protected void postInit() { - if (Log.on) Log.log(Platform.class, " color depth = " + - Toolkit.getDefaultToolkit().getColorModel().getPixelSize() + "bpp"); + if (Log.on) Log.log(Platform.class, " color depth = " + Toolkit.getDefaultToolkit().getColorModel().getPixelSize() + "bpp"); } protected void _criticalAbort(String message) { diff --git a/src/org/xwt/plat/Java12.java b/src/org/xwt/plat/Java12.java deleted file mode 100644 index eed6391..0000000 --- a/src/org/xwt/plat/Java12.java +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] -package org.xwt.plat; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.*; -import java.awt.datatransfer.*; -import java.net.*; -import java.io.*; -import java.util.*; -import org.xwt.util.*; -import org.xwt.*; -import java.lang.reflect.*; - - -/** Platform class for most reasonable Java1.2+ JVMs */ -public class Java12 extends AWT { - - public Java12() { - // disable the focus manager so we can intercept the tab key - javax.swing.FocusManager.setCurrentManager(new javax.swing.FocusManager() { - public void processKeyEvent(Component focusedComponent, KeyEvent anEvent) { } - public void focusPreviousComponent(Component aComponent) { } - public void focusNextComponent(Component aComponent) { } - }); - } - - /** this is done with reflection in case a new version of the plugin comes out that doesn't let us pull the sun.plugin.* trick */ - protected synchronized org.xwt.Proxy _detectProxy() { - return (org.xwt.Proxy)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { - try { - org.xwt.Proxy pi = new org.xwt.Proxy(); - - Class PluginProxyHandler = Class.forName("sun.plugin.protocol.PluginProxyHandler"); - Method getDefaultProxyHandler = PluginProxyHandler.getMethod("getDefaultProxyHandler", new Class[] { }); - Object proxyHandler = getDefaultProxyHandler.invoke(null, new Object[] { }); - - Class ProxyHandler = Class.forName("sun.plugin.protocol.ProxyHandler"); - Method getProxyInfo = ProxyHandler.getMethod("getProxyInfo", new Class[] { URL.class }); - Object proxyInfo = getProxyInfo.invoke(proxyHandler, new Object[] { new URL("http://www.xwt.org") }); - - Class ProxyInfo = Class.forName("sun.plugin.protocol.ProxyInfo"); - - if (((Boolean)ProxyInfo.getMethod("isSocksUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) { - pi.socksProxyHost = - (String)ProxyInfo.getMethod("getSocksProxy", new Class[] { }).invoke(proxyInfo, new Object[] { }); - pi.socksProxyPort = - ((Integer)ProxyInfo.getMethod("getSocksPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue(); - } - - if (((Boolean)ProxyInfo.getMethod("isProxyUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) { - pi.httpProxyHost = - (String)ProxyInfo.getMethod("getProxy", new Class[] { }).invoke(proxyInfo, new Object[] { }); - pi.httpProxyPort = - ((Integer)ProxyInfo.getMethod("getPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue(); - } - - if (pi.httpProxyHost != null || pi.socksProxyHost != null) return pi; - else return null; - - } catch (Throwable e) { - if (Log.on) Log.log(this, "exception while querying sun.plugin.protocol.PluginProxyHandler: " + e); - return null; - } - }}); - } - - protected Socket __getSocket(String host, int port, boolean ssl, boolean negotiate) throws IOException { - return super._getSocket(host, port, ssl, negotiate); - } - protected Socket _getSocket(final String host, final int port, final boolean ssl, final boolean negotiate) throws IOException { - return (Socket)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { - try { - return __getSocket(host, port, ssl, negotiate); - } catch (Exception e) { - if (Log.on) Log.log(Java12.class, "Error attempting to create socket"); - if (Log.on) Log.log(Java12.class, e); - return null; - } - } - }); - } - - protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) { return new Java12DoubleBuffer(w, h); } - protected Surface _createSurface(final Box root, final boolean framed) { - return (Surface)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { return new Java12Surface(root, framed); } - }); - } - - // Inner Classes ////////////////////////////////////////////////////////////////// - - private static Cursor invisibleCursor = - Toolkit.getDefaultToolkit().createCustomCursor(new BufferedImage(2, 2, BufferedImage.TYPE_INT_ARGB), - new Point(1, 1), "invisible"); - - protected static class Java12Surface extends AWTSurface { - - public Java12Surface(Box root, boolean framed) { super(root, framed); } - public void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2) { - if (ourGraphics == null) { - ourGraphics = window.getGraphics(); - - // sometimes jdk1.4 doesn't set the clip properly when we're in the middle of a resize - ourGraphics.setClip(insets.left, insets.top, width + insets.left, height + insets.top); - } - _doDrawImage(ourGraphics, ((AWTDoubleBuffer)s).i, dx + insets.left, dy + insets.top, dx2 + insets.left, dy2 + insets.top, - sx, sy, sx + (dx2 - dx), sy + (dy2 - dy), null); - } - - protected void _setMinimized(boolean b) { - if (frame == null) { - if (Log.on) Log.log(this, "JDK 1.2 can only minimize frames, not windows"); - return; - } - if (b) frame.setState(java.awt.Frame.ICONIFIED); - else frame.setState(java.awt.Frame.NORMAL); - } - - public void syncCursor() { - if (cursor.equals("invisible")) window.setCursor(invisibleCursor); - else super.syncCursor(); - } - } - - protected static class Java12DoubleBuffer extends AWTDoubleBuffer { - private static ColorModel cm = Toolkit.getDefaultToolkit().getColorModel(); - private static Hashtable emptyHashtable = new Hashtable(); - private static short[] sbank = null; - private static int[] ibank = null; - private static byte[] bbank = null; - private static int bank_start = 0; - - public void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) { - _doDrawImage(g, ((AWTPicture)source).i, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null); - } - - public Java12DoubleBuffer(int w, int h) { - SampleModel sm = cm.createCompatibleSampleModel(w, h); - int numSamples = w * h * sm.getNumDataElements(); - DataBuffer buf = null; - if (sm.getDataType() == DataBuffer.TYPE_USHORT) { - if (sbank == null || numSamples > 512 * 512 / 3) { - buf = new DataBufferUShort(numSamples); - } else { - if (numSamples > sbank.length - bank_start) { - bank_start = 0; - sbank = new short[512 * 512]; - } - buf = new DataBufferUShort(sbank, numSamples, bank_start); - bank_start += numSamples; - } - } else if (sm.getDataType() == DataBuffer.TYPE_BYTE) { - if (bbank == null || numSamples > 512 * 512 / 3) { - buf = new DataBufferByte(numSamples); - } else { - if (numSamples > bbank.length - bank_start) { - bank_start = 0; - bbank = new byte[512 * 512]; - } - buf = new DataBufferByte(bbank, numSamples, bank_start); - bank_start += numSamples; - } - } else if (sm.getDataType() == DataBuffer.TYPE_INT) { - if (ibank == null || numSamples > 512 * 512 / 3) { - buf = new DataBufferInt(numSamples); - } else { - if (numSamples > ibank.length - bank_start) { - bank_start = 0; - ibank = new int[512 * 512]; - } - buf = new DataBufferInt(ibank, numSamples, bank_start); - bank_start += numSamples; - } - } - i = new BufferedImage(cm, Raster.createWritableRaster(sm, buf, null), false, emptyHashtable); - g = i.getGraphics(); - } - } - - /** used to avoid garbage creation with getClipBounds() */ - private static Rectangle clipBounds = new Rectangle(); - - protected static void _doDrawImage(Graphics g, Image i, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver o) { - if (dx1 == dx2 || dy1 == dy2) return; - g.drawImage(i, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, o); - } - - protected org.xwt.Weak _getWeak(Object o) { return new Java12Weak(o); } - private static class Java12Weak extends java.lang.ref.WeakReference implements org.xwt.Weak { - public Java12Weak(Object o) { super(o); } - } - - private String __getClipBoard() { return super._getClipBoard(); } - protected String _getClipBoard() { - return (String)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { return __getClipBoard(); } - }); - } - - private void __setClipBoard(String s) { super._setClipBoard(s); } - protected void _setClipBoard(final String s) { - java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() { - public Object run() { - __setClipBoard(s); - return null; - } - }); - } - - protected String getDescriptiveName() { return "Java 1.2+ JVM"; } - - protected void _newBrowserWindow(String url) { - if (Main.applet == null) { - if (Log.on) Log.log(this, "Main.applet is null; cannot invoke showDocument()"); - return; - } - if (Log.on) Log.log(this, "asking browser to show URL " + url); - try { - Main.applet.getAppletContext().showDocument(new URL(url), "_blank"); - } catch (MalformedURLException e) { - if (Log.on) Log.log(this, e); - } - } - -} diff --git a/src/org/xwt/util/JSObject.java b/src/org/xwt/util/JSObject.java deleted file mode 100644 index 092646d..0000000 --- a/src/org/xwt/util/JSObject.java +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] -package org.xwt.util; - -import org.mozilla.javascript.*; -import java.net.*; -import java.io.*; -import java.util.*; -import org.xwt.*; - -/** Simple implementation of a JavaScript host object. - * - * If privateVars is set, then any "var" declaration issued on this - * scope will create a variable visible only to scripts from the same - * directory (package) as the script that made the declaration. - * - * This is implemented by making JSObject.Top the ultimate - * parentScope of all privateVars-style JSObjects. Puts to JSObjects - * which are var-decls will not climb the scope chain, and will be - * put directly to the JSObject. Puts which are not var-decls - * will climb the scope chain and will be put to Top, which will then - * re-put the value to the JSObject as a global. - */ -public class JSObject implements Scriptable { - - // Static Data /////////////////////////////////////////////////////////////////////// - - /** helper; retrieves the 'source code filename' (usually the nodeName) of the currently-executing function in this thread */ - public static String getCurrentFunctionSourceName() { - Context cx = Context.getCurrentContext(); - if (cx == null) { - if (Log.on) Log.log(JSObject.class, "Context.getCurrentContext() is null in getCurrentFunctionSourceName()"); - return "unknown"; - } - Function cf = cx.currentFunction; - if (cf == null) return null; - return (cf instanceof InterpretedFunction) ? - ((InterpretedFunction)cf).getSourceName() : ((InterpretedScript)cf).getSourceName(); - } - - /** cache for nodeNameToPackageName(); prevents creation of zillions of String objects */ - private static Hash nodeNameToPackageNameHash = new Hash(1000, 2); - - /** converts a nodeName (source code filename) into the 'package name' (resource name of its directory) */ - public static String nodeNameToPackageName(String nodeName) { - if (nodeName == null) return null; - String ret = (String)nodeNameToPackageNameHash.get(nodeName); - if (ret != null) return ret; - ret = nodeName; - for(int i=0; iname associated with nodeName */ - public Object getPrivately(String name, String nodeName) { - return properties == null ? null : properties.get(name, nodeNameToPackageName(nodeName)); - } - - /** puts a property as a private variable, accessible only to scripts in the source code file nodeName */ - public void putPrivately(String name, Object value, String nodeName) { - if (!privateVars) { - putGlobally(name, null, value); - return; - } - if (properties == null) properties = new Hash(); - - // we use NOT_FOUND to mark a variable which exists as a script-local, yet has a value of null - if (value == null) value = NOT_FOUND; - properties.put(name, nodeNameToPackageName(nodeName), value); - } - - /** forces a property to be put globally -- accessible to all scripts */ - public void putGlobally(String name, Scriptable start, Object value) { - if (name == null || name.equals("")) return; - if (properties == null) properties = new Hash(); - properties.put(name, null, value); - } - - /** - * if a put is made directly to us (rather than cascading up to - * Top), by a script for whom we are in the ultimate parent - * scope, it must be a var-declaration - */ - public void put(String name, Object value) { put(name, null, value); } - public void put(String name, Scriptable start, Object value) { - if (sealed) return; - if (name == null || name.equals("")) return; - - if (getPrivately(name, getCurrentFunctionSourceName()) != null) - putPrivately(name, value, getCurrentFunctionSourceName()); - - for(Scriptable cur = Context.enter().currentFunction; cur != null; cur = cur.getParentScope()) - if (cur == this) { - putPrivately(name, value, getCurrentFunctionSourceName()); - return; - } - putGlobally(name, start, value); - } - - /** if privateVars is enabled, we always return false, to see if the put propagates up to Top */ - public boolean has(String name, Scriptable start) { - if (!privateVars) return properties != null && properties.get(name) != null; - Top.lastByThread.put(Thread.currentThread(), this); - return false; - } - - public Object[] getIds() { - if (properties == null) return new Object[] { }; - else return properties.keys(); - } - - /** Parent scope of all JSObjects; we use the has(String) method on this object to determine if a put represents a var-declaration or a plain 'ol put */ - private static class Top implements Scriptable { - - /** Last JSObject to perform a has(), keyed by thread. - * Assumes that every Top.has() is immediately preceded by a JSObject.has() in the same thread - */ - public static Hash lastByThread = new Hash(); - - public static Top singleton = new Top(); - private Top() { } - - public boolean has(String name, Scriptable start) { return true; } - public void put(String name, Scriptable start, Object value) { - JSObject last = (JSObject)lastByThread.get(Thread.currentThread()); - if (last.properties != null && last.properties.get(name, nodeNameToPackageName(getCurrentFunctionSourceName())) != null) - last.put(name, start, value); - else last.putGlobally(name, start, value); - } - - public Object get(String name, Scriptable start) { - - // hack since Rhino needs to be able to grab these functions to create new objects - if (name.equals("Object")) return JSObject.defaultObjects.get("Object", null); - if (name.equals("Array")) return JSObject.defaultObjects.get("Array", null); - if (name.equals("Function")) return JSObject.defaultObjects.get("Function", null); - if (name.equals("TypeError")) return JSObject.defaultObjects.get("TypeError", null); - if (name.equals("ConversionError")) return JSObject.defaultObjects.get("ConversionError", null); - return ((JSObject)lastByThread.get(Thread.currentThread())).get(name, start); - } - - // Trivial methods - public String getClassName() { return "Top"; } - public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; } - public void delete(String name) { } - public Scriptable getParentScope() { return null; } - public void setParentScope(Scriptable p) { } - public boolean hasInstance(Scriptable value) { return false; } - public Scriptable getPrototype() { return null; } - public void setPrototype(Scriptable p) { } - public void delete(int i) { } - public Object getDefaultValue(Class hint) { return "Top"; } - public void put(int i, Scriptable start, Object value) { put(String.valueOf(i), start, value); } - public Object get(int i, Scriptable start) { return get(String.valueOf(i), start); } - public boolean has(int i, Scriptable start) { return has(String.valueOf(i), start); } - public Object[] getIds() { return new Object[] { }; } - - } - - // Helper class for defining functions. ////////////////////////////////////// - - public static abstract class JSFunction extends JSObject implements Function { - public JSFunction() { setSeal(true); } - public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; } - } - - // Trivial Methods /////////////////////////////////////////////////////////// - - public void setSeal(boolean doseal) { sealed = doseal; } - public void flush() { if (properties != null) properties.clear(); } - public void delete(String name) { if (Log.on) Log.log(this, "JSObject.delete() should not be reachable"); } - public void delete(int i) { if (Log.on) Log.log(this, "JSObject.delete() should not be reachable"); } - public Scriptable getParentScope() { return privateVars ? Top.singleton : null; } - public void setParentScope(Scriptable p) { } - public boolean hasInstance(Scriptable value) { return false; } - public Scriptable getPrototype() { return null; } - public void setPrototype(Scriptable p) { } - public String getClassName() { return this.getClass().getName(); } - public Object getDefaultValue(Class hint) { return toString(); } - public void put(int i, Scriptable start, Object value) { put(String.valueOf(i), start, value); } - public Object get(int i, Scriptable start) { return get(String.valueOf(i), start); } - public boolean has(int i, Scriptable start) { return has(String.valueOf(i), start); } - -} -