View Javadoc
1   /*
2    * @(#) MirkE_ExceptionHandler.java
3    *
4    * Created by:Tod Barnett on 3 Febuary, 2005.
5   
6   Copyright (c) 2004 Arizona State University - Cancer Research Institute. All rights reserved.
7   
8   MirkE is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12  
13  MirkE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17  
18  You should have received a copy of the GNU General Public License
19  along with MirkE; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
21  
22   */
23   package> edu.asu.cri.MirkE.trace;
24  
25  import java.awt.BorderLayout;
26  import java.awt.Component;
27  import java.awt.Dimension;
28  import java.awt.Toolkit;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import edu.asu.cri.MirkE.trace.MirkELogger;
32  import javax.swing.BorderFactory;
33  import javax.swing.JButton;
34  import javax.swing.JDialog;
35  import javax.swing.JPanel;
36  import javax.swing.JScrollPane;
37  import javax.swing.JTextArea;
38  import javax.swing.border.BevelBorder;
39  
40  /***
41   * Displays error messages to the user in a dialog box
42   * created has a getInstance factory method that returns a
43   * new instance of this dialog. the handler extracts the stack trace
44   * and message from the exception and displays them in a dialog
45   *
46   * <pre>
47   *    MirkE_ExceptionHandler  MirkE_ExceptionHandlerr = MirkE_ExceptionHandler.getInstance();
48   *    MirkE_ExceptionHandler.exceptionHandler(exception);
49   * </pre>
50   *
51   * @author  @author  Tod Barnett
52   * @version 1.0
53   * @see     javax.swing.JDialog
54   *
55   */
56  public class MirkE_ExceptionHandler extends JDialog {
57      /***
58  	 * Comment for <code>serialVersionUID</code>
59  	 */
60  	private static final long serialVersionUID = 3832620673154954808L;
61  
62  	/***
63       * instance of an MirkE_ExceptionHandler
64       */
65      private static MirkE_ExceptionHandler handlerInstance;
66  
67      /***
68      * layout manager
69      */
70      private BorderLayout bLayout = new BorderLayout();
71  
72      /***
73       * the parent component that requested the instantiation of this
74       * exception handler
75       */
76      private Component parent;
77  
78      /***
79       * close dialog button
80       */
81      private JButton closeButton;
82  
83      /***
84       * show the error detail button
85       */
86      private JButton detailButton;
87  
88      /***
89       * container for the button panel
90       */
91      private JPanel buttonPanel;
92  
93      /***
94       * panel that the stack trace will be extracted into
95       */
96      private JPanel detailPanel;
97  
98      /***
99       * top of message display panel
100      */
101     private JPanel summaryPanel;
102 
103     /***
104      * scrollpane for the stack trace information
105      */
106     private JScrollPane detailScrollPane;
107 
108     /***
109      * scrollpane for the exception summary information
110      */
111     private JScrollPane summaryScrollPane;
112 
113     /***
114      * shows the stack trace information
115      */
116     private JTextArea detailText;
117 
118     /***
119      * shows the exception message
120      */
121     private JTextArea summaryText;
122 
123     /***
124      * logging function
125      */
126     private MirkELogger log = new MirkELogger();
127 
128 
129     /*** Trace switch
130      *
131      * */
132 
133    private static boolean trace;  //false; // default
134    
135    
136    private static long mirkeInstanceId;
137    /*** create error map for a new instance of mirke flag
138    *	
139    * */
140 
141 
142  private static boolean newMap;  //false; // default
143     /***
144      * Creates a new <code> MirkE_ExceptionHandler<code> instance
145      * this parent dialog is set to model<code>true<code>
146      */
147     public MirkE_ExceptionHandler() {
148         super();
149         super.setModal(true);
150         init();
151     }
152 
153     /***handleException
154      * handles a throwable <code>Exception<code> the exception may or may not have a <code>cause <code>set.
155      * if the <code>cause <code>is set then the exception being handled is a wraper for <code>cause<code>.
156      *
157      * @param exception Throwable
158      * @see edu.asu.cri.MirkE.exceptions.MirkEIOException
159      * @see edu.asu.cri.MirkE.exceptions.MirkETransactionException
160      * @see edu.asu.cri.MirkE.exceptions.MirkEApplicationException
161      * @seeedu.asu.cri.MirkE.exceptions.MirkEFileNotFoundException
162      * @see java.lang.Exception
163      */
164     public void handleException(Throwable exception) {
165         System.out.println("handle exception 1");
166         resetHandler();
167         System.out.println("handle exception 2");
168         showException(exception);
169         System.out.println("handle exception 3");
170         setVisible(true);
171         System.out.println("handle exception 4");
172         //pack();
173         System.out.println("handle exception 5");
174         //show();
175         System.out.println("handle exception 6");
176 
177     }
178 
179     /*** handleException
180      * extract and display the exception information
181      *
182      * @param message String
183      * @param exception Throwable
184      * @see #handleException(Throwable exception)
185      */
186     public void handleException(String message, Throwable exception) {
187         resetHandler();
188         showException(message, exception);
189         setVisible(true);
190         pack();
191         show();
192 
193     }
194     /***
195      * append an exception message to the list of exceptions and refresh the view
196      * XXXX
197      * @param exception
198      */
199     public void append(Throwable exception){
200 
201         if (exception.getCause() != null) {
202             summaryText.setText(exception.getCause().getLocalizedMessage());    //support internationalisation
203             detailText.setText(convertException(exception.getCause()));
204             setTitle(exception.getCause().getClass().getName());
205         } else {
206             summaryText.setText(exception.getLocalizedMessage());
207             detailText.setText(convertException(exception));
208             setTitle(exception.getClass().getName());
209         }
210         validate();
211     }
212 
213     /***
214      * initialise components
215      */
216     private void init() {
217         this.setSize(400, 300);
218         this.getContentPane().setLayout(bLayout);
219         this.setResizable(false);
220         summaryPanel = new JPanel();
221         summaryText = new JTextArea();
222         detailPanel = new JPanel();
223         detailText = new JTextArea();
224         detailButton = new JButton("Detail");
225         closeButton = new JButton("Close");
226         buttonPanel = new JPanel();
227         detailScrollPane = new JScrollPane();
228         summaryScrollPane = new JScrollPane();
229         summaryScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
230         summaryPanel.setMinimumSize(new Dimension(100, 300));
231         summaryPanel.setBorder(BorderFactory.createBevelBorder(
232                 BevelBorder.RAISED));
233         summaryText.setRows(4);
234         summaryText.setColumns(100);
235         summaryText.setLineWrap(false);
236         summaryText.setEditable(false);
237         summaryPanel.add(summaryText);
238         detailText.setLineWrap(true);
239         detailText.setColumns(50);
240         detailText.setEditable(false);
241         summaryScrollPane.getViewport().add(summaryPanel);
242         detailScrollPane.getViewport().add(detailPanel);
243         detailPanel.add(detailText);
244         detailPanel.setMinimumSize(new Dimension(350, 300));
245         detailPanel.setBorder(BorderFactory.createBevelBorder(
246                 BevelBorder.RAISED));
247         this.getContentPane().add(summaryScrollPane, BorderLayout.NORTH);
248         detailButton = new JButton("Detail");
249         closeButton = new JButton("Close");
250         buttonPanel = new JPanel();
251         buttonPanel.add(detailButton);
252         buttonPanel.add(closeButton);
253         this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
254 
255         Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
256         int gridx = (int) ((dimension.getWidth() - this.getWidth()) / 2);
257         int gridy = (int) ((dimension.getHeight() - this.getHeight()) / 2);
258         this.setLocation(gridx, gridy);
259 
260         detailButton.addActionListener(new ActionListener() {
261                 public void actionPerformed(ActionEvent ae) {
262                     detailScrollPane.setMinimumSize(new Dimension(350, 300));
263                     getContentPane().add(detailScrollPane, BorderLayout.CENTER);
264                     validate();
265                 }
266             });
267 
268         closeButton.addActionListener(new ActionListener() {
269                 public void actionPerformed(ActionEvent ae) {
270                     setVisible(false);
271                     hide();
272                     summaryText.setText("");
273                     detailText.setText("");
274                     setTitle("");
275 
276                 }
277             });
278         validate();
279         hide();
280     }
281 
282     /*
283      *
284      *
285      * @param exception
286      */
287     private void showException(Throwable exception) {
288         System.out.println("handle show exception 1");
289         if (((Exception)exception).getCause() != null) {
290             System.out.println("handle show exception 2");
291             summaryText.setText(exception.getCause().getLocalizedMessage());    //support internationalisation
292             detailText.setText(convertException(exception.getCause()));
293             setTitle(exception.getCause().getClass().getName());
294         } else {
295             System.out.println("handle show exception 3");
296             summaryText.setText(exception.getLocalizedMessage());
297             detailText.setText(convertException(exception));
298             setTitle(exception.getClass().getName());
299         }
300         System.out.println("handle show exception 4");
301         validate();
302     }
303 
304     /*
305      * clear screen messages
306      */
307     private void resetHandler() {
308         summaryText.setText("");
309         detailText.setText("");
310     }
311 
312     /***
313      * enable aspect tracing
314      * @param trace true/false
315      * */
316     public static void setTraceEnabled(boolean newTrace){
317         trace = newTrace;
318     }
319 
320     /***
321      *  aspect tracing
322      *
323      * @return boolean true/false
324      * */
325     public static boolean getTraceEnabled(){
326         return trace;
327     }
328     /***
329      * ShowException
330      *
331      * @param msg message extracted from exception
332      * @param exception
333      */
334     private void showException(String msg, Throwable exception) {
335         StringBuffer buf = new StringBuffer();
336         buf.append(msg);
337         buf.append("\n");
338 
339         if (exception.getCause() != null) {
340             buf.append(exception.getCause().getLocalizedMessage());
341             summaryText.setText(buf.toString());    //support internationalisation
342             detailText.setText(convertException(exception.getCause()));
343             setTitle(exception.getCause().getClass().getName());
344         } else {
345             buf.append(exception.getLocalizedMessage());
346             summaryText.setText(buf.toString());
347             detailText.setText(convertException(exception));
348             setTitle(exception.getClass().getName());
349         }
350 
351         validate();
352     }
353 
354     /*
355      * Extract the stack trace
356      */
357     private String convertException(Throwable exception) {
358         StringBuffer buff = new StringBuffer();
359         StackTraceElement[] trace = exception.getStackTrace();
360 
361         if (trace.length > 0) {
362             for (int i = 0; i < trace.length; i++) {
363                 buff.append(trace[i].toString());
364                 buff.append("\n");
365             }
366         }
367 
368         return buff.toString();
369     }
370 
371     /***
372      * set the parent for this <CODE>Component</CODE> of this exception handler
373      *
374      * @param parent Component - the Component initialising this exception handler
375      */
376     public void setParent(Component parent) {
377         this.parent = parent;
378     }
379 
380     /***
381      * Class method returns a new instance of <code>MirkE_ExceptionHandler<code>
382      *
383      * @return MirkE_ExceptionHandler instance
384      */
385     public static synchronized MirkE_ExceptionHandler getInstance() {
386        if(handlerInstance == null){
387            handlerInstance = new MirkE_ExceptionHandler();
388            System.out.println("***** initialised an exception  handler ");
389        }
390         return handlerInstance;
391     }
392     /*** A new instance of mirke has been created  so we
393      * need a new map for the errors generated by this instance
394      * @param boolean - aNewMap true/false
395      * @param long  instanceId - mirke instance id 
396      * */
397     public static void setErrorMapRequired(boolean aNewMap,long instanceId){
398         newMap = aNewMap;
399         mirkeInstanceId = instanceId;
400     }
401     
402     /*** A new instance of mirke has been created  so we
403      * need a new map for the errors generated by this instance
404      * @return boolean - newMap true/false
405      * 
406      * */
407     public static boolean getErrorMapRequired(){
408         return newMap;
409     }
410    /***
411  *
412  */
413 public synchronized void showMe(){
414        show();
415    }
416 
417     /***
418      * debug method
419      * @param object
420      */
421     private void debug(Object object) {
422         log.warning("MirkE_ExceptionHandler",object.toString());
423     }
424 }