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   
7   import javax.swing.JOptionPane;
8   
9   import org.apache.commons.logging.Log;
10  import org.apache.commons.logging.LogFactory;
11  import org.apache.log4j.AppenderSkeleton;
12  import org.apache.log4j.Level;
13  import org.apache.log4j.spi.LoggingEvent;
14  
15  import com.jgoodies.uif.application.Application;
16  import com.jgoodies.uifextras.convenience.SendFeedbackDialog;
17  import com.melloware.jukes.gui.tool.Resources;
18  
19  /**
20   * Jgoodies Log4J appender to catch errors and display the feeback dialog.
21   * It catches errors and warns and displays them to the user using either
22   * a feedback dialog or a JOptionPane.
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 class Log4jFeedbackAppender
29      extends AppenderSkeleton {
30  
31      private static final Log LOG = LogFactory.getLog(Log4jFeedbackAppender.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       * Default constructor
38       */
39      public Log4jFeedbackAppender() {
40          super();
41      }
42  
43      /* (non-Javadoc)
44       * @see org.apache.LOG4j.AppenderSkeleton#close()
45       */
46      public void close() {
47          // do nothing
48  
49      }
50  
51      /* (non-Javadoc)
52       * @see org.apache.LOG4j.AppenderSkeleton#requiresLayout()
53       */
54      public boolean requiresLayout() {
55          return false;
56      }
57  
58      /* (non-Javadoc)
59       * @see org.apache.LOG4j.AppenderSkeleton#append(org.apache.LOG4j.spi.LoggingEvent)
60       */
61      protected void append(LoggingEvent aLoggingEvent) {
62          if (aLoggingEvent.getLevel() == Level.WARN) {
63              LOG.debug("Feeback appender showing warn.");
64              String msg = aLoggingEvent.getRenderedMessage();
65              JOptionPane.showMessageDialog(this.owner(), msg, getTitle(aLoggingEvent.getLevel()),
66                                            getMessageType(aLoggingEvent.getLevel()));
67  
68          }
69          if (aLoggingEvent.getLevel() == Level.ERROR) {
70              LOG.debug("Feeback appender showing error.");
71              String msg = aLoggingEvent.getRenderedMessage();
72              if (aLoggingEvent.getThrowableInformation() == null) {
73                  JOptionPane.showMessageDialog(this.owner(), msg, getTitle(aLoggingEvent.getLevel()),
74                                                getMessageType(aLoggingEvent.getLevel()));
75              } else {
76                  showOptionWithFeedbackDialog(aLoggingEvent.getLevel(), msg,
77                                               aLoggingEvent.getThrowableInformation().getThrowable());
78              }
79          }
80      }
81  
82      private int getMessageType(Level level) {
83          if (Level.ERROR.equals(level)) {
84              return JOptionPane.ERROR_MESSAGE;
85          } else if (Level.WARN.equals(level)) {
86              return JOptionPane.WARNING_MESSAGE;
87          } else {
88              return JOptionPane.INFORMATION_MESSAGE;
89          }
90      }
91  
92      private String getSubject(Level level) {
93          return Resources.APPLICATION_NAME + " " + getTitle(level);
94      }
95  
96      private String getTitle(Level level) {
97          if (Level.ERROR.equals(level)) {
98              return "Error";
99          } else if (Level.WARN.equals(level)) {
100             return "warn";
101         } else {
102             return "Message";
103         }
104     }
105 
106     private Frame owner() {
107         Frame frame = Application.getDefaultParentFrame();
108         return (frame == null) ? new Frame() : frame;
109     }
110 
111     private void sendFeedback(Level level, String msg, Throwable thrown) {
112         StringWriter out = new StringWriter();
113         out.write(msg);
114 
115         out.write("\n");
116         writeSystemProperties(out,
117                               new String[] {
118                                   "os.name", "os.version", "java.vm.vendor", "java.vm.version",
119                                   "application.fullversion"
120                               });
121 
122         if (thrown != null) {
123             out.write("\n\n");
124             thrown.printStackTrace(new PrintWriter(out));
125         }
126         new SendFeedbackDialog(owner(), "info@melloware.com", getSubject(level), out.toString()).open();
127     }
128 
129     private void showOptionWithFeedbackDialog(Level level, String msg, Throwable thrown) {
130         int messageType = getMessageType(level);
131         String title = getTitle(level);
132         String fullMessage = msg + "\n" + thrown.getLocalizedMessage();
133 
134         int choice = JOptionPane.showOptionDialog(owner(), fullMessage, title, -1, messageType, null, OPTIONS,
135                                                   OK_LABEL);
136         if (choice == 1) {
137             sendFeedback(level, msg, thrown);
138         }
139     }
140 
141     private void writeSystemProperties(StringWriter out, String[] keys) {
142         for (int i = 0; i < keys.length; i++) {
143             String key = keys[i];
144             String value = System.getProperty(key);
145             if (value != null) {
146                 out.write("\n");
147                 out.write(key);
148                 out.write("=");
149                 out.write(value);
150             }
151         }
152     }
153 
154 }