I was a bit overzealous when trimming out irrelevant changes to the diff and
left out dev/core/src-dummy -- here is a revised patch.

-- 
John A. Tamplin
Software Engineer (GWT), Google

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Index: dev/linux/src/com/google/gwt/dev/BootStrapPlatform.java
===================================================================
--- dev/linux/src/com/google/gwt/dev/BootStrapPlatform.java	(revision 4407)
+++ dev/linux/src/com/google/gwt/dev/BootStrapPlatform.java	(working copy)
@@ -32,7 +32,7 @@
    * it. If successful, store the loaded path in the property swt.mozilla.path
    * so SWT's Browser object can use it.
    */
-  public static void init() {
+  public static void initHostedMode() {
     String home = System.getenv("HOME");
     if (home == null || home.length() == 0) {
       System.err.println("The HOME environment variable must be defined.");
@@ -56,7 +56,7 @@
     System.setProperty("swt.mozilla.path", mozillaPath);
   }
 
-  public static void maybeInitializeAWT() {
+  public static void initGui() {
     // nothing to do
   }
 }
Index: dev/mac/src/com/google/gwt/dev/BootStrapPlatform.java
===================================================================
--- dev/mac/src/com/google/gwt/dev/BootStrapPlatform.java	(revision 4407)
+++ dev/mac/src/com/google/gwt/dev/BootStrapPlatform.java	(working copy)
@@ -30,40 +30,16 @@
     fixContextClassLoaderOnMainThread();
   }
 
-  public static void init() {
-    /*
-     * The following check must be made before attempting to initialize Safari,
-     * or we'll fail with an less-than-helpful UnsatisfiedLinkError.
-     */
-    if (!isJava5()) {
-      System.err.println("You must use a Java 1.5 runtime to use GWT Hosted Mode on Mac OS X.");
-      System.exit(-1);
-    }
-
-    LowLevelSaf.init();
-    // Ensure we were started with -XstartOnFirstThread
-    if (!hasStartOnFirstThreadFlag(LowLevelSaf.getProcessArgs())) {
-      System.err.println("Invalid launch configuration: -XstartOnFirstThread not specified.");
-      System.err.println();
-      System.err.println("On Mac OS X, GWT requires that the Java virtual machine be invoked with the");
-      System.err.println("-XstartOnFirstThread VM argument.");
-      System.err.println();
-      System.err.println("Example:");
-      System.err.println("  java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell");
-      System.exit(-1);
-    }
-  }
-
   /**
    * 
    * This works around a complicated set of OS X SWT/AWT compatibilities.
    * {...@link #setSystemProperties()} will typically need to be called first to
-   * ensure that CocoaComponent compatability mode is disabled. The constraints
+   * ensure that CocoaComponent compatibility mode is disabled. The constraints
    * of using SWT and AWT together are:
    * 
    * <p>
    * 1 - The SWT event dispatch needs to be running on the main application
-   * thread (only possible with -XstartOnFirstThread vm arg).
+   * thread (only possible with -XstartOnFirstThread VM arg).
    * </p>
    * <p>
    * 2 - The first call into AWT must be from the main thread after a SWT
@@ -75,19 +51,43 @@
    * 
    * <p>
    * NOTE: In GUI applications, {...@link #setSystemProperties()} and
-   * {...@link #maybeInitializeAWT()} will both be called during the bootstrap
-   * process. Command line applications (like
+   * {...@link #initGui()} will both be called during the bootstrap process.
+   * Command line applications (like
    * 
    * @{link com.google.gwt.dev.GWTCompiler}) avoid eagerly initializing AWT and
    *        only call {...@link #setSystemProperties()} allowing AWT to be
    *        initialized on demand.
    *        </p>
    */
-  public static void maybeInitializeAWT() {
+  public static void initGui() {
     GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
     Toolkit.getDefaultToolkit();
   }
 
+  public static void initHostedMode() {
+    /*
+     * The following check must be made before attempting to initialize Safari,
+     * or we'll fail with an less-than-helpful UnsatisfiedLinkError.
+     */
+    if (!isJava5()) {
+      System.err.println("You must use a Java 1.5 runtime to use GWT Hosted Mode on Mac OS X.");
+      System.exit(-1);
+    }
+
+    LowLevelSaf.init();
+    // Ensure we were started with -XstartOnFirstThread
+    if (!hasStartOnFirstThreadFlag(LowLevelSaf.getProcessArgs())) {
+      System.err.println("Invalid launch configuration: -XstartOnFirstThread not specified.");
+      System.err.println();
+      System.err.println("On Mac OS X, GWT requires that the Java virtual machine be invoked with the");
+      System.err.println("-XstartOnFirstThread VM argument.");
+      System.err.println();
+      System.err.println("Example:");
+      System.err.println("  java -XstartOnFirstThread -cp gwt-dev-mac.jar com.google.gwt.dev.GWTShell");
+      System.exit(-1);
+    }
+  }
+
   /**
    * This works around apple radr:5569300. When -XstartOnFirstThread is passed
    * as a jvm argument, the main thread returns null for
@@ -124,8 +124,8 @@
    * 
    * <p>
    * NOTE: In GUI applications, {...@link #setSystemProperties()} and
-   * {...@link #maybeInitializeAWT()} will both be called during the bootstrap
-   * process. Command line applications (like
+   * {...@link #initGui()} will both be called during the bootstrap process.
+   * Command line applications (like
    * 
    * @{link com.google.gwt.dev.GWTCompiler}) avoid eagerly initializing AWT and
    *        only call {...@link #setSystemProperties()} allowing AWT to be
Index: dev/core/src-dummy/com/google/gwt/dev/BootStrapPlatform.java
===================================================================
--- dev/core/src-dummy/com/google/gwt/dev/BootStrapPlatform.java	(revision 4407)
+++ dev/core/src-dummy/com/google/gwt/dev/BootStrapPlatform.java	(working copy)
@@ -26,11 +26,11 @@
     // nothing to do
   }
 
-  public static void init() {
-    // nothing to do.
+  public static void initGui() {
+    // nothing to do
   }
 
-  public static void maybeInitializeAWT() {
-    // nothing to do
+  public static void initHostedMode() {
+    // nothing to do.
   }
 }
Index: dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
===================================================================
--- dev/core/src/com/google/gwt/dev/CompileTaskRunner.java	(revision 4407)
+++ dev/core/src/com/google/gwt/dev/CompileTaskRunner.java	(working copy)
@@ -49,7 +49,7 @@
           "Build Output for " + options.getModuleNames(), 800, 600, true);
 
       // Eager AWT initialization for OS X to ensure safe coexistence with SWT.
-      BootStrapPlatform.maybeInitializeAWT();
+      BootStrapPlatform.initGui();
 
       final AbstractTreeLogger logger = loggerWindow.getLogger();
       logger.setMaxDetail(options.getLogLevel());
Index: dev/core/src/com/google/gwt/dev/HostedModeBase.java
===================================================================
--- dev/core/src/com/google/gwt/dev/HostedModeBase.java	(revision 4407)
+++ dev/core/src/com/google/gwt/dev/HostedModeBase.java	(working copy)
@@ -28,8 +28,6 @@
 import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
 import com.google.gwt.dev.shell.BrowserWindowController;
 import com.google.gwt.dev.shell.ModuleSpaceHost;
-import com.google.gwt.dev.shell.PlatformSpecific;
-import com.google.gwt.dev.shell.ShellMainWindow;
 import com.google.gwt.dev.shell.ShellModuleSpaceHost;
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
@@ -39,20 +37,11 @@
 import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
 import com.google.gwt.dev.util.arg.OptionGenDir;
 import com.google.gwt.dev.util.arg.OptionLogLevel;
-import com.google.gwt.dev.util.log.AbstractTreeLogger;
 import com.google.gwt.util.tools.ArgHandlerFlag;
 import com.google.gwt.util.tools.ArgHandlerString;
 import com.google.gwt.util.tools.ToolBase;
 
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.internal.Library;
-import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -62,7 +51,11 @@
 import java.util.Set;
 
 /**
- * The main executable class for the hosted mode shell.
+ * The main executable class for the hosted mode shell.  This class
+ * must not have any GUI dependencies.
+ *
+ * TODO: remove BrowserWidget references (which reference SWT via inheritance,
+ * though it doesn't appear to cause any harm currently.
  */
 abstract class HostedModeBase implements BrowserWindowController {
 
@@ -283,7 +276,7 @@
     }
   }
 
-  private class BrowserWidgetHostImpl implements BrowserWidgetHost {
+  protected abstract class BrowserWidgetHostImpl implements BrowserWidgetHost {
 
     public void compile() throws UnableToCompleteException {
       if (isLegacyMode()) {
@@ -303,32 +296,9 @@
       }
     }
 
-    public ModuleSpaceHost createModuleSpaceHost(BrowserWidget widget,
-        final String moduleName) throws UnableToCompleteException {
-      TreeLogger logger = getLogger();
+    public abstract ModuleSpaceHost createModuleSpaceHost(BrowserWidget widget,
+        final String moduleName) throws UnableToCompleteException;
 
-      // Switch to a wait cursor.
-      //
-      Shell widgetShell = widget.getShell();
-      try {
-        Cursor waitCursor = display.getSystemCursor(SWT.CURSOR_WAIT);
-        widgetShell.setCursor(waitCursor);
-
-        // Try to find an existing loaded version of the module def.
-        //
-        ModuleDef moduleDef = loadModule(logger, moduleName, true);
-        assert (moduleDef != null);
-
-        TypeOracle typeOracle = moduleDef.getTypeOracle(logger);
-        ShellModuleSpaceHost host = doCreateShellModuleSpaceHost(logger,
-            typeOracle, moduleDef);
-        return host;
-      } finally {
-        Cursor normalCursor = display.getSystemCursor(SWT.CURSOR_ARROW);
-        widgetShell.setCursor(normalCursor);
-      }
-    }
-
     public TreeLogger getLogger() {
       return getTopLogger();
     }
@@ -370,25 +340,13 @@
    */
   private Set<String> alreadySeenModules = new HashSet<String>();
 
-  private BrowserWidgetHostImpl browserHost = new BrowserWidgetHostImpl();
-
-  private final List<Shell> browserShells = new ArrayList<Shell>();
-
-  /**
-   * Use the default display; constructing a new one would make instantiating
-   * multiple GWTShells fail with a mysterious exception.
-   */
-  private final Display display = Display.getDefault();
-
   private boolean headlessMode = false;
 
-  private ShellMainWindow mainWnd;
-
   private boolean started;
 
   public HostedModeBase() {
     // Set any platform specific system properties.
-    BootStrapPlatform.init();
+    BootStrapPlatform.initHostedMode();
     BootStrapPlatform.applyPlatformHacks();
     options = createOptions();
   }
@@ -397,46 +355,20 @@
     options.addStartupURL(url);
   }
 
-  public final void closeAllBrowserWindows() {
-    while (!browserShells.isEmpty()) {
-      browserShells.get(0).dispose();
-    }
-  }
+  public abstract void closeAllBrowserWindows();
 
   public final int getPort() {
     return options.getPort();
   }
 
-  public TreeLogger getTopLogger() {
-    return mainWnd.getLogger();
-  }
+  public abstract TreeLogger getTopLogger();
 
-  public final boolean hasBrowserWindowsOpen() {
-    if (browserShells.isEmpty()) {
-      return false;
-    } else {
-      return true;
-    }
-  }
+  public abstract boolean hasBrowserWindowsOpen();
 
   /**
    * Launch the arguments as Urls in separate windows.
    */
-  public final void launchStartupUrls(final TreeLogger logger) {
-    // Launch a browser window for each startup url.
-    String startupURL = "";
-    try {
-      for (String prenormalized : options.getStartupURLs()) {
-        startupURL = normalizeURL(prenormalized);
-        logger.log(TreeLogger.TRACE, "Starting URL: " + startupURL, null);
-        BrowserWidget bw = openNewBrowserWindow();
-        bw.go(startupURL);
-      }
-    } catch (UnableToCompleteException e) {
-      logger.log(TreeLogger.ERROR,
-          "Unable to open new window for startup URL: " + startupURL, null);
-    }
-  }
+  public abstract void launchStartupUrls(final TreeLogger logger);
 
   public final String normalizeURL(String unknownUrlText) {
     if (unknownUrlText.indexOf(":") != -1) {
@@ -462,39 +394,6 @@
   }
 
   /**
-   * Called directly by ShellMainWindow and indirectly via BrowserWidgetHost.
-   */
-  public final BrowserWidget openNewBrowserWindow()
-      throws UnableToCompleteException {
-    boolean succeeded = false;
-    Shell s = createTrackedBrowserShell();
-    try {
-      BrowserWidget bw = PlatformSpecific.createBrowserWidget(getTopLogger(),
-          s, browserHost);
-
-      if (mainWnd != null) {
-        Rectangle r = mainWnd.getShell().getBounds();
-        int n = browserShells.size() + 1;
-        s.setBounds(r.x + n * 50, r.y + n * 50, 800, 600);
-      } else {
-        s.setSize(800, 600);
-      }
-
-      if (!isHeadless()) {
-        s.open();
-      }
-
-      bw.onFirstShown();
-      succeeded = true;
-      return bw;
-    } finally {
-      if (!succeeded) {
-        s.dispose();
-      }
-    }
-  }
-
-  /**
    * Sets up all the major aspects of running the shell graphically, including
    * creating the main window and optionally starting the embedded Tomcat
    * server.
@@ -507,7 +406,7 @@
       }
 
       // Eager AWT initialization for OS X to ensure safe coexistence with SWT.
-      BootStrapPlatform.maybeInitializeAWT();
+      BootStrapPlatform.initGui();
 
       // Tomcat's running now, so launch browsers for startup urls now.
       launchStartupUrls(getTopLogger());
@@ -588,18 +487,11 @@
 
   protected abstract int doStartUpServer();
 
-  protected final BrowserWidgetHost getBrowserHost() {
-    return browserHost;
-  }
-
   protected String getHost() {
     return "localhost";
   }
 
-  protected void initializeLogger() {
-    final AbstractTreeLogger logger = mainWnd.getLogger();
-    logger.setMaxDetail(options.getLogLevel());
-  }
+  protected abstract void initializeLogger();
 
   /**
    * Called from a selection script as it begins to load in hosted mode. This
@@ -641,16 +533,12 @@
     return moduleDef;
   }
 
-  protected boolean notDone() {
-    if (!mainWnd.isDisposed()) {
-      return true;
-    }
-    if (!browserShells.isEmpty()) {
-      return true;
-    }
-    return false;
-  }
+  protected abstract boolean notDone();
 
+  protected abstract void openAppWindow();
+
+  protected abstract void processEvents() throws Exception;
+
   protected final void pumpEventLoop() {
     TreeLogger logger = getTopLogger();
 
@@ -658,9 +546,7 @@
     //
     while (notDone()) {
       try {
-        if (!display.readAndDispatch()) {
-          sleep();
-        }
+        processEvents();
       } catch (Throwable e) {
         String msg = e.getMessage();
         msg = (msg != null ? msg : e.getClass().getName());
@@ -680,10 +566,6 @@
     doShutDownServer();
   }
 
-  protected void sleep() {
-    display.sleep();
-  }
-
   protected final boolean startUp() {
     if (started) {
       throw new IllegalStateException("Startup code has already been run");
@@ -695,6 +577,8 @@
       return false;
     }
 
+    startupHook();
+
     if (!options.isNoServer()) {
       int resultPort = doStartUpServer();
       if (resultPort < 0) {
@@ -706,58 +590,12 @@
     return true;
   }
 
-  private Shell createTrackedBrowserShell() {
-    final Shell shell = new Shell(display);
-    FillLayout fillLayout = new FillLayout();
-    fillLayout.marginWidth = 0;
-    fillLayout.marginHeight = 0;
-    shell.setLayout(fillLayout);
-    browserShells.add(shell);
-    shell.addDisposeListener(new DisposeListener() {
-      public void widgetDisposed(DisposeEvent e) {
-        if (e.widget == shell) {
-          browserShells.remove(shell);
-        }
-      }
-    });
-
-    shell.setImages(ShellMainWindow.getIcons());
-
-    return shell;
+  /**
+   * Hook for subclasses to initialize things after the window and logger are
+   * initialized but before the embedded server is started.
+   */
+  protected void startupHook() {
   }
 
-  private void loadRequiredNativeLibs() {
-    String libName = null;
-    try {
-      libName = "swt";
-      Library.loadLibrary(libName);
-    } catch (UnsatisfiedLinkError e) {
-      StringBuffer sb = new StringBuffer();
-      sb.append("Unable to load required native library '" + libName + "'");
-      sb.append("\n\tPlease specify the JVM startup argument ");
-      sb.append("\"-Djava.library.path\"");
-      throw new RuntimeException(sb.toString(), e);
-    }
-  }
-
-  private void openAppWindow() {
-    final Shell shell = new Shell(display);
-
-    FillLayout fillLayout = new FillLayout();
-    fillLayout.marginWidth = 0;
-    fillLayout.marginHeight = 0;
-    shell.setLayout(fillLayout);
-
-    shell.setImages(ShellMainWindow.getIcons());
-
-    boolean checkForUpdates = doShouldCheckForUpdates();
-
-    mainWnd = new ShellMainWindow(this, shell, options.isNoServer() ? 0
-        : getPort(), checkForUpdates);
-
-    shell.setSize(700, 600);
-    if (!isHeadless()) {
-      shell.open();
-    }
-  }
+  protected abstract void loadRequiredNativeLibs();
 }
Index: dev/core/src/com/google/gwt/dev/GWTShell.java
===================================================================
--- dev/core/src/com/google/gwt/dev/GWTShell.java	(revision 4407)
+++ dev/core/src/com/google/gwt/dev/GWTShell.java	(working copy)
@@ -36,7 +36,7 @@
  * @deprecated use {...@link HostedMode} instead
  */
 @Deprecated
-public class GWTShell extends HostedModeBase {
+public class GWTShell extends SwtHostedModeBase {
 
   /**
    * Handles the list of startup urls that can be passed at the end of the
@@ -182,6 +182,7 @@
     return new ShellOptionsImpl();
   }
 
+  @Override
   protected ArtifactAcceptor doCreateArtifactAcceptor(final ModuleDef module) {
     return new ArtifactAcceptor() {
       public void accept(TreeLogger logger, ArtifactSet artifacts)
Index: dev/core/src/com/google/gwt/dev/HostedMode.java
===================================================================
--- dev/core/src/com/google/gwt/dev/HostedMode.java	(revision 4407)
+++ dev/core/src/com/google/gwt/dev/HostedMode.java	(working copy)
@@ -47,7 +47,7 @@
  * this class is to be determined. Consider this class as having <b>no</b>
  * public API other than {...@link #main(String[])}.
  */
-public class HostedMode extends HostedModeBase {
+public class HostedMode extends SwtHostedModeBase {
 
   /**
    * Handles the -server command line flag.
Index: dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java
===================================================================
--- dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java	(revision 4407)
+++ dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java	(working copy)
@@ -18,30 +18,14 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.Precompile.PrecompileOptionsImpl;
 import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.cfg.ModuleDefLoader;
-import com.google.gwt.dev.jjs.JJSOptions;
-import com.google.gwt.dev.shell.ArtifactAcceptor;
 import com.google.gwt.dev.shell.BrowserWidget;
 import com.google.gwt.dev.shell.BrowserWidgetHost;
-import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
-import com.google.gwt.dev.shell.BrowserWindowController;
 import com.google.gwt.dev.shell.ModuleSpaceHost;
 import com.google.gwt.dev.shell.PlatformSpecific;
 import com.google.gwt.dev.shell.ShellMainWindow;
 import com.google.gwt.dev.shell.ShellModuleSpaceHost;
-import com.google.gwt.dev.util.Util;
-import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
-import com.google.gwt.dev.util.arg.ArgHandlerEnableAssertions;
-import com.google.gwt.dev.util.arg.ArgHandlerGenDir;
-import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
-import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
-import com.google.gwt.dev.util.arg.OptionGenDir;
-import com.google.gwt.dev.util.arg.OptionLogLevel;
 import com.google.gwt.dev.util.log.AbstractTreeLogger;
-import com.google.gwt.util.tools.ArgHandlerFlag;
-import com.google.gwt.util.tools.ArgHandlerString;
 import com.google.gwt.util.tools.ToolBase;
 
 import org.eclipse.swt.SWT;
@@ -54,255 +38,17 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 
-import java.io.File;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 /**
- * The main executable class for the hosted mode shell.
+ * The main executable class for hosted mode shells based on SWT.
  */
-abstract class HostedModeBase implements BrowserWindowController {
+abstract class SwtHostedModeBase extends HostedModeBase {
 
-  /**
-   * Handles the -blacklist command line argument.
-   */
-  protected static class ArgHandlerBlacklist extends ArgHandlerString {
-    @Override
-    public String getPurpose() {
-      return "Prevents the user browsing URLs that match the specified regexes (comma or space separated)";
-    }
+  private class SwtBrowserWidgetHostImpl extends BrowserWidgetHostImpl {
 
     @Override
-    public String getTag() {
-      return "-blacklist";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"blacklist-string"};
-    }
-
-    @Override
-    public boolean setString(String blacklistStr) {
-      return BrowserWidgetHostChecker.blacklistRegexes(blacklistStr);
-    }
-  }
-
-  /**
-   * Handles the -noserver command line flag.
-   */
-  protected static class ArgHandlerNoServerFlag extends ArgHandlerFlag {
-    private final OptionNoServer options;
-
-    public ArgHandlerNoServerFlag(OptionNoServer options) {
-      this.options = options;
-    }
-
-    @Override
-    public String getPurpose() {
-      return "Prevents the embedded Tomcat server from running, even if a port is specified";
-    }
-
-    @Override
-    public String getTag() {
-      return "-noserver";
-    }
-
-    @Override
-    public boolean setFlag() {
-      options.setNoServer(true);
-      return true;
-    }
-  }
-
-  /**
-   * Handles the -port command line flag.
-   */
-  protected static class ArgHandlerPort extends ArgHandlerString {
-
-    private final OptionPort options;
-
-    public ArgHandlerPort(OptionPort options) {
-      this.options = options;
-    }
-
-    @Override
-    public String[] getDefaultArgs() {
-      return new String[] {getTag(), "8888"};
-    }
-
-    @Override
-    public String getPurpose() {
-      return "Runs an embedded Tomcat instance on the specified port (defaults to 8888)";
-    }
-
-    @Override
-    public String getTag() {
-      return "-port";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"port-number | \"auto\""};
-    }
-
-    @Override
-    public boolean setString(String value) {
-      if (value.equals("auto")) {
-        options.setPort(0);
-      } else {
-        try {
-          options.setPort(Integer.parseInt(value));
-        } catch (NumberFormatException e) {
-          System.err.println("A port must be an integer or \"auto\"");
-          return false;
-        }
-      }
-      return true;
-    }
-  }
-
-  /**
-   * Handles the -whitelist command line flag.
-   */
-  protected static class ArgHandlerWhitelist extends ArgHandlerString {
-    @Override
-    public String getPurpose() {
-      return "Allows the user to browse URLs that match the specified regexes (comma or space separated)";
-    }
-
-    @Override
-    public String getTag() {
-      return "-whitelist";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"whitelist-string"};
-    }
-
-    @Override
-    public boolean setString(String whitelistStr) {
-      return BrowserWidgetHostChecker.whitelistRegexes(whitelistStr);
-    }
-  }
-
-  protected interface HostedModeBaseOptions extends JJSOptions, OptionLogLevel,
-      OptionGenDir, OptionNoServer, OptionPort, OptionStartupURLs {
-
-    /**
-     * The base shell work directory.
-     */
-    File getShellBaseWorkDir(ModuleDef moduleDef);
-  }
-
-  /**
-   * Concrete class to implement all hosted mode base options.
-   */
-  protected static class HostedModeBaseOptionsImpl extends
-      PrecompileOptionsImpl implements HostedModeBaseOptions {
-
-    private boolean isNoServer;
-    private int port;
-    private final List<String> startupURLs = new ArrayList<String>();
-
-    public void addStartupURL(String url) {
-      startupURLs.add(url);
-    }
-
-    public int getPort() {
-      return port;
-    }
-
-    public File getShellBaseWorkDir(ModuleDef moduleDef) {
-      return new File(new File(getWorkDir(), moduleDef.getName()), "shell");
-    }
-
-    public List<String> getStartupURLs() {
-      return Collections.unmodifiableList(startupURLs);
-    }
-
-    public boolean isNoServer() {
-      return isNoServer;
-    }
-
-    public void setNoServer(boolean isNoServer) {
-      this.isNoServer = isNoServer;
-    }
-
-    public void setPort(int port) {
-      this.port = port;
-    }
-  }
-
-  /**
-   * Controls whether to run a server or not.
-   * 
-   */
-  protected interface OptionNoServer {
-    boolean isNoServer();
-
-    void setNoServer(boolean isNoServer);
-  }
-
-  /**
-   * Controls what port to use.
-   * 
-   */
-  protected interface OptionPort {
-    int getPort();
-
-    void setPort(int port);
-  }
-
-  /**
-   * Controls the startup URLs.
-   */
-  protected interface OptionStartupURLs {
-    void addStartupURL(String url);
-
-    List<String> getStartupURLs();
-  }
-
-  abstract static class ArgProcessor extends ArgProcessorBase {
-    public ArgProcessor(HostedModeBaseOptions options, boolean forceServer) {
-      if (!forceServer) {
-        registerHandler(new ArgHandlerNoServerFlag(options));
-      }
-      registerHandler(new ArgHandlerPort(options));
-      registerHandler(new ArgHandlerWhitelist());
-      registerHandler(new ArgHandlerBlacklist());
-      registerHandler(new ArgHandlerLogLevel(options));
-      registerHandler(new ArgHandlerGenDir(options));
-      registerHandler(new ArgHandlerScriptStyle(options));
-      registerHandler(new ArgHandlerEnableAssertions(options));
-      registerHandler(new ArgHandlerDisableAggressiveOptimization(options));
-    }
-  }
-
-  private class BrowserWidgetHostImpl implements BrowserWidgetHost {
-
-    public void compile() throws UnableToCompleteException {
-      if (isLegacyMode()) {
-        throw new UnsupportedOperationException();
-      }
-      HostedModeBase.this.compile(getLogger());
-    }
-
-    public void compile(String[] moduleNames) throws UnableToCompleteException {
-      if (!isLegacyMode()) {
-        throw new UnsupportedOperationException();
-      }
-      for (int i = 0; i < moduleNames.length; i++) {
-        String moduleName = moduleNames[i];
-        ModuleDef moduleDef = loadModule(getLogger(), moduleName, true);
-        HostedModeBase.this.compile(getLogger(), moduleDef);
-      }
-    }
-
     public ModuleSpaceHost createModuleSpaceHost(BrowserWidget widget,
         final String moduleName) throws UnableToCompleteException {
       TreeLogger logger = getLogger();
@@ -328,28 +74,6 @@
         widgetShell.setCursor(normalCursor);
       }
     }
-
-    public TreeLogger getLogger() {
-      return getTopLogger();
-    }
-
-    public boolean initModule(String moduleName) {
-      return HostedModeBase.this.initModule(moduleName);
-    }
-
-    @Deprecated
-    public boolean isLegacyMode() {
-      return HostedModeBase.this instanceof GWTShell;
-    }
-
-    public String normalizeURL(String whatTheUserTyped) {
-      return HostedModeBase.this.normalizeURL(whatTheUserTyped);
-    }
-
-    public BrowserWidget openNewBrowserWindow()
-        throws UnableToCompleteException {
-      return HostedModeBase.this.openNewBrowserWindow();
-    }
   }
 
   static {
@@ -360,18 +84,8 @@
     Display.setAppName("GWT");
   }
 
-  protected final HostedModeBaseOptions options;
+  private BrowserWidgetHostImpl browserHost = new SwtBrowserWidgetHostImpl();
 
-  /**
-   * Cheat on the first load's refresh by assuming the module loaded by
-   * {...@link com.google.gwt.dev.shell.GWTShellServlet} is still fresh. This
-   * prevents a double-refresh on startup. Subsequent refreshes will trigger a
-   * real refresh.
-   */
-  private Set<String> alreadySeenModules = new HashSet<String>();
-
-  private BrowserWidgetHostImpl browserHost = new BrowserWidgetHostImpl();
-
   private final List<Shell> browserShells = new ArrayList<Shell>();
 
   /**
@@ -380,37 +94,25 @@
    */
   private final Display display = Display.getDefault();
 
-  private boolean headlessMode = false;
-
   private ShellMainWindow mainWnd;
 
-  private boolean started;
-
-  public HostedModeBase() {
-    // Set any platform specific system properties.
-    BootStrapPlatform.init();
-    BootStrapPlatform.applyPlatformHacks();
-    options = createOptions();
+  public SwtHostedModeBase() {
+    super();
   }
 
-  public final void addStartupURL(String url) {
-    options.addStartupURL(url);
-  }
-
+  @Override
   public final void closeAllBrowserWindows() {
     while (!browserShells.isEmpty()) {
       browserShells.get(0).dispose();
     }
   }
 
-  public final int getPort() {
-    return options.getPort();
-  }
-
+  @Override
   public TreeLogger getTopLogger() {
     return mainWnd.getLogger();
   }
 
+  @Override
   public final boolean hasBrowserWindowsOpen() {
     if (browserShells.isEmpty()) {
       return false;
@@ -422,7 +124,8 @@
   /**
    * Launch the arguments as Urls in separate windows.
    */
-  public final void launchStartupUrls(final TreeLogger logger) {
+  @Override
+  public void launchStartupUrls(final TreeLogger logger) {
     // Launch a browser window for each startup url.
     String startupURL = "";
     try {
@@ -438,29 +141,6 @@
     }
   }
 
-  public final String normalizeURL(String unknownUrlText) {
-    if (unknownUrlText.indexOf(":") != -1) {
-      // Assume it's a full url.
-      return unknownUrlText;
-    }
-
-    // Assume it's a trailing url path.
-    if (unknownUrlText.length() > 0 && unknownUrlText.charAt(0) == '/') {
-      unknownUrlText = unknownUrlText.substring(1);
-    }
-
-    int port = getPort();
-    String host = getHost();
-    if (port != 80) {
-      // CHECKSTYLE_OFF: Not really an assembled error message, so no space
-      // after ':'.
-      return "http://"; + host + ":" + port + "/" + unknownUrlText;
-      // CHECKSTYLE_ON
-    } else {
-      return "http://"; + host + "/" + unknownUrlText;
-    }
-  }
-
   /**
    * Called directly by ShellMainWindow and indirectly via BrowserWidgetHost.
    */
@@ -494,153 +174,17 @@
     }
   }
 
-  /**
-   * Sets up all the major aspects of running the shell graphically, including
-   * creating the main window and optionally starting the embedded Tomcat
-   * server.
-   */
-  public final void run() {
-    try {
-      if (!startUp()) {
-        // Failed to initalize.
-        return;
-      }
-
-      // Eager AWT initialization for OS X to ensure safe coexistence with SWT.
-      BootStrapPlatform.maybeInitializeAWT();
-
-      // Tomcat's running now, so launch browsers for startup urls now.
-      launchStartupUrls(getTopLogger());
-
-      pumpEventLoop();
-    } catch (Exception e) {
-      e.printStackTrace();
-    } finally {
-      shutDown();
-    }
-  }
-
-  public final void setPort(int port) {
-    options.setPort(port);
-  }
-
-  public final void setRunTomcat(boolean run) {
-    options.setNoServer(!run);
-  }
-
-  /**
-   * Compiles all modules.
-   */
-  protected abstract void compile(TreeLogger logger)
-      throws UnableToCompleteException;
-
-  /**
-   * Compiles a module (legacy only).
-   */
-  @Deprecated
-  protected abstract void compile(TreeLogger logger, ModuleDef moduleDef)
-      throws UnableToCompleteException;
-
-  protected abstract HostedModeBaseOptions createOptions();
-
-  protected abstract ArtifactAcceptor doCreateArtifactAcceptor(ModuleDef module);
-
-  /**
-   * Creates an instance of ShellModuleSpaceHost (or a derived class) using the
-   * specified constituent parts. This method is made to be overridden for
-   * subclasses that need to change the behavior of ShellModuleSpaceHost.
-   * 
-   * @param logger TreeLogger to use
-   * @param typeOracle
-   * @param moduleDef
-   * @param genDir
-   * @return ShellModuleSpaceHost instance
-   */
-  protected final ShellModuleSpaceHost doCreateShellModuleSpaceHost(
-      TreeLogger logger, TypeOracle typeOracle, ModuleDef moduleDef) {
-    // Clear out the shell temp directory.
-    Util.recursiveDelete(options.getShellBaseWorkDir(moduleDef), true);
-    return new ShellModuleSpaceHost(logger, typeOracle, moduleDef,
-        options.getGenDir(), new File(options.getShellBaseWorkDir(moduleDef),
-            "gen"), doCreateArtifactAcceptor(moduleDef));
-  }
-
-  /**
-   * Derived classes can override to prevent automatic update checking.
-   */
-  protected boolean doShouldCheckForUpdates() {
-    return true;
-  }
-
-  protected abstract void doShutDownServer();
-
-  protected boolean doStartup() {
-    loadRequiredNativeLibs();
-
-    // Create the main app window.
-    openAppWindow();
-
-    // Initialize the logger.
-    //
-    initializeLogger();
-    return true;
-  }
-
-  protected abstract int doStartUpServer();
-
   protected final BrowserWidgetHost getBrowserHost() {
     return browserHost;
   }
 
-  protected String getHost() {
-    return "localhost";
-  }
-
+  @Override
   protected void initializeLogger() {
     final AbstractTreeLogger logger = mainWnd.getLogger();
     logger.setMaxDetail(options.getLogLevel());
   }
 
-  /**
-   * Called from a selection script as it begins to load in hosted mode. This
-   * triggers a hosted mode link, which might actually update the running
-   * selection script.
-   * 
-   * @param moduleName the module to link
-   * @return <code>true</code> if the selection script was overwritten; this
-   *         will trigger a full-page refresh by the calling (out of date)
-   *         selection script
-   */
-  protected abstract boolean initModule(String moduleName);
-
-  /**
-   * By default we will open the application window.
-   * 
-   * @return true if we are running in headless mode
-   */
-  protected final boolean isHeadless() {
-    return headlessMode;
-  }
-
-  /**
-   * Load a module.
-   * 
-   * @param moduleName name of the module to load
-   * @param logger TreeLogger to use
-   * @param refresh if <code>true</code>, refresh the module from disk
-   * @return the loaded module
-   * @throws UnableToCompleteException
-   */
-  protected ModuleDef loadModule(TreeLogger logger, String moduleName,
-      boolean refresh) throws UnableToCompleteException {
-    refresh &= alreadySeenModules.contains(moduleName);
-    ModuleDef moduleDef = ModuleDefLoader.loadFromClassPath(logger, moduleName,
-        refresh);
-    alreadySeenModules.add(moduleName);
-    assert (moduleDef != null) : "Required module state is absent";
-    return moduleDef;
-  }
-
+  @Override
   protected boolean notDone() {
     if (!mainWnd.isDisposed()) {
       return true;
@@ -651,61 +195,39 @@
     return false;
   }
 
-  protected final void pumpEventLoop() {
-    TreeLogger logger = getTopLogger();
+  @Override
+  protected void openAppWindow() {
+    final Shell shell = new Shell(display);
 
-    // Run the event loop. When there are no open shells, quit.
-    //
-    while (notDone()) {
-      try {
-        if (!display.readAndDispatch()) {
-          sleep();
-        }
-      } catch (Throwable e) {
-        String msg = e.getMessage();
-        msg = (msg != null ? msg : e.getClass().getName());
-        logger.log(TreeLogger.ERROR, msg, e);
-      }
+    FillLayout fillLayout = new FillLayout();
+    fillLayout.marginWidth = 0;
+    fillLayout.marginHeight = 0;
+    shell.setLayout(fillLayout);
+
+    shell.setImages(ShellMainWindow.getIcons());
+
+    boolean checkForUpdates = doShouldCheckForUpdates();
+
+    mainWnd = new ShellMainWindow(this, shell, options.isNoServer() ? 0
+        : getPort(), checkForUpdates);
+
+    shell.setSize(700, 600);
+    if (!isHeadless()) {
+      shell.open();
     }
   }
 
-  protected final void setHeadless(boolean headlessMode) {
-    this.headlessMode = headlessMode;
-  }
-
-  protected final void shutDown() {
-    if (options.isNoServer()) {
-      return;
+  @Override
+  protected void processEvents() throws Exception {
+    if (!display.readAndDispatch()) {
+      sleep();
     }
-    doShutDownServer();
   }
 
   protected void sleep() {
     display.sleep();
   }
 
-  protected final boolean startUp() {
-    if (started) {
-      throw new IllegalStateException("Startup code has already been run");
-    }
-
-    started = true;
-
-    if (!doStartup()) {
-      return false;
-    }
-
-    if (!options.isNoServer()) {
-      int resultPort = doStartUpServer();
-      if (resultPort < 0) {
-        return false;
-      }
-      options.setPort(resultPort);
-    }
-
-    return true;
-  }
-
   private Shell createTrackedBrowserShell() {
     final Shell shell = new Shell(display);
     FillLayout fillLayout = new FillLayout();
@@ -726,7 +248,8 @@
     return shell;
   }
 
-  private void loadRequiredNativeLibs() {
+  @Override
+  protected void loadRequiredNativeLibs() {
     String libName = null;
     try {
       libName = "swt";
@@ -739,25 +262,4 @@
       throw new RuntimeException(sb.toString(), e);
     }
   }
-
-  private void openAppWindow() {
-    final Shell shell = new Shell(display);
-
-    FillLayout fillLayout = new FillLayout();
-    fillLayout.marginWidth = 0;
-    fillLayout.marginHeight = 0;
-    shell.setLayout(fillLayout);
-
-    shell.setImages(ShellMainWindow.getIcons());
-
-    boolean checkForUpdates = doShouldCheckForUpdates();
-
-    mainWnd = new ShellMainWindow(this, shell, options.isNoServer() ? 0
-        : getPort(), checkForUpdates);
-
-    shell.setSize(700, 600);
-    if (!isHeadless()) {
-      shell.open();
-    }
-  }
 }
Index: dev/windows/src/com/google/gwt/dev/BootStrapPlatform.java
===================================================================
--- dev/windows/src/com/google/gwt/dev/BootStrapPlatform.java	(revision 4407)
+++ dev/windows/src/com/google/gwt/dev/BootStrapPlatform.java	(working copy)
@@ -23,12 +23,12 @@
   public static void applyPlatformHacks() {
     // nothing to do
   }
-  
-  public static void init() {
+
+  public static void initGui() {
     // nothing to do
   }
 
-  public static void maybeInitializeAWT() {
+  public static void initHostedMode() {
     // nothing to do
   }
 }

Reply via email to