Project

General

Profile

Download (35.4 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.Arrays;
13
import java.util.EnumSet;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Objects;
19
import java.util.Set;
20
import java.util.Stack;
21
import java.util.UUID;
22

    
23
import org.apache.log4j.Logger;
24
import org.springframework.beans.factory.annotation.Autowired;
25
import org.springframework.transaction.TransactionStatus;
26
import org.vaadin.spring.events.EventScope;
27
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
28

    
29
import com.vaadin.server.SystemError;
30
import com.vaadin.spring.annotation.SpringComponent;
31
import com.vaadin.spring.annotation.ViewScope;
32
import com.vaadin.ui.AbstractField;
33
import com.vaadin.ui.Button;
34
import com.vaadin.ui.Label;
35
import com.vaadin.ui.UI;
36
import com.vaadin.ui.VerticalLayout;
37
import com.vaadin.ui.Window;
38

    
39
import eu.etaxonomy.cdm.api.service.INameService;
40
import eu.etaxonomy.cdm.api.service.IRegistrationService;
41
import eu.etaxonomy.cdm.api.service.config.RegistrationStatusTransitions;
42
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
43
import eu.etaxonomy.cdm.api.service.dto.RegistrationWorkingSet;
44
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
45
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager.TypeDesignationWorkingSetType;
46
import eu.etaxonomy.cdm.api.service.registration.IRegistrationWorkingSetService;
47
import eu.etaxonomy.cdm.api.utility.RoleProber;
48
import eu.etaxonomy.cdm.api.utility.UserHelper;
49
import eu.etaxonomy.cdm.ext.common.ExternalServiceException;
50
import eu.etaxonomy.cdm.ext.registration.messages.IRegistrationMessageService;
51
import eu.etaxonomy.cdm.model.common.User;
52
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
53
import eu.etaxonomy.cdm.model.name.Rank;
54
import eu.etaxonomy.cdm.model.name.Registration;
55
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
56
import eu.etaxonomy.cdm.model.name.TaxonName;
57
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
58
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
59
import eu.etaxonomy.cdm.model.reference.Reference;
60
import eu.etaxonomy.cdm.model.reference.ReferenceType;
61
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
62
import eu.etaxonomy.cdm.ref.EntityReference;
63
import eu.etaxonomy.cdm.ref.TypedEntityReference;
64
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
65
import eu.etaxonomy.cdm.service.CdmStore;
66
import eu.etaxonomy.cdm.service.UserHelperAccess;
67
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
68
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItem;
69
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStatusFieldInstantiator;
70
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStatusSelect;
71
import eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.EditorActionContext;
72
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
73
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
74
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
75
import eu.etaxonomy.cdm.vaadin.event.RegistrationEditorAction;
76
import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
77
import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEventEntityTypeFilter;
78
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
79
import eu.etaxonomy.cdm.vaadin.event.TypeDesignationWorkingsetEditorAction;
80
import eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkingsetAction;
81
import eu.etaxonomy.cdm.vaadin.permission.RolesAndPermissions;
82
import eu.etaxonomy.cdm.vaadin.theme.EditValoTheme;
83
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
84
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
85
import eu.etaxonomy.cdm.vaadin.view.name.NameTypeDesignationPopupEditor;
86
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetPopupEditor;
87
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditor;
88
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditorMode;
89
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditorView;
90
import eu.etaxonomy.cdm.vaadin.view.name.TypeDesignationWorkingsetEditorIdSet;
91
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
92
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
93
import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
94
import eu.etaxonomy.vaadin.mvp.AbstractView;
95
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
96
import eu.etaxonomy.vaadin.ui.navigation.NavigationEvent;
97
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
98
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
99

    
100
/**
101
 * @author a.kohlbecker
102
 * @since Mar 3, 2017
103
 *
104
 */
105
@SpringComponent
106
@ViewScope
107
public class RegistrationWorkingsetPresenter extends AbstractPresenter<RegistrationWorkingsetView> {
108

    
109
    private static final Logger logger = Logger.getLogger(RegistrationWorkingsetPresenter.class);
110

    
111
    private static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(
112
            "$",
113
            "blockedBy",
114
            "name.combinationAuthorship",
115
            "name.exCombinationAuthorship",
116
            "name.basionymAuthorship",
117
            "name.exBasionymAuthorship"
118
            );
119

    
120
    private static final long serialVersionUID = 1L;
121

    
122
    @Autowired
123
    private IRegistrationWorkingSetService regWorkingSetService;
124

    
125
    @Autowired
126
    private IRegistrationMessageService messageService;
127

    
128
    /**
129
     * @return the regWorkingSetService
130
     */
131
    public IRegistrationWorkingSetService getWorkingSetService() {
132
        return regWorkingSetService;
133
    }
134

    
135
    private RegistrationWorkingSet workingset;
136

    
137
    private TaxonName newTaxonNameForRegistration = null;
138

    
139

    
140
    private Map<NameTypeDesignationPopupEditor, UUID> nameTypeDesignationPopupEditorRegistrationUUIDMap = new HashMap<>();
141

    
142

    
143
    /**
144
     *
145
     */
146
    public RegistrationWorkingsetPresenter() {
147
    }
148

    
149
    /**
150
     * Always create a new Store
151
     *
152
     * @return
153
     */
154
    protected CdmStore<Registration, IRegistrationService> getRegistrationStore(){
155
        return new CdmStore<Registration, IRegistrationService>(getRepo(), getRepo().getRegistrationService());
156
    }
157

    
158
    /**
159
     * Always create a new Store
160
     *
161
     * @return
162
     */
163
    protected CdmStore<TaxonName, INameService> getTaxonNameStore(){
164
        return new  CdmStore<TaxonName, INameService>(getRepo(), getRepo().getNameService());
165
    }
166

    
167
    /**
168
     * Checks
169
     * <ol>
170
     * <li>if there is NOT any registration for this name created in the current registration system</li>
171
     * <li>Checks if the name belongs to the current workingset</li>
172
     * </ol>
173
     * If both checks are successful the method returns <code>true</code>.
174
     */
175
    public boolean canCreateNameRegistrationFor(TaxonName name) {
176
        return !getRepo().getRegistrationService().checkRegistrationExistsFor(name) && checkWokingsetContainsProtologe(name);
177
    }
178

    
179
    /**
180
     * @param name
181
     * @return
182
     */
183
    public boolean checkWokingsetContainsProtologe(TaxonName name) {
184
        Reference nomRef = name.getNomenclaturalReference();
185
        UUID citationUuid = workingset.getCitationUuid();
186
        // @formatter:off
187
        return nomRef != null && (
188
                // nomref matches
189
                nomRef.getUuid().equals(citationUuid) ||
190
                // nomref.inreference matches
191
                (nomRef.getType() != null && nomRef.getType() == ReferenceType.Section && nomRef.getInReference() != null && nomRef.getInReference().getUuid().equals(citationUuid))
192
                );
193
        // @formatter:on
194
    }
195

    
196
    /**
197
     * @param doReload TODO
198
     *
199
     */
200
    protected void refreshView(boolean doReload) {
201
        if(workingset == null){
202
            return; // nothing to do
203
        }
204
        if(doReload){
205
            loadWorkingSet(workingset.getCitationUuid());
206
        }
207
        applyWorkingset();
208
    }
209

    
210
    /**
211
     * {@inheritDoc}
212
     */
213
    @Override
214
    public void handleViewEntered() {
215
        super.handleViewEntered();
216
        // TODO currently cannot specify type more precisely, see AbstractSelect
217
        // FIXME externalize into class file!!!!!!!!!!!!
218
        getView().setStatusComponentInstantiator(new RegistrationStatusFieldInstantiator<Object>(){
219

    
220
            private static final long serialVersionUID = 7099181280977511048L;
221

    
222
            @Override
223
            public AbstractField<Object> create(RegistrationDTO regDto) {
224

    
225
                CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
226
                // submitters have GrantedAuthorities like REGISTRATION(PREPARATION).[UPDATE]{ab4459eb-3b96-40ba-bfaa-36915107d59e}
227
                UserHelper userHelper = UserHelperAccess.userHelper();
228
                Set<RegistrationStatus> availableStatus = new HashSet<>();
229

    
230
                boolean canChangeStatus = userHelper.userHasPermission(regDto.registration(), CRUD.UPDATE);
231
                availableStatus.add(regDto.getStatus());
232
                if(canChangeStatus){
233
                    if(userHelper.userIsAdmin()){
234
                        availableStatus.addAll(Arrays.asList(RegistrationStatus.values()));
235
                    } else {
236
                        availableStatus.addAll(RegistrationStatusTransitions.possibleTransitions(regDto.getStatus()));
237
                    }
238
                }
239

    
240
                RegistrationStatusSelect select = new RegistrationStatusSelect(null, selectFieldFactory.buildBeanItemContainer(
241
                        RegistrationStatus.class,
242
                        availableStatus.toArray(new RegistrationStatus[availableStatus.size()]))
243
                        );
244
                select.addValueChangeListener(e -> saveRegistrationStatusChange(regDto.getUuid(), e.getProperty().getValue()));
245
                select.setEnabled(canChangeStatus);
246
                select.setNullSelectionAllowed(false);
247
                return select;
248
            }
249

    
250

    
251
        });
252
        loadWorkingSet(getView().getCitationUuid());
253
        applyWorkingset();
254

    
255
    }
256

    
257
    private void applyWorkingset(){
258
         getView().setWorkingset(workingset);
259
        // PagingProviders and CacheGenerator for the existingNameCombobox
260
        activateComboboxes();
261
        // update the messages
262
        updateMessages();
263
    }
264

    
265
    /**
266
     *
267
     */
268
    protected void activateComboboxes() {
269
        CdmFilterablePagingProvider<TaxonName, TaxonName> pagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(
270
                getRepo().getNameService());
271
        pagingProvider.setInitStrategy(Arrays.asList("registrations", "nomenclaturalReference", "nomenclaturalReference.inReference"));
272
        CdmTitleCacheCaptionGenerator<TaxonName> titleCacheGenerator = new CdmTitleCacheCaptionGenerator<TaxonName>();
273
        getView().getAddExistingNameCombobox().setCaptionGenerator(titleCacheGenerator);
274
        getView().getAddExistingNameCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
275
    }
276

    
277
    /**
278
     *
279
     */
280
    protected void updateMessages() {
281
        User user = UserHelperAccess.userHelper().user();
282
        for (UUID registrationUuid : getView().getRegistrationItemMap().keySet()) {
283
            Button messageButton = getView().getRegistrationItemMap().get(registrationUuid).regItemButtons.getMessagesButton();
284

    
285
            RegistrationDTO regDto = workingset.getRegistrationDTO(registrationUuid).get();
286
            try {
287
                int messageCount = messageService.countActiveMessagesFor(regDto.registration(), user);
288

    
289
                boolean activeMessages = messageCount > 0;
290
                boolean currentUserIsSubmitter = regDto.getSubmitterUserName() != null && regDto.getSubmitterUserName().equals(UserHelperAccess.userHelper().userName());
291
                boolean currentUserIsCurator = UserHelperAccess.userHelper().userIs(new RoleProber(RolesAndPermissions.ROLE_CURATION));
292
                messageButton.setEnabled(false);
293
                if(currentUserIsCurator){
294
                    if(currentUserIsSubmitter){
295
                        messageButton.setDescription("No point sending messages to your self.");
296
                    } else {
297
                        messageButton.setEnabled(true);
298
                        messageButton.setDescription("Open the messages dialog.");
299
                    }
300
                } else {
301
                    messageButton.setDescription("Sorry, only a curator can start a conversation.");
302
                }
303
                if(activeMessages){
304
                    messageButton.setEnabled(true);
305
                    messageButton.addStyleName(EditValoTheme.BUTTON_HIGHLITE);
306
                    String who = currentUserIsSubmitter ? "curator" : "submitter";
307
                    messageButton.setDescription("The " + who + " is looking forward to your reply.");
308

    
309
                }
310
            } catch (ExternalServiceException e) {
311
                messageButton.setComponentError(new SystemError(e.getMessage(), e));
312
            }
313
        }
314
    }
315

    
316

    
317
    /**
318
     * @param referenceID
319
     */
320
    protected void loadWorkingSet(UUID referenceUuid) {
321
        try {
322
            workingset = getWorkingSetService().loadWorkingSetByReferenceUuid(referenceUuid, true);
323
        } catch (RegistrationValidationException error) {
324
            logger.error(error);
325
            Window errorDialog = new Window("Validation Error");
326
            errorDialog.setModal(true);
327
            VerticalLayout subContent = new VerticalLayout();
328
            subContent.setMargin(true);
329
            errorDialog.setContent(subContent);
330
            subContent.addComponent(new Label(error.getMessage()));
331
            UI.getCurrent().addWindow(errorDialog);
332
        }
333
        if(workingset == null || workingset.getCitationUuid() == null){
334
            Reference citation = getRepo().getReferenceService().find(referenceUuid);
335
            workingset = new RegistrationWorkingSet(citation);
336
        }
337
    }
338

    
339
    private void saveRegistrationStatusChange(UUID uuid, Object value) {
340
        Registration reg = getRepo().getRegistrationService().load(uuid);
341
        if(reg == null){
342
            // registration was not yet persisted, ignore
343
            return;
344
        }
345
        if(value != null && value instanceof RegistrationStatus){
346
            if(!Objects.equals(value, reg.getStatus())){
347
                reg.setStatus((RegistrationStatus)value);
348
                getRegistrationStore().saveBean(reg, (AbstractView)getView());
349
                refreshView(true);
350
            }
351
        } else {
352
            // only log here as error
353
            logger.error("Ivalid attempt to set RegistrationStatus to " + Objects.toString(value.toString(), "NULL"));
354
        }
355
    }
356

    
357

    
358
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
359
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
360

    
361
        if(!checkFromOwnView(event)){
362
            return;
363
        }
364

    
365
        ReferencePopupEditor popup = openPopupEditor(ReferencePopupEditor.class, event);
366
        popup.withReferenceTypes(RegistrationUIDefaults.PRINTPUB_REFERENCE_TYPES);
367
        popup.loadInEditor(null);
368
    }
369

    
370
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
371
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
372

    
373
        if(!checkFromOwnView(event)){
374
            return;
375
        }
376
        ReferencePopupEditor popup = openPopupEditor(ReferencePopupEditor.class, event);
377
        popup.withReferenceTypes(RegistrationUIDefaults.PRINTPUB_REFERENCE_TYPES);
378
        popup.withDeleteButton(true);
379
        popup.loadInEditor(event.getEntityUuid());
380
    }
