KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > jmi > util > Logger


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.lib.jmi.util;
20
21 import java.io.*;
22 import java.util.*;
23 import java.util.HashSet JavaDoc;
24 import java.util.Set JavaDoc;
25 import org.openide.ErrorManager;
26
27 /** Logger utility using org.openide.ErrorManager to log messages.
28  *
29  * @author Martin Matula
30  */

31 public class Logger extends ErrorManager {
32     private static final String JavaDoc PROP_MIN_SEVERITY = "org.netbeans.lib.jmi.Logger";
33     private static final String JavaDoc PROP_LOG_FILE = "org.netbeans.lib.jmi.Logger.fileName";
34
35     private static ErrorManager defaultManager = null;
36
37     /** maps Throwables to java.util.List (annotations) */
38     private static final Map map = new WeakHashMap (11);
39
40     /** The writer to the log file*/
41     private final LogWriter logWriter;
42     
43     /** Minimum value of severity to write message to the log file*/
44     private final int minLogSeverity;
45
46     /** Logger name */
47     private final String JavaDoc name;
48     
49     public static synchronized ErrorManager getDefault() {
50         if (defaultManager == null) {
51             defaultManager = ErrorManager.getDefault().getInstance(PROP_MIN_SEVERITY);
52         }
53         return defaultManager;
54     }
55
56     public Logger() {
57         name = null;
58         minLogSeverity = ErrorManager.INFORMATIONAL + 1;
59         String JavaDoc fileName = System.getProperty(PROP_LOG_FILE);
60         if (fileName == null) {
61             logWriter = new LogWriter(System.err);
62         } else {
63             if (fileName.equals("")) {
64                 logWriter = new LogWriter();
65             } else {
66                 LogWriter writer;
67                 try {
68                     writer = new LogWriter(new FileOutputStream(fileName));
69                 } catch (FileNotFoundException e) {
70                     writer = new LogWriter(System.err);
71                     notify(e);
72                 }
73                 logWriter = writer;
74             }
75         }
76     }
77     
78     public Logger(String JavaDoc name, int minSeverity, LogWriter logWriter) {
79         this.name = name;
80         this.minLogSeverity = minSeverity;
81         this.logWriter = logWriter;
82     }
83     
84     /** Annotates given exception with given values. All the
85      * previous annotations are kept and this new one is added at
86      * the top of the annotation stack (index 0 of the annotation
87      * array).
88      *
89      * @param t the exception
90      * @param severity integer describing severity, e.g. {@link #EXCEPTION}
91      * @param message message to attach to the exception or <code>null</code>
92      * @param localizedMessage localized message for the user or <code>null</code>
93      * @param stackTrace exception representing the stack trace or <code>null</code>
94      * @param date date or <code>null</code>
95      * @return the same exception <code>t</code> (as a convenience)
96      *
97      */

98     public Throwable JavaDoc annotate(Throwable JavaDoc t, int severity, String JavaDoc message, String JavaDoc localizedMessage, Throwable JavaDoc stackTrace, Date date) {
99         List annotations = (List) map.get(t);
100         
101         if (annotations == null) {
102             annotations = new ArrayList();
103             map.put(t, annotations);
104         }
105
106         annotations.add(0, new Ann(severity, message, localizedMessage, stackTrace, date));
107
108         return t;
109     }
110     
111     /** Associates annotations with an exception.
112      *
113      * @param t the exception
114      * @param arr array of annotations (or <code>null</code>)
115      * @return the same exception <code>t</code> (as a convenience)
116      *
117      */

118     public Throwable JavaDoc attachAnnotations(Throwable JavaDoc t, Annotation[] arr) {
119         List annotations = (List) map.get(t);
120         if (annotations == null) {
121             annotations = new ArrayList(arr.length + 5);
122             map.put(t, annotations);
123         }
124         annotations.addAll(0, Arrays.asList(arr));
125         return t;
126     }
127     
128     /** Finds annotations associated with a given exception.
129      * @param t the exception
130      * @return array of annotations or <code>null</code>
131      *
132      */

133     public Annotation[] findAnnotations(Throwable JavaDoc t) {
134         List annotations = (List) map.get(t);
135         if (annotations != null) {
136             return (Annotation[]) annotations.toArray(new Annotation[annotations.size()]);
137         } else {
138             return null;
139         }
140     }
141     
142     /** Returns an instance with given name.
143      * <p>By convention, you can name error managers the same as packages (or classes)
144      * they are designed to report information from.
145      * For example, <code>org.netbeans.modules.mymodule.ComplicatedParser</code>.
146      * <p>The error manager implementation should provide some way of configuring e.g.
147      * the logging level for error managers of different names. For example, in the basic
148      * NetBeans core implementation, you can define a system property with the same name
149      * as the future error manager (or a package prefix of it) whose value is the numeric
150      * logging level (e.g. <samp>-J-Dorg.netbeans.modules.mymodule.ComplicatedParser=0</samp>
151      * to log everything). Other implementations may have quite different ways of configuring
152      * the error managers.
153      * @param name the desired identifying name
154      * @return a new error manager keyed off of that name
155      *
156      */

157     public ErrorManager getInstance(String JavaDoc name) {
158         String JavaDoc loggerName = (this.name == null) ? name : this.name + "." + name;
159         String JavaDoc prop = loggerName;
160         int minLogSeverity = this.minLogSeverity;
161         while (prop != null) {
162             String JavaDoc value = System.getProperty(prop);
163             if (value != null) {
164                 try {
165                     minLogSeverity = Integer.parseInt(value);
166                 } catch (NumberFormatException JavaDoc nfe) {
167                     notify(WARNING, nfe);
168                 }
169                 break;
170             } else {
171                 int idx = prop.lastIndexOf('.');
172                 if (idx == -1)
173                     prop = null;
174                 else
175                     prop = prop.substring(0, idx);
176             }
177         }
178         return new Logger(loggerName, minLogSeverity, logWriter);
179     }
180     
181     /** Logs the message to a file and (possibly) tells the user.
182      * @param severity the severity to be applied (overrides default)
183      * @param s the log message
184      *
185      */

186     public void log(int severity, String JavaDoc s) {
187         if (isLoggable(severity)) {
188             if (name != null) {
189                 logWriter.printlnIndented("[" + name + "] " + s);
190             } else {
191                 logWriter.printlnIndented(s);
192             }
193             logWriter.flush();
194         }
195     }
196     
197     public boolean isLoggable(int severity) {
198         return severity >= minLogSeverity;
199     }
200     
201     public boolean isNotifiable(int severity) {
202         return isLoggable(severity + 1);
203     }
204
205     /** Prints the exception to the log file together with its annotations recursively
206      * @param severity the severity to be applied to the exception (overrides default), e.g. {@link #EXCEPTION}
207      * @param t the exception to notify
208      *
209      */

210     public void notify(int severity, Throwable JavaDoc t) {
211         notify(severity, t, new HashSet JavaDoc());
212     }
213     
214     private void notify(int severity, Throwable JavaDoc t, Set JavaDoc visited) {
215         if (!isNotifiable(severity))
216             return;
217         
218         if (!visited.add(t)) return;
219         Annotation[] ann = findAnnotations(t);
220
221         String JavaDoc level = (severity == INFORMATIONAL ? "INFORMATIONAL " : "");
222         if (name != null) {
223             level = "[" + name + "] " + level;
224         }
225         logWriter.printlnIndented(level + "*********** Exception occurred ************ at " + new Date());
226         t.printStackTrace(logWriter);
227         if (ann != null) {
228             logWriter.printlnIndented("ANNOTATIONS:");
229             logWriter.indent();
230             for (int i = 0; i < ann.length; i++) {
231                 logAnnotation(ann[i], visited);
232             }
233             logWriter.unindent();
234         }
235         logWriter.flush();
236     }
237     
238     private void logAnnotation(Annotation ann, Set JavaDoc visited) {
239         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(100);
240         sb.append("[" + ann.getDate() + "] ");
241         if (ann.getSeverity() == INFORMATIONAL) {
242             sb.append("INFORMATIONAL ");
243         }
244         if (ann.getLocalizedMessage() == null) {
245             if (ann.getMessage() == null) {
246                 if (ann.getStackTrace() != null) {
247                     sb.append("Exception occurred:");
248                 }
249             } else {
250                 sb.append(ann.getMessage());
251             }
252         } else {
253             sb.append(ann.getLocalizedMessage());
254         }
255         logWriter.printlnIndented(sb.toString());
256         if (ann.getStackTrace() != null) {
257 // ann.getStackTrace().printStackTrace(logWriter);
258
notify(ann.getSeverity(), ann.getStackTrace(), visited);
259         }
260     }
261
262     /** Implementation of annotation interface.
263     */

264     private static class Ann implements Annotation {
265         private final int severity;
266         private final String JavaDoc message;
267         private final String JavaDoc localizedMessage;
268         private final Throwable JavaDoc stackTrace;
269         private final Date date;
270
271         /** Constructor.
272         */

273         public Ann (int severity, String JavaDoc message, String JavaDoc localizedMessage, Throwable JavaDoc stackTrace, Date date) {
274             this.severity = severity;
275             this.message = message;
276             this.localizedMessage = localizedMessage;
277             this.stackTrace = stackTrace;
278             this.date = date;
279         }
280
281         /** Non-localized message.
282          * @return associated message or null
283          */

284         public String JavaDoc getMessage() {
285             return message;
286         }
287         /** Localized message.
288          * @return message to be presented to the user or null
289          */

290         public String JavaDoc getLocalizedMessage() {
291             return localizedMessage;
292         }
293         /** Stack trace. The stack trace should locate the method
294          * and possition in the method where error occured.
295          *
296          * @return exception representing the location of error or null
297          */

298         public Throwable JavaDoc getStackTrace() {
299             return stackTrace;
300         }
301         /** Date when the exception occured.
302          * @return the date or null
303          */

304         public Date getDate() {
305             return date;
306         }
307         /** Severity of the exception.
308          * @return number representing the severity
309          */

310         public int getSeverity() {
311             return severity;
312         }
313     } // end of Ann
314

315     private static class EmptyStream extends OutputStream {
316         public void write(int b) throws IOException{
317         }
318     }
319     
320     private static class LogWriter extends PrintWriter {
321         private static final String JavaDoc TAB = " ";
322         private int indent = 0;
323         
324         public LogWriter() {
325             super(new EmptyStream());
326         }
327         
328         public LogWriter(OutputStream stream) {
329             super(stream);
330         }
331         
332         public void printIndented(String JavaDoc str) {
333             for (int i = 0; i < indent; i++) {
334                 print(TAB);
335             }
336             print(str);
337         }
338         
339         public void printlnIndented(String JavaDoc str) {
340             print(str);
341             println();
342         }
343         
344         public void indent() {
345             indent++;
346         }
347         
348         public void unindent() {
349             indent--;
350         }
351     }
352 }
353
Popular Tags