Revision: 6105
Author: [email protected]
Date: Wed Sep  9 13:11:05 2009
Log: adding a -logdir flag to hosted mode; no more taking screenshots of  
interesting stuff.

Review by: jat
http://code.google.com/p/google-web-toolkit/source/detail?r=6105

Added:
  /trunk/dev/core/src/com/google/gwt/dev/util/log/CompositeTreeLogger.java
  /trunk/dev/oophm/src/com/google/gwt/dev/util/BrowserInfo.java
Modified:
  /trunk/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
  /trunk/dev/core/src/com/google/gwt/dev/HostedModeBase.java
  /trunk/dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java
  /trunk/dev/core/src/com/google/gwt/dev/shell/ShellMainWindow.java
   
/trunk/dev/core/src/com/google/gwt/dev/shell/log/DetachedTreeLoggerWindow.java
  /trunk/dev/core/src/com/google/gwt/dev/shell/log/TreeLoggerWidget.java
  /trunk/dev/core/src/com/google/gwt/dev/util/log/AbstractTreeLogger.java
  /trunk/dev/core/src/com/google/gwt/dev/util/log/PrintWriterTreeLogger.java
  /trunk/dev/oophm/overlay/com/google/gwt/dev/shell/ShellMainWindow.java
  /trunk/dev/oophm/src/com/google/gwt/dev/ModulePanel.java
  /trunk/dev/oophm/src/com/google/gwt/dev/ModuleTabPanel.java
  /trunk/dev/oophm/src/com/google/gwt/dev/OophmHostedModeBase.java
  /trunk/dev/oophm/src/com/google/gwt/dev/WebServerPanel.java
  /trunk/dev/oophm/src/com/google/gwt/dev/shell/log/SwingLoggerPanel.java

=======================================
--- /dev/null
+++  
/trunk/dev/core/src/com/google/gwt/dev/util/log/CompositeTreeLogger.java        
 
Wed Sep  9 13:11:05 2009
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+package com.google.gwt.dev.util.log;
+
+/**
+ * Forks logging over two child loggers.  This provides the graphics + file
+ * logging of HostedModeBase's -logfile option.
+ */
+public class CompositeTreeLogger extends AbstractTreeLogger {
+
+  private AbstractTreeLogger[] loggers;
+
+  public CompositeTreeLogger(AbstractTreeLogger... loggers) {
+    this.loggers = loggers;
+  }
+
+  @Override
+  protected AbstractTreeLogger doBranch() {
+    AbstractTreeLogger children[] = new AbstractTreeLogger[loggers.length];
+    for (int i = 0; i < loggers.length; i++) {
+      children[i] = loggers[i].doBranch();
+      children[i].indexWithinMyParent =  
loggers[i].allocateNextChildIndex();
+      children[i].parent = loggers[i];
+      children[i].logLevel = loggers[i].logLevel;
+    }
+    return new CompositeTreeLogger(children);
+  }
+
+  @Override
+  protected void doCommitBranch(AbstractTreeLogger childBeingCommitted,
+      Type type, String msg, Throwable caught, HelpInfo helpInfo) {
+    CompositeTreeLogger child = (CompositeTreeLogger) childBeingCommitted;
+    assert loggers.length == child.loggers.length;
+    for (int i = 0; i < loggers.length; i++) {
+      loggers[i].doCommitBranch(child.loggers[i], type, msg, caught,  
helpInfo);
+    }
+  }
+
+  @Override
+  protected void doLog(int indexOfLogEntryWithinParentLogger, Type type,
+      String msg, Throwable caught, HelpInfo helpInfo) {
+    for (AbstractTreeLogger logger : loggers) {
+      logger.doLog(indexOfLogEntryWithinParentLogger, type, msg, caught,
+          helpInfo);
+    }
+  }
+}
=======================================
--- /dev/null
+++ /trunk/dev/oophm/src/com/google/gwt/dev/util/BrowserInfo.java       Wed Sep 
  
