Project

General

Profile

Download (18.3 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.cdm.vaadin.view.registration;
10

    
11
import java.util.ArrayList;
12
import java.util.EnumSet;
13
import java.util.List;
14

    
15
import org.springframework.beans.factory.annotation.Autowired;
16
import org.springframework.context.event.EventListener;
17
import org.springframework.security.core.Authentication;
18

    
19
import com.vaadin.spring.annotation.SpringComponent;
20
import com.vaadin.spring.annotation.ViewScope;
21
import com.vaadin.ui.Label;
22
import com.vaadin.ui.UI;
23
import com.vaadin.ui.VerticalLayout;
24
import com.vaadin.ui.Window;
25

    
26
import eu.etaxonomy.cdm.api.service.INameService;
27
import eu.etaxonomy.cdm.api.service.IRegistrationService;
28
import eu.etaxonomy.cdm.model.common.User;
29
import eu.etaxonomy.cdm.model.name.Rank;
30
import eu.etaxonomy.cdm.model.name.Registration;
31
import eu.etaxonomy.cdm.model.name.TaxonName;
32
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
33
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
34
import eu.etaxonomy.cdm.model.reference.Reference;
35
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
36
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
37
import eu.etaxonomy.cdm.service.CdmStore;
38
import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService;
39
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
40
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
41
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
42
import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
43
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
44
import eu.etaxonomy.cdm.vaadin.event.TypeDesignationWorkingsetEditorAction;
45
import eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkflowEvent;
46
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
47
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
48
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
49
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSetType;
50
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetPopupEditor;
51
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditor;
52
import eu.etaxonomy.cdm.vaadin.view.name.TypeDesignationWorkingsetEditorIdSet;
53
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
54
import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
55
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
56
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
57

    
58
/**
59
 * @author a.kohlbecker
60
 * @since Mar 3, 2017
61
 *
62
 */
63
@SpringComponent
64
@ViewScope
65
public class RegistrationWorkingsetPresenter extends AbstractPresenter<RegistrationWorkingsetView> {
66

    
67
    private static final long serialVersionUID = 1L;
68

    
69
    @Autowired
70
    private IRegistrationWorkingSetService workingSetService;
71

    
72
    /**
73
     * @return the workingSetService
74
     */
75
    public IRegistrationWorkingSetService getWorkingSetService() {
76
        ensureBoundConversation();
77
        return workingSetService;
78
    }
79

    
80
    private RegistrationWorkingSet workingset;
81

    
82
    private TaxonName newTaxonNameForRegistration = null;
83

    
84
    private RegistrationDTO newRegistrationDTOWithExistingName;
85

    
86

    
87
    /**
88
     *
89
     */
90
    public RegistrationWorkingsetPresenter() {
91
    }
92

    
93

    
94
    /**
95
     * Always create a new Store
96
     *
97
     * @return
98
     */
99
    protected CdmStore<Registration, IRegistrationService> getRegistrationStore(){
100
        return new CdmStore<Registration, IRegistrationService>(getRepo(), getRepo().getRegistrationService());
101
    }
102

    
103
    /**
104
     * Always create a new Store
105
     *
106
     * @return
107
     */
108
    protected CdmStore<TaxonName, INameService> getTaxonNameStore(){
109
        return new  CdmStore<TaxonName, INameService>(getRepo(), getRepo().getNameService());
110
    }
111

    
112

    
113
    /**
114
     * @param taxonNameId
115
     * @return
116
     */
117
    protected Registration createNewRegistrationForName(Integer taxonNameId) {
118
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119
        // move into RegistrationWorkflowStateMachine
120
        long identifier = System.currentTimeMillis();
121
        Registration reg = Registration.NewInstance(
122
                "http://phycobank.org/" + identifier,
123
                "" + identifier,
124
                taxonNameId != null ? getRepo().getNameService().find(taxonNameId) : null,
125
                null);
126
        Authentication authentication = currentSecurityContext().getAuthentication();
127
        reg.setSubmitter((User)authentication.getPrincipal());
128
        EntityChangeEvent event = getRegistrationStore().saveBean(reg);
129
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130
        return getRepo().getRegistrationService().find(event.getEntityId());
131
    }
132

    
133

    
134
    /**
135
     *
136
     */
137
    protected void refreshView() {
138
        getConversationHolder().getSession().clear();
139
        presentWorkingSet(workingset.getCitationId());
140
    }
141

    
142

    
143
    /**
144
     * {@inheritDoc}
145
     */
146
    @Override
147
    public void handleViewEntered() {
148

    
149
        super.handleViewEntered();
150

    
151
        presentWorkingSet(getView().getCitationID());
152

    
153
        CdmFilterablePagingProvider<TaxonName> pagingProvider = new CdmFilterablePagingProvider<TaxonName>(
154
                getRepo().getNameService(), this);
155
        CdmTitleCacheCaptionGenerator<TaxonName> titleCacheGenrator = new CdmTitleCacheCaptionGenerator<TaxonName>();
156
        getView().getAddExistingNameCombobox().setCaptionGenerator(titleCacheGenrator);
157
        getView().getAddExistingNameCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
158
    }
159

    
160
    /**
161
     * Loads the WorkingSet from the data base and passes it to the view.
162
     *
163
     * @param registrationID
164
     */
165
    private void presentWorkingSet(Integer referenceID) {
166
        try {
167
            workingset = getWorkingSetService().loadWorkingSetByReferenceID(referenceID);
168
        } catch (RegistrationValidationException error) {
169
            logger.error(error);
170
            Window errorDialog = new Window("Validation Error");
171
            errorDialog.setModal(true);
172
            VerticalLayout subContent = new VerticalLayout();
173
            subContent.setMargin(true);
174
            errorDialog.setContent(subContent);
175
            subContent.addComponent(new Label(error.getMessage()));
176
            UI.getCurrent().addWindow(errorDialog);
177
        }
178
        if(workingset == null || workingset.getCitationId() == null){
179
            Reference citation = getRepo().getReferenceService().find(referenceID);
180
            workingset = new RegistrationWorkingSet(citation);
181
        }
182
        // getView().setHeaderText("Registrations for " + workingset.getCitation());
183
        getView().setWorkingset(workingset);
184
    }
185

    
186
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).ADD && #event.sourceComponent == null")
187
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
188
        ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
189
        popup.loadInEditor(null);
190
    }
