View Javadoc

1   /*
2    *  jDTAUS Core Utilities
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.core.lang.util;
22  
23  import java.io.File;
24  import java.net.URL;
25  import org.jdtaus.core.container.ContainerFactory;
26  import org.jdtaus.core.container.Implementation;
27  import org.jdtaus.core.container.ModelFactory;
28  import org.jdtaus.core.container.Specification;
29  import org.jdtaus.core.lang.ExceptionEvent;
30  import org.jdtaus.core.lang.ExceptionListener;
31  import org.jdtaus.core.messages.BugReportMessage;
32  import org.jdtaus.core.messages.ExceptionMessage;
33  import org.jdtaus.core.messages.UndefinedApplicationStateMessage;
34  import org.jdtaus.core.text.Message;
35  import org.jdtaus.core.text.MessageEvent;
36  import org.jdtaus.core.text.Messages;
37  import org.jdtaus.core.text.spi.ApplicationLogger;
38  
39  /**
40   * {@code ExceptionListener} resolving exceptions to corresponding application
41   * messages.
42   *
43   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
44   * @version $JDTAUS: ExceptionMessageProducer.java 8795 2012-12-03 16:53:46Z schulte $
45   *
46   * @see #onException(ExceptionEvent)
47   * @see org.jdtaus.core.text.util.SwingMessagePane
48   * @see org.jdtaus.core.text.util.MessageLogger
49   */
50  public final class ExceptionMessageProducer implements ExceptionListener
51  {
52      //--Constructors------------------------------------------------------------
53  
54  // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausConstructors
55      // This section is managed by jdtaus-container-mojo.
56  
57  // </editor-fold>//GEN-END:jdtausConstructors
58  
59      //------------------------------------------------------------Constructors--
60      //--Dependencies------------------------------------------------------------
61  
62  // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausDependencies
63      // This section is managed by jdtaus-container-mojo.
64  
65      /**
66       * Gets the configured <code>ApplicationLogger</code> implementation.
67       *
68       * @return The configured <code>ApplicationLogger</code> implementation.
69       */
70      private ApplicationLogger getApplicationLogger()
71      {
72          return (ApplicationLogger) ContainerFactory.getContainer().
73              getDependency( this, "ApplicationLogger" );
74  
75      }
76  
77  // </editor-fold>//GEN-END:jdtausDependencies
78  
79      //------------------------------------------------------------Dependencies--
80      //--Properties--------------------------------------------------------------
81  
82  // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
83      // This section is managed by jdtaus-container-mojo.
84  
85  // </editor-fold>//GEN-END:jdtausProperties
86  
87      //--------------------------------------------------------------Properties--
88      //--ExceptionListener-------------------------------------------------------
89  
90      /**
91       * {@inheritDoc}
92       * <p>This method resolves exceptions provided by an application's
93       * {@code ExceptionEventSource} to corresponding {@code MessageEvent}s which
94       * an application may react to by registering a listener to its
95       * {@code MessageEventSource}. Messages for checked exceptions are resolved
96       * by using any available {@code ExceptionMessageResolver} implementation
97       * stopping at the first implementation not returning {@code null}.
98       * For exceptions which are instances of {@code RuntimeException} an
99       * additional message informing the user that the application's state is
100      * undefined and that a restart is recommended is added to the produced
101      * {@code MessageEvent}. Optionally an additional message informing the user
102      * on how to report a bug is added to the produced {@code MessageEvent} if
103      * the instance got constructed using the constructor taking that
104      * information.</p>
105      *
106      * @param event The event holding the exception.
107      *
108      * @see ExceptionMessageResolver#resolve(Exception)
109      */
110     public void onException( final ExceptionEvent event )
111     {
112         if ( event != null )
113         {
114             final Throwable exception = event.getException();
115             final Throwable rootCause = event.getRootCause();
116             final Messages messages = new Messages();
117 
118             messages.addMessage( new ExceptionMessage( exception ) );
119 
120             if ( rootCause instanceof RuntimeException )
121             {
122                 messages.addMessage( new UndefinedApplicationStateMessage() );
123 
124                 if ( this.logDirectory != null )
125                 {
126                     messages.addMessage( new BugReportMessage(
127                         this.logDirectory, this.trackerUrl,
128                         this.reportAddress ) );
129 
130                 }
131             }
132             else if ( rootCause instanceof Exception )
133             {
134                 final Message[] resolved =
135                     this.resolveMessages( (Exception) rootCause );
136 
137                 if ( resolved != null )
138                 {
139                     messages.addMessages( resolved );
140                 }
141             }
142 
143             this.getApplicationLogger().log(
144                 new MessageEvent( this,
145                                   messages.getMessages(),
146                                   MessageEvent.ERROR ) );
147 
148         }
149     }
150 
151     //-------------------------------------------------------ExceptionListener--
152     //--ExceptionMessageProducer------------------------------------------------
153 
154     /**
155      * Directory holding the application's log files.
156      * @serial
157      */
158     private File logDirectory;
159 
160     /**
161      * URL of the online bugtracking system.
162      * @serial
163      */
164     private URL trackerUrl;
165 
166     /**
167      * Mail address to send the bugreport to.
168      * @serial
169      */
170     private String reportAddress;
171 
172     /** Creates a new {@code ExceptionMessageProducer} instance. */
173     public ExceptionMessageProducer()
174     {
175         super();
176         this.logDirectory = null;
177         this.trackerUrl = null;
178         this.reportAddress = null;
179     }
180 
181     /**
182      * Creates a new {@code ExceptionMessageProducer} instance taking the
183      * application's logfile directory.
184      *
185      * @param logDirectory The directory holding the application's logfiles.
186      *
187      * @throws NullPointerException if {@code logDirectory} is {@code null}.
188      *
189      * @since 1.14
190      */
191     public ExceptionMessageProducer( final File logDirectory )
192     {
193         super();
194         if ( logDirectory == null )
195         {
196             throw new NullPointerException( "logDirectory" );
197         }
198 
199         this.logDirectory = logDirectory;
200         this.trackerUrl = null;
201         this.reportAddress = null;
202     }
203 
204     /**
205      * Creates a new {@code ExceptionMessageProducer} instance taking the
206      * application's logfile directory and an URL to the application's online
207      * bugtracking system.
208      *
209      * @param logDirectory The directory holding the application's logfiles.
210      * @param trackerUrl An URL to the application's online bugtracking system.
211      *
212      * @throws NullPointerException if either {@code logDirectory} or
213      * {@code trackerUrl} is {@code null}.
214      *
215      * @since 1.14
216      */
217     public ExceptionMessageProducer( final File logDirectory,
218                                      final URL trackerUrl )
219     {
220         super();
221         if ( logDirectory == null )
222         {
223             throw new NullPointerException( "logDirectory" );
224         }
225         if ( trackerUrl == null )
226         {
227             throw new NullPointerException( "trackerUrl" );
228         }
229 
230         this.logDirectory = logDirectory;
231         this.trackerUrl = trackerUrl;
232         this.reportAddress = null;
233     }
234 
235     /**
236      * Creates a new {@code ExceptionMessageProducer} instance taking the
237      * application's logfile directory and an email address where to send
238      * bugreports to.
239      *
240      * @param logDirectory The directory holding the application's logfiles.
241      * @param reportAddress An email address to alternatively send bugreports
242      * to.
243      *
244      * @throws NullPointerException if either {@code logDirectory} or
245      * {@code reportAddress} is {@code null}.
246      *
247      * @since 1.14
248      */
249     public ExceptionMessageProducer( final File logDirectory,
250                                      final String reportAddress )
251     {
252         super();
253         if ( logDirectory == null )
254         {
255             throw new NullPointerException( "logDirectory" );
256         }
257         if ( reportAddress == null )
258         {
259             throw new NullPointerException( "reportAddress" );
260         }
261 
262         this.logDirectory = logDirectory;
263         this.trackerUrl = null;
264         this.reportAddress = reportAddress;
265     }
266 
267     /**
268      * Creates a new {@code ExceptionMessageProducer} instance taking the
269      * application's logfile directory, an URL to the application's online
270      * bugtracking system, and an email address where to send bugreports to
271      * alternatively.
272      *
273      * @param logDirectory The directory holding the application's logfiles.
274      * @param trackerUrl An URL to the application's online bugtracking system.
275      * @param reportAddress An email address to alternatively send bugreports
276      * to.
277      *
278      * @throws NullPointerException if either {@code logDirectory},
279      * {@code trackerUrl} or {@code reportAddress} is {@code null}.
280      */
281     public ExceptionMessageProducer( final File logDirectory,
282                                      final URL trackerUrl,
283                                      final String reportAddress )
284     {
285         super();
286         if ( logDirectory == null )
287         {
288             throw new NullPointerException( "logDirectory" );
289         }
290         if ( trackerUrl == null )
291         {
292             throw new NullPointerException( "trackerUrl" );
293         }
294         if ( reportAddress == null )
295         {
296             throw new NullPointerException( "reportAddress" );
297         }
298 
299         this.logDirectory = logDirectory;
300         this.trackerUrl = trackerUrl;
301         this.reportAddress = reportAddress;
302     }
303 
304     /**
305      * Resolves application messages for a given exception by querying any
306      * available {@code ExceptionMessageResolver} implementation stopping at the
307      * first implementation not returning {@code null}.
308      *
309      * @param exception The exception to resolve application messages for.
310      *
311      * @throws NullPointerException if {@code exception} is {@code null}.
312      */
313     private Message[] resolveMessages( final Exception exception )
314     {
315         if ( exception == null )
316         {
317             throw new NullPointerException( "exception" );
318         }
319 
320         Message[] messages = null;
321         final Specification spec = ModelFactory.getModel().getModules().
322             getSpecification( ExceptionMessageResolver.class.getName() );
323 
324         final Implementation[] resolvers = spec.getImplementations().
325             getImplementations();
326 
327         for ( int i = resolvers.length - 1; i >= 0 && messages == null; i-- )
328         {
329             final ExceptionMessageResolver resolver =
330                 (ExceptionMessageResolver) ContainerFactory.getContainer().
331                 getObject( ExceptionMessageResolver.class,
332                            resolvers[i].getName() );
333 
334             messages = resolver.resolve( exception );
335         }
336 
337         return messages;
338     }
339 
340     //------------------------------------------------ExceptionMessageProducer--
341 }