alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 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-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.lib.jmi.util;

import java.io.*;
import java.util.*;
import java.util.HashSet;
import java.util.Set;
import org.openide.ErrorManager;

/** Logger utility using org.openide.ErrorManager to log messages.
 *
 * @author Martin Matula
 */
public class Logger extends ErrorManager {
    private static final String PROP_MIN_SEVERITY = "org.netbeans.lib.jmi.Logger";
    private static final String PROP_LOG_FILE = "org.netbeans.lib.jmi.Logger.fileName";
    
    private static ErrorManager defaultManager = null;
    
    /** maps Throwables to java.util.List (annotations) */
    private static final Map map = new WeakHashMap (11);

    /** The writer to the log file*/
    private final LogWriter logWriter;
    
    /** Minimum value of severity to write message to the log file*/
    private final int minLogSeverity;

    /** Logger name */
    private final String name;
    
    public static synchronized ErrorManager getDefault() {
        if (defaultManager == null) {
            defaultManager = ErrorManager.getDefault().getInstance(PROP_MIN_SEVERITY);
        }
        return defaultManager;
    }

    public Logger() {
        name = null;
        minLogSeverity = ErrorManager.INFORMATIONAL + 1;
        String fileName = System.getProperty(PROP_LOG_FILE);
        if (fileName == null) {
            logWriter = new LogWriter(System.err);
        } else {
            if (fileName.equals("")) {
                logWriter = new LogWriter();
            } else {
                LogWriter writer;
                try {
                    writer = new LogWriter(new FileOutputStream(fileName));
                } catch (FileNotFoundException e) {
                    writer = new LogWriter(System.err);
                    notify(e);
                }
                logWriter = writer;
            }
        }
    }
    
    public Logger(String name, int minSeverity, LogWriter logWriter) {
        this.name = name;
        this.minLogSeverity = minSeverity;
        this.logWriter = logWriter;
    }
    
    /** Annotates given exception with given values. All the
     * previous annotations are kept and this new one is added at
     * the top of the annotation stack (index 0 of the annotation
     * array).
     *
     * @param t the exception
     * @param severity integer describing severity, e.g. {@link #EXCEPTION}
     * @param message message to attach to the exception or null
     * @param localizedMessage localized message for the user or null
     * @param stackTrace exception representing the stack trace or null
     * @param date date or null
     * @return the same exception t (as a convenience)
     *
     */
    public Throwable annotate(Throwable t, int severity, String message, String localizedMessage, Throwable stackTrace, Date date) {
        List annotations = (List) map.get(t);
        
        if (annotations == null) {
            annotations = new ArrayList();
            map.put(t, annotations);
        }

        annotations.add(0, new Ann(severity, message, localizedMessage, stackTrace, date));

        return t;
    }
    
    /** Associates annotations with an exception.
     *
     * @param t the exception
     * @param arr array of annotations (or null)
     * @return the same exception t (as a convenience)
     *
     */
    public Throwable attachAnnotations(Throwable t, Annotation[] arr) {
        List annotations = (List) map.get(t);
        if (annotations == null) {
            annotations = new ArrayList(arr.length + 5);
            map.put(t, annotations);
        }
        annotations.addAll(0, Arrays.asList(arr));
        return t;
    }
    
    /** Finds annotations associated with a given exception.
     * @param t the exception
     * @return array of annotations or null
     *
     */
    public Annotation[] findAnnotations(Throwable t) {
        List annotations = (List) map.get(t);
        if (annotations != null) {
            return (Annotation[]) annotations.toArray(new Annotation[annotations.size()]);
        } else {
            return null;
        }
    }
    