381

    
382
    @EventBusListenerMethod
383
    public void onDoneWithReferencePopupEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
384
        if(event.getPopup() instanceof ReferencePopupEditor){
385
            if(event.getReason().equals(Reason.SAVE)){
386
                refreshView(true);
387
            }
388
        }
389
    }
390

    
391
    @EventBusListenerMethod
392
    public void onDoneWithSpecimenTypeDesignationWorkingsetPopupEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
393
        if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
394
            if(event.getReason().equals(Reason.SAVE)){
395
                refreshView(true);
396
            }
397
        }
398
    }
399

    
400
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
401
    public void onRegistrationEditorAction(RegistrationEditorAction event) {
402

    
403
        if(!checkFromOwnView(event)){
404
            return;
405
        }
406

    
407
        RegistrationPopupEditor popup = openPopupEditor(RegistrationPopupEditor.class, event);
408
        popup.loadInEditor(event.getEntityUuid());
409
    }
410

    
411
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
412
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
413

    
414
        if(!checkFromOwnView(event)){
415
            return;
416
        }
417

    
418
        TaxonNamePopupEditor popup = openPopupEditor(TaxonNamePopupEditor.class, event);
419
        popup.setParentEditorActionContext(event.getContext());
420
        popup.withDeleteButton(true);