191

    
192
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
193
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
194
        ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
195
        popup.withDeleteButton(true);
196
        popup.loadInEditor(event.getEntityId());
197
    }
198

    
199
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
200
    public void onRegistrationEditorAction(RegistrationEditorAction event) {
201
        RegistrationPopupEditor popup = getNavigationManager().showInPopup(RegistrationPopupEditor.class);
202
        popup.loadInEditor(event.getEntityId());
203
    }
204

    
205
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
206
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
207

    
208
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
209
        popup.withDeleteButton(true);
210
        // disable NomReferenceCombobox:
211
        // the in the registration application inReferences should only edited centrally
212
        popup.getNomReferenceCombobox().setEnabled(false);
213
        popup.loadInEditor(event.getEntityId());
214
    }
215

    
216
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).ADD")
217
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
218

    
219
        newTaxonNameForRegistration = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
220
        newTaxonNameForRegistration.setNomenclaturalReference(getRepo().getReferenceService().find(workingset.getCitationId()));
221
        EntityChangeEvent nameSaveEvent = getTaxonNameStore().saveBean(newTaxonNameForRegistration);
222
        UserHelper.fromSession().createAuthorityForCurrentUser(TaxonName.class, nameSaveEvent.getEntityId(), EnumSet.of(CRUD.UPDATE,CRUD.DELETE));
223
        newTaxonNameForRegistration = getRepo().getNameService().find(nameSaveEvent.getEntityId());
224
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
225
        popup.withDeleteButton(true);
226
        popup.loadInEditor(newTaxonNameForRegistration.getId());
227
        // disable NomReferenceCombobox:
228
        // the in the registration application inReferences should only edited centrally
229
        popup.getNomReferenceCombobox().setEnabled(false);
230
    }
231

    
232
    /**
233
     * Creates a new <code>Registration</code> for a new name that has just been edited
234
     * using the <code>TaxonNamePopupEditor</code>. The new name was previously created
235
     * in this presenter as <code>newTaxonNameForRegistration</code> (see {@link #onTaxonNameEditorActionAdd(TaxonNameEditorAction)})
236
     * and is either filled with data (<code>Reason.SAVE</code>) or it is still empty
237
     * (<code>Reason.CANCEL</code>).
238
     *
239
     *
240
     * @param event
241
     * @throws RegistrationValidationException
242
     */
243
    @EventListener
244
    public void onDoneWithTaxonnameEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
245
        if(event.getPopup() instanceof TaxonNamePopupEditor){
246
            if(event.getReason().equals(Reason.SAVE)){
247
                if(newTaxonNameForRegistration != null){
248
                    int taxonNameId = newTaxonNameForRegistration.getId();
249
                    Registration reg = createNewRegistrationForName(taxonNameId);
250
                    workingset.add(reg);
251
                }
252
                refreshView();
253
            } else if(event.getReason().equals(Reason.CANCEL)){
254
                // clean up
255
                getTaxonNameStore().deleteBean(newTaxonNameForRegistration);
256
            }
257
            newTaxonNameForRegistration = null;
258
        }
259
    }
260

    
261

    
262
    /**
263
     * Creates a new Registration for an exiting (previously published name).
264
     *
265
     * @param event
266
     * @throws RegistrationValidationException
267
     */
268
    @EventListener(condition = "#event.action == T(eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkflowEvent.Action).start")
