57df100a22a4d699f1df09a7b096b53bd4f93e71
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / vaadin / ui / view / PopupEditorFactory.java
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 }