421
        configureTaxonNameEditor(popup);
422
        popup.loadInEditor(event.getEntityUuid());
423
        if(event.hasSource() && event.getSource().isReadOnly()){
424
            // avoid resetting readonly to false
425
            popup.setReadOnly(true);
426
        }
427

    
428
    }
429

    
430

    
431
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
432
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
433

    
434
        if(!checkFromOwnView(event)){
435
            return;
436
        }
437

    
438
        getView().getAddNewNameRegistrationButton().setEnabled(false);
439
        newTaxonNameForRegistration = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
440
        newTaxonNameForRegistration.setNomenclaturalReference(getRepo().getReferenceService().find(workingset.getCitationUuid()));
441
        EntityChangeEvent nameSaveEvent = getTaxonNameStore().saveBean(newTaxonNameForRegistration, (AbstractView) getView());
442
        newTaxonNameForRegistration = getRepo().getNameService().find(nameSaveEvent.getEntityUuid());
443
        TaxonNamePopupEditor popup = openPopupEditor(TaxonNamePopupEditor.class, event);
444
        popup.setParentEditorActionContext(event.getContext());
445
        popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE,CRUD.DELETE));
446
        popup.withDeleteButton(true);
447
        configureTaxonNameEditor(popup);
448
        popup.loadInEditor(newTaxonNameForRegistration.getUuid());
