Project

General

Profile

Download (6.53 KB) Statistics
| Branch: | Tag: | Revision:
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
}