@Override
  protected boolean doSlowStartup() {
    tempWorkDir = options.getWorkDir() == null;
    if (tempWorkDir) {
      try {
        options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc"));
      } catch (IOException e) {
        System.err.println("Unable to create hosted mode work directory");
        e.printStackTrace();
        return false;
      }
    }

    TreeLogger branch = getTopLogger().branch(TreeLogger.TRACE, "Linking modules");
    Event slowStartupEvent = SpeedTracerLogger.start(DevModeEventType.SLOW_STARTUP);
    try {
      for (ModuleDef module : startupModules.values()) {
        TreeLogger loadLogger =
            branch.branch(
                TreeLogger.DEBUG,
                "Bootstrap link for command-line module '" + module.getCanonicalName() + "'");
        link(loadLogger, module);
      }
    } catch (UnableToCompleteException e) {
      // Already logged.
      return false;
    } finally {
      slowStartupEvent.end();
    }
    return true;
  }
  @Override
  protected synchronized void produceOutput(
      TreeLogger logger,
      StandardLinkerContext linkerStack,
      ArtifactSet artifacts,
      ModuleDef module,
      boolean isRelink)
      throws UnableToCompleteException {
    TreeLogger linkLogger =
        logger.branch(TreeLogger.DEBUG, "Linking module '" + module.getName() + "'");

    OutputFileSetOnDirectory outFileSet =
        new OutputFileSetOnDirectory(options.getWarDir(), module.getName() + "/");
    OutputFileSetOnDirectory deployFileSet =
        new OutputFileSetOnDirectory(options.getDeployDir(), module.getName() + "/");
    OutputFileSet extraFileSet = new NullOutputFileSet();
    if (options.getExtraDir() != null) {
      extraFileSet = new OutputFileSetOnDirectory(options.getExtraDir(), module.getName() + "/");
    }

    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Public, outFileSet);
    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Deploy, deployFileSet);
    linkerStack.produceOutput(linkLogger, artifacts, Visibility.Private, extraFileSet);

    outFileSet.close();
    deployFileSet.close();
    try {
      extraFileSet.close();
    } catch (IOException e) {
      linkLogger.log(TreeLogger.ERROR, "Error emiting extra files", e);
      throw new UnableToCompleteException();
    }
  }
 @Override
 protected void inferStartupUrls() {
   // Look for launchable files directly under war
   File warDir = options.getWarDir();
   if (!warDir.exists()) {
     // if the war directory doesn't exist, there are no startup files there
     return;
   }
   for (File htmlFile :
       warDir.listFiles(
           new FilenameFilter() {
             public boolean accept(File dir, String name) {
               return STARTUP_FILE_PATTERN.matcher(name).matches();
             }
           })) {
     options.addStartupURL(htmlFile.getName());
   }
 }
  @Override
  protected boolean doStartup() {
    // Background scan the classpath to warm the cache.
    Thread scanThread =
        new Thread(
            new Runnable() {
              public void run() {
                ResourceOracleImpl.preload(TreeLogger.NULL);
              }
            });
    scanThread.setDaemon(true);
    scanThread.setPriority((Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2);
    scanThread.start();

    File persistentCacheDir = null;
    if (options.getWarDir() != null && !options.getWarDir().getName().endsWith(".jar")) {
      persistentCacheDir = new File(options.getWarDir(), "../");
    }

    if (!super.doStartup(persistentCacheDir)) {
      return false;
    }

    ServletValidator servletValidator = null;
    ServletWriter servletWriter = null;
    File webXml = new File(options.getWarDir(), "WEB-INF/web.xml");
    if (!options.isNoServer()) {
      if (webXml.exists()) {
        servletValidator = ServletValidator.create(getTopLogger(), webXml);
      } else {
        servletWriter = new ServletWriter();
      }
    }

    TreeLogger branch = getTopLogger().branch(TreeLogger.TRACE, "Loading modules");
    try {
      for (String moduleName : options.getModuleNames()) {
        TreeLogger moduleBranch = branch.branch(TreeLogger.TRACE, moduleName);
        ModuleDef module = loadModule(moduleBranch, moduleName, false);
        // Create a hard reference to the module to avoid gc-ing it until we
        // actually load the module from the browser.
        startupModules.put(module.getName(), module);

        if (!options.isNoServer()) {
          validateServletTags(moduleBranch, servletValidator, servletWriter, module);
        }
      }
      if (servletWriter != null) {
        servletWriter.realize(webXml);
      }
    } catch (IOException e) {
      getTopLogger().log(TreeLogger.WARN, "Unable to generate '" + webXml.getAbsolutePath() + "'");
    } catch (UnableToCompleteException e) {
      // Already logged.
      return false;
    }
    return true;
  }
  @Override
  protected void doShutDownServer() {
    if (server != null) {
      try {
        server.stop();
      } catch (UnableToCompleteException e) {
        // Already logged.
      }
      server = null;
    }

    if (tempWorkDir) {
      Util.recursiveDelete(options.getWorkDir(), false);
    }
  }
 protected String getWebServerName() {
   return options.getServletContainerLauncher().getName();
 }
  @Override
  protected int doStartUpServer() {
    // Create the war directory if it doesn't exist
    File warDir = options.getWarDir();
    if (!warDir.exists() && !warDir.mkdirs()) {
      getTopLogger().log(TreeLogger.ERROR, "Unable to create war directory " + warDir);
      return -1;
    }

    Event jettyStartupEvent = SpeedTracerLogger.start(DevModeEventType.JETTY_STARTUP);
    boolean clearCallback = true;
    try {
      ui.setCallback(RestartServerEvent.getType(), this);

      ServletContainerLauncher scl = options.getServletContainerLauncher();

      TreeLogger serverLogger = ui.getWebServerLogger(getWebServerName(), scl.getIconBytes());

      String sclArgs = options.getServletContainerLauncherArgs();
      if (sclArgs != null) {
        if (!scl.processArguments(serverLogger, sclArgs)) {
          return -1;
        }
      }

      isHttps = scl.isSecure();

      // Tell the UI if the web server is secure
      if (isHttps) {
        ui.setWebServerSecure(serverLogger);
      }

      /*
       * TODO: This is a hack to pass the base log level to the SCL. We'll have
       * to figure out a better way to do this for SCLs in general.
       */
      if (scl instanceof JettyLauncher) {
        JettyLauncher jetty = (JettyLauncher) scl;
        jetty.setBaseRequestLogLevel(getBaseLogLevelForUI());
      }
      scl.setBindAddress(bindAddress);

      if (serverLogger.isLoggable(TreeLogger.TRACE)) {
        serverLogger.log(TreeLogger.TRACE, "Starting HTTP on port " + getPort(), null);
      }
      server = scl.start(serverLogger, getPort(), options.getWarDir());
      assert (server != null);
      clearCallback = false;
      return server.getPort();
    } catch (BindException e) {
      System.err.println(
          "Port "
              + bindAddress
              + ':'
              + getPort()
              + " is already is use; you probably still have another session active");
    } catch (Exception e) {
      System.err.println("Unable to start embedded HTTP server");
      e.printStackTrace();
    } finally {
      jettyStartupEvent.end();
      if (clearCallback) {
        // Clear the callback if we failed to start the server
        ui.setCallback(RestartServerEvent.getType(), null);
      }
    }
    return -1;
  }