449
    }
450

    
451
    /**
452
     * TODO consider putting this into a Configurer Bean per UIScope.
453
     * In the configurator bean this methods popup papamerter should be of the type
454
     * AbstractPopupEditor
455
     *
456
     * @param popup
457
     */
458
    protected void configureTaxonNameEditor(TaxonNamePopupEditorView popup) {
459
        popup.enableMode(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA);
460
        popup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
461
        popup.enableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
462
        // popup.enableMode(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE);
463
    }
464

    
465
    /**
466
     * Creates a new <code>Registration</code> for a new name that has just been edited
467
     * using the <code>TaxonNamePopupEditor</code>. The new name was previously created
468
     * in this presenter as <code>newTaxonNameForRegistration</code> (see {@link #onTaxonNameEditorActionAdd(TaxonNameEditorAction)})
469
     * and is either filled with data (<code>Reason.SAVE</code>) or it is still empty
470
     * (<code>Reason.CANCEL</code>).
471
     *
472
     *
473
     * @param event
474
     * @throws RegistrationValidationException
475
     */
476
    @EventBusListenerMethod
477
    public void onDoneWithTaxonnameEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
478
        if(event.getPopup() instanceof TaxonNamePopupEditor){
479
            try {
480
                TransactionStatus txStatus = getRepo().startTransaction();
481
                if(event.getReason().equals(Reason.SAVE)){
482
                    if(newTaxonNameForRegistration != null){
483
                        UUID taxonNameUuid = newTaxonNameForRegistration.getUuid();
484
                        getRepo().getSession().refresh(newTaxonNameForRegistration);
485
                        Registration reg = getRepo().getRegistrationService().createRegistrationForName(taxonNameUuid);
486
                        // reload workingset into current session
487
                        loadWorkingSet(workingset.getCitationUuid());
488
                        workingset.add(reg);
489
                    }
490
                    refreshView(true);
491
                } else if(event.getReason().equals(Reason.CANCEL)){
492
                    if(newTaxonNameForRegistration != null){
493
                        // clean up
494
                        getTaxonNameStore().deleteBean(newTaxonNameForRegistration, (AbstractView) getView());
495
                    }
496
                }
497
                getRepo().commitTransaction(txStatus);
498
            } finally {
499
                getRepo().getSession().clear(); // #7702
500
            }
501
            newTaxonNameForRegistration = null;
502
            getView().getAddNewNameRegistrationButton().setEnabled(true);
503
        }