9 13:11:05 2009
@@ -0,0 +1,100 @@
+/**
+ * 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.util;
+
+import com.google.gwt.dev.shell.Icons;
+
+import javax.swing.ImageIcon;
+
+/**
+ * Holds information about the browser used in the UI.
+ */
+public class BrowserInfo {
+
+  private static final String UNKNOWN = "Unknown";
+  private static final String FIREFOX = "FF";
+  private static final String SAFARI = "Safari";
+  private static final String OPERA = "Opera";
+  private static final String CHROME = "Chrome";
+  private static final String IE = "IE";
+
+  /**
+   * Choose an icon and short name appropriate for this browser.  The icon
+   * may be null.
+   *
+   * @param userAgent User-Agent string from browser
+   * @return icon or null if none
+   */
+  public static BrowserInfo getBrowserInfo(String userAgent) {
+    ImageIcon browserIcon = null;
+    String shortName = getShortName(userAgent);
+    if (shortName.equals(IE)) {
+      browserIcon = Icons.getIE24();
+    } else if (shortName.equals(CHROME)) {
+      browserIcon = Icons.getChrome24();
+    } else if (shortName.equals(OPERA)) {
+      browserIcon = Icons.getOpera24();
+    } else if (shortName.equals(SAFARI)) {
+      browserIcon = Icons.getSafari24();
+    } else if (shortName.equals(FIREFOX)) {
+      browserIcon = Icons.getFirefox24();
+    }
+    return new BrowserInfo(browserIcon, shortName);
+  }
+
+  public static String getShortName(String userAgent) {
+    String lcAgent = userAgent.toLowerCase();
+    if (lcAgent.contains("msie")) {
+      return IE;
+    } else if (lcAgent.contains("chrome")) {
+      return CHROME;
+    } else if (lcAgent.contains("opera")) {
+      return OPERA;
+    } else if (lcAgent.contains("webkit") || lcAgent.contains("safari")) {
+      return SAFARI;
+    } else if (lcAgent.contains("firefox")) {
+      return FIREFOX;
+    }
+    return UNKNOWN;
+  }
+  private final ImageIcon icon;
+  private final String shortName;
+
+  /**
+   * Create a BrowserInfo instance.
+   *
+   * @param icon
+   * @param shortName
+   */
+  private BrowserInfo(ImageIcon icon, String shortName) {
+    this.icon = icon;
+    this.shortName = shortName;
+  }
+
+  /**
+   * @return the icon used to identify this browser, or null if none.
+   */
+  public ImageIcon getIcon() {
+    return icon;
+  }
+
+  /**
+   * @return the short name used to identify this browser, or null if none.
+   */
+  public String getShortName() {
+    return shortName;
+  }
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java       Tue Jul 
 
28 21:11:44 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java       Wed Sep 
  
9 13:11:05 2009
@@ -46,7 +46,8 @@
      if (options.isUseGuiLogger()) {
        // Initialize a tree logger window.
        DetachedTreeLoggerWindow loggerWindow =  
DetachedTreeLoggerWindow.getInstance(
-          "Build Output for " + options.getModuleNames(), 800, 600, true);
+          "Build Output for " + options.getModuleNames(), 800, 600, true,
+          options.getLogLevel());

        // Eager AWT initialization for OS X to ensure safe coexistence with  
SWT.
        BootStrapPlatform.initGui();
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/HostedModeBase.java  Sat Aug 22  
16:01:38 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/HostedModeBase.java  Wed Sep  9  
13:11:05 2009
@@ -84,6 +84,37 @@
        return BrowserWidgetHostChecker.blacklistRegexes(blacklistStr);
      }
    }
