Project

General

Profile

Download (17.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.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.server.SystemError;
19
import com.vaadin.spring.annotation.SpringComponent;
20
import com.vaadin.spring.annotation.ViewScope;
21

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

    
52
/**
53
 * @author a.kohlbecker
54
 * @since Mar 3, 2017
55
 *
56
 */
57
@SpringComponent
58
@ViewScope
59
public class RegistrationWorkflowPresenter extends AbstractPresenter<RegistrationWorkflowView> {
60

    
61
    private static final long serialVersionUID = 1L;
62

    
63
    @Autowired
64
    private IRegistrationWorkingSetService workingSetService;
65

    
66
    /**
67
     * @return the workingSetService
68
     */
69
    public IRegistrationWorkingSetService getWorkingSetService() {
70
        ensureBoundConversation();
71
        return workingSetService;
72
    }
73

    
74
    private RegistrationWorkingSet workingset;
75

    
76
    private TaxonName newTaxonNameForRegistration = null;
77

    
78
    private RegistrationDTO newRegistrationDTOWithExistingName;
79

    
80

    
81
    /**
82
     *
83
     */
84
    public RegistrationWorkflowPresenter() {
85
    }
86

    
87

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

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

    
106

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

    
127

    
128
    /**
129
     *
130
     */
131
    protected void refreshView() {
132
        getConversationHolder().getSession().clear();
133
        presentWorkingSet(workingset.getCitationId());
134
    }
135

    
136

    
137
    /**
138
     * {@inheritDoc}
139
     */
140
    @Override
141
    public void handleViewEntered() {
142

    
143
        super.handleViewEntered();
144

    
145
        presentWorkingSet(getView().getCitationID());
146

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

    
154
    /**
155
     * Loads the WorkingSet from the data base and passes it to the view.
156
     *
157
     * @param registrationID
158
     */
159
    private void presentWorkingSet(Integer referenceID) {
160
        try {
161
            workingset = getWorkingSetService().loadWorkingSetByReferenceID(referenceID);
162
        } catch (RegistrationValidationException error) {
163
            getView().getWorkflow().setComponentError(new SystemError(error));
164
        }
165
        if(workingset == null || workingset.getCitationId() == null){
166
            Reference citation = getRepo().getReferenceService().find(referenceID);
167
            workingset = new RegistrationWorkingSet(citation);
168
        }
169
        // getView().setHeaderText("Registrations for " + workingset.getCitation());
170
        getView().setWorkingset(workingset);
171
    }
172

    
173
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).ADD && #event.sourceComponent == null")
174
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
175
        ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
176
        popup.loadInEditor(null);
177
    }
178

    
179
    @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).EDIT && #event.sourceComponent == null")
180
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
181
        ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
182
        popup.withDeleteButton(true);
183
        popup.loadInEditor(event.getEntityId());
184
    }
185

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

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

    
195
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
196
        popup.withDeleteButton(true);
197
        // disable NomReferenceCombobox:
198
        // the in the registration application inReferences should only edited centrally
199
        popup.getNomReferenceCombobox().setEnabled(false);
200
        popup.loadInEditor(event.getEntityId());
201
    }
202

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

    
206
        newTaxonNameForRegistration = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
207
        newTaxonNameForRegistration.setNomenclaturalReference(getRepo().getReferenceService().find(workingset.getCitationId()));
208
        EntityChangeEvent nameSaveEvent = getTaxonNameStore().saveBean(newTaxonNameForRegistration);
209
        newTaxonNameForRegistration = getRepo().getNameService().find(nameSaveEvent.getEntityId());
210
        TaxonNamePopupEditor popup = getNavigationManager().showInPopup(TaxonNamePopupEditor.class);
211
        popup.withDeleteButton(true);
212
        popup.loadInEditor(newTaxonNameForRegistration.getId());
213
        // disable NomReferenceCombobox:
214
        // the in the registration application inReferences should only edited centrally
215
        popup.getNomReferenceCombobox().setEnabled(false);
216
    }
217

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

    
245

    
246
    /**
247
     * Creates a new Registration for an exiting (previously published name).
248
     *
249
     * @param event
250
     * @throws RegistrationValidationException
251
     */
252
    @EventListener(condition = "#event.action == T(eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkflowEvent.Action).start")