504
    }
505

    
506

    
507
    /**
508
     * Creates a new Registration for an exiting (previously published) name.
509
     *
510
     * @param event
511
     * @throws RegistrationValidationException
512
     */
513
    @EventBusListenerMethod
514
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkingsetAction event) throws RegistrationValidationException {
515

    
516
        if(!event.isStart()){
517
            return;
518
        }
519

    
520
        getView().getAddExistingNameCombobox().commit(); // update the chosen value in the datasource
521
        TaxonName typifiedName = getView().getAddExistingNameCombobox().getValue();
522
        if(typifiedName != null){
523
            boolean doReloadWorkingSet = false;
524
            Reference citation = getRepo().getReferenceService().find(workingset.getCitationUuid());
525
            // here we completely ignore the ExistingNameRegistrationType since the user should not have the choice
526
            // to create a typification only registration in the working (publication) set which contains
527
            // the protologe. This is known from the nomenclatural reference.
528
            if(canCreateNameRegistrationFor(typifiedName)){
529
                // the citation which is the base for workingset contains the protologe of the name and the name has not
530
                // been registered before:
531
                // create a registration for the name and the first typifications
532
                Registration newRegistrationWithExistingName = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
533
                workingset.add(new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation));
534
                doReloadWorkingSet = true;
535
            } else {
536
                if(!checkWokingsetContainsProtologe(typifiedName)){
537
                    // create a typification only registration
538
                    Registration typificationOnlyRegistration = getRepo().getRegistrationService().newRegistration();
539
                    if(!getRepo().getRegistrationService().checkRegistrationExistsFor(typifiedName)){
540
                        // oops, yet no registration for this name, so we create it as blocking registration:
541
                        Registration blockingNameRegistration = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
542
                        typificationOnlyRegistration.getBlockedBy().add(blockingNameRegistration);
543
                    }
544
                    RegistrationDTO regDTO = new RegistrationDTO(typificationOnlyRegistration, typifiedName, citation);
545
                    workingset.add(regDTO);
546
                }
547
            }
548
            // tell the view to update the workingset
549
            refreshView(doReloadWorkingSet);
550
            getView().getAddExistingNameRegistrationButton().setEnabled(false);
551
        } else {
552
            logger.error("Seletced name is NULL");
553
        }
