Project

General

Profile

Download (19.6 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
import org.springframework.transaction.TransactionStatus;
19

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

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

    
62
/**
63
 * @author a.kohlbecker
64
 * @since Mar 3, 2017
65
 *
66
 */
67
@SpringComponent
68
@ViewScope
69
public class RegistrationWorkingsetPresenter extends AbstractPresenter<RegistrationWorkingsetView> {
70

    
71
    private static final long serialVersionUID = 1L;
72

    
73
    @Autowired
74
    private IRegistrationWorkingSetService workingSetService;
75

    
76
    /**
77
     * @return the workingSetService
78
     */
79
    public IRegistrationWorkingSetService getWorkingSetService() {
80
        return workingSetService;
81
    }
82

    
83
    private RegistrationWorkingSet workingset;
84

    
85
    private TaxonName newTaxonNameForRegistration = null;
86

    
87
    private RegistrationDTO newRegistrationDTOWithExistingName;
88

    
89

    
90
    /**
91
     *
92
     */
93
    public RegistrationWorkingsetPresenter() {
94
    }
95

    
96

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

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

    
115

    
116
    /**
117
     * @param taxonNameId
118
     * @return
119
     */
120
    protected Registration createNewRegistrationForName(Integer taxonNameId) {
121
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122
        // move into RegistrationWorkflowStateMachine
123
        TransactionStatus txStatus = getRepo().startTransaction();
124
        long identifier = System.currentTimeMillis();
125
        Registration reg = Registration.NewInstance(
126
                "http://phycobank.org/" + identifier,
127
                "" + identifier,
128
                taxonNameId != null ? getRepo().getNameService().find(taxonNameId) : null,
129
                null);
130
        Authentication authentication = currentSecurityContext().getAuthentication();
131
        reg.setSubmitter((User)authentication.getPrincipal());
132
        EntityChangeEvent event = getRegistrationStore().saveBean(reg);
133
        UserHelper.fromSession().createAuthorityForCurrentUser(Registration.class, event.getEntityId(), Operation.UPDATE, RegistrationStatus.PREPARATION.name());
134
        getRepo().commitTransaction(txStatus);
135
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136
        return getRepo().getRegistrationService().find(event.getEntityId());
137
    }
138

    
139

    
140
    /**
141
     * @param doReload TODO
142
     *
143
     */
144
    protected void refreshView(boolean doReload) {
145
        if(doReload){
146
            loadWorkingSet(workingset.getCitationId());
147
        }
148
        getView().setWorkingset(workingset);
149
    }
150

    
151

    
152
    /**
153
     * {@inheritDoc}
154
     */
155
    @Override
156
    public void handleViewEntered() {
157

    
158
        super.handleViewEntered();
159

    
160
        loadWorkingSet(getView().getCitationID());
161
        getView().setWorkingset(workingset);
162

    
163
        CdmFilterablePagingProvider<TaxonName> pagingProvider = new CdmFilterablePagingProvider<TaxonName>(
164
                getRepo().getNameService());
165
        CdmTitleCacheCaptionGenerator<TaxonName> titleCacheGenrator = new CdmTitleCacheCaptionGenerator<TaxonName>();
166
        getView().getAddExistingNameCombobox().setCaptionGenerator(titleCacheGenrator);
167
        getView().getAddExistingNameCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
168
    }
169

    
170

    
171
    /**
172
     * @param referenceID
173
     */
174
    protected void loadWorkingSet(Integer referenceID) {
175
        try {
176
            workingset = getWorkingSetService().loadWorkingSetByReferenceID(referenceID);
177
        } catch (RegistrationValidationException error) {
178
            logger.error(error);
179
            Window errorDialog = new Window("Validation Error");
180
            errorDialog.setModal(true);
181
            VerticalLayout subContent = new VerticalLayout();
182
            subContent.setMargin(true);
183
            errorDialog.setContent(subContent);
184
            subContent.addComponent(new Label(error.getMessage()));
185
            UI.getCurrent().addWindow(errorDialog);
186
        }
187
        if(workingset == null || workingset.getCitationId() == null){
188
            Reference citation = getRepo().getReferenceService().find(referenceID);
189
            workingset = new RegistrationWorkingSet(citation);
190
        }
191
    }
192

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

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

    
206
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
207
    public void onRegistrationEditorAction(RegistrationEditorAction event) {
208
        RegistrationPopupEditor popup = getNavigationManager().showInPopup(RegistrationPopupEditor.class);
209
        popup.loadInEditor(event.getEntityId());
210
    }
211

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

    
215
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
216
        popup.withDeleteButton(true);
217
        // disable NomReferenceCombobox:
218
        // the in the registration application inReferences should only edited centrally
219
        popup.getNomReferenceCombobox().setEnabled(false);
220
        popup.loadInEditor(event.getEntityId());
221
    }
222

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

    
226
        newTaxonNameForRegistration = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
227
        newTaxonNameForRegistration.setNomenclaturalReference(getRepo().getReferenceService().find(workingset.getCitationId()));
228
        EntityChangeEvent nameSaveEvent = getTaxonNameStore().saveBean(newTaxonNameForRegistration);
229
        newTaxonNameForRegistration = getRepo().getNameService().find(nameSaveEvent.getEntityId());
230
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
231
        popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE,CRUD.DELETE));
