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 -~----------~----~----~----~------~----~------~--~---
