Project

General

Profile

Download (18 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.List;
13

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

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

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

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

    
64
    private static final long serialVersionUID = 1L;
65

    
66
    @Autowired
67
    private IRegistrationWorkingSetService workingSetService;
68

    
69
    /**
70
     * @return the workingSetService
71
     */
72
    public IRegistrationWorkingSetService getWorkingSetService() {
73
        ensureBoundConversation();
74
        return workingSetService;
75
    }
76

    
77
    private RegistrationWorkingSet workingset;
78

    
79
    private TaxonName newTaxonNameForRegistration = null;
80

    
81
    private RegistrationDTO newRegistrationDTOWithExistingName;
82

    
83

    
84
    /**
85
     *
86
     */
87
    public RegistrationWorkingsetPresenter() {
88
    }
89

    
90

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

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

    
109

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

    
130

    
131
    /**
132
     *
133
     */
134
    protected void refreshView() {
135
        getConversationHolder().getSession().clear();
136
        presentWorkingSet(workingset.getCitationId());
137
    }
138

    
139

    
140
    /**
141
     * {@inheritDoc}
142
     */
143
    @Override
144
    public void handleViewEntered() {
145

    
146
        super.handleViewEntered();
147

    
148
        presentWorkingSet(getView().getCitationID());
149

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

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

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

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

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

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

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

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

    
216
        newTaxonNameForRegistration = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
217
        newTaxonNameForRegistration.setNomenclaturalReference(getRepo().getReferenceService().find(workingset.getCitationId()));
218
        EntityChangeEvent nameSaveEvent = getTaxonNameStore().saveBean(newTaxonNameForRegistration);
219
        newTaxonNameForRegistration = getRepo().getNameService().find(nameSaveEvent.getEntityId());
220
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
221
        popup.withDeleteButton(true);
222
        popup.loadInEditor(newTaxonNameForRegistration.getId());
223
        // disable NomReferenceCombobox:
224
        // the in the registration application inReferences should only edited centrally
225
        popup.getNomReferenceCombobox().setEnabled(false);
226
    }
227

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

    
255

    
256
    /**
257
     * Creates a new Registration for an exiting (previously published name).
258
     *
259
     * @param event
260
     * @throws RegistrationValidationException
261
     */
262
    @EventListener(condition = "#event.action == T(eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkflowEvent.Action).start")
263
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkflowEvent event) throws RegistrationValidationException {
264

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

    
280
    }
281

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

    
285
            if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
286
                SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
287
                popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationId(), event.getEntityId()));
288
            } else {
289
                // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
290
                // FIXME implement NameTypeDesignationWorkingsetPopupEditor
291
            }
292
    }
293

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

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

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

    
352

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

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

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

    
407
    }
408

    
409
}
(12-12/19)