232
        popup.withDeleteButton(true);
233
        popup.loadInEditor(newTaxonNameForRegistration.getId());
234
        // disable NomReferenceCombobox:
235
        // the in the registration application inReferences should only edited centrally
236
        popup.getNomReferenceCombobox().setEnabled(false);
237
    }
238

    
239
    /**
240
     * Creates a new <code>Registration</code> for a new name that has just been edited
241
     * using the <code>TaxonNamePopupEditor</code>. The new name was previously created
242
     * in this presenter as <code>newTaxonNameForRegistration</code> (see {@link #onTaxonNameEditorActionAdd(TaxonNameEditorAction)})
243
     * and is either filled with data (<code>Reason.SAVE</code>) or it is still empty
244
     * (<code>Reason.CANCEL</code>).
245
     *
246
     *
247
     * @param event
248
     * @throws RegistrationValidationException
249
     */
250
    @EventListener
251
    public void onDoneWithTaxonnameEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
252
        if(event.getPopup() instanceof TaxonNamePopupEditor){
253
            TransactionStatus txStatus = getRepo().startTransaction();
254
            if(event.getReason().equals(Reason.SAVE)){
255
                if(newTaxonNameForRegistration != null){
256
                    int taxonNameId = newTaxonNameForRegistration.getId();
257
                    getRepo().getSession().refresh(newTaxonNameForRegistration);
258
                    Registration reg = createNewRegistrationForName(taxonNameId);
259
                    // reload workingset into current session
260
                    loadWorkingSet(workingset.getCitationId());
261
                    workingset.add(reg);
262
                }
263
                refreshView(true);
264
            } else if(event.getReason().equals(Reason.CANCEL)){
265
                if(newTaxonNameForRegistration != null){
266
                    // clean up
267
                    getTaxonNameStore().deleteBean(newTaxonNameForRegistration);
268
                }
269
            }
270
            getRepo().commitTransaction(txStatus);
271
            newTaxonNameForRegistration = null;
272
        }
273
    }
274

    
275

    
276
    /**
277
     * Creates a new Registration for an exiting (previously published name).
278
     *
279
     * @param event
280
     * @throws RegistrationValidationException
281
     */
282
    @EventListener(condition = "#event.action == T(eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkingsetAction.Action).start")
283
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkingsetAction event) throws RegistrationValidationException {
284

    
285
        getView().getAddExistingNameCombobox().commit();
286
        TaxonName typifiedName = getView().getAddExistingNameCombobox().getValue();
287
        if(typifiedName != null){
288
            Registration newRegistrationWithExistingName = createNewRegistrationForName(null);
289
            Reference citation = getRepo().getReferenceService().find(workingset.getCitationId());
290
            newRegistrationDTOWithExistingName = new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation);
291
            workingset.add(newRegistrationDTOWithExistingName);
292
            // tell the view to update the workingset
293
            getView().setWorkingset(workingset);
294
            getView().getAddExistingNameRegistrationButton().setEnabled(false);
295
            getView().getAddExistingNameRegistrationButton().setDescription("You first need to add a type designation to the previously created registration.");
296
        } else {
297
            logger.error("Seletced name is NULL");
298
        }
299

    
300
    }
301

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

    
305
            if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
306
                SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
307
                popup.withDeleteButton(true);
308
                popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationId(), event.getEntityId()));
309
            } else {
310
                // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
311
                // FIXME implement NameTypeDesignationWorkingsetPopupEditor
312
            }
313
    }
314

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

    
318
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
319
            SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