+
+  /**
+   * Handles the -logdir command line option.
+   */
+  protected static class ArgHandlerLogDir extends ArgHandlerString {
+    private final OptionLogDir options;
+
+    public ArgHandlerLogDir(OptionLogDir options) {
+      this.options = options;
+    }
+
+    @Override
+    public String getPurpose() {
+      return "Logs to a file in the given directory, as well as  
graphically";
+    }
+
+    @Override
+    public String getTag() {
+      return "-logdir";
+    }
+    @Override
+    public String[] getTagArgs() {
+      return new String[] {"directory"};
+    }
+
+    @Override
+    public boolean setString(String value) {
+      options.setLogFile(value);
+      return true;
+    }
+  }

    /**
     * Handles the -noserver command line flag.
@@ -232,8 +263,9 @@
      }
    }

-  protected interface HostedModeBaseOptions extends JJSOptions,  
OptionLogLevel,
-      OptionGenDir, OptionNoServer, OptionPort, OptionStartupURLs {
+  protected interface HostedModeBaseOptions extends JJSOptions,  
OptionLogDir,
+      OptionLogLevel, OptionGenDir, OptionNoServer, OptionPort,
+      OptionStartupURLs {

      /**
       * The base shell work directory.
@@ -248,12 +280,27 @@
        PrecompileOptionsImpl implements HostedModeBaseOptions {

      private boolean isNoServer;
+    private File logDir;
      private int port;
      private final List<String> startupURLs = new ArrayList<String>();

      public void addStartupURL(String url) {
        startupURLs.add(url);
      }
+
+    public boolean alsoLogToFile() {
+      return logDir != null;
+    }
+
+    public File getLogDir() {
+      return logDir;
+    }
+    public File getLogFile(String sublog) {
+      if (logDir == null) {
+        return null;
+      }
+      return new File(logDir, sublog);
+    }

      public int getPort() {
        return port;
@@ -270,6 +317,10 @@
      public boolean isNoServer() {
        return isNoServer;
      }
+
+    public void setLogFile(String filename) {
+      logDir = new File(filename);
+    }

      public void setNoServer(boolean isNoServer) {
        this.isNoServer = isNoServer;
@@ -279,6 +330,20 @@
        this.port = port;
      }
    }
+
+  /**
+   * Controls whether and where to log data to file.
+   *
+   */
+  protected interface OptionLogDir {
+    boolean alsoLogToFile();
+
+    File getLogDir();
+
+    File getLogFile(String subfile);
+
+    void setLogFile(String filename);
+  }

    /**
     * Controls whether to run a server or not.
@@ -317,6 +382,7 @@
        registerHandler(new ArgHandlerPort(options));
        registerHandler(new ArgHandlerWhitelist());
        registerHandler(new ArgHandlerBlacklist());
+      registerHandler(new ArgHandlerLogDir(options));
        registerHandler(new ArgHandlerLogLevel(options));
        registerHandler(new ArgHandlerGenDir(options));
        registerHandler(new ArgHandlerScriptStyle(options));
@@ -480,7 +546,7 @@
      // Initialize the logger.
      //
      initializeLogger();
-
+
      // Check for updates
      final TreeLogger logger = getTopLogger();
      final CheckForUpdates updateChecker
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java       Mon Aug 
 
10 16:15:14 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/SwtHostedModeBase.java       Wed Sep 
  
9 13:11:05 2009
@@ -285,7 +285,9 @@
      shell.setImages(ShellMainWindow.getIcons());

      mainWnd = new ShellMainWindow(this, shell, getTitleText(),
-        options.isNoServer() ? 0 : getPort());
+        options.isNoServer() ? 0 : getPort(),
+        options.alsoLogToFile() ? options.getLogFile("hosted.log") : null,
+        options.getLogLevel());

      shell.setSize(700, 600);
      if (!isHeadless()) {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/shell/ShellMainWindow.java   Tue  
Jul 28 21:11:44 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/shell/ShellMainWindow.java   Wed  
Sep  9 13:11:05 2009
@@ -17,6 +17,7 @@

  import com.google.gwt.core.ext.TreeLogger;
  import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.TreeLogger.Type;
  import com.google.gwt.dev.shell.BrowserWindowController.WebServerRestart;
  import com.google.gwt.dev.shell.log.TreeLoggerWidget;
  import com.google.gwt.dev.util.Util;
@@ -38,6 +39,8 @@
  import org.eclipse.swt.widgets.Shell;
  import org.eclipse.swt.widgets.ToolItem;

+import java.io.File;
+
  /**
   * Implements the GWTShell's main window control.
   */