253
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkflowEvent event) throws RegistrationValidationException {
254

    
255
        getView().getAddExistingNameCombobox().commit();
256
        TaxonName typifiedName = getView().getAddExistingNameCombobox().getValue();
257
        if(typifiedName != null){
258
            Registration newRegistrationWithExistingName = createNewRegistrationForName(null);
259
            Reference citation = getRepo().getReferenceService().find(workingset.getCitationId());
260
            newRegistrationDTOWithExistingName = new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation);
261
            workingset.add(newRegistrationDTOWithExistingName);
262
            // tell the view to update the workingset
263
            getView().setWorkingset(workingset);
264
            getView().getAddExistingNameRegistrationButton().setEnabled(false);
265
            getView().getAddExistingNameRegistrationButton().setDescription("You first need to add a type designation to the previously created registration.");
266
        } else {
267
            logger.error("Seletced name is NULL");
268
        }
269

    
270
    }
271

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

    
275
            if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
276
                SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
277
                popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationId(), event.getEntityId()));
278
            } else {
279
                // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
280
                // FIXME implement NameTypeDesignationWorkingsetPopupEditor
281
            }
282
    }
283

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

    
287
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
288
            SpecimenTypeDesignationWorkingsetPopupEditor popup = getNavigationManager().showInPopup(SpecimenTypeDesignationWorkingsetPopupEditor.class);
289
            TypeDesignationWorkingsetEditorIdSet identifierSet;
290
            Integer typifiedNameId;
291
            if(newRegistrationDTOWithExistingName != null){
292
                typifiedNameId = newRegistrationDTOWithExistingName.getTypifiedName().getId();
293
            } else {
294
                typifiedNameId = workingset.getRegistrationDTO(event.getRegistrationId())
295
                        .get()
296
                        .getTypifiedName()
297
                        .getId();
298
            }
299
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
300
                    event.getRegistrationId(),
301
                    getView().getCitationID(),
302
                    typifiedNameId
303
                    );
304
            popup.loadInEditor(identifierSet
305
                 );
306
            popup.withDeleteButton(true);
307
        } else {
308
            // TypeDesignationWorkingSetType.NAME_TYPE_DESIGNATION_WORKINGSET
309
            // FIXME implement NameTypeDesignationWorkingsetPopupEditor
310
        }
311
    }
312

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

    
342

    
343
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet)")
344
    public void onShowRegistrationWorkingSetMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
345
        List<String> messages = new ArrayList<>();
346
        for(RegistrationDTO dto : workingset.getRegistrationDTOs()){
347
            dto.getMessages().forEach(m -> messages.add(dto.getSummary() + ": " + m));
348
        }
349
        if(event.getProperty().equals("messages")){
350
            getView().openDetailsPopup("Messages", messages);
351
        }
352
    }
353

    
354
    @EventListener(classes=ShowDetailsEvent.class, condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO)")
355
    public void onShowRegistrationMessages(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
356
        RegistrationDTO regDto = workingSetService.loadDtoById((Integer)event.getIdentifier());
357
        if(event.getProperty().equals("messages")){
358
            if(getView() != null){
359
                getView().openDetailsPopup("Messages", regDto.getMessages());
360
            }
361
        }
362
    }
363

    
364
    @EventListener
365
    public void onEntityChangeEvent(EntityChangeEvent event){
366
        if(workingset == null){
367
            return;
368
        }
369
        if(Reference.class.isAssignableFrom(event.getEntityType())){
370
            if(workingset.getCitationId().equals(event.getEntityId())){
371
                refreshView();
372
            }
373
        } else
374
        if(Registration.class.isAssignableFrom(event.getEntityType())){
375
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getId() == event.getEntityId())){
376
                refreshView();
377
            }
378
        } else
379
        if(TaxonName.class.isAssignableFrom(event.getEntityType())){
380
            if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
381
                reg.getTypifiedName() != null
382
                && reg.getTypifiedName().getId() == event.getEntityId())){
383
                    refreshView();
384
            }
385
        } else
386
        if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
387
            if(workingset.getRegistrationDTOs().stream().anyMatch(
388
                    reg -> reg.getTypeDesignations().stream().anyMatch(
389
                            td -> td.getId() == event.getEntityId()
390
                            )
391
                        )
392
                    ){
393
                refreshView();
394
            }
395
        }
396

    
397
    }
398

    
399
}
(12-12/19)