Index: src/org/netbeans/core/NbErrorManager.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/NbErrorManager.java,v --- src/org/netbeans/core/NbErrorManager.java 10 Jun 2005 18:35:56 -0000 1.57 +++ src/org/netbeans/core/NbErrorManager.java 15 Jul 2005 17:10:59 -0000 @@ -19,6 +19,11 @@ import java.lang.reflect.Method; import java.io.*; import java.util.*; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; +import java.util.logging.StreamHandler; import org.xml.sax.SAXParseException; @@ -30,9 +35,11 @@ * @author Jaroslav Tulach, Jesse Glick */ public final class NbErrorManager extends ErrorManager { + /** Where to log the file */ + private Logger logger; public NbErrorManager() { - this(null, defaultSeverity(), null); + this(null, null); } /** @@ -40,39 +47,79 @@ * @see "#18141" */ NbErrorManager(PrintStream pw) { - this(null, defaultSeverity(), pw); + this(null, streamLogger (pw)); } - private static int defaultSeverity() { - String dsev = System.getProperty("ErrorManager.minimum"); - // use e.g. 17 to avoid logging WARNING messages. - if (dsev != null) { - try { - return Integer.parseInt(dsev); - } catch (NumberFormatException nfe) { - nfe.printStackTrace(); - } - } - // I.e. 2: avoid logging INFORMATIONAL messages. - return ErrorManager.INFORMATIONAL + 1; - } - - private NbErrorManager(String pfx, int sev, PrintStream pw) { - prefix = pfx; - minLogSeverity = sev; - logWriter = pw; - synchronized (uniquifiedIds) { - Integer i = (Integer)uniquifiedIds.get(pfx); - if (i == null) { - uniquifier = 1; - } else { - uniquifier = i.intValue() + 1; + private NbErrorManager(String pfx, Logger logger) { + if (logger == null) { + if (pfx == null) { + pfx = ""; // NOI18N } - uniquifiedIds.put(pfx, new Integer(uniquifier)); + logger = createLogger (pfx); } - //System.err.println("NbErrorManager[" + pfx + " #" + uniquifier + "]: minLogSeverity=" + sev); + this.logger = logger; } + public void flush () { + java.util.logging.Handler[] arr = logger.getHandlers(); + for (int i = 0; i < arr.length; i++) { + arr[i].flush(); + } + } + + private static Logger streamLogger (PrintStream pw) { + Logger log = Logger.getAnonymousLogger(); + StreamHandler s = new StreamHandler ( + pw, NbFormater.FORMATTER + ); + log.setLevel(Level.ALL); + s.setLevel(Level.ALL); + log.addHandler(s); + return log; + } + + private static java.util.logging.Handler streamHandler; + private static synchronized java.util.logging.Handler streamHandler () { + if (streamHandler == null) { + streamHandler = new StreamHandler (System.err, NbFormater.FORMATTER); + } + return streamHandler; + } + + private static java.util.logging.Handler defaultHandler; + private static synchronized java.util.logging.Handler defaultHandler () { + if (defaultHandler != null) return defaultHandler; + + String home = System.getProperty("netbeans.user"); + if (home != null && org.netbeans.core.startup.CLIOptions.isLogging()) { + try { + File f = new File (home + "/var/log"); + f.mkdirs (); + + defaultHandler = new FileHandler (home + "/var/log/messages.log", 1000000, 1, true); + defaultHandler.setFormatter(NbFormater.FORMATTER); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + if (defaultHandler == null) { + defaultHandler = streamHandler(); + } + return defaultHandler; + } + + private static Logger createLogger (String pfx) { + Logger logger = Logger.getLogger (pfx); + logger.addHandler(defaultHandler ()); + if (Boolean.getBoolean("netbeans.logger.console")) { // NOI18N + if (defaultHandler () instanceof FileHandler) { + logger.addHandler (streamHandler ()); + } + } + return logger; + } + /** maps Throwables to java.util.List (Ann) */ private static final Map map = new WeakHashMap (11); @@ -81,46 +128,16 @@ "{0}*********** Exception occurred ************ at {1,time,short} on {1,date,medium}", // NOI18N java.util.Locale.ENGLISH ); - - /** The writer to the log file*/ - private PrintStream logWriter; /** assciates each thread with the lastly notified throwable * (Thread, Reference (Throwable)) */ private static final Map lastException = new WeakHashMap (27); - /** Minimum value of severity to write message to the log file*/ - private final int minLogSeverity; - - /** Prefix preprended to customized loggers, if any. */ - private final String prefix; - - // Make sure two distinct EM impls log differently even with the same name. - private final int uniquifier; // 0 for root EM (prefix == null), else >= 1 - private static final Map uniquifiedIds = new HashMap(20); // Map - static { System.setProperty("sun.awt.exception.handler", "org.netbeans.core.NbErrorManager$AWTHandler"); // NOI18N } - /** Initializes the log stream. - */ - private PrintStream getLogWriter () { - synchronized (this) { - if (logWriter != null) return logWriter; - // to prevent further initializations during TopLogging.getLogOutputStream method - logWriter = System.err; - } - - PrintStream pw = org.netbeans.core.startup.TopLogging.getLogOutputStream(); - - synchronized (this) { - logWriter = pw; - return logWriter; - } - } - public synchronized Throwable annotate ( Throwable t, int severity, String message, String localizedMessage, @@ -177,6 +194,29 @@ public boolean isNotifiable(int severity) { return isLoggable(severity + 1); } + + private static java.util.logging.Level mapSeverity (int severity) { + if (severity == ErrorManager.UNKNOWN) { + return Level.FINEST; + } + + if (severity == ErrorManager.INFORMATIONAL) { + return Level.FINE; + } + + if (severity <= ErrorManager.WARNING) { + return Level.WARNING; + } + + if (severity <= ErrorManager.USER) { + return Level.INFO; + } + + if (severity <= ErrorManager.EXCEPTION) { + return Level.INFO; + } + return Level.SEVERE; + } /** Notifies all the exceptions associated with * this thread. @@ -215,14 +255,16 @@ } } if (wantStackTrace) { - PrintStream log = getLogWriter(); - if (prefix != null) - log.print ("[" + prefix + "] "); // NOI18N - String level = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N - - - log.println (EXC_HEADER.format (new Object[] { level, ex.getDate() })); - ex.printStackTrace(log); + Level level = mapSeverity(ex.getSeverity ()); + if (logger.isLoggable(level)) { + String l = ex.getSeverity() == INFORMATIONAL ? "INFORMATIONAL " : "";// NOI18N + String msg = EXC_HEADER.format (new Object[] { l, ex.getDate() }); + logger.log (level, msg); + StringWriter w = new StringWriter (); + ex.printStackTrace (new PrintWriter (w)); + msg = w.toString (); + logger.log (level, msg); + } } if (ex.getSeverity () > INFORMATIONAL) { @@ -255,44 +297,11 @@ } public void log(int severity, String s) { - if (isLoggable (severity)) { - //System.err.println(toString() + " logging '" + s + "' at " + severity); - PrintStream log = getLogWriter (); - - if (prefix != null) { - boolean showUniquifier; - // Print a unique EM sequence # if there is more than one - // with this name. Shortcut: if the # > 1, clearly there are. - if (uniquifier > 1) { - showUniquifier = true; - } else if (uniquifier == 1) { - synchronized (uniquifiedIds) { - int count = ((Integer)uniquifiedIds.get(prefix)).intValue(); - showUniquifier = count > 1; - } - } else { - throw new IllegalStateException("prefix != null yet uniquifier == 0"); - } - if (showUniquifier) { - log.print ("[" + prefix + " #" + uniquifier + "] "); // NOI18N - } else { - log.print ("[" + prefix + "] "); // NOI18N - } - } - log.println(s); - } + logger.log (mapSeverity(severity), s); } - /** Allows to test whether messages with given severity will be logged - * or not prior to constraction of complicated and time expensive - * logging messages. - * - * @param severity the severity to check - * @return false if the next call to log method with the same severity will - * discard the message - */ public boolean isLoggable (int severity) { - return severity >= minLogSeverity; + return logger.isLoggable (mapSeverity(severity)); } @@ -301,29 +310,8 @@ * a hierarchy. */ public final ErrorManager getInstance(String name) { - String pfx = (prefix == null) ? name : prefix + '.' + name; - int sev = minLogSeverity; - String prop = pfx; - while (prop != null) { - String value = System.getProperty (prop); - //System.err.println ("Trying; prop=" + prop + " value=" + value); - if (value != null) { - try { - sev = Integer.parseInt (value); - } catch (NumberFormatException nfe) { - notify (WARNING, nfe); - } - break; - } else { - int idx = prop.lastIndexOf ('.'); - if (idx == -1) - prop = null; - else - prop = prop.substring (0, idx); - } - } - //System.err.println ("getInstance: prefix=" + prefix + " mls=" + minLogSeverity + " name=" + name + " prefix2=" + newEM.prefix + " mls2=" + newEM.minLogSeverity); - return new NbErrorManager(pfx, sev, logWriter); + String pfx = logger.getName() + '.' + name; + return new NbErrorManager(pfx, null); } /** Method (or field) names in various exception classes which give @@ -474,7 +462,7 @@ } public String toString() { - return super.toString() + "<" + prefix + "," + minLogSeverity + ">"; // NOI18N + return super.toString() + "<" + logger + ">"; // NOI18N } /** Implementation of annotation interface. @@ -849,4 +837,44 @@ ErrorManager.getDefault().notify((ERROR << 1), t); } } + + /** Modified formater for use in NetBeans. + */ + private static final class NbFormater extends java.util.logging.Formatter { + private static String lineSeparator = System.getProperty ("line.separator"); // NOI18N + static java.util.logging.Formatter FORMATTER = new NbFormater (); + + + public String format(java.util.logging.LogRecord record) { + StringBuffer sb = new StringBuffer(); + sb.append(record.getLevel().getName()); + addLoggerName (sb, record); + sb.append(": "); + String message = formatMessage(record); + sb.append(message); + sb.append(lineSeparator); + if (record.getThrown() != null) { + try { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + record.getThrown().printStackTrace(pw); + pw.close(); + sb.append(sw.toString()); + } catch (Exception ex) { + } + } + return sb.toString(); + } + + private static void addLoggerName (StringBuffer sb, java.util.logging.LogRecord record) { + String name = record.getLoggerName (); + if (!"".equals (name)) { + if (record.getSourceClassName() != null) { + sb.append(record.getSourceClassName()); + } else { + sb.append(record.getLoggerName()); + } + } + } + } } Index: src/org/netbeans/core/NbTopManager.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/NbTopManager.java,v --- src/org/netbeans/core/NbTopManager.java 4 Jun 2005 05:11:07 -0000 1.216 +++ src/org/netbeans/core/NbTopManager.java 15 Jul 2005 17:11:02 -0000 @@ -26,6 +26,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.StringTokenizer; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.ChangeEvent; @@ -184,7 +185,7 @@ // Did not work. Toolkit.getDefaultToolkit().beep(); } - + /** * Implementation of URL displayer, which shows documents in the configured web browser. */ Index: src/org/netbeans/core/NonGuiMain.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/NonGuiMain.java,v --- src/org/netbeans/core/NonGuiMain.java 4 Jun 2005 05:11:07 -0000 1.21 +++ src/org/netbeans/core/NonGuiMain.java 15 Jul 2005 17:11:07 -0000 @@ -23,7 +23,6 @@ import java.lang.reflect.*; import java.text.MessageFormat; import org.netbeans.core.startup.CLIOptions; -import org.netbeans.core.startup.TopLogging; import org.openide.*; import org.openide.explorer.*; @@ -89,7 +88,7 @@ String sysInfo; sysInfo = NbBundle.getBundle(org.netbeans.core.NonGui.class).getString ("CTL_System_info"); // NOI18N out.println("-- " + sysInfo + " ----------------------------------------------------------------"); // NOI18N - TopLogging.printSystemInfo(out); + org.netbeans.core.startup.CLIOptions.printSystemInfo(out); out.println("-------------------------------------------------------------------------------"); // NOI18N } @@ -344,7 +343,6 @@ startGui(tmpArgs); } else { new CLIOptions().cli(tmpArgs); - CLIOptions.initialize(); } if (showInfo) { Index: src/org/netbeans/core/ui/ProductInformationPanel.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/ui/ProductInformationPanel.java,v --- src/org/netbeans/core/ui/ProductInformationPanel.java 7 Jun 2005 18:08:15 -0000 1.26 +++ src/org/netbeans/core/ui/ProductInformationPanel.java 15 Jul 2005 17:11:10 -0000 @@ -30,7 +30,6 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; -import org.netbeans.core.startup.TopLogging; import org.openide.filesystems.FileUtil; import org.openide.util.Enumerations; import org.openide.util.NbBundle; Index: startup/src/org/netbeans/core/startup/CLIOptions.java =================================================================== RCS file: /cvs/core/startup/src/org/netbeans/core/startup/CLIOptions.java,v --- startup/src/org/netbeans/core/startup/CLIOptions.java 4 Jun 2005 05:11:42 -0000 1.1 +++ startup/src/org/netbeans/core/startup/CLIOptions.java 15 Jul 2005 17:11:18 -0000 @@ -18,7 +18,9 @@ import java.beans.*; import java.io.*; import java.security.*; +import java.text.DateFormat; import java.util.Locale; +import java.util.StringTokenizer; import javax.swing.*; import javax.swing.border.*; @@ -37,14 +39,12 @@ /** The flag whether to create the log - can be set via -nologging * command line option */ - protected static boolean noLogging = false; + private static boolean noLogging = false; /** The flag whether to show the Splash screen on the startup */ - protected static boolean noSplash = false; - /** The Class that logs the IDE events to a log file */ - protected static TopLogging logger; + private static boolean noSplash = false; /* The class of the UIManager to be used for netbeans - can be set by command-line argument -ui */ - protected static Class uiClass; + static Class uiClass; /* The size of the fonts in the UI - 0 pt, the default value is set in NbTheme (for Metal L&F), for other L&Fs is set in the class Main. The value can be changed in Themes.xml in system directory or by command-line argument -fontsize */ protected static int uiFontSize = 0; @@ -188,20 +188,6 @@ return 0; } - /** Initializes logging etc. - */ - public static void initialize() { - if (!noLogging) { - try { - logger = new TopLogging(getLogDir()); - } catch (IOException e) { - System.err.println("Cannot create log file. Logging disabled."); // NOI18N - e.printStackTrace(); - } - } - StartLog.logProgress("TopLogging initialized"); // NOI18N - } - protected void usage(PrintWriter w) { w.println("Core options:"); w.println(" --laf use given LookAndFeel class instead of the default"); @@ -219,6 +205,79 @@ private static String getString (String key) { return NbBundle.getMessage (CLIOptions.class, key); } + + /** print the status line. + */ + public static void initialize() { + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH); + java.util.Date date = new java.util.Date(); + + PrintStream logPrintStream = System.err; + logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N + logPrintStream.println(">Log Session: "+ df.format (date)); // NOI18N + logPrintStream.println(">System Info: "); // NOI18N + printSystemInfo(logPrintStream); + logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N + } + + public static void printSystemInfo(PrintStream ps) { + String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N + String currentVersion = NbBundle.getMessage(CLIOptions.class, "currentVersion", buildNumber ); + ps.println(" Product Version = " + currentVersion); // NOI18N + ps.println(" Operating System = " + System.getProperty("os.name", "unknown") + + " version " + System.getProperty("os.version", "unknown") + + " running on " + System.getProperty("os.arch", "unknown")); + ps.println(" Java; VM; Vendor = " + System.getProperty("java.version", "unknown") + "; " + + System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " + + System.getProperty("java.vendor", "unknown")); + //ps.println(" Java Vendor URL = " + System.getProperty("java.vendor.url", "unknown")); + ps.println(" Java Home = " + System.getProperty("java.home", "unknown")); + //ps.println(" Java Class Version = " + System.getProperty("java.class.version", "unknown")); + ps.print (" System Locale; Encod. = " + Locale.getDefault()); // NOI18N + String branding = NbBundle.getBranding (); + if (branding != null) { + ps.print(" (" + branding + ")"); // NOI18N + } + ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N + ps.println(" Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " + + System.getProperty("user.dir", "unknown")); + ps.println(" IDE Install; User Dir = " + CLIOptions.getHomeDir () + "; " + // NOI18N + CLIOptions.getUserDir ()); // NOI18N + //ps.println(" System Directory = " + Main.getSystemDir ()); // NOI18N + ps.println(" CLASSPATH = " + System.getProperty("java.class.path", "unknown")); // NOI18N + ps.println(" Boot & ext classpath = " + createBootClassPath()); // NOI18N + ps.println(" Dynamic classpath = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N + } + + // Copied from NbClassPath: + private static String createBootClassPath() { + // boot + String boot = System.getProperty("sun.boot.class.path"); // NOI18N + StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer()); + + // std extensions + String extensions = System.getProperty("java.ext.dirs"); // NOI18N + if (extensions != null) { + for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) { + File dir = new File(st.nextToken()); + File[] entries = dir.listFiles(); + if (entries != null) { + for (int i = 0; i < entries.length; i++) { + String name = entries[i].getName().toLowerCase(Locale.US); + if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N + if (sb.length() > 0) { + sb.append(File.pathSeparatorChar); + } + sb.append(entries[i].getPath()); + } + } + } + } + } + + return sb.toString(); + } + // // Directory functions @@ -313,5 +372,13 @@ public static int getFontSize () { return uiFontSize; + } + + public static boolean isLogging() { + return !noLogging; + } + + static boolean isSplash() { + return !noSplash; } } Index: startup/src/org/netbeans/core/startup/Main.java =================================================================== RCS file: /cvs/core/startup/src/org/netbeans/core/startup/Main.java,v --- startup/src/org/netbeans/core/startup/Main.java 7 Jun 2005 04:45:59 -0000 1.2 +++ startup/src/org/netbeans/core/startup/Main.java 15 Jul 2005 17:11:21 -0000 @@ -60,7 +60,7 @@ */ public static void setSplashMaxSteps(int maxSteps) { - if (noBar || CLIOptions.noSplash || splash == null) + if (noBar || !CLIOptions.isSplash() || splash == null) return; splash.setMaxSteps(maxSteps); } @@ -69,7 +69,7 @@ */ public static void addToSplashMaxSteps(int steps) { - if (noBar || CLIOptions.noSplash || splash == null) + if (noBar || !CLIOptions.isSplash() || splash == null) return; splash.addToMaxSteps(steps); } @@ -78,7 +78,7 @@ */ public static void addAndSetSplashMaxSteps(int steps) { - if (noBar || CLIOptions.noSplash || splash == null) + if (noBar || !CLIOptions.isSplash() || splash == null) return; splash.addAndSetMaxSteps(steps); } @@ -94,7 +94,7 @@ */ public static void incrementSplashProgressBar(int steps) { - if (noBar || CLIOptions.noSplash || splash == null) + if (noBar || !CLIOptions.isSplash() || splash == null) return; splash.increment(steps); } @@ -283,8 +283,7 @@ CLIOptions.initialize(); StartLog.logProgress ("Command line parsed"); // NOI18N - - + // 5. initialize GUI StartLog.logStart ("XML Factories"); //NOI18N @@ -403,7 +402,7 @@ * during startup (Import, Setup). It makes splash screen visible again. */ protected static void showSplash () { - if (!CLIOptions.noSplash) { + if (!!CLIOptions.isSplash()) { if (splash != null) { if (Splash.isVisible(splash)) return; Index: startup/src/org/netbeans/core/startup/NbEvents.java =================================================================== RCS file: /cvs/core/startup/src/org/netbeans/core/startup/NbEvents.java,v --- startup/src/org/netbeans/core/startup/NbEvents.java 4 Jun 2005 05:11:46 -0000 1.1 +++ startup/src/org/netbeans/core/startup/NbEvents.java 15 Jul 2005 17:11:21 -0000 @@ -18,6 +18,8 @@ import java.io.File; import java.text.Collator; import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.JOptionPane; import org.openide.ErrorManager; import org.openide.filesystems.FileObject; @@ -74,7 +76,7 @@ } else if (message == FINISH_ENABLE_MODULES) { List modules = (List)args[0]; if (! modules.isEmpty()) { - System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules")); + Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_finish_enable_modules")); dumpModulesList(modules); } setStatusText( @@ -209,10 +211,10 @@ Util.err.log(ErrorManager.WARNING, "Warning: the extension " + (File)args[0] + " may be multiply loaded by modules: " + (Set/**/)args[1] + "; see: http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/classpath.html#class-path"); // NOI18N } else if (message == MISSING_JAR_FILE) { File jar = (File)args[0]; - System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath())); + Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_missing_jar_file", jar.getAbsolutePath())); } else if (message == CANT_DELETE_ENABLED_AUTOLOAD) { Module m = (Module)args[0]; - System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName())); + Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_cant_delete_enabled_autoload", m.getDisplayName())); } else if (message == MISC_PROP_MISMATCH) { // XXX does this really need to be logged to the user? // Or should it just be sent quietly to the log file? @@ -220,10 +222,10 @@ String prop = (String)args[1]; Object onDisk = (Object)args[2]; Object inMem = (Object)args[3]; - System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem})); + Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_misc_prop_mismatch", new Object[] {m.getDisplayName(), prop, onDisk, inMem})); } else if (message == PATCH) { File f = (File)args[0]; - System.err.println(NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath())); + Logger.getLogger("").log (Level.INFO, NbBundle.getMessage(NbEvents.class, "TEXT_patch", f.getAbsolutePath())); } // XXX other messages? } @@ -259,13 +261,13 @@ // #32331: use platform-specific newlines buf.append(lineSep); } - System.err.print(buf.toString()); + Logger.getLogger("").log (Level.INFO, buf.toString()); } private void notify(String text, boolean warn) { if (Boolean.getBoolean("netbeans.full.hack")) { // NOI18N // #21773: interferes with automated GUI testing. - System.err.println(text); + Logger.getLogger("").log (Level.INFO, text); } else { // Normal - display dialog. int type = warn ? JOptionPane.WARNING_MESSAGE : JOptionPane.INFORMATION_MESSAGE; Index: startup/src/org/netbeans/core/startup/TopLogging.java =================================================================== RCS file: startup/src/org/netbeans/core/startup/TopLogging.java --- startup/src/org/netbeans/core/startup/TopLogging.java 4 Jun 2005 05:11:50 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,288 +0,0 @@ -/* - * Sun Public License Notice - * - * The contents of this file are subject to the Sun Public License - * Version 1.0 (the "License"). You may not use this file except in - * compliance with the License. A copy of the License is available at - * http://www.sun.com/ - * - * The Original Code is NetBeans. The Initial Developer of the Original - * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun - * Microsystems, Inc. All Rights Reserved. - */ - -package org.netbeans.core.startup; - -import java.io.*; -import java.text.DateFormat; -import java.util.Locale; -import java.util.StringTokenizer; - -import org.openide.util.NbBundle; -import org.openide.util.RequestProcessor; - -/** - * A class that provides logging facility for the IDE - once instantiated, it - * redirects the System.err into a log file. - * @author Ian Formanek, Ales Novak, Jesse Glick - */ -public class TopLogging -{ - /** The name of the log file */ - public static final String LOG_FILE_NAME = "messages.log"; // NOI18N - - private static final boolean disabledConsole = ! Boolean.getBoolean("netbeans.logger.console"); // NOI18N - - private final PrintStream logPrintStream; - - private static TopLogging topLogging; - - /** Maximal size of log file.*/ - private static final long LOG_MAX_SIZE = - Long.getLong("org.netbeans.core.TopLogging.LOG_MAX_SIZE", 0x40000).longValue(); // NOI18N - - /** Number of old log files that are maintained.*/ - private static final int LOG_COUNT = - Integer.getInteger("org.netbeans.core.TopLogging.LOG_COUNT", 3).intValue(); // NOI18N - - - /** Creates a new TopLogging - redirects the System.err to a log file. - * @param logDir A directory for the log file - */ - TopLogging (String logDir) throws IOException { - topLogging = this; - - File logFileDir = new File (logDir); - if (! logFileDir.exists () && ! logFileDir.mkdirs ()) { - throw new IOException ("Cannot make directory to contain log file"); // NOI18N - } - File logFile = createLogFile (logFileDir, LOG_FILE_NAME); - if ((logFile.exists() && !logFile.canWrite()) || logFile.isDirectory()) { - throw new IOException ("Cannot write to file"); // NOI18N - } - - OutputStream log = new BufferedOutputStream(new FileOutputStream(logFile.getAbsolutePath(), true)); - DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH); - java.util.Date date = new java.util.Date(); - - final PrintStream stderr = System.err; - logPrintStream = new PrintStream(new StreamDemultiplexor(stderr, log), false, "UTF-8"); // NOI18N - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - logPrintStream.flush(); // #31519 - logPrintStream.close(); - } - }); - logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N - logPrintStream.println(">Log Session: "+ df.format (date)); // NOI18N - logPrintStream.println(">System Info: "); // NOI18N - printSystemInfo(logPrintStream); - logPrintStream.println("-------------------------------------------------------------------------------"); // NOI18N - - System.setErr(logPrintStream); - } - - private static TopLogging getDefault() { - if (topLogging == null) { - try { - new TopLogging(CLIOptions.getLogDir()); - } catch (IOException x) { - org.openide.ErrorManager.getDefault().notify(x); - } - } - return topLogging; - } - - /** This method limits size of log files. There is kept: actual log file - * and old log files. This method prevents from growing log file infinitely.*/ - private static File createLogFile (File parent, String chld) { - long firstModified = 0; - File renameTo = null; - File retFile = new File (parent, chld); - - if (!retFile.exists() || retFile.length() < LOG_MAX_SIZE) - return retFile; - - for (int i = 1; i < LOG_COUNT;i++) { - String logName = chld + "."+i; // NOI18N - File logFile = new File (parent, logName); - - if (!logFile.exists()) { - renameTo = logFile; - break; - } - - long logModif = logFile.lastModified(); - if ((firstModified == 0 || logModif < firstModified) && logModif > 0) { - firstModified = logModif; - renameTo = logFile; - } - } - - if (renameTo != null) { - if (renameTo.exists()) renameTo.delete(); - retFile.renameTo(renameTo); - } - - return retFile; - } - - public static void printSystemInfo(PrintStream ps) { - String buildNumber = System.getProperty ("netbeans.buildnumber"); // NOI18N - String currentVersion = NbBundle.getMessage(TopLogging.class, "currentVersion", buildNumber ); - ps.println(" Product Version = " + currentVersion); // NOI18N - ps.println(" Operating System = " + System.getProperty("os.name", "unknown") - + " version " + System.getProperty("os.version", "unknown") - + " running on " + System.getProperty("os.arch", "unknown")); - ps.println(" Java; VM; Vendor = " + System.getProperty("java.version", "unknown") + "; " + - System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " + - System.getProperty("java.vendor", "unknown")); - //ps.println(" Java Vendor URL = " + System.getProperty("java.vendor.url", "unknown")); - ps.println(" Java Home = " + System.getProperty("java.home", "unknown")); - //ps.println(" Java Class Version = " + System.getProperty("java.class.version", "unknown")); - ps.print (" System Locale; Encod. = " + Locale.getDefault()); // NOI18N - String branding = NbBundle.getBranding (); - if (branding != null) { - ps.print(" (" + branding + ")"); // NOI18N - } - ps.println("; " + System.getProperty("file.encoding", "unknown")); // NOI18N - ps.println(" Home Dir; Current Dir = " + System.getProperty("user.home", "unknown") + "; " + - System.getProperty("user.dir", "unknown")); - ps.println(" IDE Install; User Dir = " + CLIOptions.getHomeDir () + "; " + // NOI18N - CLIOptions.getUserDir ()); // NOI18N - //ps.println(" System Directory = " + Main.getSystemDir ()); // NOI18N - ps.println(" CLASSPATH = " + System.getProperty("java.class.path", "unknown")); // NOI18N - ps.println(" Boot & ext classpath = " + createBootClassPath()); // NOI18N - ps.println(" Dynamic classpath = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); // NOI18N - } - - // Copied from NbClassPath: - private static String createBootClassPath() { - // boot - String boot = System.getProperty("sun.boot.class.path"); // NOI18N - StringBuffer sb = (boot != null ? new StringBuffer(boot) : new StringBuffer()); - - // std extensions - String extensions = System.getProperty("java.ext.dirs"); // NOI18N - if (extensions != null) { - for (StringTokenizer st = new StringTokenizer(extensions, File.pathSeparator); st.hasMoreTokens();) { - File dir = new File(st.nextToken()); - File[] entries = dir.listFiles(); - if (entries != null) { - for (int i = 0; i < entries.length; i++) { - String name = entries[i].getName().toLowerCase(Locale.US); - if (name.endsWith(".zip") || name.endsWith(".jar")) { // NOI18N - if (sb.length() > 0) { - sb.append(File.pathSeparatorChar); - } - sb.append(entries[i].getPath()); - } - } - } - } - } - - return sb.toString(); - } - - protected void finalize() throws Throwable { - logPrintStream.flush(); - logPrintStream.close(); - } - - /** @since JST-PENDING needed by NbErrorManager */ - public static PrintStream getLogOutputStream() { - if (System.getProperty("netbeans.user") == null) { // NOI18N - // No user directory. E.g. from . Skip ide.log. - return System.err; - } - return TopLogging.getDefault().logPrintStream; - } - - private static final class StreamDemultiplexor extends OutputStream implements Runnable { - - /** task to flush the log file, or null */ - private RequestProcessor.Task logFlushTask; - - /** processor in which to flush them */ - private static final RequestProcessor RP = new RequestProcessor("Flush ide.log"); // NOI18N - - /** a lock for flushing */ - private static final Object FLUSH_LOCK = new String("org.netbeans.core.TopLogging.StreamDemultiplexor.FLUSH_LOCK"); // NOI18N - - /** delay for flushing */ - private static final int FLUSH_DELAY = Integer.getInteger("netbeans.logger.flush.delay", 15000).intValue(); // NOI18N - - private final OutputStream stderr; - private final OutputStream log; - - StreamDemultiplexor(PrintStream stderr, OutputStream log) { - this.stderr = stderr; - this.log = log; - } - - public void write(int b) throws IOException { - log.write(b); - if (! disabledConsole) - stderr.write(b); - flushLog(); - } - - public void write(byte b[]) throws IOException { - log.write(b); - if (! disabledConsole) stderr.write(b); - flushLog(); - } - - public void write(byte b[], - int off, - int len) - throws IOException { - log.write(b, off, len); - if (! disabledConsole) stderr.write(b, off, len); - flushLog(); - } - - public void flush() throws IOException { - log.flush(); - stderr.flush(); - } - - public void close() throws IOException { - log.close(); - stderr.close(); - } - - /** - * Flush the log file asynch. - * Waits for e.g. 15 seconds after the first write. - * Note that this is only a delay to force a flush; if there is a lot - * of content, the buffer will fill up and it may have been written out - * long before. This just catches any trailing content. - * @see "#31519" - */ - private void flushLog() { - synchronized (FLUSH_LOCK) { - if (logFlushTask == null) { - logFlushTask = RP.create(this); - logFlushTask.schedule(FLUSH_DELAY); - } - } - } - - /** - * Flush log messages periodically. - */ - public void run() { - synchronized (FLUSH_LOCK) { - try { - flush(); - } catch (IOException e) { - e.printStackTrace(); - } - logFlushTask = null; - } - } - - } -} Index: test/unit/src/org/netbeans/core/NbErrorManagerTest.java =================================================================== RCS file: /cvs/core/test/unit/src/org/netbeans/core/NbErrorManagerTest.java,v --- test/unit/src/org/netbeans/core/NbErrorManagerTest.java 10 Jun 2005 18:35:56 -0000 1.6 +++ test/unit/src/org/netbeans/core/NbErrorManagerTest.java 15 Jul 2005 17:11:22 -0000 @@ -40,12 +40,32 @@ private NbErrorManager err; private ByteArrayOutputStream w; protected void setUp() throws Exception { - w = new ByteArrayOutputStream(); + clearWorkDir(); + System.setProperty("netbeans.user", getWorkDirPath()); + + w = new ByteArrayOutputStream() { + public String toString () { + err.flush(); + return super.toString (); + } + }; err = new NbErrorManager(new PrintStream(w)); } public void testEMFound() throws Exception { - assertEquals(NbErrorManager.class, Lookup.getDefault().lookup(ErrorManager.class).getClass()); + ErrorManager em = (ErrorManager)Lookup.getDefault ().lookup (ErrorManager.class); + assertNotNull ("em", em); + assertEquals(NbErrorManager.class, em.getClass()); + + em.log (em.EXCEPTION, "Exception!"); + + File f = new File (new File (new File (getWorkDirPath (), "var"), "log"), "messages.log"); + if (!f.exists ()) { + fail ( + "Cannot find messages.log, parent contains just: " + + java.util.Arrays.asList (f.getParentFile().list()) + ); + } } public void testBasicNotify() throws Exception { @@ -56,7 +76,7 @@ assertTrue(s.indexOf("java.lang.NullPointerException: unloc msg") != -1); assertTrue(s.indexOf("testBasicNotify") != -1); } - +/* public void testLog() throws Exception { assertFalse(err.isLoggable(ErrorManager.INFORMATIONAL)); err.log("some msg"); @@ -79,7 +99,7 @@ assertTrue(s.indexOf("sub msg #2") != -1); assertTrue(s.indexOf("quux.hoho.yaya") != -1); } - +*/ /** @see "#15611" */ public void testNestedThrowables() throws Exception { NullPointerException npe = new NullPointerException("unloc msg");