Project

General

Profile

« Previous | Next » 

Revision 68afc0ec

Added by Andreas Kohlbecker about 5 years ago

ref #8050 moving transactional code from RegistrationWorkingsetPresenter to new service class

View differences:

src/main/java/eu/etaxonomy/cdm/service/IRegistrationWorkflowService.java
1
/**
2
* Copyright (C) 2019 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.service;
10

  
11
import java.util.List;
12
import java.util.UUID;
13

  
14
import org.springframework.transaction.annotation.Transactional;
15

  
16
import eu.etaxonomy.cdm.api.service.dto.RegistrationWorkingSet;
17
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
18
import eu.etaxonomy.cdm.model.name.Registration;
19
import eu.etaxonomy.cdm.model.name.TaxonName;
20

  
21
/**
22
 * @author a.kohlbecker
23
 * @since Mar 26, 2019
24
 *
25
 */
26
public interface IRegistrationWorkflowService {
27

  
28
    /**
29
     * @param taxonName
30
     * @param relatedBlockingRegistrations
31
     *  The blocking registrations to be added to the new Registration
32
     */
33
    @Transactional
34
    Registration createRegistration(TaxonName taxonName, List<Registration> relatedBlockingRegistrations);
35

  
36
    @Transactional
37
    boolean createRegistrationforExistingName(RegistrationWorkingSet workingset, TaxonName typifiedName) throws RegistrationValidationException;
38

  
39
    @Transactional(readOnly=true)
40
    void reloadRegistration(Registration registration);
41

  
42
    @Transactional
43
    void addBlockingRegistration(UUID taxonNameUUID, Registration registration);
44

  
45
    @Transactional
46
    void addTypeDesignation(UUID typeDesignationUuid, Registration registration);
47

  
48
    @Transactional(readOnly=true)
49
    boolean canCreateNameRegistrationFor(RegistrationWorkingSet workingset, TaxonName name);
50

  
51
    boolean checkWokingsetContainsProtologe(RegistrationWorkingSet workingset, TaxonName name);
52

  
53
}
src/main/java/eu/etaxonomy/cdm/service/RegistrationWorkflowService.java
1
/**
2
* Copyright (C) 2019 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.service;
10

  
11
import java.util.Arrays;
12
import java.util.List;
13
import java.util.UUID;
14

  
15
import org.apache.log4j.Logger;
16
import org.springframework.beans.factory.annotation.Autowired;
17
import org.springframework.beans.factory.annotation.Qualifier;
18
import org.springframework.stereotype.Service;
19

  
20
import eu.etaxonomy.cdm.api.application.CdmRepository;
21
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
22
import eu.etaxonomy.cdm.api.service.dto.RegistrationWorkingSet;
23
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
24
import eu.etaxonomy.cdm.model.name.Registration;
25
import eu.etaxonomy.cdm.model.name.TaxonName;
26
import eu.etaxonomy.cdm.model.reference.Reference;
27
import eu.etaxonomy.cdm.model.reference.ReferenceType;
28

  
29
/**
30
 * @author a.kohlbecker
31
 * @since Mar 25, 2019
32
 *
33
 */
