Project

General

Profile

Download (18.8 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.EntityReference;
47
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
48
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
49
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
50
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSetType;
51
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetPopupEditor;
52
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditor;
53
import eu.etaxonomy.cdm.vaadin.view.name.TypeDesignationWorkingsetEditorIdSet;
54
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
55
import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
56
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
57
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
58

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

    
68
    private static final long serialVersionUID = 1L;
69

    
70
    @Autowired
71
    private IRegistrationWorkingSetService workingSetService;
72

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

    
81
    private RegistrationWorkingSet workingset;
82

    
83
    private TaxonName newTaxonNameForRegistration = null;
84

    
85
    private RegistrationDTO newRegistrationDTOWithExistingName;
86

    
87

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

    
94

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

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

    
113

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

    
134

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

    
143

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

    
150
        super.handleViewEntered();
151

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

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

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

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

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

    
200
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
201
    public void onRegistrationEditorAction(RegistrationEditorAction event) {
202
        RegistrationPopupEditor popup = getNavigationManager().showInPopup(RegistrationPopupEditor.class);
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 onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
208

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

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

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

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

    
262

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

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

    
287
    }
288

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

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

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

    
304
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
305
            SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
306
            TypeDesignationWorkingsetEditorIdSet identifierSet;
307
            Integer typifiedNameId;
308
            if(newRegistrationDTOWithExistingName != null){
309
                typifiedNameId = newRegistrationDTOWithExistingName.getTypifiedName().getId();
310
            } else {
311
                RegistrationDTO registrationDTO = workingset.getRegistrationDTO(event.getRegistrationId()).get();
312
                EntityReference typifiedNameRef = registrationDTO.getTypifiedName();
313
                if(typifiedNameRef != null){
314
                    // case for registrations without name, in which case the typifiedName is only defined via the typedesignations
315
                    typifiedNameId = typifiedNameRef.getId();
316
                } else {
317
                    // case of registrations with a name in the nomenclatural act.
318
                    typifiedNameId = registrationDTO.getName().getId();
319
                }
320
            }
321
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
322
                    event.getRegistrationId(),
323
                    getView().getCitationID(),
324
                    typifiedNameId
325
                    );
326
            popup.loadInEditor(identifierSet
327
                 );
328
            popup.withDeleteButton(true);
329
        } else {
330
            // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
331
            // FIXME implement NameTypeDesignationWorkingsetPopupEditor
332
        }
333
    }
334

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

    
364

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

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

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

    
419
    }
420

    
421
}
(12-12/19)