Project

General

Profile

Download (6.53 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.mvp;
10

    
11
import java.util.EnumSet;
12

    
13
import org.apache.log4j.Logger;
14
import org.hibernate.HibernateException;
15
import org.springframework.context.event.EventListener;
16

    
17
import eu.etaxonomy.cdm.api.service.IService;
18
import eu.etaxonomy.cdm.model.common.CdmBase;
19
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
20
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
21
import eu.etaxonomy.cdm.service.CdmStore;
22
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
23
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
24
import eu.etaxonomy.vaadin.mvp.event.EditorPreSaveEvent;
25
import eu.etaxonomy.vaadin.mvp.event.EditorSaveEvent;
26

    
27
/**
28
 * Provides generic save operations of modified cdm entities.
29
 *
30
 * @author a.kohlbecker
31
 * @since Apr 5, 2017
32
 *
33
 */
34
public abstract class AbstractCdmEditorPresenter<DTO extends CdmBase, V extends ApplicationView<?>> extends AbstractEditorPresenter<DTO, V> {
35

    
36
    private static final long serialVersionUID = 2218185546277084261L;
37

    
38
    private static final Logger logger = Logger.getLogger(AbstractCdmEditorPresenter.class);
39

    
40
    /**
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

    
47
    public AbstractCdmEditorPresenter() {
48
        super();
49
        logger.trace(this._toString() + " constructor");
50
    }
51

    
52
    CdmStore<DTO, IService<DTO>> store ;
53

    
54
    protected CdmAuthority newAuthorityCreated;
55

    
56
    protected CdmStore<DTO, IService<DTO>> getStore() {
57
        if(store == null){
58
            store = new CdmStore<>(getRepo(), getService());
59
        }
60
        return store;
61
    }
62

    
63
    @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

    
101
    /**
102
     * @return
103
     */
104
    protected abstract IService<DTO> getService();
105

    
106
    @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

    
111
        if(!isFromOwnView(preSaveEvent)){
112
            return;
113
        }
114
        super.onEditorPreSaveEvent(preSaveEvent);
115
    }
116

    
117
    @SuppressWarnings("unchecked")
118
    @Override
119
    @EventListener // the generic type parameter <DTO> must not be used here otherwise events will not be received
120
    public void onEditorSaveEvent(EditorSaveEvent saveEvent){
121

    
122
        if(!isFromOwnView(saveEvent)){
123
            return;
124
        }
125

    
126

    
127
        // the bean is now updated with the changes made by the user
128
        DTO bean = (DTO) saveEvent.getBean();
129

    
130
        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
        }
142
    }
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
     *
152
     * @deprecated editors should operate on DTOs instead, remove this method if unused.
153
     */
154
    @Deprecated
155
    protected DTO handleTransientProperties(DTO bean) {
156
        // no need to handle transient properties in the generic case
157
        return bean;
158
    }
159

    
160
    @Override
161
    protected DTO prepareAsFieldGroupDataSource(DTO bean){
162
        DTO mergedBean = getStore().mergedBean(bean);
163
        // DTO mergedBean = bean;
164
        return mergedBean;
165
    }
166

    
167
    /**
168
     * If the bean is contained in the session it is being updated by
169
     * doing an evict and merge. The fieldGroup is updated with the merged bean.
170
     *
171
     * @param bean
172
     *
173
     * @return The bean merged to the session or original bean in case a merge was not necessary.
174
     */
175
    private DTO mergedBean(DTO bean) {
176
        DTO mergedBean = getStore().mergedBean(bean);
177
        ((AbstractPopupEditor<DTO, AbstractCdmEditorPresenter<DTO, V>>)getView()).updateItemDataSource(mergedBean);
178
        return mergedBean;
179

    
180
    }
181

    
182
    @Override
183
    protected final void saveBean(DTO bean){
184
        // blank implementation, since this is not needed in this or any sub class
185
        // see onEditorSaveEvent() instead
186
    }
187

    
188
    @Override
189
    protected final void deleteBean(DTO bean){
190
        EntityChangeEvent changeEvent = getStore().deleteBean(bean);
191
        if(changeEvent != null){
192
            eventBus.publishEvent(changeEvent);
193
        }
194

    
195
    }
196

    
197
    /**
198
     * @param crud
199
     */
200
    public void setGrantsForCurrentUser(EnumSet<CRUD> crud) {
201
        this.crud = crud;
202

    
203
    }
204

    
205

    
206
}
(1-1/8)