Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/eireneh/util/Reporter.java


1   package com.eireneh.util;
2   
3   import com.eireneh.util.event.*;
4   
5   /**
6    * This package looks after Exceptions and messages as they happen. It would be
7    * nice not to need this class - the principle being that any library that
8    * encounters an error can throw an exception to indicate that there is a
9    * problem. However this is not always the case. For example:
10   * <li>static class constructors should not throw, unless the class really is
11   *     of no use given the error, and yet we may want to tell the user that
12   *     there was a (non-critical) error.</li>
13   * <li>Any library routine that works in a loop, applying some (potentially
14   *     failing) functionality, may want to continue the work without throwing
15   *     in response to a single error.</li>
16   * <li>The class being implemented may implement an interface that disallows
17   *     nested exceptions and yet does not want to loose the root cause error
18   *     information. (This is the weakest of the above arguements, but probably
19   *     still valid.)</li>
20   * However in many of the times this class is used, this is the reason:
21   * <li>Within UI specific code - to throw up a dialog box (or whatever). Now
22   *     this use is currently tollerated, however it is probably a poor idea to
23   *     use GUI agnostic messaging in a GUI specific context. But I'm not
24   *     bothered enough to change it now. Specifically this use is deprecated
25   *     because it makes the app more susceptible to the configuration of the
26   *     things that listen to reports.</li>
27   *
28   * <table border='1' cellPadding='3' cellSpacing='0' width="100%">
29   * <tr><td bgColor='white'class='TableRowColor'><font size='-7'>
30   * Distribution Licence:<br />
31   * Project B is free software; you can redistribute it
32   * and/or modify it under the terms of the GNU General Public License,
33   * version 2 as published by the Free Software Foundation.<br />
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37   * General Public License for more details.<br />
38   * The License is available on the internet
39   * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, by writing to
40   * <i>Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
41   * MA 02111-1307, USA</i>, Or locally at the Licence link below.<br />
42   * The copyright to this program is held by it's authors.
43   * </font></td></tr></table>
44   * @see <a href='http://www.eireneh.com/servlets/Web'>Project B Home</a>
45   * @see docs.Licence
46   * @author Joe Walker
47   */
48  public class Reporter
49  {
50      /**
51       * Enforce Singleton
52       */
53      private Reporter()
54      {
55      }
56  
57      /**
58       * Something has gone wrong. We need to tell the user or someone, but
59       * we can carry on. In general having caught an exception and passed
60       * it to Reporter.informUser(), you should not throw another Exception.
61       * Called to fire a commandEntered event to all the Listeners
62       * @param source The cause of the problem, a Component if possible.
63       * @param ex The Exception that was thrown
64       */
65      public static void informUser(Object source, Throwable prob)
66      {
67          if (prob instanceof ThreadDeath)
68              throw (ThreadDeath) prob;
69  
70          // There is a danger here because fireCapture calls informUser
71          // if something goes wrong. It feels dangerous, but is probably ok
72          // The only problem that I can think of is that if there are 2
73          // CaptureListeners with problems then the 2nd will be hit twice.
74          fireCapture(new ReporterEvent(prob));
75      }
76  
77      /**
78       * Something has happened. We need to tell the user or someone.
79       *
80       * <p>Maybe we should have an extra parameter (or even several
81       * versions of this method like log*()) that describes the severity
82       * of the message. A Sw*ng listener could use this to decide the
83       * icon in the OptionPane for example.</p>
84       *
85       * @param source The cause of the message, a Component if possible.
86       * @param message The message to pass to the user
87       */
88      public static void informUser(String message)
89      {
90          fireCapture(new ReporterEvent(message));
91      }
92  
93      /**
94       * Add an Exception listener to the list of things wanting
95       * to know whenever we capture an Exception
96       */
97      public static void addReporterListener(ReporterListener li)
98      {
99          inform_list.add(ReporterListener.class, li);
100     }
101 
102     /**
103      * Remove an Exception listener from the list of things wanting
104      * to know whenever we capture an Exception
105      */
106     public static void removeReporterListener(ReporterListener li)
107     {
108         inform_list.remove(ReporterListener.class, li);
109     }
110 
111     /**
112      * Log a message
113      * @param source Where the message comes from
114      * @param message The text message
115      */
116     protected static void fireCapture(ReporterEvent ev)
117     {
118         // Guaranteed to return a non-null array
119         Object[] listeners = inform_list.getListenerList();
120 
121         // Process the listeners last to first, notifying
122         // those that are interested in this event
123         for (int i=listeners.length-2; i>=0; i-=2)
124         {
125             if (listeners[i] == ReporterListener.class)
126             {
127                 ReporterListener li = (ReporterListener) listeners[i+1];
128                 try
129                 {
130                     if (ev.getException() != null)
131                         li.reportException(ev);
132                     else
133                         li.reportMessage(ev);
134                 }
135                 catch (Throwable ex)
136                 {
137                     if (ex instanceof ThreadDeath)
138                         throw (ThreadDeath) ex;
139 
140                     inform_list.remove(CaptureListener.class, li);
141 
142                     log.log(Level.WARNING, "Dispatch failure", ex);
143                 }
144             }
145         }
146     }
147 
148     /** The log stream */
149     protected static Logger log = Logger.getLogger("bible.passage");
150 
151     /** The list of listeners */
152     protected static EventListenerList inform_list = new EventListenerList();
153 }