269
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkflowEvent event) throws RegistrationValidationException {
270

    
271
        getView().getAddExistingNameCombobox().commit();
272
        TaxonName typifiedName = getView().getAddExistingNameCombobox().getValue();
273
        if(typifiedName != null){
274
            Registration newRegistrationWithExistingName = createNewRegistrationForName(null);
275
            Reference citation = getRepo().getReferenceService().find(workingset.getCitationId());
276
            newRegistrationDTOWithExistingName = new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation);
277
            workingset.add(newRegistrationDTOWithExistingName);
278
            // tell the view to update the workingset
279
            getView().setWorkingset(workingset);
280
            getView().getAddExistingNameRegistrationButton().setEnabled(false);
281
            getView().getAddExistingNameRegistrationButton().setDescription("You first need to add a type designation to the previously created registration.");
282
        } else {
283
            logger.error("Seletced name is NULL");
284
        }
285

    
286
    }
287

    
288
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
289
    public void onTypeDesignationsEditorActionEdit(TypeDesignationWorkingsetEditorAction event) {
290

    
291
            if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
292
                SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
293
                popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationId(), event.getEntityId()));
294
            } else {
295
                // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
296
                // FIXME implement NameTypeDesignationWorkingsetPopupEditor
297
            }
298
    }
299

    
300
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).ADD && #event.sourceComponent == null")
301
    public void onAddNewTypeDesignationWorkingset(TypeDesignationWorkingsetEditorAction event) {
302

    
303
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
304
            SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
305
            TypeDesignationWorkingsetEditorIdSet identifierSet;
306
            Integer typifiedNameId;
307
            if(newRegistrationDTOWithExistingName != null){
308
                typifiedNameId = newRegistrationDTOWithExistingName.getTypifiedName().getId();
309
            } else {
310
                typifiedNameId = workingset.getRegistrationDTO(event.getRegistrationId())
311
                        .get()
312
                        .getTypifiedName()
313
                        .getId();
314
            }
315
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
316
                    event.getRegistrationId(),
317
                    getView().getCitationID(),
318
                    typifiedNameId
319
                    );
320
            popup.loadInEditor(identifierSet
321
                 );
322
            popup.withDeleteButton(true);
323
        } else {
324
            // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
325
            // FIXME implement NameTypeDesignationWorkingsetPopupEditor
326
        }
327
    }
328

    
329
    /**
330
     * Performs final actions after a TypeDesignationEditor which has been
331
     * opened to add a TypeDesignation to a Registration object which was
332
     * created for an previously published name. Prior adding a typedesignation,
333
     * the according Registration object is dangling, that has no association to
334
     * any entity denoting an nomenclatural act which has a reference to a
335
     * publication. This means that the registration object is not in the
336
     * working set.
337
     *
338
     *
339
     * @param event
340
     * @throws RegistrationValidationException
341
     */
342
    @EventListener
343
    public void onDoneWithTypeDesignationEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
344
        if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
345
            if(event.getReason().equals(Reason.SAVE)){
346
                 refreshView();
347
            } else if(event.getReason().equals(Reason.CANCEL)){
348
                // clean up
349
                if(newRegistrationDTOWithExistingName != null){
350
                    getRegistrationStore().deleteBean(newRegistrationDTOWithExistingName.registration());
351
                }
352
            }
353
            // set newRegistrationDTOWithExistingName NULL in any case
354
            newRegistrationDTOWithExistingName = null;
355
        }
356
    }
357

    
358

    
359
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet)")
360
    public void onShowRegistrationWorkingSetMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
361
        List<String> messages = new ArrayList<>();
362
        for(RegistrationDTO dto : workingset.getRegistrationDTOs()){
363
            dto.getMessages().forEach(m -> messages.add(dto.getSummary() + ": " + m));
364
        }
365
        if(event.getProperty().equals("messages")){
366
            getView().openDetailsPopup("Messages", messages);
367
        }
368
    }
369

    
370
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO)")
371
    public void onShowRegistrationMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
372
        RegistrationDTO regDto = workingSetService.loadDtoById((Integer)event.getIdentifier());
373
        if(event.getProperty().equals("messages")){
374
            if(getView() != null){
375
                getView().openDetailsPopup("Messages", regDto.getMessages());
376
            }
377
        }
378
    }
379

    
380
    @EventListener
381
    public void onEntityChangeEvent(EntityChangeEvent event){
382
        if(workingset == null){
383
            return;
384
        }
385
        if(Reference.class.isAssignableFrom(event.getEntityType())){
386
            if(workingset.getCitationId().equals(event.getEntityId())){
387
                refreshView();
388
            }
389
        } else
390
        if(Registration.class.isAssignableFrom(event.getEntityType())){
391
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getId() == event.getEntityId())){
392
                refreshView();
393
            }
394
        } else
395
        if(TaxonName.class.isAssignableFrom(event.getEntityType())){
396
            if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
397
                reg.getTypifiedName() != null
398
                && reg.getTypifiedName().getId() == event.getEntityId())){
399
                    refreshView();
400
            }
401
        } else
402
        if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
403
            if(workingset.getRegistrationDTOs().stream().anyMatch(
404
                    reg -> reg.getTypeDesignations().stream().anyMatch(
405
                            td -> td.getId() == event.getEntityId()
406
                            )
407
                        )
408
                    ){
409
                refreshView();
410
            }
411
        }
412

    
413
    }
414

    
415
}
(12-12/19)