Project

General

Profile

Download (9.93 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.addon.config;
10

    
11
import java.io.IOException;
12
import java.util.Arrays;
13
import java.util.Properties;
14

    
15
import javax.servlet.annotation.WebServlet;
16

    
17
import org.apache.log4j.Logger;
18
import org.springframework.beans.BeansException;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.context.ApplicationContext;
21
import org.springframework.context.ApplicationContextAware;
22
import org.springframework.context.annotation.Bean;
23
import org.springframework.context.annotation.ComponentScan;
24
import org.springframework.context.annotation.ComponentScan.Filter;
25
import org.springframework.context.annotation.Configuration;
26
import org.springframework.context.annotation.FilterType;
27
import org.springframework.context.annotation.Lazy;
28
import org.springframework.security.authentication.AuthenticationProvider;
29

    
30
import com.vaadin.server.DeploymentConfiguration;
31
import com.vaadin.server.ServiceException;
32
import com.vaadin.server.VaadinServletService;
33
import com.vaadin.spring.annotation.EnableVaadin;
34
import com.vaadin.spring.annotation.SpringUI;
35
import com.vaadin.spring.annotation.UIScope;
36
import com.vaadin.spring.server.SpringVaadinServlet;
37
import com.vaadin.ui.UI;
38

    
39
import eu.etaxonomy.cdm.api.application.CdmRepository;
40
import eu.etaxonomy.cdm.common.ConfigFileUtil;
41
import eu.etaxonomy.cdm.dataInserter.RegistrationRequiredDataInserter;
42
import eu.etaxonomy.cdm.opt.config.DataSourceConfigurer;
43
import eu.etaxonomy.cdm.vaadin.security.annotation.EnableAnnotationBasedAccessControl;
44
import eu.etaxonomy.cdm.vaadin.server.CdmSpringVaadinServletService;
45
import eu.etaxonomy.cdm.vaadin.ui.ConceptRelationshipUI;
46
import eu.etaxonomy.cdm.vaadin.ui.DistributionStatusUI;
47
import eu.etaxonomy.cdm.vaadin.ui.InactiveUIException;
48
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUI;
49
import eu.etaxonomy.cdm.vaadin.ui.StatusEditorUI;
50
import eu.etaxonomy.vaadin.ui.annotation.EnableVaadinSpringNavigation;
51

    
52
/**
53
 *
54
 * @author a.kohlbecker
55
 * @since Feb 8, 2017
56
 *
57
 */
58
@Configuration
59
@ComponentScan(basePackages={
60
        "eu.etaxonomy.vaadin.ui",
61
        "eu.etaxonomy.cdm.vaadin",
62
        "eu.etaxonomy.cdm.service",
63
        "org.springframework.context.event"
64
        },
65
        // exclude UI classes, these are provided via the @Bean annotated methods below
66
        excludeFilters={@Filter(
67
                pattern="eu\\.etaxonomy\\.cdm\\.vaadin\\.ui\\..*",
68
                type=FilterType.REGEX
69
                )
70
            })
71
@EnableVaadin   // this imports VaadinConfiguration
72
@EnableVaadinSpringNavigation // activate the NavigationManagerBean
73
@EnableAnnotationBasedAccessControl // enable annotation based per view access control
74
public class CdmVaadinConfiguration implements ApplicationContextAware  {
75

    
76
    /**
77
     *
78
     */
79
    private static final String CDM_VAADIN_UI_ACTIVATED = "cdm-vaadin.ui.activated";
80

    
81
    public static final Logger logger = Logger.getLogger(CdmVaadinConfiguration.class);
82

    
83
    @Autowired
84
    @Lazy
85
    //FIXME consider to set the instanceName (instanceID) in the spring environment to avoid a bean reference here
86
    private DataSourceConfigurer dataSourceConfigurer;
87

    
88
    /*
89
     * NOTE: It is necessary to map the URLs starting with /VAADIN/* since none of the
90
     * @WebServlets is mapped to the root path. It is sufficient to configure one of the
91
     * servlets with this path see BookOfVaadin 5.9.5. Servlet Mapping with URL Patterns
92
     */
93
    @WebServlet(value = {"/app/*", "/VAADIN/*"}, asyncSupported = true)
94
    public static class Servlet extends SpringVaadinServlet {
95

    
96
        private static final long serialVersionUID = -2615042297393028775L;
97

    
98
        @Override
99
        protected VaadinServletService createServletService(
100
                DeploymentConfiguration deploymentConfiguration)
101
                throws ServiceException {
102

    
103
            //  - The SpringVaadinServletService is needed when using a custom service URL
104
            //  - The CdmSpringVaadinServletService allows to attach listeners to the requestEnd and
105
            //    requestStart method this is important for proper unbinding of Conversations from
106
            //    the request threads.
107
            //    see ViewScopeConversationHolder
108
            CdmSpringVaadinServletService service = new CdmSpringVaadinServletService(
109
                    this, deploymentConfiguration, getServiceUrlPath());
110
            service.init();
111
            return service;
112
        }
113

    
114
        /**
115
         *
116
        @SuppressWarnings("serial")
117
        @Override
118
        protected void servletInitialized() throws ServletException {
119
            getService().addSessionInitListener(new SessionInitListener() {
120

    
121
                @Override
122
                public void sessionInit(SessionInitEvent sessionInitEvent) throws ServiceException {
123
                    VaadinSession session = sessionInitEvent.getSession();
124
                    session.setErrorHandler(new DefaultErrorHandler(){
125

    
126
                        @Override
127
                        public void error(ErrorEvent errorEvent) {
128
                            if(errorEvent.getThrowable() instanceof InactiveUIException){
129
                                //TODO redirect to an ErrorUI or show and error Page
130
                                // better use Spring MVC Error handlers instead?
131
                            } else {
132
                                doDefault(errorEvent);
133
                            }
134
                        }
135

    
136
                    });
137

    
138
                }});
139

    
140
        }
141
         */
142

    
143
    }
144

    
145
    public CdmVaadinConfiguration() {
146
        logger.debug("CdmVaadinConfiguration enabled");
147
    }
148

    
149
    @Bean
150
    @UIScope
151
    public ConceptRelationshipUI conceptRelationshipUI() throws InactiveUIException {
152
        if(isUIEnabled(ConceptRelationshipUI.class)){
153
            return new ConceptRelationshipUI();
154
        }
155
        return null;
156
    }
157

    
158
    @Bean
159
    @UIScope
160
    public RegistrationUI registrationUI() throws InactiveUIException {
161
        if(isUIEnabled(RegistrationUI.class)){
162
            return new RegistrationUI();
163
        }
164
        return null;
165
    }
166

    
167
    @Bean
168
    public RegistrationRequiredDataInserter registrationRequiredDataInserter() throws BeansException, InactiveUIException{
169
        RegistrationRequiredDataInserter inserter = null;
170
        if(isUIEnabled(RegistrationUI.class)){
171
            inserter = new RegistrationRequiredDataInserter();
172
            inserter.setRunAsAuthenticationProvider((AuthenticationProvider) applicationContext.getBean("runAsAuthenticationProvider"));
173
            inserter.setCdmRepository((CdmRepository) applicationContext.getBean("cdmRepository"));
174
        }
175
        return inserter;
176
    }
177

    
178
    @Bean
179
    @UIScope
180
    public DistributionStatusUI distributionStatusUI() throws InactiveUIException {
181
        if(isUIEnabled(DistributionStatusUI.class)){
182
            return new DistributionStatusUI();
183
        }
184
        return null;
185
    }
186

    
187
    @Bean
188
    @UIScope
189
    public StatusEditorUI statusEditorUI() throws InactiveUIException {
190
        if(isUIEnabled(StatusEditorUI.class)){
191
            return new StatusEditorUI();
192
        }
193
        return null;
194
    }
195

    
196
    static final String PROPERTIES_NAME = "vaadin-apps";
197

    
198
    private Properties appProps = null;
199

    
200
    private ApplicationContext applicationContext;
201

    
202
    //@formatter:off
203
    private static final String APP_FILE_CONTENT=
204
            "########################################################\n"+
205
            "#                                                       \n"+
206
            "# Vaadin application specific configurations            \n"+
207
            "#                                                       \n"+
208
            "########################################################\n"+
209
            "                                                        \n"+
210
            "# Enablement of vaadin uis.                             \n"+
211
            "#                                                       \n"+
212
            "# Multiple uis can be defined as comma separated list.  \n"+
213
            "# Whitespace before and after the comma will be ignored.\n"+
214
            "# Valid values are the path properties of the @SpringUI \n"+
215
            "# annotation which is used for UI classes.              \n"+
216
            "cdm-vaadin.ui.activated=concept,distribution,editstatus \n";
217
    //@formatter:on
218

    
219
    /**
220
     * Checks if the ui class supplied is activated by listing it in the properties by its {@link SpringUI#path()} value.
221
     *
222
     * @param type
223
     * @return
224
     * @throws InactiveUIException
225
     */
226
    private boolean isUIEnabled(Class<? extends UI>uiClass) throws InactiveUIException {
227

    
228
        String path = uiClass.getAnnotation(SpringUI.class).path().trim();
229

    
230
        try {
231
            if(appProps == null){
232
                String currentDataSourceId = dataSourceConfigurer.dataSourceProperties().getCurrentDataSourceId();
233
                appProps = new ConfigFileUtil()
234
                        .setDefaultContent(APP_FILE_CONTENT)
235
                        .getProperties(currentDataSourceId, PROPERTIES_NAME);
236
            }
237
            if(appProps.get(CDM_VAADIN_UI_ACTIVATED) != null){
238
                String[] uiPaths = appProps.get(CDM_VAADIN_UI_ACTIVATED).toString().split("\\s*,\\s*");
239
                if(Arrays.asList(uiPaths).stream().anyMatch(p -> p.trim().equals(path))){
240
                    return true;
241
                }
242
            }
243
            throw new InactiveUIException(path); // FIXME should return false instead
244
        } catch (IOException e) {
245
            logger.error("Error reading the vaadin ui properties file. File corrupted?. Stopping instance ...");
246
            throw new RuntimeException(e);
247
        }
248
    }
249

    
250
    /**
251
     * {@inheritDoc}
252
     */
253
    @Override
254
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
255
        this.applicationContext = applicationContext;
256

    
257
    }
258

    
259

    
260
}
(1-1/2)