@@ -201,7 +204,8 @@
    private Toolbar toolbar;

    public ShellMainWindow(BrowserWindowController browserWindowController,
-      Shell parent, String titleText, int serverPort) {
+      Shell parent, String titleText, int serverPort, File logFile,
+      Type logLevel) {
      super(parent, SWT.NONE);
      this.browserWindowController = browserWindowController;

@@ -235,7 +239,7 @@

      // Create the log pane.
      {
-      logPane = new TreeLoggerWidget(this);
+      logPane = new TreeLoggerWidget(this, logFile, logLevel);
        GridData data = new GridData();
        data.grabExcessHorizontalSpace = true;
        data.grabExcessVerticalSpace = true;
=======================================
---  
/trunk/dev/core/src/com/google/gwt/dev/shell/log/DetachedTreeLoggerWindow.java  
 
Tue Jul 28 21:11:44 2009
+++  
/trunk/dev/core/src/com/google/gwt/dev/shell/log/DetachedTreeLoggerWindow.java  
 
Wed Sep  9 13:11:05 2009
@@ -15,6 +15,7 @@
   */
  package com.google.gwt.dev.shell.log;

+import com.google.gwt.core.ext.TreeLogger.Type;
  import com.google.gwt.dev.shell.LowLevel;
  import com.google.gwt.dev.util.log.AbstractTreeLogger;

@@ -42,10 +43,10 @@
     */
    public static synchronized DetachedTreeLoggerWindow getInstance(
        final String caption, final int width, final int height,
-      final boolean autoScroll) {
+      final boolean autoScroll, Type logLevel) {
      if (singleton == null) {
        singleton = new DetachedTreeLoggerWindow(caption, width, height,
-          autoScroll);
+          autoScroll, logLevel);
      }
      return singleton;
    }
@@ -55,7 +56,7 @@
    private boolean isRunning = false;

    private DetachedTreeLoggerWindow(final String caption, final int width,
-      final int height, final boolean autoScroll) {
+      final int height, final boolean autoScroll, Type logLevel) {

      shell = new Shell(Display.getCurrent());
      shell.setText(caption);
@@ -64,7 +65,8 @@
      fillLayout.marginHeight = 0;
      shell.setLayout(fillLayout);

-    final TreeLoggerWidget treeLoggerWidget = new TreeLoggerWidget(shell);
+    final TreeLoggerWidget treeLoggerWidget = new TreeLoggerWidget(shell,  
null,
+        logLevel);
      treeLoggerWidget.setAutoScroll(autoScroll);
      logger = treeLoggerWidget.getLogger();

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/shell/log/TreeLoggerWidget.java      
 
Tue Jul 28 21:11:44 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/shell/log/TreeLoggerWidget.java      
 
Wed Sep  9 13:11:05 2009
@@ -15,10 +15,14 @@
   */
  package com.google.gwt.dev.shell.log;

+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.shell.BrowserWidget;
  import com.google.gwt.dev.shell.log.TreeItemLogger.LogEvent;
  import com.google.gwt.dev.util.log.AbstractTreeLogger;
+import com.google.gwt.dev.util.log.CompositeTreeLogger;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

  import org.eclipse.swt.SWT;
  import org.eclipse.swt.custom.SashForm;
@@ -43,6 +47,8 @@
  import org.eclipse.swt.widgets.Tree;
  import org.eclipse.swt.widgets.TreeItem;

+import java.io.File;
+import java.io.IOException;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.net.URL;
@@ -57,11 +63,19 @@

    private final Text details;

-  private final TreeItemLogger logger;
+  private final AbstractTreeLogger logger;
+
+  private final TreeItemLogger uiLogger;

    private final Tree tree;

-  public TreeLoggerWidget(Composite parent) {
+  /**
+   * Creates a graphical widget, and optionally logging to file as well.
+   *
+   * @param parent the graphical interface parent
+   * @param logFile the file to log to
+   */
+  public TreeLoggerWidget(Composite parent, File logFile, Type logLevel) {
      super(parent, SWT.NONE);

      setLayout(new FillLayout());
@@ -97,7 +111,21 @@
        }
      });

-    logger = new TreeItemLogger();
+    uiLogger = new TreeItemLogger();
+    AbstractTreeLogger bestLogger = uiLogger;
+    if (logFile != null) {
+      try {
+        PrintWriterTreeLogger fileLogger = new  
PrintWriterTreeLogger(logFile);
+        bestLogger = new CompositeTreeLogger(uiLogger, fileLogger);
+        fileLogger.setMaxDetail(logLevel);
+        uiLogger.setMaxDetail(logLevel);
+      } catch (IOException ex) {
+        uiLogger.log(TreeLogger.ERROR, "Can't log to " +
+            logFile.getAbsolutePath(), ex);
+      }
+    }
+    logger = bestLogger;
+    logger.setMaxDetail(logLevel);

      // The detail
      details = new Text(sash, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY |  
SWT.BORDER
@@ -238,7 +266,7 @@
            return;
          }

-        if (logger.uiFlush(tree)) {
+        if (uiLogger.uiFlush(tree)) {
            // Sync to the end of the tree.
            //
            if (autoScroll) {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/util/log/AbstractTreeLogger.java     
 
Mon May 18 11:47:32 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/util/log/AbstractTreeLogger.java     
 
Wed Sep  9 13:11:05 2009
@@ -85,15 +85,15 @@
    }

    public int indexWithinMyParent;
-
-  private TreeLogger.Type logLevel = TreeLogger.ALL;
+
+  protected TreeLogger.Type logLevel = TreeLogger.ALL;
+
+  protected AbstractTreeLogger parent;

    private int nextChildIndex;

    private final Object nextChildIndexLock = new Object();

-  private AbstractTreeLogger parent;
-
    private UncommittedBranchData uncommitted;

    /**
@@ -225,6 +225,38 @@
    public String toString() {
      return getLoggerId();
    }
+
+  protected int allocateNextChildIndex() {
+    synchronized (nextChildIndexLock) {
+      // postincrement because we want indices to start at 0
+      return nextChildIndex++;
+    }
+  }
+
+  /**
+   * Commits the branch after ensuring that the parent logger (if there is  
one)
+   * has been committed first.
+   */
+  protected synchronized void commitMyBranchEntryInMyParentLogger() {
+    // (Only the root logger doesn't have a parent.)
+    //
+    if (parent != null) {
+      if (uncommitted != null) {
+        // Commit the parent first.
+        //
+        parent.commitMyBranchEntryInMyParentLogger();
+
+        // Let the subclass do its thing to commit this branch.
+        //
+        parent.doCommitBranch(this, uncommitted.type, uncommitted.message,
+            uncommitted.caught, uncommitted.helpInfo);
+
+        // Release the uncommitted state.
+        //
+        uncommitted = null;
+      }
+    }
+  }

    /**
     * Derived classes should override this method to return a branched  
logger.
@@ -267,13 +299,6 @@
    protected abstract void doLog(int indexOfLogEntryWithinParentLogger,
        TreeLogger.Type type, String msg, Throwable caught, HelpInfo  
helpInfo);

-  private int allocateNextChildIndex() {
-    synchronized (nextChildIndexLock) {
-      // postincrement because we want indices to start at 0
-      return nextChildIndex++;
-    }
-  }
-
    /**
     * Scans <code>t</code> and its causes for {...@link OutOfMemoryError}.
     *
@@ -292,31 +317,6 @@

      return false;
    }
-
-  /**
-   * Commits the branch after ensuring that the parent logger (if there is  
one)
-   * has been committed first.
-   */
-  private synchronized void commitMyBranchEntryInMyParentLogger() {
-    // (Only the root logger doesn't have a parent.)
-    //
-    if (parent != null) {
-      if (uncommitted != null) {
-        // Commit the parent first.
-        //
-        parent.commitMyBranchEntryInMyParentLogger();
-
-        // Let the subclass do its thing to commit this branch.
-        //
-        parent.doCommitBranch(this, uncommitted.type, uncommitted.message,
-            uncommitted.caught, uncommitted.helpInfo);
-
-        // Release the uncommitted state.
-        //
-        uncommitted = null;
-      }
-    }
-  }

    private String getLoggerId() {
      if (parent != null) {
=======================================
---  
/trunk/dev/core/src/com/google/gwt/dev/util/log/PrintWriterTreeLogger.java      
 
Tue Apr  1 16:48:44 2008
+++  
/trunk/dev/core/src/com/google/gwt/dev/util/log/PrintWriterTreeLogger.java      
 
Wed Sep  9 13:11:05 2009
@@ -15,6 +15,9 @@
   */
  package com.google.gwt.dev.util.log;

+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
  import java.io.PrintWriter;
  import java.net.URL;

@@ -26,6 +29,8 @@
    private final String indent;

    private final PrintWriter out;
+
+  private final Object mutex = new Object();

    public PrintWriterTreeLogger() {
      this(new PrintWriter(System.out, true));
@@ -34,12 +39,22 @@
    public PrintWriterTreeLogger(PrintWriter out) {
      this(out, "");
    }
+
+  public PrintWriterTreeLogger(File logFile) throws IOException {
+    boolean existing = logFile.exists();
+    this.out = new PrintWriter(new FileWriter(logFile, true), true);
+    this.indent = "";
+    if (existing) {
+      out.println();  // blank line to mark relaunch
+    }
+  }

    protected PrintWriterTreeLogger(PrintWriter out, String indent) {
      this.out = out;
      this.indent = indent;
    }

+  @Override
    protected AbstractTreeLogger doBranch() {
      return new PrintWriterTreeLogger(out, indent + "   ");
    }
@@ -53,23 +68,25 @@
    @Override
    protected void doLog(int indexOfLogEntryWithinParentLogger, Type type,
        String msg, Throwable caught, HelpInfo helpInfo) {
-    out.print(indent);
-    if (type.needsAttention()) {
-      out.print("[");
-      out.print(type.getLabel());
-      out.print("] ");
-    }
-
-    out.println(msg);
-    if (helpInfo != null) {
-      URL url = helpInfo.getURL();
-      if (url != null) {
-        out.print(indent);
-        out.println("For additional info see: " + url.toString());
-      }
-    }
-    if (caught != null) {
-      caught.printStackTrace(out);
+    synchronized (mutex) { // ensure thread interleaving...
+      out.print(indent);
+      if (type.needsAttention()) {
+        out.print("[");
+        out.print(type.getLabel());
+        out.print("] ");
+      }
+
+      out.println(msg);
+      if (helpInfo != null) {
+        URL url = helpInfo.getURL();
+        if (url != null) {
+          out.print(indent);
+          out.println("For additional info see: " + url.toString());
+        }
+      }
+      if (caught != null) {
+        caught.printStackTrace(out);
+      }
      }
    }
  }
=======================================
--- /trunk/dev/oophm/overlay/com/google/gwt/dev/shell/ShellMainWindow.java      
 
Mon Aug  3 11:59:02 2009
+++ /trunk/dev/oophm/overlay/com/google/gwt/dev/shell/ShellMainWindow.java      
 
Wed Sep  9 13:11:05 2009
@@ -21,6 +21,7 @@

  import java.awt.BorderLayout;
  import java.awt.GridLayout;
+import java.io.File;

  import javax.swing.BorderFactory;
  import javax.swing.JLabel;
@@ -33,7 +34,7 @@

    private SwingLoggerPanel logWindow;

-  public ShellMainWindow(TreeLogger.Type maxLevel) {
+  public ShellMainWindow(TreeLogger.Type maxLevel, File logFile) {
      super(new BorderLayout());
      // TODO(jat): add back when we have real options
      if (false) {
@@ -49,7 +50,7 @@
        panel.add(launchPanel);
        add(panel, BorderLayout.NORTH);
      }
-    logWindow = new SwingLoggerPanel(maxLevel);
+    logWindow = new SwingLoggerPanel(maxLevel, logFile);
      add(logWindow);
    }

=======================================
--- /trunk/dev/oophm/src/com/google/gwt/dev/ModulePanel.java    Sat Aug 22  
16:01:38 2009
+++ /trunk/dev/oophm/src/com/google/gwt/dev/ModulePanel.java    Wed Sep  9  
13:11:05 2009
@@ -24,6 +24,7 @@
  import java.awt.BorderLayout;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
+import java.io.File;

  import javax.swing.JButton;
  import javax.swing.JOptionPane;
@@ -41,7 +42,7 @@
    private boolean disconnected;

    public ModulePanel(Type maxLevel, String moduleName,
-      Session session) {
+      Session session, File logFile) {
      super(new BorderLayout());
      this.session = session;
      if (false) {
@@ -57,7 +58,7 @@
        topPanel.add(compileButton);
        add(topPanel, BorderLayout.NORTH);
      }
-    loggerPanel = new SwingLoggerPanel(maxLevel);
+    loggerPanel = new SwingLoggerPanel(maxLevel, logFile);
      add(loggerPanel);
      session.addModule(moduleName, this);
    }
=======================================
--- /trunk/dev/oophm/src/com/google/gwt/dev/ModuleTabPanel.java Fri Sep  4  
12:23:59 2009
+++ /trunk/dev/oophm/src/com/google/gwt/dev/ModuleTabPanel.java Wed Sep  9  
13:11:05 2009
@@ -17,7 +17,7 @@

  import com.google.gwt.core.ext.TreeLogger.Type;
  import com.google.gwt.dev.OophmHostedModeBase.TabPanelCollection;
-import com.google.gwt.dev.shell.Icons;
+import com.google.gwt.dev.util.BrowserInfo;

  import java.awt.BorderLayout;
  import java.awt.CardLayout;
@@ -26,6 +26,7 @@
  import java.awt.Font;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
+import java.io.File;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.text.DateFormat;
@@ -224,40 +225,6 @@
        moduleDropdown.setSelectedItem(sessionModule);
      }
    }
-
-  /**
-   * Holds information about the browser used in the UI.
-   */
-  private static class BrowserInfo {
-
-    private final ImageIcon icon;
-    private final String shortName;
-
-    /**
-     * Create a BrowserInfo instance.
-     *
-     * @param icon
-     * @param shortName
-     */
-    public BrowserInfo(ImageIcon icon, String shortName) {
-      this.icon = icon;
-      this.shortName = shortName;
-    }
-
-    /**
-     * @return the icon used to identify this browser, or null if none.
-     */
-    public ImageIcon getIcon() {
-      return icon;
-    }
-
-    /**
-     * @return the short name used to identify this browser, or null if  
none.
-     */
-    public String getShortName() {
-      return shortName;
-    }
-  }

    /**
     * Renderer used to show entries in the module dropdown box.
@@ -384,7 +351,7 @@
      cardLayout = new CardLayout();
      deckPanel.setLayout(cardLayout);
      add(deckPanel);
-    BrowserInfo browserInfo = getBrowserInfo(userAgent);
+    BrowserInfo browserInfo = BrowserInfo.getBrowserInfo(userAgent);

      // Construct the tab title and tooltip
      String tabTitle = url;
@@ -426,10 +393,11 @@

    public synchronized ModulePanel addModuleSession(Type maxLevel,
        String moduleName,
-      String sessionKey) {
+      String sessionKey,
+      File logFile) {
      Session session = findOrCreateSession(sessionKey);

-    ModulePanel panel = new ModulePanel(maxLevel, moduleName, session);
+    ModulePanel panel = new ModulePanel(maxLevel, moduleName, session,  
logFile);
      return panel;
    }

@@ -478,32 +446,6 @@
      }
      return session;
    }
-
-  /**
-   * Choose an icon appropriate for this browser, or null if none.
-   *
-   * @param userAgent User-Agent string from browser
-   * @return icon or null if none
-   */
-  private BrowserInfo getBrowserInfo(String userAgent) {
-    ImageIcon browserIcon = null;
-    String shortName = null;
-    String lcAgent = userAgent.toLowerCase();
-    if (lcAgent.contains("msie")) {
-      browserIcon = Icons.getIE24();
-      shortName = "IE";
-    } else if (lcAgent.contains("chrome")) {
-      browserIcon = Icons.getChrome24();
-      shortName = "Chrome";
-    } else if (lcAgent.contains("webkit") || lcAgent.contains("safari")) {
-      browserIcon = Icons.getSafari24();
-      shortName = "Safari";
-    } else if (lcAgent.contains("firefox")) {
-      browserIcon = Icons.getFirefox24();
-      shortName = "FF";
-    }
-    return new BrowserInfo(browserIcon, shortName);
-  }

    private String getTabTitle(URL parsedUrl) {
      String tabTitle = parsedUrl.getPath();
=======================================
--- /trunk/dev/oophm/src/com/google/gwt/dev/OophmHostedModeBase.java    Sat  
Aug 22 16:01:38 2009
+++ /trunk/dev/oophm/src/com/google/gwt/dev/OophmHostedModeBase.java    Wed  
Sep  9 13:11:05 2009
@@ -27,6 +27,7 @@
  import com.google.gwt.dev.shell.OophmSessionHandler;
  import com.google.gwt.dev.shell.ShellMainWindow;
  import com.google.gwt.dev.shell.ShellModuleSpaceHost;
+import com.google.gwt.dev.util.BrowserInfo;
  import com.google.gwt.dev.util.collect.HashMap;
  import com.google.gwt.dev.util.log.AbstractTreeLogger;
  import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
@@ -35,6 +36,7 @@
  import java.awt.Cursor;
  import java.awt.event.WindowAdapter;
  import java.awt.event.WindowEvent;
+import java.io.File;
  import java.io.PrintWriter;
  import java.net.MalformedURLException;
  import java.net.URL;
@@ -185,7 +187,10 @@
        if (!isHeadless()) {
          tabPanel = findModuleTab(userAgent, remoteSocket, url, tabKey,
              moduleName);
-        tab = tabPanel.addModuleSession(maxLevel, moduleName, sessionKey);
+        String agentTag =  
BrowserInfo.getShortName(userAgent).toLowerCase();
+        tab = tabPanel.addModuleSession(maxLevel, moduleName, sessionKey,
+            options.getLogFile(String.format("%s-%s-%d.log", moduleName,
+                agentTag, getNextSessionCounter(options.getLogDir()))));
          logger = tab.getLogger();
          TreeLogger branch = logger.branch(TreeLogger.INFO, "Loading  
module "
              + moduleName);
@@ -276,6 +281,8 @@

    private static final Random RNG = new Random();

+  private static int sessionCounter = 0;
+
    /**
     * Produce a random string that has low probability of collisions.
     *
@@ -447,6 +454,23 @@
    protected final BrowserWidgetHost getBrowserHost() {
      return browserHost;
    }
+
+  protected int getNextSessionCounter(File logdir) {
+    if (sessionCounter == 0) {
+      // first time only, figure out the "last" session count already in  
use
+      for (String filename : logdir.list()) {
+        if (filename.matches("^[A-Za-z0-9_$]*-[a-z]*-[0-9]*.log$")) {
+          String substring = filename.substring(filename.lastIndexOf('-')  
+ 1,
+              filename.length() - 4);
+          int number = Integer.parseInt(substring);
+          if (number > sessionCounter) {
+            sessionCounter = number;
+          }
+        }
+      }
+    }
+    return ++sessionCounter;
+  }

    /**
     * @return the icon to use for the web server tab
@@ -498,10 +522,15 @@
      ImageIcon gwtIcon = loadImageIcon("icon24.png");
      frame = new JFrame("GWT Development Mode");
      tabs = new JTabbedPane();
-    mainWnd = new ShellMainWindow(options.getLogLevel());
+    if (options.alsoLogToFile()) {
+      options.getLogDir().mkdirs();
+    }
+    mainWnd = new ShellMainWindow(options.getLogLevel(),
+        options.getLogFile("main.log"));
      tabs.addTab("Development Mode", gwtIcon, mainWnd, "GWT Development  
mode");
      if (!options.isNoServer()) {
        webServerLog = new WebServerPanel(getPort(), options.getLogLevel(),
+          options.getLogFile("webserver.log"),
            new RestartAction() {
              public void restartServer(TreeLogger logger) {
                try {
=======================================
--- /trunk/dev/oophm/src/com/google/gwt/dev/WebServerPanel.java Tue Jul 28  
21:11:44 2009
+++ /trunk/dev/oophm/src/com/google/gwt/dev/WebServerPanel.java Wed Sep  9  
13:11:05 2009
@@ -21,6 +21,7 @@
  import java.awt.BorderLayout;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
+import java.io.File;

  import javax.swing.JButton;
  import javax.swing.JPanel;
@@ -38,14 +39,15 @@

    private SwingLoggerPanel logWindow;

-  public WebServerPanel(int serverPort, TreeLogger.Type maxLevel) {
-    this(serverPort, maxLevel, null);
+  public WebServerPanel(int serverPort, TreeLogger.Type maxLevel,
+      File logFile) {
+    this(serverPort, maxLevel, logFile, null);
    }

    public WebServerPanel(int serverPort, TreeLogger.Type maxLevel,
-      final RestartAction restartServerAction) {
+      File logFile, final RestartAction restartServerAction) {
      super(new BorderLayout());
-    logWindow = new SwingLoggerPanel(maxLevel);
+    logWindow = new SwingLoggerPanel(maxLevel, logFile);
      if (restartServerAction != null) {
        JPanel panel = new JPanel();
        JButton restartButton = new JButton("Restart Server");
=======================================
--- /trunk/dev/oophm/src/com/google/gwt/dev/shell/log/SwingLoggerPanel.java     
 
Sat Aug 22 16:01:38 2009
+++ /trunk/dev/oophm/src/com/google/gwt/dev/shell/log/SwingLoggerPanel.java     
 
Wed Sep  9 13:11:05 2009
@@ -21,6 +21,8 @@
  import com.google.gwt.dev.shell.CloseButton.Callback;
  import com.google.gwt.dev.shell.log.SwingTreeLogger.LogEvent;
  import com.google.gwt.dev.util.log.AbstractTreeLogger;
+import com.google.gwt.dev.util.log.CompositeTreeLogger;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

  import java.awt.BorderLayout;
  import java.awt.Color;
@@ -35,6 +37,8 @@
  import java.awt.event.ActionListener;
  import java.awt.event.InputEvent;
  import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Enumeration;

@@ -264,7 +268,7 @@

    private boolean disconnected = false;

-  public SwingLoggerPanel(TreeLogger.Type maxLevel) {
+  public SwingLoggerPanel(TreeLogger.Type maxLevel, File logFile) {
      super(new BorderLayout());
      regexFilter = "";
      levelFilter = maxLevel;
@@ -368,8 +372,22 @@
      treeView.setMinimumSize(minSize);
      splitter.setDividerLocation(0.80);
      add(splitter);
-    logger = new SwingTreeLogger(this);
-    logger.setMaxDetail(maxLevel);
+
+    AbstractTreeLogger uiLogger = new SwingTreeLogger(this);
+    AbstractTreeLogger bestLogger = uiLogger;
+    if (logFile != null) {
+      try {
+        PrintWriterTreeLogger fileLogger = new  
PrintWriterTreeLogger(logFile);
+        bestLogger = new CompositeTreeLogger(bestLogger, fileLogger);
+        fileLogger.setMaxDetail(maxLevel);
+        uiLogger.setMaxDetail(maxLevel);
+      } catch (IOException ex) {
+        bestLogger.log(TreeLogger.ERROR, "Can't log to file "
+            + logFile.getAbsolutePath(), ex);
+      }
+    }
+    bestLogger.setMaxDetail(maxLevel);
+    logger = bestLogger;
      KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_F,
          InputEvent.CTRL_DOWN_MASK);
      getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(key, "find");

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

Reply via email to