Project

General

Profile

Download (11.2 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.List;
14
import java.util.Properties;
15

    
16
import javax.servlet.annotation.WebServlet;
17

    
18
import org.apache.log4j.Logger;
19
import org.hibernate.SessionFactory;
20
import org.hibernate.event.service.spi.EventListenerRegistry;
21
import org.hibernate.event.spi.EventType;
22
import org.hibernate.internal.SessionFactoryImpl;
23
import org.springframework.beans.BeansException;
24
import org.springframework.beans.factory.annotation.Autowired;
25
import org.springframework.context.ApplicationContext;
26
import org.springframework.context.ApplicationContextAware;
27
import org.springframework.context.annotation.Bean;
28
import org.springframework.context.annotation.ComponentScan;
29
import org.springframework.context.annotation.ComponentScan.Filter;
30
import org.springframework.context.annotation.Configuration;
31
import org.springframework.context.annotation.FilterType;
32
import org.springframework.core.env.Environment;
33
import org.springframework.security.authentication.AuthenticationProvider;
34
import org.vaadin.spring.events.annotation.EnableEventBus;
35

    
36
import com.vaadin.spring.annotation.EnableVaadin;
37
import com.vaadin.spring.annotation.SpringUI;
38
import com.vaadin.spring.annotation.UIScope;
39
import com.vaadin.spring.server.SpringVaadinServlet;
40
import com.vaadin.ui.UI;
41

    
42
import eu.etaxonomy.cdm.api.application.AbstractDataInserter;
43
import eu.etaxonomy.cdm.api.application.CdmRepository;
44
import eu.etaxonomy.cdm.api.application.DummyDataInserter;
45
import eu.etaxonomy.cdm.api.cache.CdmCacher;
46
import eu.etaxonomy.cdm.api.config.ApplicationConfiguration;
47
import eu.etaxonomy.cdm.api.config.ApplicationConfigurationFile;
48
import eu.etaxonomy.cdm.api.service.idminter.RegistrationIdentifierMinter;
49
import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher;
50
import eu.etaxonomy.cdm.dataInserter.RegistrationRequiredDataInserter;
51
import eu.etaxonomy.cdm.persistence.hibernate.GrantedAuthorityRevokingRegistrationUpdateLister;
52
import eu.etaxonomy.cdm.vaadin.security.annotation.EnableAnnotationBasedAccessControl;
53
import eu.etaxonomy.cdm.vaadin.ui.ConceptRelationshipUI;
54
import eu.etaxonomy.cdm.vaadin.ui.DistributionStatusUI;
55
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUI;
56
import eu.etaxonomy.cdm.vaadin.ui.StatusEditorUI;
57
import eu.etaxonomy.vaadin.ui.annotation.EnableVaadinSpringNavigation;
58

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

    
84
    public static final String CDM_VAADIN_UI_ACTIVATED = "cdm-vaadin.ui.activated";
85
    public static final String CDM_SERVICE_MINTER_REGSTRATION_MINID = "cdm.service.minter.registration.minLocalId";
86
    public static final String CDM_SERVICE_MINTER_REGSTRATION_MAXID = "cdm.service.minter.registration.maxLocalId";
87
    public static final String CDM_SERVICE_MINTER_REGSTRATION_IDFORMAT = "cdm.service.minter.registration.identifierFormatString";
88

    
89
    public static final Logger logger = Logger.getLogger(CdmVaadinConfiguration.class);
90

    
91
    @Autowired
92
    Environment env;
93

    
94
    @Autowired
95
    private SessionFactory sessionFactory;
96

    
97
    @Autowired
98
    private ApplicationConfiguration appConfig;
99

    
100
    @Autowired
101
    private void  setTermCacher(CdmCacher termCacher){
102
        CdmTransientEntityCacher.setDefaultCacher(termCacher);
103
    }
104

    
105
    private boolean registrationUiHibernateEventListenersDone = false;
106

    
107

    
108
    ApplicationConfigurationFile configFile = new ApplicationConfigurationFile(PROPERTIES_FILE_NAME, APP_FILE_CONTENT);
109

    
110
    /*
111
     * NOTE: It is necessary to map the URLs starting with /VAADIN/* since none of the
112
     * @WebServlets is mapped to the root path. It is sufficient to configure one of the
113
     * servlets with this path see BookOfVaadin 5.9.5. Servlet Mapping with URL Patterns
114
     */
115
    @WebServlet(value = {"/app/*", "/VAADIN/*"}, asyncSupported = true)
116
    public static class Servlet extends SpringVaadinServlet {
117

    
118
        private static final long serialVersionUID = -2615042297393028775L;
119

    
120

    
121
        /**
122
         *
123
        @SuppressWarnings("serial")
124
        @Override
125
        protected void servletInitialized() throws ServletException {
126
            getService().addSessionInitListener(new SessionInitListener() {
127

    
128
                @Override
129
                public void sessionInit(SessionInitEvent sessionInitEvent) throws ServiceException {
130
                    VaadinSession session = sessionInitEvent.getSession();
131
                    session.setErrorHandler(new DefaultErrorHandler(){
132

    
133
                        @Override
134
                        public void error(ErrorEvent errorEvent) {
135
                            // ...
136
                        }
137

    
138
                    });
139
                    ).getServiceRegistry().getService
140

    
141
                }});
142

    
143
        }
144
         */
145

    
146
    }
147

    
148
    public CdmVaadinConfiguration() {
149
        logger.debug("CdmVaadinConfiguration enabled");
150
    }
151

    
152
    @Bean
153
    @UIScope
154
    public ConceptRelationshipUI conceptRelationshipUI() {
155
        if(isUIEnabled(ConceptRelationshipUI.class)){
156
            return new ConceptRelationshipUI();
157
        }
158
        return null;
159
    }
160

    
161
    @Bean
162
    @UIScope
163
    public RegistrationUI registrationUI() {
164
        if(isUIEnabled(RegistrationUI.class)){
165
            registerRegistrationUiHibernateEventListeners();
166

    
167
            return new RegistrationUI();
168
        }
169
        return null;
170
    }
171

    
172
    /**
173
     * this is only a quick implementation for testing,
174
     * TODO see also the NOTE on CdmListenerIntegrator class declaration for a prospective better solution
175
     */
176
    protected void registerRegistrationUiHibernateEventListeners() {
177
        if(!registrationUiHibernateEventListenersDone){
178
            EventListenerRegistry listenerRegistry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
179
                    EventListenerRegistry.class);
180
            GrantedAuthorityRevokingRegistrationUpdateLister listener = new GrantedAuthorityRevokingRegistrationUpdateLister();
181
            listenerRegistry.appendListeners(EventType.POST_UPDATE, listener);
182
            registrationUiHibernateEventListenersDone = true;
183
        }
184
    }
