1 |
5ba148ae
|
Andreas Kohlbecker
|
/**
|
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.mvp;
|
10 |
|
|
|
11 |
55ecdf3a
|
Andreas Kohlbecker
|
import java.util.EnumSet;
|
12 |
|
|
|
13 |
c46954e3
|
Andreas Kohlbecker
|
import org.apache.log4j.Logger;
|
14 |
55ecdf3a
|
Andreas Kohlbecker
|
import org.hibernate.HibernateException;
|
15 |
5ba148ae
|
Andreas Kohlbecker
|
import org.springframework.context.event.EventListener;
|
16 |
|
|
|
17 |
262c713c
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.api.service.IService;
|
18 |
5ba148ae
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
19 |
55ecdf3a
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
|
20 |
|
|
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
|
21 |
262c713c
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.service.CdmStore;
|
22 |
9d5ae601
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
|
23 |
55ecdf3a
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
|
24 |
c46954e3
|
Andreas Kohlbecker
|
import eu.etaxonomy.vaadin.mvp.event.EditorPreSaveEvent;
|
25 |
|
|
import eu.etaxonomy.vaadin.mvp.event.EditorSaveEvent;
|
26 |
5ba148ae
|
Andreas Kohlbecker
|
|
27 |
|
|
/**
|
28 |
c46954e3
|
Andreas Kohlbecker
|
* Provides generic save operations of modified cdm entities.
|
29 |
|
|
*
|
30 |
5ba148ae
|
Andreas Kohlbecker
|
* @author a.kohlbecker
|
31 |
|
|
* @since Apr 5, 2017
|
32 |
|
|
*
|
33 |
|
|
*/
|
34 |
c46954e3
|
Andreas Kohlbecker
|
public abstract class AbstractCdmEditorPresenter<DTO extends CdmBase, V extends ApplicationView<?>> extends AbstractEditorPresenter<DTO, V> {
|
35 |
5ba148ae
|
Andreas Kohlbecker
|
|
36 |
|
|
private static final long serialVersionUID = 2218185546277084261L;
|
37 |
|
|
|
38 |
c46954e3
|
Andreas Kohlbecker
|
private static final Logger logger = Logger.getLogger(AbstractCdmEditorPresenter.class);
|
39 |
|
|
|
40 |
55ecdf3a
|
Andreas Kohlbecker
|
/**
|
41 |
|
|
* if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
|
42 |
|
|
* granted to the current use as long this grant is not assigned yet.
|
43 |
|
|
*/
|
44 |
|
|
protected EnumSet<CRUD> crud = null;
|
45 |
|
|
|
46 |
262c713c
|
Andreas Kohlbecker
|
|
47 |
c46954e3
|
Andreas Kohlbecker
|
public AbstractCdmEditorPresenter() {
|
48 |
|
|
super();
|
49 |
|
|
logger.trace(this._toString() + " constructor");
|
50 |
|
|
}
|
51 |
|
|
|
52 |
1af6dc9f
|
Andreas Kohlbecker
|
CdmStore<DTO, IService<DTO>> store ;
|
53 |
|
|
|
54 |
55ecdf3a
|
Andreas Kohlbecker
|
protected CdmAuthority newAuthorityCreated;
|
55 |
|
|
|
56 |
262c713c
|
Andreas Kohlbecker
|
protected CdmStore<DTO, IService<DTO>> getStore() {
|
57 |
|
|
if(store == null){
|
58 |
|
|
store = new CdmStore<>(getRepo(), getService());
|
59 |
|
|
}
|
60 |
|
|
return store;
|
61 |
|
|
}
|
62 |
|
|
|
63 |
55ecdf3a
|
Andreas Kohlbecker
|
@Override
|
64 |
|
|
protected DTO loadBeanById(Object identifier) {
|
65 |
|
|
|
66 |
|
|
if(identifier != null) {
|
67 |
|
|
Integer integerID = (Integer)identifier;
|
68 |
|
|
// CdmAuthority is needed before the bean is loaded into the session.
|
69 |
|
|
// otherwise adding the authority to the user would cause a flush
|
70 |
|
|
guaranteePerEntityCRUDPermissions(integerID);
|
71 |
|
|
return loadCdmEntityById(integerID);
|
72 |
|
|
} else {
|
73 |
|
|
DTO cdmEntitiy = loadCdmEntityById(null);
|
74 |
|
|
if(cdmEntitiy != null){
|
75 |
|
|
guaranteePerEntityCRUDPermissions(cdmEntitiy);
|
76 |
|
|
}
|
77 |
|
|
return cdmEntitiy;
|
78 |
|
|
}
|
79 |
|
|
|
80 |
|
|
}
|
81 |
|
|
|
82 |
|
|
|
83 |
|
|
/**
|
84 |
|
|
* @param identifier
|
85 |
|
|
* @return
|
86 |
|
|
*/
|
87 |
|
|
protected abstract DTO loadCdmEntityById(Integer identifier);
|
88 |
|
|
|
89 |
|
|
/**
|
90 |
|
|
* Grant per entity CdmAuthority to the current user <b>for the bean which is not yet loaded</b>
|
91 |
|
|
* into the editor. The <code>CRUD</code> to be granted are stored in the <code>crud</code> field.
|
92 |
|
|
*/
|
93 |
|
|
protected abstract void guaranteePerEntityCRUDPermissions(Integer identifier);
|
94 |
|
|
|
95 |
|
|
/**
|
96 |
|
|
* Grant per entity CdmAuthority to the current user for the bean which is loaded
|
97 |
|
|
* into the editor. The <code>CRUD</code> to be granted are stored in the <code>crud</code> field.
|
98 |
|
|
*/
|
99 |
|
|
protected abstract void guaranteePerEntityCRUDPermissions(DTO bean);
|
100 |
262c713c
|
Andreas Kohlbecker
|
|
101 |
538800b4
|
Andreas Kohlbecker
|
/**
|
102 |
a2cc9f8d
|
Andreas Kohlbecker
|
* @return
|
103 |
538800b4
|
Andreas Kohlbecker
|
*/
|
104 |
262c713c
|
Andreas Kohlbecker
|
protected abstract IService<DTO> getService();
|
105 |
5ba148ae
|
Andreas Kohlbecker
|
|
106 |
2c2bbc38
|
Andreas Kohlbecker
|
@SuppressWarnings("unchecked")
|
107 |
|
|
@Override
|
108 |
|
|
@EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
|
109 |
|
|
public void onEditorPreSaveEvent(EditorPreSaveEvent preSaveEvent){
|
110 |
fe785c1e
|
Andreas Kohlbecker
|
|
111 |
2c2bbc38
|
Andreas Kohlbecker
|
if(!isFromOwnView(preSaveEvent)){
|
112 |
|
|
return;
|
113 |
|
|
}
|
114 |
fe785c1e
|
Andreas Kohlbecker
|
super.onEditorPreSaveEvent(preSaveEvent);
|
115 |
2c2bbc38
|
Andreas Kohlbecker
|
}
|
116 |
|
|
|
117 |
|
|
@SuppressWarnings("unchecked")
|
118 |
5ba148ae
|
Andreas Kohlbecker
|
@Override
|
119 |
a2cc9f8d
|
Andreas Kohlbecker
|
@EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
|
120 |
5ba148ae
|
Andreas Kohlbecker
|
public void onEditorSaveEvent(EditorSaveEvent saveEvent){
|
121 |
fe785c1e
|
Andreas Kohlbecker
|
|
122 |
96783004
|
Andreas Kohlbecker
|
if(!isFromOwnView(saveEvent)){
|
123 |
|
|
return;
|
124 |
|
|
}
|
125 |
fe785c1e
|
Andreas Kohlbecker
|
|
126 |
55ecdf3a
|
Andreas Kohlbecker
|
|
127 |
5ba148ae
|
Andreas Kohlbecker
|
// the bean is now updated with the changes made by the user
|
128 |
2c2bbc38
|
Andreas Kohlbecker
|
DTO bean = (DTO) saveEvent.getBean();
|
129 |
3436c944
|
Andreas Kohlbecker
|
|
130 |
55ecdf3a
|
Andreas Kohlbecker
|
bean = handleTransientProperties(bean);
|
131 |
|
|
try {
|
132 |
|
|
EntityChangeEvent changeEvent = getStore().saveBean(bean);
|
133 |
|
|
|
134 |
|
|
if(changeEvent != null){
|
135 |
|
|
eventBus.publishEvent(changeEvent);
|
136 |
|
|
}
|
137 |
|
|
} catch (HibernateException e){
|
138 |
|
|
if(newAuthorityCreated != null){
|
139 |
|
|
UserHelper.fromSession().removeAuthorityForCurrentUser(newAuthorityCreated);
|
140 |
|
|
}
|
141 |
a2cc9f8d
|
Andreas Kohlbecker
|
}
|
142 |
2c2bbc38
|
Andreas Kohlbecker
|
}
|
143 |
|
|
|
144 |
|
|
/**
|
145 |
|
|
* EditorPresneters for beans with transient properties should overwrite this method to
|
146 |
|
|
* update the beanItem with the changes made to the transient properties.
|
147 |
|
|
* <p>
|
148 |
|
|
* This is necessary because Vaadin MethodProperties are readonly when no setter is
|
149 |
|
|
* available. This can be the case with transient properties. Automatic updating
|
150 |
|
|
* of the property during the fieldGroup commit does not work in this case.
|
151 |
262c713c
|
Andreas Kohlbecker
|
*
|
152 |
|
|
* @deprecated editors should operate on DTOs instead, remove this method if unused.
|
153 |
2c2bbc38
|
Andreas Kohlbecker
|
*/
|
154 |
262c713c
|
Andreas Kohlbecker
|
@Deprecated
|
155 |
2c2bbc38
|
Andreas Kohlbecker
|
protected DTO handleTransientProperties(DTO bean) {
|
156 |
|
|
// no need to handle transient properties in the generic case
|
157 |
|
|
return bean;
|
158 |
5ba148ae
|
Andreas Kohlbecker
|
}
|
159 |
|
|
|
160 |
fe785c1e
|
Andreas Kohlbecker
|
@Override
|
161 |
|
|
protected DTO prepareAsFieldGroupDataSource(DTO bean){
|
162 |
|
|
DTO mergedBean = getStore().mergedBean(bean);
|
163 |
|
|
// DTO mergedBean = bean;
|
164 |
|
|
return mergedBean;
|
165 |
|
|
}
|
166 |
|
|
|
167 |
5ba148ae
|
Andreas Kohlbecker
|
/**
|
168 |
262c713c
|
Andreas Kohlbecker
|
* If the bean is contained in the session it is being updated by
|
169 |
c46954e3
|
Andreas Kohlbecker
|
* doing an evict and merge. The fieldGroup is updated with the merged bean.
|
170 |
|
|
*
|
171 |
262c713c
|
Andreas Kohlbecker
|
* @param bean
|
172 |
5ba148ae
|
Andreas Kohlbecker
|
*
|
173 |
c46954e3
|
Andreas Kohlbecker
|
* @return The bean merged to the session or original bean in case a merge was not necessary.
|
174 |
5ba148ae
|
Andreas Kohlbecker
|
*/
|
175 |
538800b4
|
Andreas Kohlbecker
|
private DTO mergedBean(DTO bean) {
|
176 |
262c713c
|
Andreas Kohlbecker
|
DTO mergedBean = getStore().mergedBean(bean);
|
177 |
a2cc9f8d
|
Andreas Kohlbecker
|
((AbstractPopupEditor<DTO, AbstractCdmEditorPresenter<DTO, V>>)getView()).updateItemDataSource(mergedBean);
|
178 |
|
|
return mergedBean;
|
179 |
c46954e3
|
Andreas Kohlbecker
|
|
180 |
|
|
}
|
181 |
|
|
|
182 |
5ba148ae
|
Andreas Kohlbecker
|
@Override
|
183 |
|
|
protected final void saveBean(DTO bean){
|
184 |
|
|
// blank implementation, since this is not needed in this or any sub class
|
185 |
262c713c
|
Andreas Kohlbecker
|
// see onEditorSaveEvent() instead
|
186 |
5ba148ae
|
Andreas Kohlbecker
|
}
|
187 |
|
|
|
188 |
538800b4
|
Andreas Kohlbecker
|
@Override
|
189 |
|
|
protected final void deleteBean(DTO bean){
|
190 |
262c713c
|
Andreas Kohlbecker
|
EntityChangeEvent changeEvent = getStore().deleteBean(bean);
|
191 |
|
|
if(changeEvent != null){
|
192 |
|
|
eventBus.publishEvent(changeEvent);
|
193 |
538800b4
|
Andreas Kohlbecker
|
}
|
194 |
|
|
|
195 |
262c713c
|
Andreas Kohlbecker
|
}
|
196 |
538800b4
|
Andreas Kohlbecker
|
|
197 |
55ecdf3a
|
Andreas Kohlbecker
|
/**
|
198 |
|
|
* @param crud
|
199 |
|
|
*/
|
200 |
|
|
public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
|
201 |
|
|
this.crud = crud;
|
202 |
|
|
|
203 |
|
|
}
|
204 |
|
|
|
205 |
|
|
|
206 |
5ba148ae
|
Andreas Kohlbecker
|
}
|