View Javadoc
1   package fr.ifremer.quadrige3.ui.swing;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 UI Common
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  import fr.ifremer.quadrige3.ui.swing.action.AbstractAction;
28  import jaxx.runtime.swing.JAXXRuntimeException;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.nuiton.jaxx.application.ApplicationTechnicalException;
32  import org.nuiton.jaxx.application.swing.action.ApplicationActionException;
33  import org.springframework.security.access.AccessDeniedException;
34  import org.springframework.security.core.AuthenticationException;
35  
36  import java.lang.reflect.InvocationTargetException;
37  
38  /**
39   * <p>ExceptionHandler class.</p>
40   *
41   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
42   */
43  public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
44  
45      private static final Log LOG = LogFactory.getLog(ExceptionHandler.class);
46  
47      /** {@inheritDoc} */
48      @Override
49      public void uncaughtException(Thread t, Throwable ex) {
50  
51          if (ex instanceof ClassCastException) {
52  
53              String message = ex.getMessage();
54              if (
55                      "javax.swing.plaf.nimbus.DerivedColor$UIResource cannot be cast to java.awt.Font".equals(message)
56                      || "java.lang.Boolean cannot be cast to javax.swing.Painter".equals(message)
57                      || "java.lang.Character cannot be cast to javax.swing.Painter".equals(message)
58                      || "java.lang.Integer cannot be cast to javax.swing.Painter".equals(message)
59                      || "javax.swing.plaf.FontUIResource cannot be cast to javax.swing.Painter".equals(message)
60                      || "javax.swing.plaf.FontUIResource cannot be cast to java.lang.Boolean".equals(message)
61                      || "javax.swing.plaf.BorderUIResource cannot be cast to java.awt.Font".equals(message)
62                          // not absolutely sure of this message (Mantis #59200)
63                      || "java.lang.ArrayIndexOutOfBoundsException: the rowIndex was 0, but should be int [0,-1]".equals(message)
64                      || "java.lang.IndexOutOfBoundsException: valid viewIndex: 0 <= index < 0 but was: 0".equals(message)
65              ) {
66                  LOG.warn("Swallow Swing error: " + message);
67                  return;
68              }
69  
70          }
71  
72          handleException(t.getName(), ex);
73      }
74  
75      /**
76       * <p>handle.</p>
77       *
78       * @param thrown a {@link java.lang.Throwable} object.
79       */
80      public void handle(Throwable thrown) {
81          // for EDT exceptions
82          handleException(Thread.currentThread().getName(), thrown);
83      }
84  
85      /**
86       * <p>handleException.</p>
87       *
88       * @param tname a {@link java.lang.String} object.
89       * @param ex a {@link java.lang.Throwable} object.
90       */
91      protected void handleException(String tname, Throwable ex) {
92          Throwable cause = ex;
93  
94          // if exception coming from reflection, try to get the target exception
95          while (cause.getCause() instanceof InvocationTargetException) {
96              // try to get inner comprehensive cause
97              cause = cause.getCause();
98          }
99          if (cause instanceof InvocationTargetException) {
100             cause = ((InvocationTargetException) cause).getTargetException();
101         }
102 
103         // threat ApplicationActionException inner exception
104         if (cause instanceof ApplicationActionException) {
105             ApplicationActionException actionException = (ApplicationActionException) cause;
106             Throwable innerException = actionException.getCause();
107 
108             // if inner exception is already managed by the action, avoid it
109             if (actionException.getAction() instanceof AbstractAction
110                 && (innerException instanceof AuthenticationException
111                 || innerException instanceof AccessDeniedException)) {
112                 return;
113             }
114 
115             // try to get next exception
116             cause = innerException;
117         } else {
118             // ApplicationActionException already logged, but log all others
119             if (LOG.isErrorEnabled()) {
120                 LOG.error("Global application exception [" + tname + "]", cause);
121             }
122 
123         }
124         // default exception message
125         String message = cause.getMessage();
126 
127         if (cause instanceof ApplicationTechnicalException) {
128             cause = cause.getCause();
129         }
130 
131         if (cause instanceof JAXXRuntimeException) {
132             cause = cause.getCause();
133             message = cause.getMessage();
134         }
135 
136         // TODO à tester
137         ApplicationUIContext.getInstance().getErrorHelper().showErrorDialog(message, cause);
138 //        JOptionPane.showMessageDialog(null, message, "Global application exception", JOptionPane.ERROR_MESSAGE);
139 
140     }
141 }