Project

General

Profile

Download (7.34 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2021 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.ui;
10

    
11

    
12
import org.apache.log4j.Logger;
13
import org.springframework.beans.factory.annotation.Autowired;
14
import org.vaadin.spring.events.EventBus.UIEventBus;
15

    
16
import com.flowingcode.vaadin.addons.errorwindow.WindowErrorHandler;
17
import com.vaadin.navigator.View;
18
import com.vaadin.navigator.ViewDisplay;
19
import com.vaadin.server.ExternalResource;
20
import com.vaadin.server.Page;
21
import com.vaadin.server.Resource;
22
import com.vaadin.server.Responsive;
23
import com.vaadin.server.VaadinRequest;
24
import com.vaadin.server.VaadinSession;
25
import com.vaadin.spring.navigator.SpringViewProvider;
26
import com.vaadin.ui.Component;
27
import com.vaadin.ui.UI;
28
import com.vaadin.ui.themes.ValoTheme;
29

    
30
import eu.etaxonomy.cdm.addon.config.UIDisabledException;
31
import eu.etaxonomy.cdm.database.PermissionDeniedException;
32
import eu.etaxonomy.cdm.vaadin.event.error.DelegatingErrorHandler;
33
import eu.etaxonomy.cdm.vaadin.event.error.ErrorTypeErrorHandlerWrapper;
34
import eu.etaxonomy.cdm.vaadin.event.error.PermissionDeniedErrorHandler;
35
import eu.etaxonomy.cdm.vaadin.event.error.UIDisabledErrorHandler;
36
import eu.etaxonomy.cdm.vaadin.permission.ReleasableResourcesView;
37
import eu.etaxonomy.cdm.vaadin.view.RedirectToLoginView;
38
import eu.etaxonomy.vaadin.ui.UIInitializedEvent;
39
import eu.etaxonomy.vaadin.ui.navigation.NavigationManagerBean;
40

    
41
/**
42
 * @author a.kohlbecker
43
 * @since Nov 11, 2021
44
 */
45
public abstract class AbstractUI extends UI {
46

    
47
    private static final long serialVersionUID = 7430086500775997281L;
48

    
49
    private static Logger logger = Logger.getLogger(AbstractUI.class);
50

    
51
    abstract protected ViewDisplay getViewDisplay();
52

    
53
    @Autowired
54
    protected SpringViewProvider viewProvider;
55

    
56
    @Autowired
57
    final private void setNavigationManagerBean(NavigationManagerBean navigatorBean) {
58
        // logger.debug("setNavigationManagerBean()" + navigatorBean.toString());
59
        setNavigator(navigatorBean);
60
    }
61

    
62
    final private NavigationManagerBean getNavigationManagerBean() {
63
        if(getNavigator() != null) {
64
            return (NavigationManagerBean) getNavigator();
65
        }
66
        return null;
67
    }
68

    
69
    @Autowired
70
    protected UIEventBus uiEventBus;
71

    
72
//    private boolean enabled;
73

    
74
    public AbstractUI() {
75
        super();
76
    }
77

    
78
    public AbstractUI(Component content) {
79
        super(content);
80
    }
81

    
82
    @Override
83
    protected void init(VaadinRequest request) {
84

    
85
        logger.debug(this.getClass().getSimpleName() + ".init()");
86
        registerErrorHandlers();
87

    
88
        configureAccessDeniedView();
89

    
90
        assert getInitialViewName() != null;
91
        assert getViewDisplay() != null;
92

    
93
        logger.debug(this.getClass().getSimpleName() + ".init() ViewDisplay: " + getViewDisplay().getClass().getSimpleName() + ", initialViewName: " + getInitialViewName());
94

    
95
        if(!isEnabled()) {
96
            throw new UIDisabledException(getClass().getSimpleName());
97
        }
98

    
99
        initAdditionalContent();
100

    
101
        getNavigationManagerBean().setViewDisplay(getViewDisplay());
102
        getNavigationManagerBean().setDefaultViewName(getInitialViewName());
103

    
104
        Responsive.makeResponsive(this);
105

    
106
        addDetachListener(e -> {
107
            if(getNavigator() != null) {
108
                // no point using viewProvider.getView() without the navigator
109
                for(String viewName : viewProvider.getViewNamesForCurrentUI()){
110
                    View view = viewProvider.getView(viewName);
111
                    if(view != null && view instanceof ReleasableResourcesView) {
112
                        ((ReleasableResourcesView)view).releaseResourcesOnAccessDenied();
113
                    }
114
                }
115
            }
116
        });
117

    
118
        if(getBrandName() != null) {
119
            //TODO create annotation:
120
            // @Styles(files={""}, branding="brand")
121
            //
122
            // the branding can either be specified or can be read from the properties file in .cdmLibrary/remote-webapp/{instance-name}-app.properties
123
            // See CdmUtils for appropriate methods to access this folder
124
            // the 'vaadin://' protocol refers to the VAADIN folder
125
            Resource registryCssFile = new ExternalResource("vaadin://branding/" + getBrandName() + "/css/branding.css");
126
            Page.getCurrent().getStyles().add(registryCssFile);
127
        }
128

    
129
        uiEventBus.publish(this, new UIInitializedEvent());
130
    }
131

    
132
//    /**
133
//     * @return
134
//     */
135
//    @Override
136
//    protected abstract String getUIName();
137

    
138
    /**
139
     * @return The name of the initial view to show
140
     */
141
    abstract protected String getInitialViewName();
142

    
143
    /**
144
     * Branding can either be specified or can be read from the properties file
145
     * in <code>.cdmLibrary/remote-webapp/{instance-name}-app.properties</code>
146
     * See CdmUtils for appropriate methods to access this folder the
147
     * <code>'vaadin://'</code> protocol refers to the VAADIN folder.
148
     * <p>
149
     * Can be overridden by implementing classes to set a brand.
150
     *
151
     * @return <code>NULL</code> for no branding or
152
     */
153
    protected String getBrandName() {
154
        return null;
155
    }
156

    
157
    /**
158
     * Implementing classes may add additional content to the UI. This
159
     * will for example be interesting when using the {@link ValoTheme.UI_WITH_MENU}
160
     * style.
161
     */
162
    abstract protected void initAdditionalContent();
163

    
164
    protected void registerErrorHandlers() {
165
        DelegatingErrorHandler delegatingErrorHander = new DelegatingErrorHandler();
166
        WindowErrorHandler errorHandler = new WindowErrorHandler(
167
                this,
168
                RegistrationUIDefaults.ERROR_CONTACT_MESSAGE_LINE + "</br></br>"
169
                + "<i>To help analyzing the problem please describe your actions that lead to this error and provide the error details from below in your email. "
170
                + "You also might want to add a sreenshot of the browser page in error.</i>");
171
        delegatingErrorHander.registerHandler(
172
                new ErrorTypeErrorHandlerWrapper<PermissionDeniedException>(PermissionDeniedException.class, new PermissionDeniedErrorHandler(this))
173
                );
174
        delegatingErrorHander.registerHandler(
175
                new ErrorTypeErrorHandlerWrapper<UIDisabledException>(UIDisabledException.class, new UIDisabledErrorHandler(this))
176
                );
177
        delegatingErrorHander.registerHandler(
178
                new ErrorTypeErrorHandlerWrapper<Exception>(Exception.class, errorHandler)
179
                );
180
        setErrorHandler(delegatingErrorHander);
181
        VaadinSession.getCurrent().setErrorHandler(delegatingErrorHander);
182
    }
183

    
184
    protected void configureAccessDeniedView() {
185
        viewProvider.setAccessDeniedViewClass(RedirectToLoginView.class);
186
    }
187

    
188
    private String pageFragmentAsState() {
189
        Page page = Page.getCurrent();
190
        String fragment = page.getUriFragment();
191
        String state = null;
192
        if(fragment != null && fragment.startsWith("!")){
193
            state = fragment.substring(1, fragment.length());
194
        }
195
        return state;
196
    }
197

    
198
//    @Override
199
//   public void setEnabled(boolean state) {
200
//        this.enabled = state;
201
//    }
202
//
203
//    @Override
204
//   public boolean isEnabled() {
205
//        return enabled;
206
//    }
207

    
208

    
209
}
(2-2/12)