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 8641 2012-09-27 06:45:17Z 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(
127                         new BugReportMessage( this.logDirectory,
128                                               this.trackerUrl,
129                                               this.reportAddress ) );
130 
131                 }
132             }
133             else if ( rootCause instanceof Exception )
134             {
135                 final Message[] resolved =
136                     this.resolveMessages( (Exception) rootCause );
137 
138                 if ( resolved != null )
139                 {
140                     messages.addMessages( resolved );
141                 }
142             }
143 
144             this.getApplicationLogger().log(
145                 new MessageEvent( this,
146                                   messages.getMessages(),
147                                   MessageEvent.ERROR ) );
148 
149         }
150     }
151 
152     //-------------------------------------------------------ExceptionListener--
153     //--ExceptionReporter-------------------------------------------------------
154 
155     /**
156      * Directory holding the application's log files.
157      * @serial
158      */
159     private File logDirectory;
160 
161     /**
162      * URL of the online bugtracking system.
163      * @serial
164      */
165     private URL trackerUrl;
166 
167     /**
168      * Mail address to send the bugreport to.
169      * @serial
170      */
171     private String reportAddress;
172 
173     /** Creates a new {@code ExceptionMessageProducer} instance. */
174     public ExceptionMessageProducer()
175     {
176         super();
177         this.logDirectory = null;
178         this.trackerUrl = null;
179         this.reportAddress = null;
180     }
181 
182     /**
183      * Creates a new {@code ExceptionMessageProducer} instance taking the
184      * application's logfile directory, an URL to the application's online
185      * bugtracking system, and an email address where to send bugreports to
186      * alternatively.
187      *
188      * @param logDirectory the directory holding the application's logfiles.
189      * @param trackerUrl an URL to the application's online bugtracking system.
190      * @param reportAddress an email address to alternatively send bugreports
191      * to.
192      *
193      * @throws NullPointerException if either {@code logDirectory},
194      * {@code trackerUrl} or {@code reportAddress} is {@code null}.
195      */
196     public ExceptionMessageProducer( final File logDirectory,
197                                      final URL trackerUrl,
198                                      final String reportAddress )
199     {
200         super();
201         if ( logDirectory == null )
202         {
203             throw new NullPointerException( "logDirectory" );
204         }
205         if ( trackerUrl == null )
206         {
207             throw new NullPointerException( "trackerUrl" );
208         }
209         if ( reportAddress == null )
210         {
211             throw new NullPointerException( "reportAddress" );
212         }
213 
214         this.logDirectory = logDirectory;
215         this.trackerUrl = trackerUrl;
216         this.reportAddress = reportAddress;
217     }
218 
219     /**
220      * Resolves application messages for a given exception by querying any
221      * available {@code ExceptionMessageResolver} implementation stopping at the
222      * first implementation not returning {@code null}.
223      *
224      * @param exception the exception to resolve application messages for.
225      *
226      * @throws NullPointerException if {@code exception} is {@code null}.
227      */
228     private Message[] resolveMessages( final Exception exception )
229     {
230         if ( exception == null )
231         {
232             throw new NullPointerException( "exception" );
233         }
234 
235         Message[] messages = null;
236         final Specification spec = ModelFactory.getModel().getModules().
237             getSpecification( ExceptionMessageResolver.class.getName() );
238 
239         final Implementation[] resolvers = spec.getImplementations().
240             getImplementations();
241 
242         for ( int i = resolvers.length - 1; i >= 0 && messages == null; i-- )
243         {
244             final ExceptionMessageResolver resolver =
245                 (ExceptionMessageResolver) ContainerFactory.getContainer().
246                 getObject( ExceptionMessageResolver.class,
247                            resolvers[i].getName() );
248 
249             messages = resolver.resolve( exception );
250         }
251 
252         return messages;
253     }
254 
255     //-------------------------------------------------------ExceptionReporter--
256 }