View Javadoc

1   package com.melloware.jukes.gui.tool.logging;
2   
3   import java.awt.Frame;
4   import java.io.PrintWriter;
5   import java.io.StringWriter;
6   import java.util.logging.Handler;
7   import java.util.logging.Level;
8   import java.util.logging.LogRecord;
9   
10  import javax.swing.JOptionPane;
11  
12  import org.apache.commons.logging.Log;
13  import org.apache.commons.logging.LogFactory;
14  
15  import com.jgoodies.uif.application.Application;
16  import com.jgoodies.uifextras.convenience.SendFeedbackDialog;
17  
18  /**
19   * This class pops up message dialogs to LOG messages with
20   * a level greater or equal to Level.warn. In addition,
21   * a <code>ConsoleHandler</code> is used to write
22   * all messages to the console, too.  If any AWT or Java errors are trapped too.
23   * <p>
24   * Copyright (c) 1999-2007 Melloware, Inc. <http://www.melloware.com>
25   * @author Emil A. Lefkof III <info@melloware.com>
26   * @version 4.0
27   */
28  public final class AwtLogHandler
29      extends Handler {
30  
31      private static final Log LOG = LogFactory.getLog(AwtLogHandler.class);
32      private static final String OK_LABEL = "OK";
33      private static final String FEEDBACK_LABEL = "Send Feedback...";
34      private static final Object[] OPTIONS = new Object[] { OK_LABEL, FEEDBACK_LABEL };
35  
36      /**
37       * Constructor.
38       */
39      public AwtLogHandler() {
40          super();
41      }
42  
43      public void close() {
44          // Implements Handler; this implementation does nothing
45      }
46  
47      public void flush() {
48          // Implements Handler; this implementation does nothing
49      }
50  
51      /**
52       * Handles AWT errors or anything else that comes down the line.
53       * @param throwable the Throwable instance to handle
54       */
55      public void handle(Throwable throwable) {
56          if (LOG.isDebugEnabled()) {
57              LOG.debug("Generic Exception Caught: " + throwable);
58          }
59          
60          // check whether to dispose the error or show feedback dialog.
61          if (shouldDisposeError(throwable) == false) {
62             showOptionWithFeedbackDialog(Level.SEVERE, "Generic Application Error has occurred.", throwable); 
63          } 
64      }
65      
66      /**
67       * A list of exceptions that should not display the feedback dialog.  This
68       * is useful for known errors like the JDK6 TrayIcon ClassCastException.
69       * <p>
70       * @param throwable the Throwable instance to check for disposal
71       */
72      private boolean shouldDisposeError(Throwable throwable) {
73         boolean dispose = false;
74         if (throwable instanceof java.lang.ClassCastException) {
75            if (throwable.getLocalizedMessage().equals("java.awt.TrayIcon cannot be cast to java.awt.Component")) {
76               dispose = true;
77            }
78         }
79         return dispose;
80      }
81  
82      // JGoodies Handler ******************************************************
83  
84      public void log(Level level, String catalog, String msg, Throwable throwable) {
85          LOG.info("LogManager Exception Caught");
86          
87          if (level.intValue() >= Level.WARNING.intValue()) {
88              JOptionPane.showMessageDialog(this.owner(), msg, getTitle(level), getMessageType(level));
89          }
90          
91          if (level.intValue() >= Level.SEVERE.intValue()) {
92              if (throwable == null) {
93                  JOptionPane.showMessageDialog(this.owner(), msg, getTitle(level), getMessageType(level));
94              } else {
95                  showOptionWithFeedbackDialog(level, msg, throwable);
96              }
97          }
98      }
99  
100     public void publish(LogRecord LOGRecord) {
101         int level = LOGRecord.getLevel().intValue();
102 
103         LOG.info("LogManager Publish");
104         // Don't pop up Windows for Level < warn.
105         if (level < Level.WARNING.intValue()) {
106             return;
107         }
108 
109         String msg = LOGRecord.getMessage();
110         if (LOGRecord.getThrown() == null) {
111             JOptionPane.showMessageDialog(owner(), msg, getTitle(LOGRecord.getLevel()),
112                                           getMessageType(LOGRecord.getLevel()));
113         } else {
114             showOptionWithFeedbackDialog(LOGRecord.getLevel(), msg, LOGRecord.getThrown());
115         }
116     }
117 
118     private int getMessageType(Level level) {
119         if (Level.SEVERE.equals(level)) {
120             return JOptionPane.ERROR_MESSAGE;
121         } else if (Level.WARNING.equals(level)) {
122             return JOptionPane.WARNING_MESSAGE;
123         } else {
124             return JOptionPane.INFORMATION_MESSAGE;
125         }
126     }
127 
128     private String getSubject(Level level) {
129         return "Execution " + getTitle(level);
130     }
131 
132     private String getTitle(Level level) {
133         if (Level.SEVERE.equals(level)) {
134             return "Error";
135         } else if (Level.WARNING.equals(level)) {
136             return "warn";
137         } else {
138             return "Message";
139         }
140     }
141 
142     private Frame owner() {
143         Frame frame = Application.getDefaultParentFrame();
144         return (frame == null) ? new Frame() : frame;
145     }
146 
147     private void sendFeedback(Level level, String msg, Throwable thrown) {
148         StringWriter out = new StringWriter();
149         out.write(msg);
150 
151         out.write("\n");
152         writeSystemProperties(out,
153                               new String[] {
154                                   "os.name", "os.version", "java.vm.vendor", "java.vm.version",
155                                   "application.fullversion"
156                               });
157 
158         if (thrown != null) {
159             out.write("\n\n");
160             thrown.printStackTrace(new PrintWriter(out));
161         }
162         new SendFeedbackDialog(owner(), "info@melloware.com", getSubject(level), out.toString()).open();
163     }
164 
165     private void showOptionWithFeedbackDialog(Level level, String msg, Throwable thrown) {
166         int messageType = getMessageType(level);
167         String title = getTitle(level);
168         String fullMessage = msg + "\n" + thrown.getLocalizedMessage();
169 
170         int choice = JOptionPane.showOptionDialog(owner(), fullMessage, title, -1, messageType, null, OPTIONS,
171                                                   OK_LABEL);
172         if (choice == 1) {
173             sendFeedback(level, msg, thrown);
174         }
175     }
176 
177     private void writeSystemProperties(StringWriter out, String[] keys) {
178         for (int i = 0; i < keys.length; i++) {
179             String key = keys[i];
180             String value = System.getProperty(key);
181             if (value != null) {
182                 out.write("\n");
183                 out.write(key);
184                 out.write("=");
185                 out.write(value);
186             }
187         }
188     }
189 }