554

    
555
    }
556

    
557

    
558
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
559
    public void onTypeDesignationsEditorActionEdit(TypeDesignationWorkingsetEditorAction event) {
560

    
561
        if(!checkFromOwnView(event)){
562
            return;
563
        }
564

    
565
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
566
            SpecimenTypeDesignationWorkingsetPopupEditor popup = openPopupEditor(SpecimenTypeDesignationWorkingsetPopupEditor.class, event);
567
            popup.setParentEditorActionContext(event.getContext());
568
            popup.withDeleteButton(true);
569
            popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationUuid(), event.getBaseEntityRef()));
570
            if(event.hasSource()){
571
                // propagate readonly state from source button to popup
572
                popup.setReadOnly(event.getSource().isReadOnly());
573
            }
574
        } else {
575
            NameTypeDesignationPopupEditor popup = openPopupEditor(NameTypeDesignationPopupEditor.class, event);
576
            popup.setParentEditorActionContext(event.getContext());
577
            popup.withDeleteButton(true);
578
            popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationUuid(), event.getBaseEntityRef()));
579

    
580
            popup.getCitationCombobox().setEnabled(false);
581
            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
582

    
583
            if(event.hasSource()){
584
                // propagate readonly state from source button to popup
585
                popup.setReadOnly(event.getSource().isReadOnly());
586
            }
587
            nameTypeDesignationPopupEditorRegistrationUUIDMap.put(popup, event.getRegistrationUuid());
588
        }
589
    }
590

    
591
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
592
    public void onTypeDesignationWorkingsetAdd(TypeDesignationWorkingsetEditorAction event) {
593

    
594
        if(!event.hasSource()){
595
            return;
596
        }
597

    
598
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
599
            SpecimenTypeDesignationWorkingsetPopupEditor popup = openPopupEditor(SpecimenTypeDesignationWorkingsetPopupEditor.class, event);
600
            popup.setParentEditorActionContext(event.getContext());
601
            TypeDesignationWorkingsetEditorIdSet identifierSet;
602
            UUID typifiedNameUuid;
603

    
604
            RegistrationDTO registrationDTO = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
605
            EntityReference typifiedNameRef = registrationDTO.getTypifiedNameRef();
606
            if(typifiedNameRef != null){
607
                // case for registrations without name, in which case the typifiedName is only defined via the typedesignations
608
                typifiedNameUuid = typifiedNameRef.getUuid();
609
            } else {
610
                // case of registrations with a name in the nomenclatural act.
611
                typifiedNameUuid = registrationDTO.getNameRef().getUuid();
612
            }
613

    
614
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
615
                    event.getRegistrationUuid(),
616
                    getView().getCitationUuid(),
617
                    typifiedNameUuid
618
                    );