34
@Service("registrationWorkflowService")
35
public class RegistrationWorkflowService implements IRegistrationWorkflowService {
36

  
37
    private static Logger logger = Logger.getLogger(RegistrationWorkflowService.class);
38

  
39
    @Autowired
40
    @Qualifier("cdmRepository")
41
    private CdmRepository repo;
42

  
43
    private CdmRepository getRepo() {
44
        return repo;
45
    }
46

  
47

  
48
    @Override
49
    public Registration createRegistration(TaxonName taxonName, List<Registration> preparedBlockingResitrations) {
50

  
51
        if(taxonName.isPersited()){
52
            getRepo().getSession().refresh(taxonName);
53
        }
54

  
55
        Registration reg = getRepo().getRegistrationService().createRegistrationForName(taxonName.getUuid());
56
        if(!preparedBlockingResitrations.isEmpty()){
57
            for(Registration blockingReg : preparedBlockingResitrations){
58
                blockingReg = getRepo().getRegistrationService().load(blockingReg.getUuid());
59
                reg.getBlockedBy().add(blockingReg);
60
            }
61
            // save again
62
            getRepo().getRegistrationService().saveOrUpdate(reg);
63
            preparedBlockingResitrations.clear();
64
        }
65
        return reg;
66
    }
67

  
68

  
69
    @Override
70
    public boolean createRegistrationforExistingName(RegistrationWorkingSet workingset, TaxonName typifiedName) throws RegistrationValidationException {
71

  
72
        boolean doReloadWorkingSet = false;
73
        Reference citation = getRepo().getReferenceService().load(workingset.getCitationUuid(), Arrays.asList("authorship.$", "inReference.authorship.$"));
74
        // here we completely ignore the ExistingNameRegistrationType since the user should not have the choice
75
        // to create a typification only registration in the working (publication) set which contains
76
        // the protologe. This is known from the nomenclatural reference.
77
        if(canCreateNameRegistrationFor(workingset, typifiedName)){
78
            // the citation which is the base for workingset contains the protologe of the name and the name has not
79
            // been registered before:
80
            // create a registration for the name and the first typifications
81
            Registration newRegistrationWithExistingName = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
82
            workingset.add(new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation));
83
            doReloadWorkingSet = true;
84
        } else {
85
            if(!checkWokingsetContainsProtologe(workingset, typifiedName)){
86
                // create a typification only registration
87
                Registration typificationOnlyRegistration = getRepo().getRegistrationService().newRegistration();
88
                if(!getRepo().getRegistrationService().checkRegistrationExistsFor(typifiedName)){
89
                    // oops, yet no registration for this name, so we create it as blocking registration:
90
                    Registration blockingNameRegistration = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
91
                    typificationOnlyRegistration.getBlockedBy().add(blockingNameRegistration);
92
                }
93
                RegistrationDTO regDTO = new RegistrationDTO(typificationOnlyRegistration, typifiedName, citation);
94
                workingset.add(regDTO);
95
            }
96
        }
97
        return doReloadWorkingSet;
98
    }
99

  
100
    @Override
101
    public void addTypeDesignation(UUID typeDesignationUuid, Registration registration) {
102
        reloadRegistration(registration);
103
        getRepo().getRegistrationService().addTypeDesignation(registration, typeDesignationUuid);
104
        getRepo().getRegistrationService().saveOrUpdate(registration);
105
    }
106

  
107
    /**
108
     * @param taxonNameUUID
109
     * @param registration
110
     */
111
    @Override
112
    public void addBlockingRegistration(UUID taxonNameUUID, Registration registration) {
113
        Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(taxonNameUUID);
114
        reloadRegistration(registration);
115
        registration.getBlockedBy().add(blockingRegistration);
116
        if(registration.isPersited()){
117
            getRepo().getRegistrationService().saveOrUpdate(registration);
118
            logger.debug("Blocking registration created, added to registion and persited");
119
        }
120
    }
121

  
122
    /**
123
     * @param registration
124
     * @return
125
     */
126
    @Override
127
    public void reloadRegistration(Registration registration) {
128
        if(registration.isPersited()){
129
             Registration registrationReloaded = getRepo().getRegistrationService().load(registration.getUuid());
130
             if(registrationReloaded == null){
131
                 throw new NullPointerException("Registration not found for Registration#" + registration.getUuid() + " which has been hold in the rootContext");
132
             }
133
             registration = registrationReloaded;
134
         } else {
135
             logger.trace("Registration is not yet persisted.");
136
         }
137
    }
138

  
139
    /**
140
     * Checks
141
     * <ol>
142
     * <li>if there is NOT any registration for this name created in the current registration system</li>
143
     * <li>Checks if the name belongs to the current workingset</li>
144
     * </ol>
145
     * If both checks are successful the method returns <code>true</code>.
146
     */
147
    @Override
148
    public boolean canCreateNameRegistrationFor(RegistrationWorkingSet workingset, TaxonName name) {
149
        return !getRepo().getRegistrationService().checkRegistrationExistsFor(name) && checkWokingsetContainsProtologe(workingset, name);
150
    }
151

  
152
    /**
153
     * @param name
154
     * @return
155
     */
156
    @Override
157
    public boolean checkWokingsetContainsProtologe(RegistrationWorkingSet workingset, TaxonName name) {
158
        Reference nomRef = name.getNomenclaturalReference();
159
        UUID citationUuid = workingset.getCitationUuid();
160
        // @formatter:off
161
        return nomRef != null && (
162
                // nomref matches
163
                nomRef.getUuid().equals(citationUuid) ||
164
                // nomref.inreference matches
165
                (nomRef.getType() != null && nomRef.getType() == ReferenceType.Section && nomRef.getInReference() != null && nomRef.getInReference().getUuid().equals(citationUuid))
166
                );
167
        // @formatter:on
168
    }
