Project

General

Profile

Download (35.2 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.ui.config.TaxonNamePopupEditorConfig;
85
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
86
import eu.etaxonomy.cdm.vaadin.view.name.NameTypeDesignationPopupEditor;
87
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetPopupEditor;
88
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditor;
89
import eu.etaxonomy.cdm.vaadin.view.name.TypeDesignationWorkingsetEditorIdSet;
90
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
91
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
92
import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
93
import eu.etaxonomy.vaadin.mvp.AbstractView;
94
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
95
import eu.etaxonomy.vaadin.ui.navigation.NavigationEvent;
96
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
97
import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
98

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

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

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

    
119
    private static final long serialVersionUID = 1L;
120

    
121
    @Autowired
122
    private IRegistrationWorkingSetService regWorkingSetService;
123

    
124
    @Autowired
125
    private IRegistrationMessageService messageService;
126

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

    
134
    private RegistrationWorkingSet workingset;
135

    
136
    private TaxonNamePopupEditor newNameForRegistrationPopupEditor = null;
137

    
138
    private Map<NameTypeDesignationPopupEditor, UUID> nameTypeDesignationPopupEditorRegistrationUUIDMap = new HashMap<>();
139

    
140

    
141
    /**
142
     *
143
     */
144
    public RegistrationWorkingsetPresenter() {
145
    }
146

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

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

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

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

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

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

    
218
            private static final long serialVersionUID = 7099181280977511048L;
219

    
220
            @Override
221
            public AbstractField<Object> create(RegistrationDTO regDto) {
222

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

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

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

    
248

    
249
        });
250
        loadWorkingSet(getView().getCitationUuid());
251
        applyWorkingset();
252

    
253
    }
254

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

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

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

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

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

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

    
314

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

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

    
355

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

    
359
        if(!checkFromOwnView(event)){
360
            return;
361
        }
362

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

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

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

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

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

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

    
401
        if(!checkFromOwnView(event)){
402
            return;
403
        }
404

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

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

    
412
        if(!checkFromOwnView(event)){
413
            return;
414
        }
415

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

    
426
    }
427

    
428

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

    
432
        if(!checkFromOwnView(event)){
433
            return;
434
        }
435

    
436
        getView().getAddNewNameRegistrationButton().setEnabled(false);
437
        if(newNameForRegistrationPopupEditor == null){
438
            TaxonNamePopupEditor popup = openPopupEditor(TaxonNamePopupEditor.class, event);
439
            newNameForRegistrationPopupEditor = popup;
440
            popup.setParentEditorActionContext(event.getContext());
441
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE,CRUD.DELETE));
442
            popup.withDeleteButton(true);
443
            popup.setCdmEntityInstantiator(new BeanInstantiator<TaxonName>() {
444

    
445
                @Override
446
                public TaxonName createNewBean() {
447
                    TaxonName newTaxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
448
                    newTaxonName.setNomenclaturalReference(getRepo().getReferenceService().load(workingset.getCitationUuid()));
449
                    return newTaxonName;
450
                }
451
            });
452
            TaxonNamePopupEditorConfig.configureForNomenclaturalAct(popup);
453
            popup.loadInEditor(null);
454
        }
455
    }
456

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

    
495

    
496
    /**
497
     * Creates a new Registration for an exiting (previously published) name.
498
     *
499
     * @param event
500
     * @throws RegistrationValidationException
501
     */
502
    @EventBusListenerMethod
503
    public void onRegistrationWorkflowEventActionStart(RegistrationWorkingsetAction event) throws RegistrationValidationException {
504

    
505
        if(!event.isStart()){
506
            return;
507
        }
508

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

    
544
    }
545

    
546

    
547
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
548
    public void onTypeDesignationsEditorActionEdit(TypeDesignationWorkingsetEditorAction event) {
549

    
550
        if(!checkFromOwnView(event)){
551
            return;
552
        }
553

    
554
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET ){
555
            SpecimenTypeDesignationWorkingsetPopupEditor popup = openPopupEditor(SpecimenTypeDesignationWorkingsetPopupEditor.class, event);
556
            popup.setParentEditorActionContext(event.getContext());
557
            popup.withDeleteButton(true);
558
            popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationUuid(), event.getBaseEntityRef()));
559
            if(event.hasSource()){
560
                // propagate readonly state from source button to popup
561
                popup.setReadOnly(event.getSource().isReadOnly());
562
            }