619
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
620
            popup.loadInEditor(identifierSet);
621
            popup.withDeleteButton(true);
622
            if(event.hasSource()){
623
                // propagate readonly state from source component to popup
624
                popup.setReadOnly(event.getSource().isReadOnly());
625
            }
626
        } else {
627
            NameTypeDesignationPopupEditor popup = openPopupEditor(NameTypeDesignationPopupEditor.class, event);
628
            popup.setParentEditorActionContext(event.getContext());
629
            popup.withDeleteButton(true);
630
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
631
            RegistrationDTO regDto = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
632
            Reference citation = regDto.getCitation();
633
            nameTypeDesignationPopupEditorRegistrationUUIDMap.put(popup, event.getRegistrationUuid());
634
            popup.setBeanInstantiator(new BeanInstantiator<NameTypeDesignation>() {
635

    
636
                @Override
637
                public NameTypeDesignation createNewBean() {
638

    
639
                    TaxonName typifiedName = getRepo().getNameService().load(event.getTypifiedNameUuid(), Arrays.asList(new String[]{"typeDesignations", "homotypicalGroup"}));
640
                    NameTypeDesignation nameTypeDesignation  = NameTypeDesignation.NewInstance();
641
                    nameTypeDesignation.setCitation(citation);
642
                    nameTypeDesignation.getTypifiedNames().add(typifiedName);
643
                    return nameTypeDesignation;
644
                }
645
            });
646
            popup.loadInEditor(null);
647
            popup.getCitationCombobox().setEnabled(false);
648
            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
649
            if(event.hasSource()){
650
                // propagate readonly state from source component to popup
651
                popup.setReadOnly(event.getSource().isReadOnly());
652
            }
653
        }
654
    }
655

    
656
    /**
657
     * Performs final actions after a TypeDesignationEditor which has been
658
     * opened to add a TypeDesignation to a Registration object which was
659
     * created for an previously published name. Prior adding a typedesignation,
660
     * the according Registration object is dangling, that has no association to
661
     * any entity denoting an nomenclatural act which has a reference to a
662
     * publication. This means that the registration object is not in the
663
     * working set.
664
     *
665
     *
666
     * @param event
667
     * @throws RegistrationValidationException
668
     */
669
    @EventBusListenerMethod
670
    public void onDoneWithTypeDesignationEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
671
        if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
672
            if(event.getReason().equals(Reason.SAVE)){
673
                // NOTE: adding the SpecimenTypeDesignations to the registration is done in the
674
                // SpecimenTypeDesignationWorkingSetServiceImpl.save(SpecimenTypeDesignationWorkingSetDTO dto) method
675
                refreshView(true);
676
            } else if(event.getReason().equals(Reason.CANCEL)){
677
                // noting to do
678
            }
679
        } else if(event.getPopup() instanceof NameTypeDesignationPopupEditor){
680
            if(event.getReason().equals(Reason.SAVE)){
681
                UUID typeDesignationUuid = ((NameTypeDesignationPopupEditor)event.getPopup()).getBean().getUuid();
682
                getRepo().getSession().clear();
683
                UUID regUUID = nameTypeDesignationPopupEditorRegistrationUUIDMap.get(event.getPopup());
684
                getRepo().getRegistrationService().addTypeDesignation(regUUID, typeDesignationUuid);
685
                getRepo().getSession().clear();
686
                nameTypeDesignationPopupEditorRegistrationUUIDMap.remove(event.getPopup());
687
                refreshView(true);
688
            } else if(event.getReason().equals(Reason.CANCEL)){
689
                // noting to do
690
            }
691

    
692
        }
693
        // ignore other editors
694
    }
695

    
696

    
697
    @EventBusListenerMethod(filter = ShowDetailsEventEntityTypeFilter.RegistrationWorkingSet.class)
