Project

General

Profile

Download (7.25 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.vaadin.ui.view;
10

    
11
import java.io.Serializable;
12
import java.lang.reflect.Field;
13
import java.lang.reflect.InvocationTargetException;
14
import java.lang.reflect.Method;
15
import java.lang.reflect.ParameterizedType;
16
import java.lang.reflect.Type;
17

    
18
import javax.sql.DataSource;
19

    
20
import org.hibernate.SessionFactory;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.beans.factory.annotation.Qualifier;
23
import org.springframework.context.ApplicationEventPublisher;
24
import org.springframework.context.annotation.Lazy;
25
import org.springframework.transaction.PlatformTransactionManager;
26

    
27
import com.vaadin.spring.annotation.SpringComponent;
28
import com.vaadin.spring.annotation.UIScope;
29

    
30
import eu.etaxonomy.cdm.api.application.CdmRepository;
31
import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService;
32
import eu.etaxonomy.cdm.service.ISpecimenTypeDesignationWorkingSetService;
33
import eu.etaxonomy.cdm.vaadin.view.name.NameTypeDesignationPresenter;
34
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetEditorPresenter;
35
import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
36
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
37
import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
38
import eu.etaxonomy.vaadin.mvp.AbstractView;
39
import eu.etaxonomy.vaadin.ui.navigation.NavigationManager;
40

    
41
/**
42
 * @author a.kohlbecker
43
 * @since May 30, 2017
44
 *
45
 */
46
@SpringComponent
47
@UIScope
48
public class PopupEditorFactory implements Serializable {
49

    
50

    
51
    private static final long serialVersionUID = -3371003970671610677L;
52

    
53
    @Autowired
54
    protected ApplicationEventPublisher eventBus;
55

    
56
    @Autowired
57
    @Qualifier("cdmRepository")
58
    private CdmRepository repo;
59

    
60
    @Autowired
61
    private SessionFactory sessionFactory;
62

    
63
    @Autowired
64
    private DataSource dataSource;
65

    
66
    @Autowired
67
    private PlatformTransactionManager transactionManager;
68

    
69
    @Autowired
70
    private ISpecimenTypeDesignationWorkingSetService specimenTypeDesignationWorkingSetService;
71

    
72
    @Autowired
73
    private IRegistrationWorkingSetService registrationWorkingSetService;
74

    
75
    @Autowired
76
    @Lazy
77
    private NavigationManager navigationManager;
78

    
79
    private Field presenterRepoField;
80
    private Field presenterNavigationManagerField;
81
    private Field presenterEventBusField;
82

    
83
    private Field viewEventBusField;
84
    private Field specimenTypeDesignationWorkingSetServiceField;
85
    private Method viewInjectPresenterMethod;
86

    
87
    private Field Field;
88

    
89
    private Method viewInitMethod;
90

    
91
    public PopupEditorFactory(){
92
        initFieldsAccess();
93
    }
94

    
95

    
96
    /**
97
     *
98
     */
99
    private void initFieldsAccess() {
100

    
101
        try {
102
            presenterRepoField = AbstractPresenter.class.getDeclaredField("repo");
103
            presenterRepoField.setAccessible(true);
104

    
105
            presenterNavigationManagerField = AbstractPresenter.class.getDeclaredField("navigationManager");
106
            presenterNavigationManagerField.setAccessible(true);
107

    
108
            presenterEventBusField = AbstractEditorPresenter.class.getDeclaredField("eventBus");
109
            presenterEventBusField.setAccessible(true);
110

    
111
            viewEventBusField = AbstractView.class.getDeclaredField("eventBus");
112
            viewEventBusField.setAccessible(true);
113

    
114
            viewInjectPresenterMethod = AbstractView.class.getDeclaredMethod("injectPresenter", AbstractPresenter.class);
115
            viewInjectPresenterMethod.setAccessible(true);
116

    
117
            viewInitMethod = AbstractView.class.getDeclaredMethod("init");
118
            viewInitMethod.setAccessible(true);
119

    
120
            specimenTypeDesignationWorkingSetServiceField = SpecimenTypeDesignationWorkingsetEditorPresenter.class.getDeclaredField("specimenTypeDesignationWorkingSetService");
121
            specimenTypeDesignationWorkingSetServiceField.setAccessible(true);
122

    
123
            Field = NameTypeDesignationPresenter.class.getDeclaredField("registrationWorkingSetService");
124
            Field.setAccessible(true);
125

    
126
        } catch (NoSuchFieldException | SecurityException | NoSuchMethodException  e) {
127
            throw new RuntimeException("Severe error during initialization. Please check the classes AbstractPresenter, AbstractEditorPresenter, AbstractView for modificactions.", e);
128
        }
129

    
130
    }
131

    
132

    
133
    /**
134
     * @param popupViewClass
135
     * @return
136
     */
137
    public <V extends PopupView, P extends AbstractPresenter> PopupView newPopupView(Class<V> popupViewClass) {
138

    
139
        Class<? extends AbstractPresenter<?>> presenterClass = findGenericPresenterType(popupViewClass);
140
        try {
141

    
142
            P presenter = (P) presenterClass.newInstance();
143

    
144
            injectPresenterBeans(presenterClass, presenter);
145

    
146
            PopupView view = popupViewClass.newInstance();
147
            if(AbstractView.class.isAssignableFrom(popupViewClass)){
148
                AbstractView<P> abstractView = (AbstractView<P>)view;
149
                viewEventBusField.set(abstractView, eventBus);
150
                viewInjectPresenterMethod.invoke(abstractView, presenter);
151
                // invoke the @PostConstruct method
152

    
153
                viewInitMethod.invoke(abstractView);
154
            }
155
            return view;
156
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
157
            throw new RuntimeException(String.format("Error creating the view class '%s' with presenter class '%s'", popupViewClass, presenterClass), e);
158
        }
159
    }
160

    
161

    
162
    /**
163
     * @param presenterClass
164
     * @param presenter
165
     * @throws IllegalAccessException
166
     * @throws InvocationTargetException
167
     * @throws IllegalArgumentException
168
     */
169
    public <P extends AbstractPresenter> void injectPresenterBeans(
170
            Class<? extends AbstractPresenter<?>> presenterClass, P presenter) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
171
        presenterRepoField.set(presenter, repo);
172
        presenterNavigationManagerField.set(presenter, navigationManager);
173

    
174
        if(AbstractEditorPresenter.class.isAssignableFrom(presenterClass)){
175
            presenterEventBusField.set(presenter, eventBus);
176
        }
177
        if(SpecimenTypeDesignationWorkingsetEditorPresenter.class.equals(presenterClass)){
178
            specimenTypeDesignationWorkingSetServiceField.set(presenter, specimenTypeDesignationWorkingSetService);
179
        }
180
        if(NameTypeDesignationPresenter.class.equals(presenterClass)){
181
            Field.set(presenter, registrationWorkingSetService);
182
        }
183
    }
184

    
185
    /**
186
     * @param popupViewClass
187
     * @return
188
     */
189
    @SuppressWarnings("unchecked")
190
    private Class<? extends AbstractPresenter<?>> findGenericPresenterType(Class<?  extends PopupView> popupViewClass) {
191

    
192
        ParameterizedType genericSuperClass = (ParameterizedType)popupViewClass.getGenericSuperclass();
193
        Type[] typeArgs = genericSuperClass.getActualTypeArguments();
194
        if(AbstractPopupEditor.class.isAssignableFrom(popupViewClass)){
195
           return (Class<? extends AbstractPresenter<?>>) typeArgs[1];
196
        } else {
197
           return (Class<? extends AbstractPresenter<?>>) typeArgs[0];
198
        }
199
    }
200

    
201

    
202
}
(3-3/6)