    /** Returns an instance with given name.
     * 

By convention, you can name error managers the same as packages (or classes) * they are designed to report information from. * For example, org.netbeans.modules.mymodule.ComplicatedParser. *

The error manager implementation should provide some way of configuring e.g. * the logging level for error managers of different names. For example, in the basic * NetBeans core implementation, you can define a system property with the same name * as the future error manager (or a package prefix of it) whose value is the numeric * logging level (e.g. -J-Dorg.netbeans.modules.mymodule.ComplicatedParser=0 * to log everything). Other implementations may have quite different ways of configuring * the error managers. * @param name the desired identifying name * @return a new error manager keyed off of that name * */ public ErrorManager getInstance(String name) { String loggerName = (this.name == null) ? name : this.name + "." + name; String prop = loggerName; int minLogSeverity = this.minLogSeverity; while (prop != null) { String value = System.getProperty(prop); if (value != null) { try { minLogSeverity = 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); } } return new Logger(loggerName, minLogSeverity, logWriter); } /** Logs the message to a file and (possibly) tells the user. * @param severity the severity to be applied (overrides default) * @param s the log message * */ public void log(int severity, String s) { if (isLoggable(severity)) { if (name != null) { logWriter.printlnIndented("[" + name + "] " + s); } else { logWriter.printlnIndented(s); } logWriter.flush(); } } public boolean isLoggable(int severity) { return severity >= minLogSeverity; } public boolean isNotifiable(int severity) { return isLoggable(severity + 1); } /** Prints the exception to the log file together with its annotations recursively * @param severity the severity to be applied to the exception (overrides default), e.g. {@link #EXCEPTION} * @param t the exception to notify * */ public void notify(int severity, Throwable t) { notify(severity, t, new HashSet()); } private void notify(int severity, Throwable t, Set visited) { if (!isNotifiable(severity)) return; if (!visited.add(t)) return; Annotation[] ann = findAnnotations(t); String level = (severity == INFORMATIONAL ? "INFORMATIONAL " : ""); if (name != null) { level = "[" + name + "] " + level; } logWriter.printlnIndented(level + "*********** Exception occurred ************ at " + new Date()); t.printStackTrace(logWriter); if (ann != null) { logWriter.printlnIndented("ANNOTATIONS:"); logWriter.indent(); for (int i = 0; i < ann.length; i++) { logAnnotation(ann[i], visited); } logWriter.unindent(); } logWriter.flush(); } private void logAnnotation(Annotation ann, Set visited) { StringBuffer sb = new StringBuffer(100); sb.append("[" + ann.getDate() + "] "); if (ann.getSeverity() == INFORMATIONAL) { sb.append("INFORMATIONAL "); } if (ann.getLocalizedMessage() == null) { if (ann.getMessage() == null) { if (ann.getStackTrace() != null) { sb.append("Exception occurred:"); } } else { sb.append(ann.getMessage()); } } else { sb.append(ann.getLocalizedMessage()); } logWriter.printlnIndented(sb.toString()); if (ann.getStackTrace() != null) { // ann.getStackTrace().printStackTrace(logWriter); notify(ann.getSeverity(), ann.getStackTrace(), visited); } } /** Implementation of annotation interface. */ private static class Ann implements Annotation { private final int severity; private final String message; private final String localizedMessage; private final Throwable stackTrace; private final Date date; /** Constructor. */ public Ann (int severity, String message, String localizedMessage, Throwable stackTrace, Date date) { this.severity = severity; this.message = message; this.localizedMessage = localizedMessage; this.stackTrace = stackTrace; this.date = date; } /** Non-localized message. * @return associated message or null */ public String getMessage() { return message; } /** Localized message. * @return message to be presented to the user or null */ public String getLocalizedMessage() { return localizedMessage; } /** Stack trace. The stack trace should locate the method * and possition in the method where error occured. * * @return exception representing the location of error or null */ public Throwable getStackTrace() { return stackTrace; } /** Date when the exception occured. * @return the date or null */ public Date getDate() { return date; } /** Severity of the exception. * @return number representing the severity */ public int getSeverity() { return severity; } } // end of Ann private static class EmptyStream extends OutputStream { public void write(int b) throws IOException{ } } private static class LogWriter extends PrintWriter { private static final String TAB = " "; private int indent = 0; public LogWriter() { super(new EmptyStream()); } public LogWriter(OutputStream stream) { super(stream); } public void printIndented(String str) { for (int i = 0; i < indent; i++) { print(TAB); } print(str); } public void printlnIndented(String str) { print(str); println(); } public void indent() { indent++; } public void unindent() { indent--; } } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.