diff --git a/SPAAppTest/.classpath b/SPAAppTest/.classpath index 4070f2c..024c193 100644 --- a/SPAAppTest/.classpath +++ b/SPAAppTest/.classpath @@ -5,7 +5,7 @@ - + diff --git a/SPAAppTest/tests/.classpath b/SPAAppTest/tests/.classpath index 7376270..50169ec 100644 --- a/SPAAppTest/tests/.classpath +++ b/SPAAppTest/tests/.classpath @@ -7,8 +7,8 @@ - - + + diff --git a/SPAAppTest/tests/.settings/SPATests.launch b/SPAAppTest/tests/.settings/SPATests.launch index d088862..5a6122f 100644 --- a/SPAAppTest/tests/.settings/SPATests.launch +++ b/SPAAppTest/tests/.settings/SPATests.launch @@ -5,7 +5,7 @@ - + diff --git a/SPAAppTest/tests/src/com/google/gwt/user/server/rpc/LogFilterServletContext.java b/SPAAppTest/tests/src/com/google/gwt/user/server/rpc/LogFilterServletContext.java new file mode 100644 index 0000000..eaafffa --- /dev/null +++ b/SPAAppTest/tests/src/com/google/gwt/user/server/rpc/LogFilterServletContext.java @@ -0,0 +1,261 @@ +package com.google.gwt.user.server.rpc; +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * Modified March 2014 for SPALibrary to remove support for JEE 6 Servlet requirements since GAE servlet-api doesn't have that yet + */ + + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.Map; +import java.util.Set; + +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; +import javax.servlet.FilterRegistration.Dynamic; +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; + +@SuppressWarnings(value = {"deprecation", "unchecked"}) +abstract class LogFilterServletContext implements ServletContext { + private final ServletContext realContext; + + public LogFilterServletContext(ServletContext realContext) { + this.realContext = realContext; + } + + public Object getAttribute(String name) { + return realContext.getAttribute(name); + } + + public Enumeration getAttributeNames() { + return realContext.getAttributeNames(); + } + + public ServletContext getContext(String uripath) { + return realContext.getContext(uripath); + } + + public String getContextPath() { + return realContext.getContextPath(); + } + + public String getInitParameter(String name) { + return realContext.getInitParameter(name); + } + + public Enumeration getInitParameterNames() { + return realContext.getInitParameterNames(); + } + + public int getMajorVersion() { + return realContext.getMajorVersion(); + } + + public String getMimeType(String file) { + return realContext.getMimeType(file); + } + + public int getMinorVersion() { + return realContext.getMinorVersion(); + } + + public RequestDispatcher getNamedDispatcher(String name) { + return realContext.getNamedDispatcher(name); + } + + public String getRealPath(String path) { + return realContext.getRealPath(path); + } + + public RequestDispatcher getRequestDispatcher(String path) { + return realContext.getRequestDispatcher(path); + } + + public URL getResource(String path) throws MalformedURLException { + return realContext.getResource(path); + } + + public InputStream getResourceAsStream(String path) { + return realContext.getResourceAsStream(path); + } + + public Set getResourcePaths(String path) { + return realContext.getResourcePaths(path); + } + + public String getServerInfo() { + return realContext.getServerInfo(); + } + + public Servlet getServlet(String name) throws ServletException { + return realContext.getServlet(name); + } + + public String getServletContextName() { + return realContext.getServletContextName(); + } + + public Enumeration getServletNames() { + return realContext.getServletNames(); + } + + public Enumeration getServlets() { + return realContext.getServlets(); + } + + public void log(Exception exception, String msg) { + if (shouldLog(exception, msg)) { + realContext.log(exception, msg); + } + } + + public void log(String msg) { + if (shouldLog(null, msg)) { + realContext.log(msg); + } + } + + public void log(String msg, Throwable throwable) { + if (shouldLog(throwable, msg)) { + realContext.log(msg, throwable); + } + } + + public void removeAttribute(String name) { + realContext.removeAttribute(name); + } + + public void setAttribute(String name, Object object) { + realContext.setAttribute(name, object); + } +/* + public Dynamic addFilter(String arg0, Class arg1) { + return realContext.addFilter(arg0, arg1); + } + + public Dynamic addFilter(String arg0, Filter arg1) { + return realContext.addFilter(arg0, arg1); + } + + public Dynamic addFilter(String arg0, String arg1) { + return realContext.addFilter(arg0, arg1); + } + + public void addListener(Class arg0) { + realContext.addListener(arg0); + } + + public void addListener(String arg0) { + realContext.addListener(arg0); + } + + public void addListener(T arg0) { + realContext.addListener(arg0); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet( + String arg0, Class arg1) { + return realContext.addServlet(arg0, arg1); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, Servlet arg1) { + return realContext.addServlet(arg0, arg1); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { + return realContext.addServlet(arg0, arg1); + } + + public T createFilter(Class arg0) throws ServletException { + return realContext.createFilter(arg0); + } + + public T createListener(Class arg0) throws ServletException { + return realContext.createListener(arg0); + } + + public T createServlet(Class arg0) throws ServletException { + return realContext.createServlet(arg0); + } + + public void declareRoles(String... arg0) { + realContext.declareRoles(arg0); + } + + public ClassLoader getClassLoader() { + return realContext.getClassLoader(); + } + + public Set getDefaultSessionTrackingModes() { + return realContext.getDefaultSessionTrackingModes(); + } + + public int getEffectiveMajorVersion() { + return realContext.getEffectiveMajorVersion(); + } + + public int getEffectiveMinorVersion() { + return realContext.getEffectiveMinorVersion(); + } + + public Set getEffectiveSessionTrackingModes() { + return realContext.getEffectiveSessionTrackingModes(); + } + + public FilterRegistration getFilterRegistration(String arg0) { + return realContext.getFilterRegistration(arg0); + } + + public Map getFilterRegistrations() { + return realContext.getFilterRegistrations(); + } + + public JspConfigDescriptor getJspConfigDescriptor() { + return realContext.getJspConfigDescriptor(); + } + + public ServletRegistration getServletRegistration(String arg0) { + return realContext.getServletRegistration(arg0); + } + + public Map getServletRegistrations() { + return realContext.getServletRegistrations(); + } + + public SessionCookieConfig getSessionCookieConfig() { + return realContext.getSessionCookieConfig(); + } + + public boolean setInitParameter(String arg0, String arg1) { + return realContext.setInitParameter(arg0, arg1); + } + + public void setSessionTrackingModes(Set arg0) { + realContext.setSessionTrackingModes(arg0); + } +*/ + protected abstract boolean shouldLog(Throwable t, String msg); +} \ No newline at end of file diff --git a/SPALibrary/.classpath b/SPALibrary/.classpath index a9ff0c6..e797514 100644 --- a/SPALibrary/.classpath +++ b/SPALibrary/.classpath @@ -1,7 +1,7 @@ - + diff --git a/SPALibrary/AndroidManifest.xml b/SPALibrary/AndroidManifest.xml index bda8a9d..a18b478 100644 --- a/SPALibrary/AndroidManifest.xml +++ b/SPALibrary/AndroidManifest.xml @@ -1,11 +1,11 @@ + android:versionCode="2" + android:versionName="0.4.2" android:installLocation="internalOnly"> + android:targetSdkVersion="19" /> - + @@ -24,13 +24,12 @@ - + - diff --git a/SPALibrary/libs/servlet-api.jar b/SPALibrary/libs/servlet-api.jar index 9f532f5..4bbde03 100644 Binary files a/SPALibrary/libs/servlet-api.jar and b/SPALibrary/libs/servlet-api.jar differ diff --git a/SPALibrary/src/com/google/gwt/core/client/GWT.java b/SPALibrary/src/com/google/gwt/core/client/GWT.java new file mode 100644 index 0000000..b976259 --- /dev/null +++ b/SPALibrary/src/com/google/gwt/core/client/GWT.java @@ -0,0 +1,331 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * Modified in March 2014 to remove Schedule Dependency + */ +package com.google.gwt.core.client; + +import com.google.gwt.core.client.impl.Impl; + +/** + * Supports core functionality that in some cases requires direct support from + * the compiler and runtime systems such as runtime type information and + * deferred binding. + */ +public final class GWT { + /** + * This interface is used to catch exceptions at the "top level" just before + * they escape to the browser. This is used in places where the browser calls + * into user code such as event callbacks, timers, and RPC. + * + * In Development Mode, the default handler prints a stack trace to the log + * window. In Production Mode, the default handler is null and thus exceptions + * are allowed to escape, which provides an opportunity to use a JavaScript + * debugger. + */ + public interface UncaughtExceptionHandler { + void onUncaughtException(Throwable e); + } + + /** + * An {@link UncaughtExceptionHandler} that logs errors to + * {@link GWT#log(String, Throwable)}. This is the default exception handler + * in Development Mode. In Production Mode, the default exception handler is + * null. + */ + private static final class DefaultUncaughtExceptionHandler implements + UncaughtExceptionHandler { + @Override + public void onUncaughtException(Throwable e) { + log("Uncaught exception escaped", e); + } + } + + /** + * This constant is used by {@link #getPermutationStrongName} when running in + * Development Mode. + */ + public static final String HOSTED_MODE_PERMUTATION_STRONG_NAME = "HostedMode"; + + /** + * Defaults to null in Production Mode and an instance of + * {@link DefaultUncaughtExceptionHandler} in Development Mode. + */ + private static UncaughtExceptionHandler uncaughtExceptionHandler = null; + + /** + * Instantiates a class via deferred binding. + * + *

