KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > util > Exceptions


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.openide.util;
20
21 import java.io.IOException JavaDoc;
22 import java.io.PrintStream JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.io.StringWriter JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.ResourceBundle JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import java.util.concurrent.Callable JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.LogRecord JavaDoc;
34 import java.util.logging.Logger JavaDoc;
35
36
37 /** Useful utility and methods to work with exceptions.
38  * Allows to annotate exceptions with messages, extract such messages
39  * and provides a common utility method to report an exception.
40  *
41  * @since 7.2
42  */

43 public final class Exceptions extends Object JavaDoc {
44     private Exceptions() {
45     }
46     
47     private static final String JavaDoc LOC_MSG_PLACEHOLDER = "msg"; // NOI18N
48

49     /** Attaches additional message to given exception. This message will
50      * be visible when one does <code>e.printStackTrace()</code>.
51      *
52      * @param e exception to annotate
53      * @param msg the message to add to the exception
54      * @return the exception <code>e</code>
55      */

56     public static <E extends Throwable JavaDoc> E attachMessage(E e, String JavaDoc msg) {
57         AnnException ae = AnnException.findOrCreate(e, true);
58         LogRecord JavaDoc rec = new LogRecord JavaDoc(Level.ALL, msg);
59         ae.addRecord(rec);
60         return e;
61     }
62
63     /** Attaches additional localized message to given exception. This message
64      * can be extracted later by using {@link #findLocalizedMessage}.
65      *
66      * @param e exception to annotate
67      * @param localizedMessage the localized message to add to the exception
68      * @return the exception <code>e</code>
69      */

70     public static <E extends Throwable JavaDoc> E attachLocalizedMessage(E e, final String JavaDoc localizedMessage) {
71         AnnException ae = AnnException.findOrCreate(e, true);
72         LogRecord JavaDoc rec = new LogRecord JavaDoc(Level.ALL, LOC_MSG_PLACEHOLDER);
73         ResourceBundle JavaDoc rb = new ResourceBundle JavaDoc() {
74             public Object JavaDoc handleGetObject(String JavaDoc key) {
75                 if (LOC_MSG_PLACEHOLDER.equals(key)) {
76                     return localizedMessage;
77                 } else {
78                     return null;
79                 }
80             }
81
82             public Enumeration JavaDoc<String JavaDoc> getKeys() {
83                 return Enumerations.singleton(LOC_MSG_PLACEHOLDER);
84             }
85         };
86         rec.setResourceBundle(rb);
87         ae.addRecord(rec);
88         return e;
89     }
90
91     /** Extracts previously attached localized message for a given throwable.
92      * Complements {@link #attachLocalizedMessage}.
93      *
94      * @param t the exception to search for a message in
95      * @return localized message attached to provided exception or <code>null</code>
96      * if no such message has been attached
97      */

98     public static String JavaDoc findLocalizedMessage(Throwable JavaDoc t) {
99         while (t != null) {
100             String JavaDoc msg;
101             AnnException extra = AnnException.extras.get(t);
102             if (extra != null) {
103                 msg = extractLocalizedMessage(extra);
104             } else {
105                 msg = extractLocalizedMessage(t);
106             }
107             
108             if (msg != null) {
109                 return msg;
110             }
111             
112             t = t.getCause();
113         }
114         return null;
115     }
116
117     private static String JavaDoc extractLocalizedMessage(final Throwable JavaDoc t) {
118         String JavaDoc msg = null;
119         if (t instanceof Callable JavaDoc) {
120             Object JavaDoc res = null;
121             try {
122                 res = ((Callable JavaDoc) t).call();
123             } catch (Exception JavaDoc ex) {
124                 Logger.global.log(Level.WARNING, null, t);
125             }
126             if (res instanceof LogRecord JavaDoc[]) {
127                 for (LogRecord JavaDoc r : (LogRecord JavaDoc[])res) {
128                     ResourceBundle JavaDoc b = r.getResourceBundle();
129                     if (b != null) {
130                         msg = b.getString(r.getMessage());
131                         break;
132                     }
133                 }
134             }
135         }
136         return msg;
137     }
138     
139     /** Notifies an exception with a severe level. Such exception is going
140      * to be printed to log file and possibly also notified to alarm the
141      * user somehow.
142      *
143      * @param t the exception to notify
144      */

145     public static void printStackTrace(Throwable JavaDoc t) {
146         AnnException extra = AnnException.extras.get(t);
147         if (extra != null) {
148             assert t == extra.getCause();
149             t = extra;
150         }
151         Logger.global.log(OwnLevel.UNKNOWN, null, t);
152     }
153
154     /** An exception that has a log record associated with itself, so
155      * the NbErrorManager can extract info about the annotation.
156      */

157     private static final class AnnException extends Exception JavaDoc implements Callable JavaDoc<LogRecord JavaDoc[]> {
158         private List JavaDoc<LogRecord JavaDoc> records;
159         
160         private AnnException() {
161             super();
162         }
163         
164         private AnnException(String JavaDoc msg) {
165             super(msg);
166         }
167
168         @Override JavaDoc
169         public String JavaDoc getMessage() {
170             StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
171             String JavaDoc sep = "";
172             for (LogRecord JavaDoc r : records) {
173                 String JavaDoc m = r.getMessage();
174                 if (m != null && !m.equals(LOC_MSG_PLACEHOLDER)) {
175                     sb.append(sep);
176                     sb.append(m);
177                     sep = "\n";
178                 }
179             }
180             return sb.toString();
181         }
182         
183         
184         /** additional mapping from throwables that refuse initCause call */
185         private static Map JavaDoc<Throwable JavaDoc, AnnException> extras = new WeakHashMap JavaDoc<Throwable JavaDoc, AnnException>();
186
187         static AnnException findOrCreate(Throwable JavaDoc t, boolean create) {
188             if (t instanceof AnnException) {
189                 return (AnnException)t;
190             }
191             if (t.getCause() == null) {
192                 if (create) {
193                     try {
194                         t.initCause(new AnnException());
195                     } catch (IllegalStateException JavaDoc x) {
196                         AnnException ann = extras.get(t);
197                         if (ann == null) {
198                             ann = new AnnException(t.getMessage());
199                             ann.initCause(t);
200                             Logger.getLogger(Exceptions.class.getName()).log(Level.FINE, "getCause was null yet initCause failed for " + t, x);
201                             extras.put(t, ann);
202                         }
203                         return ann;
204                     }
205                 }
206                 return (AnnException)t.getCause();
207             }
208             return findOrCreate(t.getCause(), create);
209         }
210
211         public synchronized void addRecord(LogRecord JavaDoc rec) {
212             if (records == null) {
213                 records = new ArrayList JavaDoc<LogRecord JavaDoc>();
214             }
215             records.add(rec);
216         }
217
218         public LogRecord JavaDoc[] call() {
219             List JavaDoc<LogRecord JavaDoc> r = records;
220             LogRecord JavaDoc[] empty = new LogRecord JavaDoc[0];
221             return r == null ? empty : r.toArray(empty);
222         }
223
224         @Override JavaDoc
225         public void printStackTrace(PrintStream JavaDoc s) {
226             super.printStackTrace(s);
227             logRecords(s);
228         }
229
230         @Override JavaDoc
231         public void printStackTrace(PrintWriter JavaDoc s) {
232             super.printStackTrace(s);
233             logRecords(s);
234         }
235
236         @Override JavaDoc
237         public Throwable JavaDoc fillInStackTrace() {
238             return this;
239         }
240
241         @Override JavaDoc
242         public String JavaDoc toString() {
243             return getMessage();
244         }
245
246         private void logRecords(Appendable JavaDoc a) {
247             List JavaDoc<LogRecord JavaDoc> r = records;
248             if (r == null) {
249                 return;
250             }
251             try {
252
253                 for (LogRecord JavaDoc log : r) {
254                     if (log.getMessage() != null) {
255                         a.append(log.getMessage()).append("\n");;
256                     }
257                     if (log.getThrown() != null) {
258                         StringWriter JavaDoc w = new StringWriter JavaDoc();
259                         log.getThrown().printStackTrace(new PrintWriter JavaDoc(w));
260                         a.append(w.toString()).append("\n");
261                     }
262                 }
263             } catch (IOException JavaDoc ex) {
264                 ex.printStackTrace();
265             }
266         }
267     } // end AnnException
268
private static final class OwnLevel extends Level JavaDoc {
269         public static final Level JavaDoc UNKNOWN = new OwnLevel("SEVERE", Level.SEVERE.intValue() + 1); // NOI18N
270

271         private OwnLevel(String JavaDoc s, int i) {
272             super(s, i);
273         }
274     } // end of OwnLevel
275
}
276
Popular Tags