Revision: 6146 Author: [email protected] Date: Tue Sep 15 18:41:30 2009 Log: - Fixes the incompatible exceptions in JSValueGlue - Adds toString implementation - Hacky fix for handling NativeString type - Removed an unnecessary variable
Patch by: amitmanjhi Review by: jat (TBR) http://code.google.com/p/google-web-toolkit/source/detail?r=6146 Modified: /branches/farewellSwt/dev/oophm/overlay/com/google/gwt/dev/shell/JsValueGlue.java /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java ======================================= --- /branches/farewellSwt/dev/oophm/overlay/com/google/gwt/dev/shell/JsValueGlue.java Wed Dec 3 15:31:00 2008 +++ /branches/farewellSwt/dev/oophm/overlay/com/google/gwt/dev/shell/JsValueGlue.java Tue Sep 15 18:41:30 2009 @@ -170,7 +170,12 @@ } // Just don't know what do to with this. - throw new HostedModeException(msgPrefix + ": JS value of type " + /* + * TODO (amitmanjhi): does throwing a HostedModeException here and catching + * a RuntimeException in user test + * com.google.gwt.dev.jjs.test.HostedTest::testObjectReturns() make sense + */ + throw new IllegalArgumentException(msgPrefix + ": JS value of type " + value.getTypeString() + ", expected " + TypeInfo.getSourceRepresentation(type)); } ======================================= --- /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java Thu Sep 10 16:26:01 2009 +++ /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java Tue Sep 15 18:41:30 2009 @@ -46,24 +46,61 @@ */ public class HtmlUnitSessionHandler extends SessionHandler { + private class ToStringMethod extends ScriptableObject implements Function { + + private static final int EXPECTED_NUM_ARGS = 0; + private static final long serialVersionUID = 1592865718416163348L; + + public Object call(Context context, Scriptable scope, Scriptable thisObj, + Object[] args) { + // Allow extra arguments for forward compatibility + if (args.length < EXPECTED_NUM_ARGS) { + throw Context.reportRuntimeError("Bad number of parameters for function" + + " toString: expected " + + EXPECTED_NUM_ARGS + + ", got " + + args.length); + } + // thisObj is the javaObject. + Value thisValue = makeValueFromJsval(context, thisObj); + return JavaObject.getReturnValueFromJavaMethod(context, + HtmlUnitSessionHandler.this, sessionData.getChannel(), + TO_STRING_DISPATCH_ID, thisValue, EMPTY_VALUES); + } + + public Scriptable construct(Context cx, Scriptable scope, Object[] args) { + throw Context.reportRuntimeError("Function connect can't be used as a " + + "constructor"); + } + + @Override + public String getClassName() { + return "function toString"; + } + } + + private static final Value EMPTY_VALUES[] = new Value[0]; + private static final int TO_STRING_DISPATCH_ID = 0; + Map<Integer, JavaObject> javaObjectCache; - int nextId; /** * The htmlPage is also used to synchronize calls to Java code. */ private HtmlPage htmlPage; - private Set<Integer> javaObjectsToFree; + private JavaScriptEngine jsEngine; - private IdentityHashMap<Scriptable, Integer> jsObjectToRef; - + + private IdentityHashMap<Scriptable, Integer> jsObjectToRef; private final PrintWriterTreeLogger logger = new PrintWriterTreeLogger(); private int nextRefId = 1; private Map<Integer, Scriptable> refToJsObject; - private SessionData sessionData; + + private final ToStringMethod toStringMethod = new ToStringMethod(); + private final Window window; HtmlUnitSessionHandler(Window window) { @@ -78,9 +115,8 @@ javaObjectsToFree = new HashSet<Integer>(); nextRefId = 1; refToJsObject = new HashMap<Integer, Scriptable>(); - + // related to JavaObject cache. - nextId = 1; // skipping zero, reserved. javaObjectCache = new HashMap<Integer, JavaObject>(); } @@ -101,7 +137,7 @@ public JavaObject getOrCreateJavaObject(int refId, Context context) { JavaObject javaObject = javaObjectCache.get(refId); if (javaObject == null) { - javaObject = new JavaObject(context, sessionData, nextId++); + javaObject = new JavaObject(context, sessionData, refId); javaObjectCache.put(refId, javaObject); } return javaObject; @@ -113,6 +149,10 @@ throw new UnsupportedOperationException( "getProperty should not be called on the client-side"); } + + public Object getToStringTearOff(Context jsContext) { + return toStringMethod; + } public String getUserAgent() { return "HtmlUnit-" @@ -202,6 +242,17 @@ return returnVal; } if (value instanceof Scriptable) { + if (value instanceof ScriptableObject) { + /* + * HACK: check for native types like NativeString. NativeString is + * package-protected. What other types do we need to check? + */ + ScriptableObject scriptableValue = (ScriptableObject) value; + String className = scriptableValue.getClassName(); + if (className.equals("String")) { + return new Value(scriptableValue.toString()); + } + } Integer refId = jsObjectToRef.get((Scriptable) value); if (refId == null) { refId = nextRefId++; ======================================= --- /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java Thu Sep 10 16:26:01 2009 +++ /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java Tue Sep 15 18:41:30 2009 @@ -40,6 +40,32 @@ return sessionData.getSessionHandler().getOrCreateJavaObject( javaRef.getRefid(), context); } + + static Object getReturnValueFromJavaMethod(Context cx, + HtmlUnitSessionHandler sessionHandler, BrowserChannel channel, + int dispatchId, Value thisValue, Value valueArgs[]) { + ReturnMessage returnMessage = null; + synchronized (sessionHandler.getHtmlPage()) { + try { + new InvokeOnServerMessage(channel, dispatchId, thisValue, valueArgs).send(); + } catch (IOException e) { + return Undefined.instance; + } + try { + returnMessage = ((BrowserChannelClient) channel).reactToMessagesWhileWaitingForReturn(sessionHandler); + } catch (IOException e) { + return Undefined.instance; + } catch (BrowserChannelException e) { + return Undefined.instance; + } + } + Value returnValue = returnMessage.getReturnValue(); + if (returnMessage.isException()) { + throw new RuntimeException("JavaObject.call failed, returnMessage: " + + returnValue.toString()); + } + return sessionHandler.makeJsvalFromValue(cx, returnValue); + } static boolean isJavaObject(Context jsContext, ScriptableObject javaObject) { return javaObject instanceof JavaObject; @@ -87,34 +113,15 @@ args[1]); int dispatchId = ((Number) args[0]).intValue(); - ReturnMessage returnMessage = null; - synchronized (sessionData.getSessionHandler().getHtmlPage()) { - try { - new InvokeOnServerMessage(sessionData.getChannel(), dispatchId, - thisValue, valueArgs).send(); - } catch (IOException e) { - return Undefined.instance; - } - try { - returnMessage = ((BrowserChannelClient) sessionData.getChannel()).reactToMessagesWhileWaitingForReturn(sessionData.getSessionHandler()); - } catch (IOException e) { - return Undefined.instance; - } catch (BrowserChannelException e) { - return Undefined.instance; - } - } - Value returnValue = returnMessage.getReturnValue(); - if (returnMessage.isException()) { - throw new RuntimeException("JavaObject.call failed, returnMessage: " - + returnValue.toString()); - } /* * Return a object array ret. ret[0] is a boolean indicating whether an * exception was thrown or not. ret[1] is the exception or the return value. + * If there is an exception, a RuntimeException is thrown. */ Object ret[] = new Object[2]; ret[0] = Boolean.FALSE; - ret[1] = sessionData.getSessionHandler().makeJsvalFromValue(cx, returnValue); + ret[1] = getReturnValueFromJavaMethod(cx, sessionData.getSessionHandler(), + sessionData.getChannel(), dispatchId, thisValue, valueArgs); return ret; } @@ -122,12 +129,20 @@ throw Context.reportRuntimeError("JavaObject can't be used as a " + "constructor"); } + + // ignoring the 'start' argument. + @Override + public Object get(int index, Scriptable start) { + Value value = ServerMethods.getProperty(sessionData.getChannel(), + sessionData.getSessionHandler(), objectRef, index); + return sessionData.getSessionHandler().makeJsvalFromValue(jsContext, value); + } // ignoring the 'start' argument. @Override public Object get(String name, Scriptable start) { if ("toString".equals(name)) { - return sessionData.getToStringTearOff(); + return sessionData.getSessionHandler().getToStringTearOff(jsContext); } if ("id".equals(name)) { return objectRef; @@ -138,14 +153,6 @@ System.err.println("Unknown property name in get " + name); return Undefined.instance; } - - // ignoring the 'start' argument. - @Override - public Object get(int index, Scriptable start) { - Value value = ServerMethods.getProperty(sessionData.getChannel(), - sessionData.getSessionHandler(), objectRef, index); - return sessionData.getSessionHandler().makeJsvalFromValue(jsContext, value); - } @Override public String getClassName() { ======================================= --- /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java Thu Sep 10 16:26:01 2009 +++ /branches/farewellSwt/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java Tue Sep 15 18:41:30 2009 @@ -35,8 +35,4 @@ return sessionHandler; } - public Object getToStringTearOff() { - // TODO Auto-generated method stub - return null; - } -} +} --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