185

    
186
    @Bean
187
    public AbstractDataInserter registrationRequiredDataInserter() throws BeansException{
188
        if(isUIEnabled(RegistrationUI.class)){
189
            RegistrationRequiredDataInserter inserter = new RegistrationRequiredDataInserter();
190

    
191
            inserter.setRunAsAuthenticationProvider((AuthenticationProvider) applicationContext.getBean("runAsAuthenticationProvider"));
192
            inserter.setCdmRepository((CdmRepository) applicationContext.getBean("cdmRepository"));
193
            return inserter;
194
        } else {
195
            // the return type implements ApplicationListener and thus must not be null,
196
            // therefore we return a empty dummy implementation.
197
            return new DummyDataInserter();
198
        }
199
    }
200

    
201
    @Bean
202
    public RegistrationIdentifierMinter registrationIdentifierMinter() throws IOException {
203
        RegistrationIdentifierMinter minter = new RegistrationIdentifierMinter();
204

    
205
        minter.setMinLocalId(appConfig.getProperty(configFile , CDM_SERVICE_MINTER_REGSTRATION_MINID));
206
        minter.setMaxLocalId(appConfig.getProperty(configFile , CDM_SERVICE_MINTER_REGSTRATION_MAXID));
207
        minter.setIdentifierFormatString(appConfig.getProperty(configFile , CDM_SERVICE_MINTER_REGSTRATION_IDFORMAT));
208
        return minter;
209
    }
210

    
211
    @Bean
212
    @UIScope
213
    public DistributionStatusUI distributionStatusUI() {
214
        if(isUIEnabled(DistributionStatusUI.class)){
215
            return new DistributionStatusUI();
216
        }
217
        return null;
218
    }
219

    
220
    @Bean
221
    @UIScope
222
    public StatusEditorUI statusEditorUI() {
223
        if(isUIEnabled(StatusEditorUI.class)){
224
            return new StatusEditorUI();
225
        }
226
        return null;
227
    }
228

    
229

    
230

    
231

    
232
    static final String PROPERTIES_FILE_NAME = "vaadin-apps";
233

    
234
    private Properties appProps = null;
235

    
236
    private ApplicationContext applicationContext;
237

    
238
    private List<String> activeUIpaths;
239

    
240
    //@formatter:off
241
    private static final String APP_FILE_CONTENT=
242
            "########################################################\n"+
243
            "#                                                       \n"+
244
            "# Vaadin application specific configurations            \n"+
245
            "#                                                       \n"+
246
            "########################################################\n"+
247
            "                                                        \n"+
248
            "# Enablement of vaadin uis.                             \n"+
249
            "#                                                       \n"+
250
            "# Multiple uis can be defined as comma separated list.  \n"+
251
            "# Whitespace before and after the comma will be ignored.\n"+
252
            "# Valid values are the path properties of the @SpringUI \n"+
253
            "# annotation which is used for UI classes.              \n"+
254
            "cdm-vaadin.ui.activated=concept,distribution,editstatus \n";
255
    //@formatter:on
256

    
257
    /**
258
     * Checks if the ui class supplied is activated by listing it in the properties by its {@link SpringUI#path()} value.
259
     *
260
     * TODO see https://dev.e-taxonomy.eu/redmine/issues/7139 (consider using spring profiles to enable vaadin UI contexts)
261
     *
262
     * @param type
263
     * @return
264
     */
265
    private boolean isUIEnabled(Class<? extends UI>uiClass) {
266

    
267
        String path = uiClass.getAnnotation(SpringUI.class).path().trim();
268

    
269
        if(activeUIpaths == null){
270
            String activatedVaadinUIs = env.getProperty(CDM_VAADIN_UI_ACTIVATED);
271
            if(activatedVaadinUIs == null){
272
                // not in environment? Read it from the config file!
273
                activatedVaadinUIs = appConfig.getProperty(configFile , CDM_VAADIN_UI_ACTIVATED);
274
            }
275

    
276
            if(activatedVaadinUIs != null) {
277
                String[] uiPaths = activatedVaadinUIs.split("\\s*,\\s*");
278
                this.activeUIpaths = Arrays.asList(uiPaths);
279
            }
280
        }
281
        if(activeUIpaths.stream().anyMatch(p -> p.trim().equals(path))){
282
            return true;
283
        }
284
        return false;
285

    
286
    }
287

    
288

    
289

    
290
    /**
291
     * {@inheritDoc}
292
     */
293
    @Override
294
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
295
        this.applicationContext = applicationContext;
296
    }
297

    
298

    
299
}
(1-1/2)