169

  
170
}
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java
23 23

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

  
......
56 55
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
57 56
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
58 57
import eu.etaxonomy.cdm.model.reference.Reference;
59
import eu.etaxonomy.cdm.model.reference.ReferenceType;
60 58
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
61 59
import eu.etaxonomy.cdm.ref.EntityReference;
62 60
import eu.etaxonomy.cdm.ref.TypedEntityReference;
......
64 62
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
65 63
import eu.etaxonomy.cdm.service.CdmFilterablePagingProviderFactory;
66 64
import eu.etaxonomy.cdm.service.CdmStore;
65
import eu.etaxonomy.cdm.service.IRegistrationWorkflowService;
67 66
import eu.etaxonomy.cdm.service.UserHelperAccess;
68 67
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationItem;
69 68
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStatusFieldInstantiator;
......
113 112
    @Autowired
114 113
    private IRegistrationWorkingSetService regWorkingSetService;
115 114

  
115
    @Autowired
116
    private IRegistrationWorkflowService registrationWorkflowService;
117

  
116 118
    @Autowired
117 119
    private CdmFilterablePagingProviderFactory pagingProviderFactory;
118 120

  
......
175 177
        return new  CdmStore<TaxonName, INameService>(getRepo(), getRepo().getNameService());
176 178
    }
177 179

  
178
    /**
179
     * Checks
180
     * <ol>
181
     * <li>if there is NOT any registration for this name created in the current registration system</li>
182
     * <li>Checks if the name belongs to the current workingset</li>
183
     * </ol>
184
     * If both checks are successful the method returns <code>true</code>.
185
     */
186
    public boolean canCreateNameRegistrationFor(TaxonName name) {
187
        return !getRepo().getRegistrationService().checkRegistrationExistsFor(name) && checkWokingsetContainsProtologe(name);
188
    }
189 180

  
190
    /**
191
     * @param name
192
     * @return
193
     */
194
    public boolean checkWokingsetContainsProtologe(TaxonName name) {
195
        Reference nomRef = name.getNomenclaturalReference();
196
        UUID citationUuid = workingset.getCitationUuid();
197
        // @formatter:off
198
        return nomRef != null && (
199
                // nomref matches
200
                nomRef.getUuid().equals(citationUuid) ||
201
                // nomref.inreference matches
202
                (nomRef.getType() != null && nomRef.getType() == ReferenceType.Section && nomRef.getInReference() != null && nomRef.getInReference().getUuid().equals(citationUuid))
203
                );
204
        // @formatter:on
205
    }
