Rearrange how module logging is handled.
Patch by: jat
Review by: rdayal
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7027 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index 25cb7b3..503df51 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -17,7 +17,6 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.TreeLogger.HelpInfo;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
import com.google.gwt.dev.Precompile.PrecompileOptionsImpl;
@@ -38,7 +37,6 @@
import com.google.gwt.dev.ui.DevModeUI;
import com.google.gwt.dev.ui.DoneCallback;
import com.google.gwt.dev.ui.DoneEvent;
-import com.google.gwt.dev.ui.DevModeUI.ModuleHandle;
import com.google.gwt.dev.util.BrowserInfo;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.ArgHandlerGenDir;
@@ -57,7 +55,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -77,22 +74,25 @@
*/
public class UiBrowserWidgetHostImpl implements BrowserWidgetHost {
- public ModuleSpaceHost createModuleSpaceHost(TreeLogger mainLogger,
- String moduleName, String userAgent, String url, String tabKey,
- String sessionKey, BrowserChannelServer serverChannel,
- byte[] userAgentIcon) throws UnableToCompleteException {
+ public ModuleHandle createModuleLogger(String moduleName, String userAgent,
+ String url, String tabKey, String sessionKey,
+ BrowserChannelServer serverChannel, byte[] userAgentIcon) {
if (sessionKey == null) {
// if we don't have a unique session key, make one up
sessionKey = randomString();
}
- TreeLogger logger = mainLogger;
TreeLogger.Type maxLevel = options.getLogLevel();
String agentTag = BrowserInfo.getShortName(userAgent);
String remoteSocket = serverChannel.getRemoteEndpoint();
- ModuleHandle module = ui.loadModule(userAgent, remoteSocket, url, tabKey,
- moduleName, sessionKey, agentTag, userAgentIcon, maxLevel);
+ ModuleHandle module = ui.getModuleLogger(userAgent, remoteSocket, url,
+ tabKey, moduleName, sessionKey, agentTag, userAgentIcon, maxLevel);
+ return module;
+ }
+
+ public ModuleSpaceHost createModuleSpaceHost(ModuleHandle module,
+ String moduleName) throws UnableToCompleteException {
// TODO(jat): add support for closing an active module
- logger = module.getLogger();
+ TreeLogger logger = module.getLogger();
try {
// Try to find an existing loaded version of the module def.
ModuleDef moduleDef = loadModule(logger, moduleName, true);
@@ -102,26 +102,13 @@
ShellModuleSpaceHost host = doCreateShellModuleSpaceHost(logger,
moduleDef.getCompilationState(logger), moduleDef);
-
- loadedModules.put(host, module);
return host;
} catch (RuntimeException e) {
logger.log(TreeLogger.ERROR, "Exception initializing module", e);
- ui.unloadModule(module);
+ module.unload();
throw e;
}
}
-
- public TreeLogger getLogger() {
- return getTopLogger();
- }
-
- public void unloadModule(ModuleSpaceHost moduleSpaceHost) {
- ModuleHandle module = loadedModules.remove(moduleSpaceHost);
- if (module != null) {
- ui.unloadModule(module);
- }
- }
}
/**
@@ -589,7 +576,8 @@
private static final AtomicLong uniqueId = new AtomicLong();
- public static String normalizeURL(String unknownUrlText, int port, String host) {
+ public static String normalizeURL(String unknownUrlText, int port,
+ String host) {
if (unknownUrlText.indexOf(":") != -1) {
// Assume it's a full url.
return unknownUrlText;
@@ -676,8 +664,6 @@
private boolean headlessMode = false;
- private final Map<ModuleSpaceHost, ModuleHandle> loadedModules = new IdentityHashMap<ModuleSpaceHost, ModuleHandle>();
-
private boolean started;
private TreeLogger topLogger;
@@ -709,16 +695,19 @@
public void launchStartupUrls(final TreeLogger logger) {
ensureCodeServerListener();
String startupURL = "";
- try {
- for (String prenormalized : options.getStartupURLs()) {
- startupURL = normalizeURL(prenormalized, getPort(), getHost());
- logger.log(TreeLogger.TRACE, "Starting URL: " + startupURL, null);
- launchURL(startupURL);
+ Map<String, URL> startupUrls = new HashMap<String, URL>();
+ for (String prenormalized : options.getStartupURLs()) {
+ startupURL = normalizeURL(prenormalized, getPort(), getHost());
+ logger.log(TreeLogger.TRACE, "Starting URL: " + startupURL, null);
+ try {
+ URL url = processUrl(startupURL);
+ startupUrls.put(prenormalized, url);
+ } catch (UnableToCompleteException e) {
+ logger.log(TreeLogger.ERROR,
+ "Unable to process startup URL " + startupURL, null);
}
- } catch (UnableToCompleteException e) {
- logger.log(TreeLogger.ERROR,
- "Unable to open new window for startup URL: " + startupURL, null);
}
+ ui.setStartupUrls(startupUrls);
}
/**
@@ -737,7 +726,7 @@
// Eager AWT init for OS X to ensure safe coexistence with SWT.
BootStrapPlatform.initGui();
- if (startUp() && !options.useRemoteUI()) {
+ if (startUp()) {
// The web server is running now, so launch browsers for startup urls.
launchStartupUrls(getTopLogger());
}
@@ -838,7 +827,7 @@
if (listener == null) {
codeServerPort = options.getCodeServerPort();
listener = new BrowserListener(getTopLogger(), codeServerPort,
- new OophmSessionHandler(browserHost));
+ new OophmSessionHandler(getTopLogger(), browserHost));
listener.start();
try {
// save the port we actually used if it was auto
@@ -862,55 +851,6 @@
return headlessMode;
}
- protected void launchURL(String url) throws UnableToCompleteException {
- /*
- * TODO(jat): properly support launching arbitrary browsers -- need some UI
- * API tweaks to support that.
- */
- URL parsedUrl = null;
- try {
- parsedUrl = new URL(url);
- String path = parsedUrl.getPath();
- String query = parsedUrl.getQuery();
- String hash = parsedUrl.getRef();
- String hostedParam = BrowserListener.getDevModeURLParams(listener.getEndpointIdentifier());
- if (query == null) {
- query = hostedParam;
- } else {
- query += '&' + hostedParam;
- }
- path += '?' + query;
- if (hash != null) {
- path += '#' + hash;
- }
- parsedUrl = new URL(parsedUrl.getProtocol(), parsedUrl.getHost(),
- parsedUrl.getPort(), path);
- url = parsedUrl.toExternalForm();
- } catch (MalformedURLException e) {
- getTopLogger().log(TreeLogger.ERROR, "Invalid URL " + url, e);
- throw new UnableToCompleteException();
- }
-
- final URL helpInfoUrl = parsedUrl;
- getTopLogger().log(TreeLogger.INFO,
- "Waiting for browser connection to " + url, null, new HelpInfo() {
- @Override
- public String getAnchorText() {
- return "Launch default browser";
- }
-
- @Override
- public String getPrefix() {
- return "";
- }
-
- @Override
- public URL getURL() {
- return helpInfoUrl;
- }
- });
- }
-
/**
* Perform an initial hosted mode link, without overwriting newer or
* unmodified files in the output folder.
@@ -951,6 +891,37 @@
return moduleDef;
}
+ protected URL processUrl(String url) throws UnableToCompleteException {
+ /*
+ * TODO(jat): properly support launching arbitrary browsers -- need some UI
+ * API tweaks to support that.
+ */
+ URL parsedUrl = null;
+ try {
+ parsedUrl = new URL(url);
+ String path = parsedUrl.getPath();
+ String query = parsedUrl.getQuery();
+ String hash = parsedUrl.getRef();
+ String hostedParam = BrowserListener.getDevModeURLParams(listener.getEndpointIdentifier());
+ if (query == null) {
+ query = hostedParam;
+ } else {
+ query += '&' + hostedParam;
+ }
+ path += '?' + query;
+ if (hash != null) {
+ path += '#' + hash;
+ }
+ parsedUrl = new URL(parsedUrl.getProtocol(), parsedUrl.getHost(),
+ parsedUrl.getPort(), path);
+ url = parsedUrl.toExternalForm();
+ } catch (MalformedURLException e) {
+ getTopLogger().log(TreeLogger.ERROR, "Invalid URL " + url, e);
+ throw new UnableToCompleteException();
+ }
+ return parsedUrl;
+ }
+
protected abstract void produceOutput(TreeLogger logger,
StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef module)
throws UnableToCompleteException;
@@ -990,8 +961,8 @@
return false;
}
options.setPort(resultPort);
- getTopLogger().log(TreeLogger.TRACE,
- "Started web server on port " + resultPort);
+ getTopLogger().log(TreeLogger.TRACE, "Started web server on port "
+ + resultPort);
}
return true;
diff --git a/dev/core/src/com/google/gwt/dev/HeadlessUI.java b/dev/core/src/com/google/gwt/dev/HeadlessUI.java
index 6a6ce61..c70e10f 100644
--- a/dev/core/src/com/google/gwt/dev/HeadlessUI.java
+++ b/dev/core/src/com/google/gwt/dev/HeadlessUI.java
@@ -34,17 +34,16 @@
}
@Override
- public ModuleHandle loadModule(String userAgent, String remoteSocket,
+ public ModuleHandle getModuleLogger(String userAgent, String remoteSocket,
String url, String tabKey, String moduleName, String sessionKey,
String agentTag, byte[] agentIcon, Type logLevel) {
return new ModuleHandle() {
public TreeLogger getLogger() {
return getConsoleLogger();
}
- };
- }
- @Override
- public void unloadModule(ModuleHandle module) {
+ public void unload() {
+ }
+ };
}
}
diff --git a/dev/core/src/com/google/gwt/dev/ModuleHandle.java b/dev/core/src/com/google/gwt/dev/ModuleHandle.java
new file mode 100644
index 0000000..4da2f92
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/ModuleHandle.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009 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.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+
+/**
+ * Opaque handle to a module instance - external code can only get a logger or
+ * notify the module handle it is no longer needed.
+ */
+public interface ModuleHandle {
+
+ /**
+ * @return the logger for this module.
+ */
+ TreeLogger getLogger();
+
+ /**
+ * Mark the module instance associated with this handle as unloaded.
+ */
+ void unload();
+}
diff --git a/dev/core/src/com/google/gwt/dev/SwingUI.java b/dev/core/src/com/google/gwt/dev/SwingUI.java
index 1a1fbfd..eb2cd1b 100644
--- a/dev/core/src/com/google/gwt/dev/SwingUI.java
+++ b/dev/core/src/com/google/gwt/dev/SwingUI.java
@@ -16,6 +16,7 @@
package com.google.gwt.dev;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.TreeLogger.HelpInfo;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.dev.DevModeBase.HostedModeBaseOptions;
import com.google.gwt.dev.WebServerPanel.RestartAction;
@@ -35,6 +36,7 @@
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -78,6 +80,12 @@
public ModulePanel getTab() {
return tab;
}
+
+ public void unload() {
+ if (tab != null) {
+ tab.disconnect();
+ }
+ }
}
/**
@@ -164,6 +172,36 @@
}
@Override
+ public ModuleHandle getModuleLogger(String userAgent, String remoteSocket,
+ String url, String tabKey, String moduleName, String sessionKey,
+ String agentTag, byte[] agentIcon, TreeLogger.Type logLevel) {
+ // TODO(jat): add support for closing an active module
+ ModuleTabPanel tabPanel = null;
+ ModulePanel tab = null;
+ tabPanel = findModuleTab(userAgent, remoteSocket, url, tabKey,
+ moduleName, agentIcon);
+ tab = tabPanel.addModuleSession(logLevel, moduleName, sessionKey,
+ options.getLogFile(String.format("%s-%s-%d.log", moduleName, agentTag,
+ getNextSessionCounter(options.getLogDir()))));
+ TreeLogger logger = tab.getLogger();
+ TreeLogger branch = logger.branch(TreeLogger.INFO, "Loading module "
+ + moduleName);
+ if (url != null) {
+ branch.log(TreeLogger.INFO, "Top URL: " + url);
+ }
+ branch.log(TreeLogger.INFO, "User agent: " + userAgent);
+ branch.log(TreeLogger.TRACE, "Remote socket: " + remoteSocket);
+ if (tabKey != null) {
+ branch.log(TreeLogger.DEBUG, "Tab key: " + tabKey);
+ }
+ if (sessionKey != null) {
+ branch.log(TreeLogger.DEBUG, "Session key: " + sessionKey);
+ }
+ // TODO: Switch to a wait cursor?
+ return new SwingModuleHandle(logger, tab);
+ }
+
+ @Override
public TreeLogger getTopLogger() {
return topLogger;
}
@@ -229,41 +267,30 @@
}
@Override
- public ModuleHandle loadModule(String userAgent, String remoteSocket,
- String url, String tabKey, String moduleName, String sessionKey,
- String agentTag, byte[] agentIcon, TreeLogger.Type logLevel) {
- // TODO(jat): add support for closing an active module
- ModuleTabPanel tabPanel = null;
- ModulePanel tab = null;
- tabPanel = findModuleTab(userAgent, remoteSocket, url, tabKey,
- moduleName, agentIcon);
- tab = tabPanel.addModuleSession(logLevel, moduleName, sessionKey,
- options.getLogFile(String.format("%s-%s-%d.log", moduleName, agentTag,
- getNextSessionCounter(options.getLogDir()))));
- TreeLogger logger = tab.getLogger();
- TreeLogger branch = logger.branch(TreeLogger.INFO, "Loading module "
- + moduleName);
- if (url != null) {
- branch.log(TreeLogger.INFO, "Top URL: " + url);
- }
- branch.log(TreeLogger.INFO, "User agent: " + userAgent);
- branch.log(TreeLogger.TRACE, "Remote socket: " + remoteSocket);
- if (tabKey != null) {
- branch.log(TreeLogger.DEBUG, "Tab key: " + tabKey);
- }
- if (sessionKey != null) {
- branch.log(TreeLogger.DEBUG, "Session key: " + sessionKey);
- }
- // TODO: Switch to a wait cursor?
- return new SwingModuleHandle(logger, tab);
- }
+ public void setStartupUrls(Map<String, URL> urls) {
+ // TODO(jat): provide UI for selecting URLs and launching
+ ArrayList<String> keys = new ArrayList<String>(urls.keySet());
+ Collections.sort(keys);
+ for (String url : keys) {
+ final URL helpInfoUrl = urls.get(url);
+ getTopLogger().log(TreeLogger.INFO, "Waiting for browser connection to "
+ + helpInfoUrl.toExternalForm(), null,
+ new HelpInfo() {
+ @Override
+ public String getAnchorText() {
+ return "Launch default browser";
+ }
- @Override
- public void unloadModule(ModuleHandle module) {
- SwingModuleHandle handle = (SwingModuleHandle) module;
- Disconnectable tab = handle.getTab();
- if (tab != null) {
- tab.disconnect();
+ @Override
+ public String getPrefix() {
+ return "";
+ }
+
+ @Override
+ public URL getURL() {
+ return helpInfoUrl;
+ }
+ });
}
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserChannel.java b/dev/core/src/com/google/gwt/dev/shell/BrowserChannel.java
index 96dd267..5e536fd 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserChannel.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserChannel.java
@@ -254,8 +254,7 @@
/**
* Load a new instance of a module.
- *
- * @param logger
+ *
* @param channel
* @param moduleName
* @param userAgent
@@ -267,9 +266,9 @@
* 24x24) representing the user agent or null if unavailable
* @return a TreeLogger to use for the module's logs
*/
- public abstract TreeLogger loadModule(TreeLogger logger,
- BrowserChannel channel, String moduleName, String userAgent, String url,
- String tabKey, String sessionKey, byte[] userAgentIcon);
+ public abstract TreeLogger loadModule(BrowserChannel channel,
+ String moduleName, String userAgent, String url, String tabKey,
+ String sessionKey, byte[] userAgentIcon);
public abstract ExceptionOrReturnValue setProperty(BrowserChannel channel,
int refId, int dispId, Value newValue);
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
index 52801b5..b9c062a 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
@@ -373,7 +373,7 @@
Thread.currentThread().setName(
"Code server for " + moduleName + " from " + userAgent + " on " + url
+ " @ " + sessionKey);
- logger = handler.loadModule(logger, this, moduleName, userAgent, url,
+ logger = handler.loadModule(this, moduleName, userAgent, url,
tabKey, sessionKey, iconBytes);
try {
// send LoadModule response
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHost.java b/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHost.java
index 1002d4e..0e7bd0e 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHost.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserWidgetHost.java
@@ -15,8 +15,8 @@
*/
package com.google.gwt.dev.shell;
-import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.ModuleHandle;
/**
* Interface that unifies access to the <code>BrowserWidget</code>,
@@ -25,9 +25,8 @@
public interface BrowserWidgetHost {
/**
- * For OOPHM.
+ * Create a logger for a module instance.
*
- * @param logger
* @param moduleName
* @param userAgent
* @param url URL of top-level window, may be null for old browser plugins
@@ -37,16 +36,22 @@
* @param serverChannel connection from the client
* @param userAgentIcon byte array containing an icon (which fits in 24x24)
* for this user agent or null if unavailable
+ * @return ModuleHandle instance -- caller is responsible for calling
+ * {@link ModuleHandle#unload()} on it when done
*/
- ModuleSpaceHost createModuleSpaceHost(TreeLogger logger, String moduleName,
- String userAgent, String url, String tabKey, String sessionKey,
- BrowserChannelServer serverChannel, byte[] userAgentIcon)
- throws UnableToCompleteException;
-
- TreeLogger getLogger();
+ ModuleHandle createModuleLogger(String moduleName, String userAgent,
+ String url, String tabKey, String sessionKey,
+ BrowserChannelServer serverChannel, byte[] userAgentIcon);
/**
- * For OOPHM.
+ * Create a ModuleSpaceHost for the specified module.
+ *
+ * @param module ModuleHandle returned from a previous createModuleLogger
+ * call.
+ * @param moduleName name of module to create
+ * @return ModuleSpaceHost instance
+ * @throws UnableToCompleteException
*/
- void unloadModule(ModuleSpaceHost moduleSpaceHost);
+ ModuleSpaceHost createModuleSpaceHost(ModuleHandle module, String moduleName)
+ throws UnableToCompleteException;
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java b/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
index 9c87d9f..a2a415c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
+++ b/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
@@ -250,9 +250,9 @@
}
@Override
- public TreeLogger loadModule(TreeLogger logger, BrowserChannel channel,
- String moduleName, String userAgent, String url, String tabKey,
- String sessionKey, byte[] userAgentIcon) {
+ public TreeLogger loadModule(BrowserChannel channel, String moduleName,
+ String userAgent, String url, String tabKey, String sessionKey,
+ byte[] userAgentIcon) {
throw new UnsupportedOperationException("loadModule must not be called");
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java b/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
index f65ec0f..91482e9 100644
--- a/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
+++ b/dev/core/src/com/google/gwt/dev/shell/OophmSessionHandler.java
@@ -16,6 +16,7 @@
package com.google.gwt.dev.shell;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.ModuleHandle;
import com.google.gwt.dev.shell.BrowserChannel.SessionHandler;
import com.google.gwt.dev.shell.BrowserChannel.Value;
import com.google.gwt.dev.shell.JsValue.DispatchMethod;
@@ -34,16 +35,20 @@
private BrowserWidgetHost host;
- private TreeLogger logger;
-
private Map<BrowserChannelServer, ModuleSpace> moduleMap = Collections.synchronizedMap(new HashMap<BrowserChannelServer, ModuleSpace>());
+ private Map<BrowserChannelServer, ModuleHandle> moduleHandleMap = Collections.synchronizedMap(new HashMap<BrowserChannelServer, ModuleHandle>());
+
+ private final TreeLogger topLogger;
+
/**
* Listens for new connections from browsers.
+ * @param topLogger logger to use for non-module-related messages
+ * @param host BrowserWidgetHost instance
*/
- public OophmSessionHandler(BrowserWidgetHost host) {
+ public OophmSessionHandler(TreeLogger topLogger, BrowserWidgetHost host) {
this.host = host;
- logger = host.getLogger();
+ this.topLogger = topLogger;
}
@Override
@@ -60,7 +65,9 @@
int dispId) {
BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
ModuleSpace moduleSpace = moduleMap.get(serverChannel);
- assert moduleSpace != null;
+ ModuleHandle moduleHandle = moduleHandleMap.get(serverChannel);
+ assert moduleSpace != null && moduleHandle != null;
+ TreeLogger logger = moduleHandle.getLogger();
ServerObjectsTable localObjects = serverChannel.getJavaObjectsExposedInBrowser();
try {
JsValueOOPHM obj = new JsValueOOPHM();
@@ -94,7 +101,9 @@
BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
ServerObjectsTable localObjects = serverChannel.getJavaObjectsExposedInBrowser();
ModuleSpace moduleSpace = moduleMap.get(serverChannel);
- assert moduleSpace != null;
+ ModuleHandle moduleHandle = moduleHandleMap.get(serverChannel);
+ assert moduleSpace != null && moduleHandle != null;
+ TreeLogger logger = moduleHandle.getLogger();
CompilingClassLoader cl = moduleSpace.getIsolatedClassLoader();
// Treat dispatch id 0 as toString()
@@ -155,21 +164,21 @@
}
@Override
- public synchronized TreeLogger loadModule(TreeLogger loadModuleLogger,
- BrowserChannel channel, String moduleName, String userAgent, String url,
- String tabKey, String sessionKey, byte[] userAgentIcon) {
- logger = loadModuleLogger;
+ public synchronized TreeLogger loadModule(BrowserChannel channel,
+ String moduleName, String userAgent, String url, String tabKey,
+ String sessionKey, byte[] userAgentIcon) {
+ PerfLogger.start("OophmSessionHandler.loadModule " + moduleName);
+ BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
+ ModuleHandle moduleHandle = host.createModuleLogger(moduleName, userAgent,
+ url, tabKey, sessionKey, serverChannel, userAgentIcon);
+ TreeLogger logger = moduleHandle.getLogger();
+ moduleHandleMap.put(serverChannel, moduleHandle);
+ ModuleSpace moduleSpace = null;
try {
- PerfLogger.start("OophmSessionHandler.loadModule " + moduleName);
// Attach a new ModuleSpace to make it programmable.
- //
- BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
- ModuleSpaceHost msh = host.createModuleSpaceHost(loadModuleLogger,
- moduleName, userAgent, url, tabKey, sessionKey, serverChannel,
- userAgentIcon);
- logger = msh.getLogger();
- ModuleSpace moduleSpace = new ModuleSpaceOOPHM(msh, moduleName,
- serverChannel);
+ ModuleSpaceHost msh = host.createModuleSpaceHost(moduleHandle,
+ moduleName);
+ moduleSpace = new ModuleSpaceOOPHM(msh, moduleName, serverChannel);
moduleMap.put(serverChannel, moduleSpace);
PerfLogger.start("ModuleSpace.onLoad");
moduleSpace.onLoad(logger);
@@ -178,14 +187,20 @@
// that can go wrong trying to load a module, including Error-derived
// things like NoClassDefFoundError.
//
- this.logger.log(TreeLogger.ERROR, "Failed to load module '" + moduleName
- + "' from user agent '" + userAgent + "' at "
+ moduleHandle.getLogger().log(TreeLogger.ERROR, "Failed to load module '"
+ + moduleName + "' from user agent '" + userAgent + "' at "
+ channel.getRemoteEndpoint(), e);
+ if (moduleSpace != null) {
+ moduleSpace.dispose();
+ }
+ moduleHandle.unload();
+ moduleMap.remove(serverChannel);
+ moduleHandleMap.remove(serverChannel);
} finally {
PerfLogger.end();
PerfLogger.end();
}
- return this.logger;
+ return moduleHandle.getLogger();
}
@Override
@@ -193,7 +208,9 @@
int dispId, Value newValue) {
BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
ModuleSpace moduleSpace = moduleMap.get(serverChannel);
- assert moduleSpace != null;
+ ModuleHandle moduleHandle = moduleHandleMap.get(serverChannel);
+ assert moduleSpace != null && moduleHandle != null;
+ TreeLogger logger = moduleHandle.getLogger();
ServerObjectsTable localObjects = serverChannel.getJavaObjectsExposedInBrowser();
try {
JsValueOOPHM obj = new JsValueOOPHM();
@@ -220,16 +237,18 @@
@Override
public void unloadModule(BrowserChannel channel, String moduleName) {
BrowserChannelServer serverChannel = (BrowserChannelServer) channel;
+ ModuleHandle moduleHandle = moduleHandleMap.get(serverChannel);
ModuleSpace moduleSpace = moduleMap.get(serverChannel);
- if (moduleSpace == null) {
- logger.log(TreeLogger.ERROR, "Unload request without a module loaded",
+ if (moduleSpace == null || moduleHandle == null) {
+ topLogger.log(TreeLogger.ERROR, "Unload request without a module loaded",
null);
return;
}
- logger.log(TreeLogger.INFO, "Unloading module "
+ moduleHandle.getLogger().log(TreeLogger.INFO, "Unloading module "
+ moduleSpace.getModuleName() + " (" + moduleName + ")", null);
- host.unloadModule(moduleSpace.host);
moduleSpace.dispose();
+ moduleHandle.unload();
moduleMap.remove(serverChannel);
+ moduleHandleMap.remove(serverChannel);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
index dcb7968..1d81ada 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
@@ -17,6 +17,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.dev.ModuleHandle;
import com.google.gwt.dev.shell.BrowserListener;
import com.google.gwt.dev.ui.DevModeUI;
import com.google.gwt.dev.ui.DoneCallback;
@@ -85,7 +86,7 @@
}
@Override
- public ModuleHandle loadModule(String userAgent, String remoteSocket,
+ public ModuleHandle getModuleLogger(String userAgent, String remoteSocket,
String url, String tabKey, String moduleName, String sessionKey,
String agentTag, byte[] agentIcon, Type logLevel) {
@@ -100,6 +101,24 @@
public TreeLogger getLogger() {
return moduleLogger;
}
+
+ public void unload() {
+ synchronized (modulesLock) {
+ if (!modules.contains(this)) {
+ return;
+ }
+ }
+
+ ViewerServiceTreeLogger moduleLogger = (ViewerServiceTreeLogger) (getLogger());
+
+ try {
+ viewerServiceClient.disconnectLog(moduleLogger.getLogHandle());
+ } finally {
+ synchronized (modulesLock) {
+ modules.remove(this);
+ }
+ }
+ }
};
synchronized (modulesLock) {
modules.add(handle);
@@ -154,23 +173,4 @@
public boolean supportsRestartWebServer() {
return hasCallback(RestartServerEvent.getType());
}
-
- @Override
- public void unloadModule(ModuleHandle module) {
- synchronized (modulesLock) {
- if (!modules.contains(module)) {
- return;
- }
- }
-
- ViewerServiceTreeLogger moduleLogger = (ViewerServiceTreeLogger) (module.getLogger());
-
- try {
- viewerServiceClient.disconnectLog(moduleLogger.getLogHandle());
- } finally {
- synchronized (modulesLock) {
- modules.remove(module);
- }
- }
- }
}
diff --git a/dev/core/src/com/google/gwt/dev/ui/CloseModuleCallback.java b/dev/core/src/com/google/gwt/dev/ui/CloseModuleCallback.java
index 5ef7b74..52bdd7e 100644
--- a/dev/core/src/com/google/gwt/dev/ui/CloseModuleCallback.java
+++ b/dev/core/src/com/google/gwt/dev/ui/CloseModuleCallback.java
@@ -15,7 +15,7 @@
*/
package com.google.gwt.dev.ui;
-import com.google.gwt.dev.ui.DevModeUI.ModuleHandle;
+import com.google.gwt.dev.ModuleHandle;
/**
* Callback for a request to close an active module from the UI.
@@ -28,7 +28,7 @@
* the UI), there will be separate calls for each one.
*
* @param moduleHandle module handle returned from
- * {@link DevModeUI#loadModule}.
+ * {@link DevModeUI#getModuleLogger}.
*/
void onCloseModule(ModuleHandle moduleHandle);
-}
\ No newline at end of file
+}
diff --git a/dev/core/src/com/google/gwt/dev/ui/DevModeUI.java b/dev/core/src/com/google/gwt/dev/ui/DevModeUI.java
index f77f545..572baf6 100644
--- a/dev/core/src/com/google/gwt/dev/ui/DevModeUI.java
+++ b/dev/core/src/com/google/gwt/dev/ui/DevModeUI.java
@@ -17,8 +17,10 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.dev.ModuleHandle;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
@@ -29,19 +31,6 @@
public abstract class DevModeUI {
/**
- * Opaque handle to a module - it is returned from loadModule and the client
- * can only pass it to unloadModule or get a logger for messages about that
- * module.
- */
- public interface ModuleHandle {
-
- /**
- * @return the logger for this module.
- */
- TreeLogger getLogger();
- }
-
- /**
* Map of callbacks.
*/
private final Map<UiEvent.Type<? extends UiCallback>, UiCallback> callbacks
@@ -58,45 +47,6 @@
private Type logLevel;
/**
- * Create a top-level logger for messages which are not associated with the
- * web server or any module. Defaults to logging to stdout.
- *
- * @return TreeLogger instance to use
- */
- public TreeLogger getTopLogger() {
- return getConsoleLogger();
- }
-
- /**
- * Create the web server portion of the UI if not already created, and
- * return its TreeLogger instance.
- *
- * <p>Note that the {@link RestartServerEvent} should already have a callback
- * registered when this is called -- the UI is not required to change the
- * UI if it is registered later.
- *
- * @param serverName short name of the web server or null if only the icon
- * should be used
- * @param serverIcon byte array containing an icon (fitting into 24x24) to
- * use for the server, or null if only the name should be used
- * @return TreeLogger instance
- */
- public abstract TreeLogger getWebServerLogger(String serverName,
- byte[] serverIcon);
-
- /**
- * Initialize the UI - must be called exactly once and before any other method
- * on this class.
- *
- * <p>Subclasses should call super.initialize(logLevel).
- *
- * @param logLevel log level for all logging
- */
- public void initialize(Type logLevel) {
- this.logLevel = logLevel;
- }
-
- /**
* Show that a module is loaded in the UI.
*
* <p>Note that the {@link CloseModuleEvent} should already have a callback
@@ -117,9 +67,48 @@
* @param logLevel logging detail requested
* @return a handle to the module
*/
- public abstract ModuleHandle loadModule(String userAgent,
+ public abstract ModuleHandle getModuleLogger(String userAgent,
String remoteSocket, String url, String tabKey, String moduleName,
String sessionKey, String agentTag, byte[] agentIcon, Type logLevel);
+
+ /**
+ * Create a top-level logger for messages which are not associated with the
+ * web server or any module. Defaults to logging to stdout.
+ *
+ * @return TreeLogger instance to use
+ */
+ public TreeLogger getTopLogger() {
+ return getConsoleLogger();
+ }
+
+ /**
+ * Create the web server portion of the UI if not already created, and
+ * return its TreeLogger instance.
+ *
+ * <p>Note that the {@link RestartServerEvent} should already have a callback
+ * registered when this is called -- the UI is not required to change the
+ * UI if it is registered later.
+ *
+ * @param serverName short name of the web server or null if only the icon
+ * should be used
+ * @param serverIcon byte array containing an icon (fitting into 24x24) to
+ * use for the server, or null if only the name should be used
+ * @return TreeLogger instance
+ */
+ public abstract TreeLogger getWebServerLogger(String serverName,
+ byte[] serverIcon);
+
+ /**
+ * Initialize the UI - must be called exactly once and before any other method
+ * on this class.
+ *
+ * <p>Subclasses should call super.initialize(logLevel).
+ *
+ * @param logLevel log level for all logging
+ */
+ public void initialize(Type logLevel) {
+ this.logLevel = logLevel;
+ }
/**
* Sets the callback for a given event type..
@@ -135,13 +124,15 @@
}
/**
- * Show that a previously loaded module has been unloaded.
+ * Set the URLs that should be available to start.
*
- * @param module ModuleHandle instance returned from loadModule on this UI
- * instance
+ * @param urls map of URLs -- the key is the name supplied with -startupUrls,
+ * and the value is the mapped URL with all parameters included
*/
- public abstract void unloadModule(ModuleHandle module);
-
+ public void setStartupUrls(Map<String, URL> urls) {
+ // do nothing by default
+ }
+
/**
* Call callback for a given event.
*
diff --git a/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java b/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
index 6c47e9f..d981c37 100644
--- a/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
@@ -156,9 +156,9 @@
}
@Override
- public TreeLogger loadModule(TreeLogger logger, BrowserChannel channel,
- String moduleName, String userAgent, String url, String tabKey,
- String sessionKey, byte[] userAgentIcon) {
+ public TreeLogger loadModule(BrowserChannel channel, String moduleName,
+ String userAgent, String url, String tabKey, String sessionKey,
+ byte[] userAgentIcon) {
loadedModule = moduleName;
this.moduleName = moduleName;
this.userAgent = userAgent;
@@ -166,7 +166,7 @@
this.tabKey = tabKey;
this.sessionKey = sessionKey;
this.userAgentIcon = userAgentIcon;
- return logger;
+ return new FailErrorLogger();
}
@Override