563
        } else {
564
            NameTypeDesignationPopupEditor popup = openPopupEditor(NameTypeDesignationPopupEditor.class, event);
565
            popup.setParentEditorActionContext(event.getContext());
566
            popup.withDeleteButton(true);
567
            popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationUuid(), event.getBaseEntityRef()));
568

    
569
            popup.getCitationCombobox().setEnabled(false);
570
            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
571

    
572
            if(event.hasSource()){
573
                // propagate readonly state from source button to popup
574
                popup.setReadOnly(event.getSource().isReadOnly());
575
            }
576
            nameTypeDesignationPopupEditorRegistrationUUIDMap.put(popup, event.getRegistrationUuid());
577
        }
578
    }
579

    
580
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
581
    public void onTypeDesignationWorkingsetAdd(TypeDesignationWorkingsetEditorAction event) {
582

    
583
        if(!event.hasSource()){
584
            return;
585
        }
586

    
587
        if(event.getWorkingSetType() == TypeDesignationWorkingSetType.SPECIMEN_TYPE_DESIGNATION_WORKINGSET){
588
            SpecimenTypeDesignationWorkingsetPopupEditor popup = openPopupEditor(SpecimenTypeDesignationWorkingsetPopupEditor.class, event);
589
            popup.setParentEditorActionContext(event.getContext());
590
            TypeDesignationWorkingsetEditorIdSet identifierSet;
591
            UUID typifiedNameUuid;
592

    
593
            RegistrationDTO registrationDTO = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
594
            EntityReference typifiedNameRef = registrationDTO.getTypifiedNameRef();
595
            if(typifiedNameRef != null){
596
                // case for registrations without name, in which case the typifiedName is only defined via the typedesignations
597
                typifiedNameUuid = typifiedNameRef.getUuid();
598
            } else {
599
                // case of registrations with a name in the nomenclatural act.
600
                typifiedNameUuid = registrationDTO.getNameRef().getUuid();
601
            }
602

    
603
            identifierSet = new TypeDesignationWorkingsetEditorIdSet(
604
                    event.getRegistrationUuid(),
605
                    getView().getCitationUuid(),
606
                    typifiedNameUuid
607
                    );
608
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
609
            popup.loadInEditor(identifierSet);
610
            popup.withDeleteButton(true);
611
            if(event.hasSource()){
612
                // propagate readonly state from source component to popup
613
                popup.setReadOnly(event.getSource().isReadOnly());
614
            }
615
        } else {
616
            NameTypeDesignationPopupEditor popup = openPopupEditor(NameTypeDesignationPopupEditor.class, event);
617
            popup.setParentEditorActionContext(event.getContext());
618
            popup.withDeleteButton(true);
619
            popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
620
            RegistrationDTO regDto = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
621
            Reference citation = regDto.getCitation();
622
            nameTypeDesignationPopupEditorRegistrationUUIDMap.put(popup, event.getRegistrationUuid());
623
            popup.setBeanInstantiator(new BeanInstantiator<NameTypeDesignation>() {
624

    
625
                @Override
626
                public NameTypeDesignation createNewBean() {
627

    
628
                    TaxonName typifiedName = getRepo().getNameService().load(event.getTypifiedNameUuid(), Arrays.asList(new String[]{"typeDesignations", "homotypicalGroup"}));
629
                    NameTypeDesignation nameTypeDesignation  = NameTypeDesignation.NewInstance();
630
                    nameTypeDesignation.setCitation(citation);
631
                    nameTypeDesignation.getTypifiedNames().add(typifiedName);
632
                    return nameTypeDesignation;
633
                }
634
            });
635
            popup.loadInEditor(null);
636
            popup.getCitationCombobox().setEnabled(false);
637
            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
638
            if(event.hasSource()){
639
                // propagate readonly state from source component to popup
640
                popup.setReadOnly(event.getSource().isReadOnly());
641
            }
642
        }
643
    }
644

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

    
681
        }
682
        // ignore other editors
683
    }
684

    
685

    
686
    @EventBusListenerMethod(filter = ShowDetailsEventEntityTypeFilter.RegistrationWorkingSet.class)
687
    public void onShowDetailsEventForRegistrationWorkingSet(ShowDetailsEvent<RegistrationWorkingSet,?> event) {
688

    
689
        if(event.getProperty().equals(RegistrationItem.VALIDATION_PROBLEMS)){
690
            List<String> messages = new ArrayList<>();
691
            for(RegistrationDTO dto : workingset.getRegistrationDTOs()){
692
                dto.getValidationProblems().forEach(m -> messages.add(dto.getSummary() + ": " + m));
693
            }
694
            getView().openDetailsPopup("Validation Problems", messages);
695
        }
696
    }