206 181

  
207 182
    /**
208 183
     * @param doReload reload the workingset from the persistent storage.
......
468 443
        if(event.getPopup() instanceof TaxonNamePopupEditor){
469 444
            if(newNameForRegistrationPopupEditor != null && event.getPopup().equals(newNameForRegistrationPopupEditor)){
470 445
                if(event.getReason().equals(Reason.SAVE)){
471

  
472 446
                    try {
473
                        // TODO move into a service class --------------
474
                        TransactionStatus txStatus = getRepo().startTransaction();
475
                        try {
476
                            UUID taxonNameUuid = newNameForRegistrationPopupEditor.getBean().getUuid();
477
                            if(newNameForRegistrationPopupEditor.getBean().cdmEntity().isPersited()){
478
                                getRepo().getSession().refresh(newNameForRegistrationPopupEditor.getBean().cdmEntity());
479
                            }
480
                            Registration reg = getRepo().getRegistrationService().createRegistrationForName(taxonNameUuid);
481
                            if(!newNameBlockingRegistrations.isEmpty()){
482
                                for(Registration blockingReg : newNameBlockingRegistrations){
483
                                    blockingReg = getRepo().getRegistrationService().load(blockingReg.getUuid());
484
                                    reg.getBlockedBy().add(blockingReg);
485
                                }
486
                                getRepo().getRegistrationService().saveOrUpdate(reg);
487
                                newNameBlockingRegistrations.clear();
488
                            }
489
                           getRepo().commitTransaction(txStatus);
490
                        } catch (Exception e){
491
                            getRepo().getTransactionManager().rollback(txStatus);
492
                            throw e;
493
                        }
494
                        // --------------------------------------------------
495
                        // reload workingset into current session
447
                        TaxonName taxonName = newNameForRegistrationPopupEditor.getBean().cdmEntity();
448
                        registrationWorkflowService.createRegistration(taxonName, newNameBlockingRegistrations);
496 449
                        loadWorkingSet(workingset.getCitationUuid());
450
                        refreshView(true);
451
                        getView().getAddNewNameRegistrationButton().setEnabled(true);
497 452
                    } finally {
498 453
                        getRepo().getSession().clear(); // #7702
499 454
                        refreshView(true);
500 455
                        getView().getAddNewNameRegistrationButton().setEnabled(true);
501 456
                    }
502 457
                }
503

  
504 458
                // nullify and clear the memory on this popup editor in any case (SAVE, CANCEL, DELETE)
505 459
                newNameForRegistrationPopupEditor = null;
506 460
                newNameBlockingRegistrations.clear();
......
512 466
    }
513 467

  
514 468

  
469

  
470

  
515 471
    /**
516 472
     * Creates a new Registration for an exiting (previously published) name.
517 473
     *
......
530 486
        if(typifiedName != null){
531 487
            boolean doReloadWorkingSet = false;
532 488
            try {
533
                // TODO move into a service class --------------
534
                TransactionStatus txStatus = getRepo().startTransaction(true);
535
                try {
536
                    Reference citation = getRepo().getReferenceService().load(workingset.getCitationUuid(), Arrays.asList("authorship.$", "inReference.authorship.$"));
537
                    // here we completely ignore the ExistingNameRegistrationType since the user should not have the choice
538
                    // to create a typification only registration in the working (publication) set which contains
539
                    // the protologe. This is known from the nomenclatural reference.
540
                    if(canCreateNameRegistrationFor(typifiedName)){
541
                        // the citation which is the base for workingset contains the protologe of the name and the name has not
542
                        // been registered before:
543
                        // create a registration for the name and the first typifications
544
                        Registration newRegistrationWithExistingName = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
545
                        workingset.add(new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation));
546
                        doReloadWorkingSet = true;
547
                    } else {
548
                        if(!checkWokingsetContainsProtologe(typifiedName)){
549
                            // create a typification only registration
550
                            Registration typificationOnlyRegistration = getRepo().getRegistrationService().newRegistration();
551
                            if(!getRepo().getRegistrationService().checkRegistrationExistsFor(typifiedName)){
552
                                // oops, yet no registration for this name, so we create it as blocking registration:
553
                                Registration blockingNameRegistration = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
554
                                typificationOnlyRegistration.getBlockedBy().add(blockingNameRegistration);
555
                            }
556
                            RegistrationDTO regDTO = new RegistrationDTO(typificationOnlyRegistration, typifiedName, citation);
557
                            workingset.add(regDTO);
558
                        }
559
                    }
560
                    getRepo().commitTransaction(txStatus);
561
                } catch (Exception e){
562
                    getRepo().getTransactionManager().rollback(txStatus);
563
                    throw e;
564
                }
565
                // --------------------------------------------------
566
                // tell the view to update the workingset
489
                doReloadWorkingSet = registrationWorkflowService.createRegistrationforExistingName(workingset, typifiedName);
567 490
            } finally {
568 491
                getRepo().getSession().clear(); // #7702;
569 492
                refreshView(doReloadWorkingSet);
......
575 498

  
576 499
    }
577 500

  
578

  
579 501
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
580 502
    public void onTypeDesignationsEditorActionEdit(TypeDesignationWorkingsetEditorAction event) {
581 503

  
......
702 624
                UUID typeDesignationUuid = ((NameTypeDesignationPopupEditor)event.getPopup()).getBean().getUuid();
703 625

  
704 626
                try {
627
                    Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getPopup()).getEditorActionContext();
628
                    Registration registration = findRegistrationInContext(context);
705 629
                    getRepo().getSession().clear();
706
                    // TODO move into a service class --------------
707
                    TransactionStatus txStatus = getRepo().startTransaction();
708
                    try {
709
                        UUID regUUID = nameTypeDesignationPopupEditorRegistrationUUIDMap.get(event.getPopup());
710
                        Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getPopup()).getEditorActionContext();
711
                        Registration registration = findRegistrationInContext(context);
712
                        getRepo().getRegistrationService().addTypeDesignation(registration, typeDesignationUuid);
713
                        getRepo().getRegistrationService().saveOrUpdate(registration);
714
                        nameTypeDesignationPopupEditorRegistrationUUIDMap.remove(event.getPopup());
715
                        getRepo().commitTransaction(txStatus);
716
                    } catch (Exception e){
717
                        getRepo().getTransactionManager().rollback(txStatus);
718
                        throw e;
719
                    }
720
                    // TODO move into a service class --------------
630
                    registrationWorkflowService.addTypeDesignation(typeDesignationUuid, registration);
631
                    nameTypeDesignationPopupEditorRegistrationUUIDMap.remove(event.getPopup());
721 632
                } finally {
722 633
                    getRepo().getSession().clear();
723 634
                    refreshView(true);
......
770 681
                Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getSourceView()).getEditorActionContext();
771 682
                EditorActionContext rootContext = context.get(0);
772 683
                if(rootContext.getParentView().equals(getView()) && event.getSourceView() != newNameForRegistrationPopupEditor){
773

  
774 684
                    try {
775 685
                        getRepo().getSession().clear();
776
                        // TODO move into a service class --------------
777
                        TransactionStatus txStatus = getRepo().startTransaction();
778
                        try {
779
                            // create a blocking registration, the new Registration will be persisted
780
                            UUID taxonNameUUID = event.getEntityUuid();
686
                        // create a blocking registration, the new Registration will be persisted
687
                        UUID taxonNameUUID = event.getEntityUuid();
688

  
689
                        if(context.get(1).getParentView() instanceof TaxonNamePopupEditor && !((TaxonNamePopupEditor)context.get(1).getParentView()).getBean().cdmEntity().isPersited()){
690
                            // Oha!! The event came from a popup editor and the
691
                            // first popup in the context is a TaxonNameEditor with un-persisted name
692
                            // This is a name for a new registration which has not yet been created.
693
                            // It is necessary to store blocking registrations in the newNameBlockingRegistrations
781 694
                            Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(taxonNameUUID);
782

  
783
                            if(context.get(1).getParentView() instanceof TaxonNamePopupEditor && !((TaxonNamePopupEditor)context.get(1).getParentView()).getBean().cdmEntity().isPersited()){
784
                                // Oha!! The event came from a popup editor and the
785
                                // first popup in the context is a TaxonNameEditor with un-persisted name
786
                                // This is a name for a new registration which has not yet been created.
787
                                // It is necessary to store blocking registrations in the newNameBlockingRegistrations
788
                                newNameBlockingRegistrations.add(blockingRegistration);
789
                                logger.debug("Blocking registration created and memorized");
790
                            } else {
791
                                // some new name somehow related to an existing registration
792
                                Registration registration = findRegistrationInContext(context);
793
                                registration.getBlockedBy().add(blockingRegistration);
794

  
795
                                if(registration.isPersited()){
796
                                    getRepo().getRegistrationService().saveOrUpdate(registration);
797
                                    logger.debug("Blocking registration created, added to registion and persited");
798
                                }
799
                            }
800
                            getRepo().commitTransaction(txStatus);
801
                        } catch (Exception e){
802
                            getRepo().getTransactionManager().rollback(txStatus);
803
                            throw e;
695
                            newNameBlockingRegistrations.add(blockingRegistration);
696
                            logger.debug("Blocking registration created and memorized");
697
                        } else {
698
                            Registration registration = findRegistrationInContext(context);
699
                            // some new name somehow related to an existing registration
700
                            registrationWorkflowService.addBlockingRegistration(taxonNameUUID, registration);
804 701
                        }
805
                        // TODO move into a service class --------------
806 702
                    } finally {
807 703
                        getRepo().getSession().clear();
808 704
                    }
......
832 728
    }
833 729

  
834 730
    /**
731
     * Finds the Registration in the EditorContext stack
732
     *
835 733
     * @param context
836 734
     * @return
837 735
     */
