Project

General

Profile

Download (3.43 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.event.error;
10

    
11
import java.lang.reflect.InvocationTargetException;
12
import java.util.ArrayList;
13
import java.util.List;
14

    
15
import org.apache.logging.log4j.LogManager;
16
import org.apache.logging.log4j.Logger;
17

    
18
import com.vaadin.event.ListenerMethod;
19
import com.vaadin.server.ErrorEvent;
20
import com.vaadin.server.ErrorHandler;
21
import com.vaadin.server.ServerRpcManager.RpcInvocationException;
22
import com.vaadin.ui.Notification;
23

    
24
/**
25
 * Vaadin allows setting an com.vaadin.server.ErrorHandler for UIs and components.
26
 * The caveat with this built in approach is that there is only one {@link com.vaadin.server.ErrorHandler}
27
 * for any type of errors. This <code>DelegatingErrorHandler</code> allows registering handlers for specific types of errors.
28
 *
29
 * see https://dev.e-taxonomy.eu/redmine/issues/7241
30
 *
31
 * @author freimeier
32
 * @author a.kohlbecker
33
 *
34
 */
35
public class DelegatingErrorHandler implements ErrorHandler{
36

    
37
    private static final long serialVersionUID = 3378605204517477112L;
38

    
39
    private final static Logger logger = LogManager.getLogger();
40

    
41
    List<ErrorTypeHandler<? extends Throwable>> handlers = new ArrayList<>();
42

    
43
    public <E extends Throwable> void  registerHandler(ErrorTypeHandler<E> handler) {
44
        assert findHandler(handler.supports()) == null;
45
        handlers.add(handler);
46
    }
47

    
48
    @SuppressWarnings("unchecked")
49
    public <E extends Throwable> ErrorTypeHandler<E> findHandler(Class<E> errorClass){
50
        for(ErrorTypeHandler<?> h : handlers){
51
            if(h.supports().isAssignableFrom(errorClass)){
52
                return (ErrorTypeHandler<E>) h;
53
            }
54
        }
55
        return null;
56

    
57
    }
58

    
59
    /* (non-Javadoc)
60
     * @see com.vaadin.server.ErrorHandler#error(com.vaadin.server.ErrorEvent)
61
     */
62
    @Override
63
    public void error(ErrorEvent event) {
64

    
65
        Throwable throwable = event.getThrowable();
66
        while(throwable != null && (
67
                RpcInvocationException.class.isAssignableFrom(throwable.getClass()) ||
68
                InvocationTargetException.class.isAssignableFrom(throwable.getClass()) ||
69
                ListenerMethod.MethodException.class.isAssignableFrom(throwable.getClass())
70
                )
71
            ){
72
            // we are only interested into the cause in these cases
73
            throwable = throwable.getCause().getCause();
74
        }
75
        if(throwable == null){
76
            // nothing more specific found, use the original exception
77
            throwable = event.getThrowable();
78
        }
79
        while(throwable != null){
80
            event.setThrowable(throwable);
81
            if(delegate(event, throwable)){
82
                break;
83
            }
84
            throwable = throwable.getCause();
85
        }
86
        if(event.getThrowable() != null){
87
            Notification.show(event.getThrowable().getMessage());
88
          }
89
    }
90

    
91
    private <E extends Throwable> boolean delegate(ErrorEvent event, E throwable){
92

    
93
        Class<E> errorClass = (Class<E>) throwable.getClass();
94
        logger.debug(errorClass);
95
        ErrorTypeHandler<E> handler = findHandler(errorClass);
96
        if(handler != null){
97
            handler.handleError(event, throwable);
98
            return true;
99
        }
100
        return false;
101
    }
102
}
(1-1/6)