1 19 package org.openide.util; 20 21 import java.io.IOException ; 22 import java.io.PrintStream ; 23 import java.io.PrintWriter ; 24 import java.io.StringWriter ; 25 import java.util.ArrayList ; 26 import java.util.Enumeration ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.ResourceBundle ; 30 import java.util.WeakHashMap ; 31 import java.util.concurrent.Callable ; 32 import java.util.logging.Level ; 33 import java.util.logging.LogRecord ; 34 import java.util.logging.Logger ; 35 36 37 43 public final class Exceptions extends Object { 44 private Exceptions() { 45 } 46 47 private static final String LOC_MSG_PLACEHOLDER = "msg"; 49 56 public static <E extends Throwable > E attachMessage(E e, String msg) { 57 AnnException ae = AnnException.findOrCreate(e, true); 58 LogRecord rec = new LogRecord (Level.ALL, msg); 59 ae.addRecord(rec); 60 return e; 61 } 62 63 70 public static <E extends Throwable > E attachLocalizedMessage(E e, final String localizedMessage) { 71 AnnException ae = AnnException.findOrCreate(e, true); 72 LogRecord rec = new LogRecord (Level.ALL, LOC_MSG_PLACEHOLDER); 73 ResourceBundle rb = new ResourceBundle () { 74 public Object handleGetObject(String key) { 75 if (LOC_MSG_PLACEHOLDER.equals(key)) { 76 return localizedMessage; 77 } else { 78 return null; 79 } 80 } 81 82 public Enumeration <String > getKeys() { 83 return Enumerations.singleton(LOC_MSG_PLACEHOLDER); 84 } 85 }; 86 rec.setResourceBundle(rb); 87 ae.addRecord(rec); 88 return e; 89 } 90 91 98 public static String findLocalizedMessage(Throwable t) { 99 while (t != null) { 100 String 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 extractLocalizedMessage(final Throwable t) { 118 String msg = null; 119 if (t instanceof Callable ) { 120 Object res = null; 121 try { 122 res = ((Callable ) t).call(); 123 } catch (Exception ex) { 124 Logger.global.log(Level.WARNING, null, t); 125 } 126 if (res instanceof LogRecord []) { 127 for (LogRecord r : (LogRecord [])res) { 128 ResourceBundle 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 145 public static void printStackTrace(Throwable 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 157 private static final class AnnException extends Exception implements Callable <LogRecord []> { 158 private List <LogRecord > records; 159 160 private AnnException() { 161 super(); 162 } 163 164 private AnnException(String msg) { 165 super(msg); 166 } 167 168 @Override 169 public String getMessage() { 170 StringBuilder sb = new StringBuilder (); 171 String sep = ""; 172 for (LogRecord r : records) { 173 String 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 185 private static Map <Throwable , AnnException> extras = new WeakHashMap <Throwable , AnnException>(); 186 187 static AnnException findOrCreate(Throwable 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 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 rec) { 212 if (records == null) { 213 records = new ArrayList <LogRecord >(); 214 } 215 records.add(rec); 216 } 217 218 public LogRecord [] call() { 219 List <LogRecord > r = records; 220 LogRecord [] empty = new LogRecord [0]; 221 return r == null ? empty : r.toArray(empty); 222 } 223 224 @Override 225 public void printStackTrace(PrintStream s) { 226 super.printStackTrace(s); 227 logRecords(s); 228 } 229 230 @Override 231 public void printStackTrace(PrintWriter s) { 232 super.printStackTrace(s); 233 logRecords(s); 234 } 235 236 @Override 237 public Throwable fillInStackTrace() { 238 return this; 239 } 240 241 @Override 242 public String toString() { 243 return getMessage(); 244 } 245 246 private void logRecords(Appendable a) { 247 List <LogRecord > r = records; 248 if (r == null) { 249 return; 250 } 251 try { 252 253 for (LogRecord log : r) { 254 if (log.getMessage() != null) { 255 a.append(log.getMessage()).append("\n");; 256 } 257 if (log.getThrown() != null) { 258 StringWriter w = new StringWriter (); 259 log.getThrown().printStackTrace(new PrintWriter (w)); 260 a.append(w.toString()).append("\n"); 261 } 262 } 263 } catch (IOException ex) { 264 ex.printStackTrace(); 265 } 266 } 267 } private static final class OwnLevel extends Level { 269 public static final Level UNKNOWN = new OwnLevel("SEVERE", Level.SEVERE.intValue() + 1); 271 private OwnLevel(String s, int i) { 272 super(s, i); 273 } 274 } } 276 | Popular Tags |