......
841 739
        RegistrationDTO registrationDTO = workingset.getRegistrationDTO(regReference.getUuid()).get();
842 740
        Registration registration = registrationDTO.registration();
843 741

  
844
        if(registration.isPersited()){
845
             registration = getRepo().getRegistrationService().load(registration.getUuid());
846
             if(registration == null){
847
                 throw new NullPointerException("Registration not found for " + regReference + " which has been hold in the rootContext");
848
             }
849
         } else {
850
             logger.trace("Registration is not yet persisted.");
851
         }
742
        // registration = reloadRegistration(registration);
852 743
        return registration;
853 744
    }
854 745

  
746

  
747

  
855 748
    @EventBusListenerMethod(filter = ShowDetailsEventEntityTypeFilter.RegistrationDTO.class)
856 749
    public void onShowDetailsEventForRegistrationDTO(ShowDetailsEvent<RegistrationDTO, UUID> event) {
857 750

  
......
917 810
        cache.dispose();
918 811
    }
919 812

  
813
    /**
814
     * @param name
815
     * @return
816
     */
817
    public boolean canCreateNameRegistrationFor(TaxonName name) {
818
        return registrationWorkflowService.canCreateNameRegistrationFor(workingset, name);
819
    }
820

  
821
    /**
822
     * @param name
823
     * @return
824
     */
825
    public boolean checkWokingsetContainsProtologe(TaxonName name) {
826
        return registrationWorkflowService.checkWokingsetContainsProtologe(workingset, name);
827
    }
828

  
920 829
}

Also available in: Unified diff