Project

General

Profile

Download (35.5 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.NameTypeDesignationEditorView;
87
import eu.etaxonomy.cdm.vaadin.view.name.NameTypeDesignationPopupEditor;
88
import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetPopupEditor;
89
import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditor;
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 TaxonNamePopupEditor newNameForRegistrationPopupEditor = null;
138

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

    
141

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

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

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

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

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

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

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

    
219
            private static final long serialVersionUID = 7099181280977511048L;
220

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

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

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

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

    
249

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

    
254
    }
255

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

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

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

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

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

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

    
315

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

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

    
356

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

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

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

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

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

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

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

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

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

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

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

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

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

    
427
    }
428

    
429

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

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

    
437
        getView().getAddNewNameRegistrationButton().setEnabled(false);
438
        if(newNameForRegistrationPopupEditor == null){
439
            TaxonNamePopupEditor popup = openPopupEditor(TaxonNamePopupEditor.class, event);
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
                        getRepo().getSession().refresh(newNameForRegistrationPopupEditor.getBean().cdmEntity());
477
                        Registration reg = getRepo().getRegistrationService().createRegistrationForName(taxonNameUuid);
478
                        // reload workingset into current session
479
                        loadWorkingSet(workingset.getCitationUuid());
480
                        workingset.add(reg);
481
                    }
482
                    refreshView(true);
483
                    getRepo().commitTransaction(txStatus);
484
                }
485
            } finally {
486
                getRepo().getSession().clear(); // #7702
487
            }
488
            newNameForRegistrationPopupEditor = null;
489
            getView().getAddNewNameRegistrationButton().setEnabled(true);
490
        }
491
    }
492

    
493

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

    
503
        if(!event.isStart()){
504
            return;
505
        }
506

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

    
542
    }
543

    
544

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

    
548
        if(!checkFromOwnView(event)){
549
            return;
550
        }
551

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

    
567
            popup.getCitationCombobox().setEnabled(false);
568
            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
569

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

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

    
581
        if(!event.hasSource()){
582
            return;
583
        }
584

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

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

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

    
623
                @Override
624
                public NameTypeDesignation createNewBean() {
625

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

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

    
679
        }
680
        // ignore other editors
681
    }
682

    
683

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

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

    
696
    @EventBusListenerMethod
697
    public void onEntityChangeEvent(EntityChangeEvent event){
698

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

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

    
712
        } else
713
        if(Registration.class.isAssignableFrom(event.getEntityType())){
714
            if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getUuid() == event.getEntityUuid())){
715
                refreshView(true);
716
            }
717
        } else
718
        if(TaxonName.class.isAssignableFrom(event.getEntityType())){
719
            if(event.getType().equals(EntityChangeEvent.Type.CREATED)){
720
                Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getSourceView()).getEditorActionContext();
721
                EditorActionContext rootContext = context.get(0);
722
                if(rootContext.getParentView().equals(getView())){
723
                    // new name! create a blocking registration
724
                    UUID taxonNameUUID = event.getEntityUuid();
725
                    Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(taxonNameUUID);
726
                    TypedEntityReference<Registration> regReference = (TypedEntityReference<Registration>)rootContext.getParentEntity();
727
                    Registration registration = null;
728
                    for(int i = context.size()-1; i>0; i--){
729
                        if(NameTypeDesignationEditorView.class.isAssignableFrom(context.elementAt(i).getParentView().getClass())){
730
                            UUID registrationUUID = nameTypeDesignationPopupEditorRegistrationUUIDMap.get(context.elementAt(i).getParentView());
731
                            RegistrationDTO registrationDTO = workingset.getRegistrationDTO(registrationUUID).get();
732
                            registration = registrationDTO.registration();
733
                        }
734
                    }
735
                    if(registration == null){
736
                        throw new NullPointerException("Registration not found for the NameTypeDesignation");
737
                    }
738
                    registration.getBlockedBy().add(blockingRegistration);
739
                    getRepo().getRegistrationService().saveOrUpdate(registration);
740
                    logger.debug("Blocking registration created");
741
                } else {
742
                    // in case of creating a new name for a registration the parent view is the TaxonNamePopupEditor
743
                    // this is set
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)