697

    
698
    @EventBusListenerMethod
699
    public void onEntityChangeEvent(EntityChangeEvent event){
700

    
701
        if(workingset == null){
702
            return;
703
        }
704
        if(Reference.class.isAssignableFrom(event.getEntityType())){
705

    
706
            if(workingset.getCitationUuid().equals(event.getEntityUuid())){
707
                if(event.isRemovedType()){
708
                    viewEventBus.publish(EventScope.UI, this, new NavigationEvent(StartRegistrationViewBean.NAME));
709
                } else {
710
                    refreshView(true);
711
                }
712
            }
713

    
714
        } else
715
        if(Registration.class.isAssignableFrom(event.getEntityType())){
716
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getUuid() == event.getEntityUuid())){
717
                refreshView(true);
718
            }
719
        } else
720
        if(TaxonName.class.isAssignableFrom(event.getEntityType())){
721
            if(event.getType().equals(EntityChangeEvent.Type.CREATED)){
722
                Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getSourceView()).getEditorActionContext();
723
                EditorActionContext rootContext = context.get(0);
724
                if(rootContext.getParentView().equals(getView())){
725
                    // new name! create a blocking registration
726
                    UUID taxonNameUUID = event.getEntityUuid();
727
                    Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(taxonNameUUID);
728
                    TypedEntityReference<Registration> regReference = (TypedEntityReference<Registration>)rootContext.getParentEntity();
729
                    RegistrationDTO registrationDTO = workingset.getRegistrationDTO(regReference.getUuid()).get();
730
                    Registration registration = registrationDTO.registration();
731
                    if(registration == null){
732
                        throw new NullPointerException("Registration not found for " + regReference + " which has been hold in the rootContext");
733
                    }
734
                    registration.getBlockedBy().add(blockingRegistration);
735
                    getRepo().getRegistrationService().saveOrUpdate(registration);
736
                    logger.debug("Blocking registration created");
737
                } else {
738
                    // in case of creating a new name for a registration the parent view is the TaxonNamePopupEditor
739
                    // this is set
740
                    logger.debug("Non blocking registration, since a new name for a new registration has been created");
741
                }
742
            }
743
            if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
744
                reg.getTypifiedNameRef() != null
745
                && reg.getTypifiedNameRef().getUuid().equals(event.getEntityUuid()))){
746
                    refreshView(true);
747
            }
748
        } else
749
        if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
750
            if(workingset.getRegistrationDTOs().stream().anyMatch(
751
                    reg -> reg.typeDesignations() != null && reg.typeDesignations().stream().anyMatch(
752
                            td -> td.getUuid() == event.getEntityUuid()
753
                            )
754
                        )
755
                    ){
756
                refreshView(true);
757
            }
758
        }
759
    }
760

    
761

    
762
    @EventBusListenerMethod(filter = ShowDetailsEventEntityTypeFilter.RegistrationDTO.class)
763
    public void onShowDetailsEventForRegistrationDTO(ShowDetailsEvent<RegistrationDTO, UUID> event) {
764

    
765
        // FIXME check from own view!!!
766
        if(getView() == null){
767
            return;
768
        }
769

    
770
        UUID registrationUuid = event.getIdentifier();
771

    
772
        RegistrationDTO regDto = getWorkingSetService().loadDtoByUuid(registrationUuid);
773
        if(event.getProperty().equals(RegistrationItem.BLOCKED_BY)){
774

    
775
            Set<RegistrationDTO> blockingRegs = getWorkingSetService().loadBlockingRegistrations(registrationUuid);
776
            getView().setBlockingRegistrations(registrationUuid, blockingRegs);
777
        } else if(event.getProperty().equals(RegistrationItem.MESSAGES)){
778

    
779
            RegistrationMessagesPopup popup = openPopupEditor(RegistrationMessagesPopup.class, null);
780
            popup.loadMessagesFor(regDto.getUuid());
781

    
782
        } else if(event.getProperty().equals(RegistrationItem.VALIDATION_PROBLEMS)){
783
            getView().openDetailsPopup("Validation Problems", regDto.getValidationProblems());
784
        }
785

    
786

    
787
    }
788

    
789
}
(13-13/20)