320
            TypeDesignationWorkingsetEditorIdSet identifierSet;
321
            Integer typifiedNameId;
322
            if(newRegistrationDTOWithExistingName != null){
323
                typifiedNameId = newRegistrationDTOWithExistingName.getTypifiedNameRef().getId();
324
            } else {
325
                RegistrationDTO registrationDTO = workingset.getRegistrationDTO(event.getRegistrationId()).get();
326
                EntityReference typifiedNameRef = registrationDTO.getTypifiedNameRef();
327
                if(typifiedNameRef != null){
328
                    // case for registrations without name, in which case the typifiedName is only defined via the typedesignations
329
                    typifiedNameId = typifiedNameRef.getId();
330
                } else {
331
                    // case of registrations with a name in the nomenclatural act.
332
                    typifiedNameId = registrationDTO.getNameRef().getId();
333
                }
334
            }
335
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
336
                    event.getRegistrationId(),
337
                    getView().getCitationID(),
338
                    typifiedNameId
339
                    );
340
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE));
341
            popup.loadInEditor(identifierSet);
342
            popup.withDeleteButton(true);
343
        } else {
344
            // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
345
            // FIXME implement NameTypeDesignationWorkingsetPopupEditor
346
        }
347
    }
348

    
349
    /**
350
     * Performs final actions after a TypeDesignationEditor which has been
351
     * opened to add a TypeDesignation to a Registration object which was
352
     * created for an previously published name. Prior adding a typedesignation,
353
     * the according Registration object is dangling, that has no association to
354
     * any entity denoting an nomenclatural act which has a reference to a
355
     * publication. This means that the registration object is not in the
356
     * working set.
357
     *
358
     *
359
     * @param event
360
     * @throws RegistrationValidationException
361
     */
362
    @EventListener
363
    public void onDoneWithTypeDesignationEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
364
        if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
365
            if(event.getReason().equals(Reason.SAVE)){
366
                refreshView(true);
367
            } else if(event.getReason().equals(Reason.CANCEL)){
368
                // clean up
369
                if(newRegistrationDTOWithExistingName != null){
370
                    getRegistrationStore().deleteBean(newRegistrationDTOWithExistingName.registration());
371
                }
372
            }
373
            // set newRegistrationDTOWithExistingName NULL in any case
374
            newRegistrationDTOWithExistingName = null;
375
        }
376
    }
377

    
378

    
379
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet)")
380
    public void onShowRegistrationWorkingSetMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
381
        List<String> messages = new ArrayList<>();
382
        for(RegistrationDTO dto : workingset.getRegistrationDTOs()){
383
            dto.getMessages().forEach(m -> messages.add(dto.getSummary() + ": " + m));
384
        }
385
        if(event.getProperty().equals("messages")){
386
            getView().openDetailsPopup("Messages", messages);
387
        }
388
    }
389

    
390
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO)")
391
    public void onShowRegistrationMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
392
        RegistrationDTO regDto = workingSetService.loadDtoById((Integer)event.getIdentifier());
393
        if(event.getProperty().equals("messages")){
394
            if(getView() != null){
395
                getView().openDetailsPopup("Messages", regDto.getMessages());
396
            }
397
        }
398
    }
399

    
400
    @EventListener
401
    public void onEntityChangeEvent(EntityChangeEvent event){
402
        if(workingset == null){
403
            return;
404
        }
405
        if(Reference.class.isAssignableFrom(event.getEntityType())){
406
            if(workingset.getCitationId().equals(event.getEntityId())){
407
                refreshView(true);
408
            }
409
        } else
410
        if(Registration.class.isAssignableFrom(event.getEntityType())){
411
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getId() == event.getEntityId())){
412
                refreshView(true);
413
            }
414
        } else
415
        if(TaxonName.class.isAssignableFrom(event.getEntityType())){
416
            if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
417
                reg.getTypifiedNameRef() != null
418
                && reg.getTypifiedNameRef().getId() == event.getEntityId())){
419
                    refreshView(true);
420
            }
421
        } else
422
        if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
423
            if(workingset.getRegistrationDTOs().stream().anyMatch(
424
                    reg -> reg.getTypeDesignations().stream().anyMatch(
425
                            td -> td.getId() == event.getEntityId()
426
                            )
427
                        )
428
                    ){
429
                refreshView(true);
430
            }
431
        }
432

    
433
    }
434

    
435
}
(12-12/19)