+ * The argument to {@link #create(Class)} must be a class literal + * because the Production Mode compiler must be able to statically determine + * the requested type at compile-time. This can be tricky because using a + * {@link Class} variable may appear to work correctly in Development Mode. + *

+ * + * @param classLiteral a class literal specifying the base class to be + * instantiated + * @return the new instance, which must be cast to the requested class + */ + public static T create(Class classLiteral) { + /* + * In Production Mode, the compiler directly replaces calls to this method + * with a new Object() type expression of the correct rebound type. + */ + return com.google.gwt.core.shared.GWT.create(classLiteral); + } + + public static void exportUnloadModule() { + Impl.exportUnloadModule(); + } + + /** + * Gets the URL prefix of the hosting page, useful for prepending to relative + * paths of resources which may be relative to the host page. Typically, you + * should use {@link #getModuleBaseURL()} unless you have a specific reason to + * load a resource relative to the host page. + * + * @return if non-empty, the base URL is guaranteed to end with a slash + */ + public static String getHostPageBaseURL() { + return Impl.getHostPageBaseURL(); + } + + /** + * Gets the URL prefix that should be prepended to URLs that point to + * static files generated by the GWT compiler, such as files in the + * module's public path. + * + *

+ * Normally this will be the same value as {@link #getModuleBaseURL}, but + * may be different when a GWT app is configured to get its static resources + * from a different server. + *

+ * + * @return if non-empty, the base URL is guaranteed to end with a slash + */ + public static String getModuleBaseForStaticFiles() { + return Impl.getModuleBaseURLForStaticFiles(); + } + + /** + * Gets the URL prefix that should be prepended to URLs that + * are intended to be module-relative, such as RPC entry points. + * + *

If the URL points to an output file of the GWT compiler (such as + * a file in the public path), use {@link #getModuleBaseForStaticFiles()} + * instead.

+ * + * @return if non-empty, the base URL is guaranteed to end with a slash + */ + public static String getModuleBaseURL() { + return Impl.getModuleBaseURL(); + } + + /** + * Gets the name of the running module. + */ + public static String getModuleName() { + return Impl.getModuleName(); + } + + /** + * Returns the permutation's strong name. This can be used to distinguish + * between different permutations of the same module. In Development Mode, + * this method will return {@value #HOSTED_MODE_PERMUTATION_STRONG_NAME}. + */ + public static String getPermutationStrongName() { + if (GWT.isScript()) { + return Impl.getPermutationStrongName(); + } else { + return HOSTED_MODE_PERMUTATION_STRONG_NAME; + } + } + + /** + * @deprecated Use {@link Object#getClass()}, {@link Class#getName()} + */ + @Deprecated + public static String getTypeName(Object o) { + return (o == null) ? null : o.getClass().getName(); + } + + /** + * Returns the currently active uncaughtExceptionHandler. + * + * @return the currently active handler, or null if no handler is active. + * + * @see #reportUncaughtException(Throwable) + */ + public static UncaughtExceptionHandler getUncaughtExceptionHandler() { + return uncaughtExceptionHandler; + } + + /** + * Reports an exception caught at the "top level" to a handler set via + * {@link #setUncaughtExceptionHandler(UncaughtExceptionHandler)}. This is + * used in places where the browser calls into user code such as event + * callbacks, timers, and RPC. + *

+ * If no {@code UncaughtExceptionHandler} is set, the exception is reported + * to browser. Browsers usually log these exceptions to the JavaScript + * console. + */ + public static void reportUncaughtException(Throwable e) { + Impl.reportUncaughtException(e); + } + + /** + * Returns the empty string when running in Production Mode, but returns a + * unique string for each thread in Development Mode (for example, different + * windows accessing the dev mode server will each have a unique id, and + * hitting refresh without restarting dev mode will result in a new unique id + * for a particular window. + * + * TODO(unnurg): Remove this function once Dev Mode rewriting classes are in + * gwt-dev. + */ + public static String getUniqueThreadId() { + return com.google.gwt.core.shared.GWT.getUniqueThreadId(); + } + + public static String getVersion() { + String version = com.google.gwt.core.shared.GWT.getVersion(); + if (version == null) { + version = getVersion0(); + } + return version; + } + + /** + * Returns true when running inside the normal GWT environment, + * either in Development Mode or Production Mode. Returns false + * if this code is running in a plain JVM. This might happen when running + * shared code on the server, or during the bootstrap sequence of a + * GWTTestCase test. + */ + public static boolean isClient() { + return com.google.gwt.core.shared.GWT.isClient(); + } + + /** + * Returns true when running in production mode. Returns + * false when running either in development mode, or when running + * in a plain JVM. + */ + public static boolean isProdMode() { + return com.google.gwt.core.shared.GWT.isProdMode(); + } + + /** + * Determines whether or not the running program is script or bytecode. + */ + public static boolean isScript() { + return com.google.gwt.core.shared.GWT.isScript(); + } + + /** + * Logs a message to the development shell logger in Development Mode, or to + * the console in Super Dev Mode. Calls are optimized out in Production Mode. + */ + public static void log(String message) { + com.google.gwt.core.shared.GWT.log(message); + } + + /** + * Logs a message to the development shell logger in Development Mode, or to + * the console in Super Dev Mode. Calls are optimized out in Production Mode. + */ + public static void log(String message, Throwable e) { + com.google.gwt.core.shared.GWT.log(message, e); + } + + /** + * Emits a JavaScript "debugger" statement on the line that called this method. + * If the user has the browser's debugger open, the debugger will stop when the + * GWT application executes that line. There is no effect in Dev Mode or in + * server-side code. + */ + public static void debugger() { + } + + /** + * The same as {@link #runAsync(RunAsyncCallback)}, except with an extra + * parameter to provide a name for the call. The name parameter should be + * supplied with a class literal. If two GWT.runAsync calls use the same + * class literal, the codesplitter will put the corresponding code in + * the same code fragment. + */ + @SuppressWarnings("unused") // parameter will be used following replacement + public static void runAsync(Class name, final RunAsyncCallback callback) { + runAsyncImpl(callback); + } + + + /** + * Run the specified callback once the necessary code for it has been loaded. + */ + public static void runAsync(final RunAsyncCallback callback) { + runAsyncImpl(callback); + } + + private static void runAsyncImpl(final RunAsyncCallback callback) { +// Scheduler.get().scheduleDeferred(new ScheduledCommand() { +// @Override public void execute() { +// callback.onSuccess(); +// } +// }); + callback.onSuccess(); + } + + /** + * Sets a custom uncaught exception handler. See + * {@link #getUncaughtExceptionHandler()} for details. + * + * @param handler the handler that should be called when an exception is + * about to escape to the browser, or null to clear the + * handler and allow exceptions to escape. + */ + public static void setUncaughtExceptionHandler( + UncaughtExceptionHandler handler) { + uncaughtExceptionHandler = handler; + } + + /** + * Called via reflection in Development Mode; do not ever call this method in + * Production Mode. + */ + static void setBridge(GWTBridge bridge) { + com.google.gwt.core.shared.GWT.setBridge(bridge); + if (bridge != null) { + setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler()); + } + } + + private static native String getVersion0() /*-{ + return $gwt_version; + }-*/; + + /** + * If enabled via <set-property name="gwt.unloadEnabled" value="true"/> invoking this method causes the module + * to be removed from memory and all {@link com.google.gwt.core.client.impl.Disposable} instances to be + * cleaned up. This method is not typically called by the GWT module itself, but exported so that another module + * may call it. + * @see com.google.gwt.core.client.GWT#exportUnloadModule() + */ + private static void unloadModule() { + Impl.unloadModule(); + } +} diff --git a/SPALibrary/src/com/google/gwt/core/client/JavaScriptException.java b/SPALibrary/src/com/google/gwt/core/client/JavaScriptException.java index c49bae3..005bab4 100644 --- a/SPALibrary/src/com/google/gwt/core/client/JavaScriptException.java +++ b/SPALibrary/src/com/google/gwt/core/client/JavaScriptException.java @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. * - * Modified for the SPA Library May 2013 to eliminate the JavascriptObject dependency + * Modified for SPALibrary in Mar 2014 to remove StackTraceCreator Dependancy */ package com.google.gwt.core.client; @@ -46,6 +46,8 @@ */ public final class JavaScriptException extends RuntimeException { + private static final Object NOT_SET = new Object(); + private static String getExceptionDescription(Object e) { if (e instanceof JavaScriptObject) { return getExceptionDescription0((JavaScriptObject) e); @@ -74,12 +76,10 @@ private static native String getExceptionName0(JavaScriptObject e) /*-{ return (e == null) ? null : e.name; }-*/; - private static String getExceptionProperties(Object e) { - return ""; - // SP EDIT +// private static String getExceptionProperties(Object e) { // return (GWT.isScript() && e instanceof JavaScriptObject) // ? StackTraceCreator.getProperties((JavaScriptObject) e) : ""; - } +// } /** * The original description of the JavaScript exception this class wraps, @@ -128,28 +128,40 @@ public JavaScriptException(Object e, String description) { * thrown object, although this is not possible in all browsers. */ if (GWT.isScript()) { - // StackTraceCreator.createStackTrace(this); + //StackTraceCreator.createStackTrace(this); } } - + public JavaScriptException(String name, String description) { this.message = "JavaScript " + name + " exception: " + description; this.name = name; this.description = description; - this.e = null; + this.e = NOT_SET; } /** - * Used for server-side instantiation during JUnit runs. Exceptions are - * manually marshaled through - * com.google.gwt.junit.client.impl.ExceptionWrapper objects. - * + * Used for testing instantiations. + * * @param message the detail message */ protected JavaScriptException(String message) { super(message); this.message = this.description = message; - this.e = null; + this.e = NOT_SET; + } + + /** + * Returns {@code true} if a thrown object is not set for the exception. + */ + public boolean isThrownSet() { + return e != NOT_SET; + } + + /** + * Returns the original thrown object from javascript; may be {@code null}. + */ + public Object getThrown() { + return e == NOT_SET ? null : e; } /** @@ -157,24 +169,23 @@ protected JavaScriptException(String message) { * null. */ public String getDescription() { - if (message == null) { - init(); - } + ensureInit(); return description; } /** * Returns the original JavaScript the exception; may be null. + * + * @deprecated deprecated in favor for {@link #getThrown()} and {@link #isThrownSet()} */ + @Deprecated public JavaScriptObject getException() { return (e instanceof JavaScriptObject) ? (JavaScriptObject) e : null; } @Override public String getMessage() { - if (message == null) { - init(); - } + ensureInit(); return message; } @@ -183,16 +194,17 @@ public String getMessage() { * null. */ public String getName() { - if (message == null) { - init(); - } + ensureInit(); return name; } - private void init() { - name = getExceptionName(e); - description = description + ": " + getExceptionDescription(e); - message = "(" + name + ") " + getExceptionProperties(e) + description; + private void ensureInit() { + if (message == null) { + Object exception = getThrown(); + name = getExceptionName(exception); + description = description + ": " + getExceptionDescription(exception); + message = "(" + name + ") " + /*getExceptionProperties(exception) +*/ description; + } } -} +} \ No newline at end of file diff --git a/SPALibrary/src/com/google/gwt/core/client/impl/Impl.java b/SPALibrary/src/com/google/gwt/core/client/impl/Impl.java index 26f8d34..9cc4d7d 100644 --- a/SPALibrary/src/com/google/gwt/core/client/impl/Impl.java +++ b/SPALibrary/src/com/google/gwt/core/client/impl/Impl.java @@ -13,12 +13,14 @@ * License for the specific language governing permissions and limitations under * the License. * - * Modified for the SPA Library May 2013 to eliminate the SchedulerImpl dependency + * Modified for SPALibrary in March 2014 to remove Scheduler Dependency */ package com.google.gwt.core.client.impl; import com.google.gwt.core.client.Duration; import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; +import com.google.gwt.core.client.JavaScriptException; import com.google.gwt.core.client.JavaScriptObject; /** @@ -27,6 +29,8 @@ */ public final class Impl { + public static boolean moduleUnloaded = false; + private static final int WATCHDOG_ENTRY_DEPTH_CHECK_INTERVAL_MS = 2000; /** @@ -45,6 +49,25 @@ public final class Impl { */ private static int watchdogEntryDepthTimerId = -1; + private static UnloadSupport unloadSupport = GWT.isScript() ? + (UnloadSupport) GWT.create(UnloadSupport.class) : new UnloadSupport(); + + static { + exportUnloadModule(); + } + + public static void clearInterval(int timerId) { + unloadSupport.clearInterval(timerId); + } + + public static void clearTimeout(int timerId) { + unloadSupport.clearTimeout(timerId); + } + + public static void dispose(Disposable d) { + unloadSupport.dispose(d); + } + /** * This method should be used whenever GWT code is entered from a JS context * and there is no GWT code in the same module on the call stack. Examples @@ -59,7 +82,7 @@ public final class Impl { * The function passed to this method will be invoked via * Function.apply() with the current this value and * the invocation arguments passed to $entry. - * + * * @param jsFunction a JS function to invoke, which is typically a JSNI * reference to a static Java method * @return the value returned when jsFunction is invoked, or @@ -80,6 +103,10 @@ public static native JavaScriptObject entry(JavaScriptObject jsFunction) /*-{ }; }-*/; + public static void exportUnloadModule() { + unloadSupport.exportUnloadModule(); + } + /** * Gets an identity-based hash code on the passed-in Object by adding an * expando. This method should not be used with null or any @@ -135,7 +162,7 @@ public static native String getModuleName() /*-{ * Returns the obfuscated name of members in the compiled output. This is a * thin wrapper around JNameOf AST nodes and is therefore meaningless to * implement in Development Mode. - * + * * @param jsniIdent a string literal specifying a type, field, or method. Raw * type names may also be used to obtain the name of the type's seed * function. @@ -158,6 +185,57 @@ public static native String getPermutationStrongName() /*-{ return $strongName; }-*/; + /** + * UncaughtExceptionHandler that is used by unit tests to spy on uncaught + * exceptions. + */ + private static UncaughtExceptionHandler uncaughtExceptionHandlerForTest; + + /** + * Set an uncaught exception handler to spy on uncaught exceptions in unit + * tests. + *

+ * Setting this method will not interfere with any exception handling logic; + * i.e. {@link GWT#getUncaughtExceptionHandler()} will still return null if a + * handler is not set via {@link GWT#setUncaughtExceptionHandler}. + */ + public static void setUncaughtExceptionHandlerForTest( + UncaughtExceptionHandler handler) { + uncaughtExceptionHandlerForTest = handler; + } + + public static void reportUncaughtException(Throwable e) { + if (Impl.uncaughtExceptionHandlerForTest != null) { + Impl.uncaughtExceptionHandlerForTest.onUncaughtException(e); + } + + UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler(); + if (handler != null) { + if (handler == Impl.uncaughtExceptionHandlerForTest) { + return; // Already reported so we're done. + } + // TODO(goktug): Handler might throw an exception but catching and reporting it to browser + // here breaks assumptions of some existing hybrid apps that uses UCE for exception + // conversion. We don't have an alternative functionality (yet) and it is too risky to include + // the change in the release at last minute. + handler.onUncaughtException(e); + return; // Done. + } + + // Make sure that the exception is not swallowed and let the browser handle it + reportToBrowser(e); + } + + private static void reportToBrowser(Throwable e) { + reportToBrowser(e instanceof JavaScriptException ? ((JavaScriptException) e).getThrown() : e); + } + + private static native void reportToBrowser(Object e) /*-{ + $wnd.setTimeout(function () { + throw e; + }, 0); + }-*/; + /** * Indicates if $entry has been called. */ @@ -165,6 +243,10 @@ public static boolean isEntryOnStack() { return entryDepth > 0; } + public static boolean isModuleUnloaded() { + return moduleUnloaded; + } + /** * Indicates if $entry is present on the stack more than once. */ @@ -185,12 +267,31 @@ public static native JavaScriptObject registerEntry() /*-{ } }-*/; + public static void scheduleDispose(Disposable d) { + unloadSupport.scheduleDispose(d); + } + + public static int setInterval(JavaScriptObject func, int time) { + return unloadSupport.setInterval(func, time); + } + + public static int setTimeout(JavaScriptObject func, int time) { + return unloadSupport.setTimeout(func, time); + } + + public static void unloadModule() { + if (unloadSupport.isUnloadSupported()) { + moduleUnloaded = true; + unloadSupport.disposeAll(); + } + } + private static native Object apply(Object jsFunction, Object thisObj, - Object arguments) /*-{ + Object args) /*-{ if (@com.google.gwt.core.client.GWT::isScript()()) { - return jsFunction.apply(thisObj, arguments); + return jsFunction.apply(thisObj, args); } else { - var _ = jsFunction.apply(thisObj, arguments); + var _ = jsFunction.apply(thisObj, args); if (_ != null) { // Wrap for Development Mode _ = Object(_); @@ -215,8 +316,7 @@ private static boolean enter() { // We want to disable some actions in the reentrant case if (entryDepth++ == 0) { - //SP EDIT - // SchedulerImpl.INSTANCE.flushEntryCommands(); + //SchedulerImpl.INSTANCE.flushEntryCommands(); return true; } return false; @@ -226,7 +326,11 @@ private static boolean enter() { * Implements {@link #entry(JavaScriptObject)}. */ private static Object entry0(Object jsFunction, Object thisObj, - Object arguments) throws Throwable { + Object args) throws Throwable { + // if module is unloaded, don't run anything + if (unloadSupport.isUnloadSupported() && Impl.isModuleUnloaded()) { + return null; + } boolean initialEntry = enter(); try { @@ -242,14 +346,14 @@ private static Object entry0(Object jsFunction, Object thisObj, * doing something useful with it. */ try { - return apply(jsFunction, thisObj, arguments); + return apply(jsFunction, thisObj, args); } catch (Throwable t) { - GWT.getUncaughtExceptionHandler().onUncaughtException(t); + reportUncaughtException(t); return undefined(); } } else { // Can't handle any exceptions, let them percolate normally - return apply(jsFunction, thisObj, arguments); + return apply(jsFunction, thisObj, args); } /* @@ -266,8 +370,7 @@ private static Object entry0(Object jsFunction, Object thisObj, */ private static void exit(boolean initialEntry) { if (initialEntry) { - // SP EDIT - //SchedulerImpl.INSTANCE.flushFinallyCommands(); + // SchedulerImpl.INSTANCE.flushFinallyCommands(); } // Decrement after we call flush @@ -298,7 +401,7 @@ private static native Object undefined() /*-{ }-*/; private static native void watchdogEntryDepthCancel(int timerId) /*-{ - $wnd.clearTimeout(timerId); + @com.google.gwt.core.client.impl.Impl::clearTimeout(I)(timerId); }-*/; private static void watchdogEntryDepthRun() { @@ -311,7 +414,7 @@ private static void watchdogEntryDepthRun() { } private static native int watchdogEntryDepthSchedule() /*-{ - return $wnd.setTimeout(function() { + return @com.google.gwt.core.client.impl.Impl::setTimeout(Lcom/google/gwt/core/client/JavaScriptObject;I)(function() { @com.google.gwt.core.client.impl.Impl::watchdogEntryDepthRun()(); }, 10); }-*/; diff --git a/SPWebTest/.classpath b/SPWebTest/.classpath index f99bd78..3a2641d 100644 --- a/SPWebTest/.classpath +++ b/SPWebTest/.classpath @@ -3,10 +3,10 @@ - - + - + + diff --git a/SPWebTest/.settings/SPAWebTest.launch b/SPWebTest/.settings/SPAWebTest.launch index 9224498..97c385e 100644 --- a/SPWebTest/.settings/SPAWebTest.launch +++ b/SPWebTest/.settings/SPAWebTest.launch @@ -1,7 +1,7 @@ - + @@ -18,7 +18,7 @@ - + - + diff --git a/SPWebTest/.settings/com.google.appengine.eclipse.core.prefs b/SPWebTest/.settings/com.google.appengine.eclipse.core.prefs index 3a6477b..68e89fa 100644 --- a/SPWebTest/.settings/com.google.appengine.eclipse.core.prefs +++ b/SPWebTest/.settings/com.google.appengine.eclipse.core.prefs @@ -1,5 +1,5 @@ eclipse.preferences.version=1 -filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.8.6.jar|appengine-api-labs.jar|appengine-endpoints.jar|appengine-jsr107cache-1.8.6.jar|jsr107cache-1.1.jar +filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.9.0.jar|appengine-api-labs.jar|appengine-endpoints-deps.jar|appengine-endpoints.jar|appengine-jsr107cache-1.9.0.jar|jsr107cache-1.1.jar gaeDatanucleusEnabled=false gaeDatanucleusVersion=v2 gaeHrdEnabled=true diff --git a/SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.8.6.jar b/SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.9.0.jar similarity index 71% rename from SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.8.6.jar rename to SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.9.0.jar index cffa3d3..0dbe20b 100644 Binary files a/SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.8.6.jar and b/SPWebTest/war/WEB-INF/lib/appengine-api-1.0-sdk-1.9.0.jar differ diff --git a/SPWebTest/war/WEB-INF/lib/appengine-api-labs.jar b/SPWebTest/war/WEB-INF/lib/appengine-api-labs.jar index 453391f..3a15b87 100644 Binary files a/SPWebTest/war/WEB-INF/lib/appengine-api-labs.jar and b/SPWebTest/war/WEB-INF/lib/appengine-api-labs.jar differ diff --git a/SPWebTest/war/WEB-INF/lib/appengine-endpoints-deps.jar b/SPWebTest/war/WEB-INF/lib/appengine-endpoints-deps.jar new file mode 100644 index 0000000..5033402 Binary files /dev/null and b/SPWebTest/war/WEB-INF/lib/appengine-endpoints-deps.jar differ diff --git a/SPWebTest/war/WEB-INF/lib/appengine-endpoints.jar b/SPWebTest/war/WEB-INF/lib/appengine-endpoints.jar index a1e91d1..b34d5ef 100644 Binary files a/SPWebTest/war/WEB-INF/lib/appengine-endpoints.jar and b/SPWebTest/war/WEB-INF/lib/appengine-endpoints.jar differ diff --git a/SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.8.6.jar b/SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.9.0.jar similarity index 62% rename from SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.8.6.jar rename to SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.9.0.jar index 675f1f8..fa3050d 100644 Binary files a/SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.8.6.jar and b/SPWebTest/war/WEB-INF/lib/appengine-jsr107cache-1.9.0.jar differ diff --git a/SPWebTest/war/WEB-INF/lib/gwt-servlet.jar b/SPWebTest/war/WEB-INF/lib/gwt-servlet.jar index b154974..2e85a1a 100644 Binary files a/SPWebTest/war/WEB-INF/lib/gwt-servlet.jar and b/SPWebTest/war/WEB-INF/lib/gwt-servlet.jar differ diff --git a/gwt-syncproxy/.classpath b/gwt-syncproxy/.classpath index 219efd3..bb484fe 100644 --- a/gwt-syncproxy/.classpath +++ b/gwt-syncproxy/.classpath @@ -6,10 +6,9 @@ - + - - + diff --git a/gwt-syncproxy/.settings/com.google.appengine.eclipse.core.prefs b/gwt-syncproxy/.settings/com.google.appengine.eclipse.core.prefs index f90d069..262395d 100644 --- a/gwt-syncproxy/.settings/com.google.appengine.eclipse.core.prefs +++ b/gwt-syncproxy/.settings/com.google.appengine.eclipse.core.prefs @@ -1,2 +1,2 @@ eclipse.preferences.version=1 -filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.8.6.jar|appengine-api-labs.jar|appengine-endpoints.jar|appengine-jsr107cache-1.8.6.jar|datanucleus-appengine-1.0.10.final.jar|datanucleus-core-1.1.5.jar|datanucleus-jpa-1.1.5.jar|geronimo-jpa_3.0_spec-1.1.1.jar|geronimo-jta_1.1_spec-1.1.1.jar|jdo2-api-2.3-eb.jar|jsr107cache-1.1.jar +filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.9.0.jar|appengine-api-labs.jar|appengine-endpoints-deps.jar|appengine-endpoints.jar|appengine-jsr107cache-1.9.0.jar|datanucleus-appengine-1.0.10.final.jar|datanucleus-core-1.1.5.jar|datanucleus-jpa-1.1.5.jar|geronimo-jpa_3.0_spec-1.1.1.jar|geronimo-jta_1.1_spec-1.1.1.jar|jdo2-api-2.3-eb.jar|jsr107cache-1.1.jar diff --git a/gwt-syncproxy/src/com/gdevelop/gwt/syncrpc/RemoteServiceInvocationHandler.java b/gwt-syncproxy/src/com/gdevelop/gwt/syncrpc/RemoteServiceInvocationHandler.java index 04e2959..3e19483 100644 --- a/gwt-syncproxy/src/com/gdevelop/gwt/syncrpc/RemoteServiceInvocationHandler.java +++ b/gwt-syncproxy/src/com/gdevelop/gwt/syncrpc/RemoteServiceInvocationHandler.java @@ -130,8 +130,17 @@ public Object invoke(Object proxy, Method method, Object[] args) "There is no sync version of " + serviceIntfName + "Async"); } - Method syncMethod = clazz.getMethod(method.getName(), + Method syncMethod = null; + try{ + syncMethod = clazz.getMethod(method.getName(), syncParamTypes); + }catch(NoSuchMethodException nsme){ + String temp = ""; + for(Class cl:syncParamTypes){ + temp += cl.getSimpleName() + ","; + } + throw new NoSuchMethodException("SPNoMeth " + method.getName() + " class " + clazz.getSimpleName() + " params " + temp); + } if (syncMethod != null) { returnType = syncMethod.getReturnType(); } else { @@ -197,7 +206,8 @@ public void run() { * payload); if (callback != null){ callback.onSuccess(result); } * return result; */ - } catch (Throwable ex) { + } + catch (Throwable ex) { if (callback != null) { callback.onFailure(ex); return null; diff --git a/gwt-syncproxy/test/com/gdevelop/gwt/syncrpc/test/ExceptionTest.java b/gwt-syncproxy/test/com/gdevelop/gwt/syncrpc/test/ExceptionTest.java index 82f49ef..5913e73 100644 --- a/gwt-syncproxy/test/com/gdevelop/gwt/syncrpc/test/ExceptionTest.java +++ b/gwt-syncproxy/test/com/gdevelop/gwt/syncrpc/test/ExceptionTest.java @@ -5,7 +5,6 @@ import com.gdevelop.gwt.syncrpc.SyncProxy; import com.google.gwt.event.shared.UmbrellaException; import com.google.gwt.user.client.rpc.ExceptionsTestService; -import com.google.gwt.user.client.rpc.ExceptionsTestService.ExceptionsTestServiceException; import com.google.gwt.user.client.rpc.TestSetFactory; import com.google.gwt.user.client.rpc.TestSetValidator; @@ -17,7 +16,7 @@ public class ExceptionTest extends TestCase { public ExceptionTest() { } - public void testException() throws ExceptionsTestServiceException { + public void testException(){ final UmbrellaException expected = TestSetFactory .createUmbrellaException(); UmbrellaException result = service.echo(expected);