698
    public void onShowDetailsEventForRegistrationWorkingSet(ShowDetailsEvent<RegistrationWorkingSet,?> event) {
699

    
700
        if(event.getProperty().equals(RegistrationItem.VALIDATION_PROBLEMS)){
701
            List<String> messages = new ArrayList<>();
702
            for(RegistrationDTO dto : workingset.getRegistrationDTOs()){
703
                dto.getValidationProblems().forEach(m -> messages.add(dto.getSummary() + ": " + m));
704
            }
705
            getView().openDetailsPopup("Validation Problems", messages);
706
        }
707
    }
708

    
709
    @EventBusListenerMethod
710
    public void onEntityChangeEvent(EntityChangeEvent event){
711

    
712
        if(workingset == null){
713
            return;
714
        }
715
        if(Reference.class.isAssignableFrom(event.getEntityType())){
716

    
717
            if(workingset.getCitationUuid().equals(event.getEntityUuid())){
718
                if(event.isRemovedType()){
719
                    viewEventBus.publish(EventScope.UI, this, new NavigationEvent(StartRegistrationViewBean.NAME));
720
                } else {
721
                    refreshView(true);
722
                }
723
            }
724

    
725
        } else
726
        if(Registration.class.isAssignableFrom(event.getEntityType())){
727
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getUuid() == event.getEntityUuid())){
728
                refreshView(true);
729
            }
730
        } else
731
        if(TaxonName.class.isAssignableFrom(event.getEntityType()) && isFromOwnView(event)){
732
            if(event.getType().equals(EntityChangeEvent.Type.CREATED)){
733
                // new name! create a blocking registration
734
                Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getSourceView()).getEditorActionContext();
735
                EditorActionContext rootContext = context.get(0);
736
                if(rootContext.getParentView().equals(getView())){
737
                    Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(event.getEntityUuid());
738
                    TypedEntityReference<Registration> regReference = (TypedEntityReference<Registration>)rootContext.getParentEntity();
739
                    Registration registration = getRepo().getRegistrationService().load(regReference.getUuid(), REGISTRATION_INIT_STRATEGY);
740
                    registration.getBlockedBy().add(blockingRegistration);
741
                    getRepo().getRegistrationService().saveOrUpdate(registration);
742
                    logger.debug("Blocking registration created");
743
                } else {
744
                    logger.debug("Non blocking registration, since a new name for a new registration has been created");
745
                }
746
            }
747
            if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
748
                reg.getTypifiedNameRef() != null
749
                && reg.getTypifiedNameRef().getUuid().equals(event.getEntityUuid()))){
750
                    refreshView(true);
751
            }
752
        } else
753
        if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
754
            if(workingset.getRegistrationDTOs().stream().anyMatch(
755
                    reg -> reg.typeDesignations() != null && reg.typeDesignations().stream().anyMatch(
756
                            td -> td.getUuid() == event.getEntityUuid()
757
                            )
758
                        )
759
                    ){
760
                refreshView(true);
761
            }
762
        }
763
    }
764

    
765

    
766
    @EventBusListenerMethod(filter = ShowDetailsEventEntityTypeFilter.RegistrationDTO.class)
767
    public void onShowDetailsEventForRegistrationDTO(ShowDetailsEvent<RegistrationDTO, UUID> event) {
768

    
769
        // FIXME check from own view!!!
770
        if(getView() == null){
771
            return;
772
        }
773

    
774
        UUID registrationUuid = event.getIdentifier();
775

    
776
        RegistrationDTO regDto = getWorkingSetService().loadDtoByUuid(registrationUuid);
777
        if(event.getProperty().equals(RegistrationItem.BLOCKED_BY)){
778

    
779
            Set<RegistrationDTO> blockingRegs = getWorkingSetService().loadBlockingRegistrations(registrationUuid);
780
            getView().setBlockingRegistrations(registrationUuid, blockingRegs);
781
        } else if(event.getProperty().equals(RegistrationItem.MESSAGES)){
782

    
783
            RegistrationMessagesPopup popup = openPopupEditor(RegistrationMessagesPopup.class, null);
784
            popup.loadMessagesFor(regDto.getUuid());
785

    
786
        } else if(event.getProperty().equals(RegistrationItem.VALIDATION_PROBLEMS)){
787
            getView().openDetailsPopup("Validation Problems", regDto.getValidationProblems());
788
        }
789

    
790

    
791
    }
792

    
793
}
(13-13/20)