19 |
19 |
import java.util.UUID;
|
20 |
20 |
|
21 |
21 |
import org.apache.log4j.Logger;
|
22 |
|
import org.hibernate.Session;
|
23 |
|
import org.hibernate.Transaction;
|
24 |
22 |
import org.springframework.beans.factory.annotation.Autowired;
|
25 |
|
import org.springframework.security.core.Authentication;
|
26 |
23 |
import org.springframework.transaction.TransactionStatus;
|
27 |
24 |
import org.vaadin.spring.events.EventScope;
|
28 |
25 |
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
... | ... | |
33 |
30 |
import com.vaadin.ui.AbstractField;
|
34 |
31 |
import com.vaadin.ui.Button;
|
35 |
32 |
import com.vaadin.ui.Label;
|
|
33 |
import com.vaadin.ui.Notification;
|
|
34 |
import com.vaadin.ui.Notification.Type;
|
36 |
35 |
import com.vaadin.ui.UI;
|
37 |
36 |
import com.vaadin.ui.VerticalLayout;
|
38 |
37 |
import com.vaadin.ui.Window;
|
... | ... | |
43 |
42 |
import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
|
44 |
43 |
import eu.etaxonomy.cdm.api.service.dto.RegistrationWorkingSet;
|
45 |
44 |
import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
|
46 |
|
import eu.etaxonomy.cdm.api.service.idminter.IdentifierMinter.Identifier;
|
47 |
|
import eu.etaxonomy.cdm.api.service.idminter.RegistrationIdentifierMinter;
|
48 |
45 |
import eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager.TypeDesignationWorkingSetType;
|
49 |
46 |
import eu.etaxonomy.cdm.api.service.registration.IRegistrationWorkingSetService;
|
50 |
47 |
import eu.etaxonomy.cdm.api.utility.UserHelper;
|
... | ... | |
61 |
58 |
import eu.etaxonomy.cdm.model.reference.Reference;
|
62 |
59 |
import eu.etaxonomy.cdm.model.reference.ReferenceType;
|
63 |
60 |
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
|
64 |
|
import eu.etaxonomy.cdm.persistence.hibernate.permission.Operation;
|
65 |
61 |
import eu.etaxonomy.cdm.ref.EntityReference;
|
66 |
62 |
import eu.etaxonomy.cdm.ref.TypedEntityReference;
|
67 |
63 |
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
|
... | ... | |
125 |
121 |
@Autowired
|
126 |
122 |
private IRegistrationWorkingSetService regWorkingSetService;
|
127 |
123 |
|
128 |
|
@Autowired
|
129 |
|
private RegistrationIdentifierMinter minter;
|
130 |
|
|
131 |
124 |
@Autowired
|
132 |
125 |
private IRegistrationMessageService messageService;
|
133 |
126 |
|
... | ... | |
142 |
135 |
|
143 |
136 |
private TaxonName newTaxonNameForRegistration = null;
|
144 |
137 |
|
145 |
|
private RegistrationDTO newRegistrationDTOWithExistingName;
|
|
138 |
// private RegistrationDTO newRegistrationDTOWithExistingName;
|
146 |
139 |
|
147 |
|
private RegistrationDTO newNameTypeDesignationTarget;
|
|
140 |
private RegistrationDTO typeDesignationTarget;
|
148 |
141 |
|
149 |
142 |
|
150 |
143 |
/**
|
... | ... | |
180 |
173 |
* If both checks are successful the method returns <code>true</code>.
|
181 |
174 |
*/
|
182 |
175 |
public boolean canCreateNameRegistrationFor(TaxonName name) {
|
183 |
|
return !checkRegistrationExistsFor(name) && checkWokingsetContainsProtologe(name);
|
|
176 |
return !getRepo().getRegistrationService().checkRegistrationExistsFor(name) && checkWokingsetContainsProtologe(name);
|
184 |
177 |
}
|
185 |
178 |
|
186 |
179 |
/**
|
... | ... | |
200 |
193 |
// @formatter:on
|
201 |
194 |
}
|
202 |
195 |
|
203 |
|
/**
|
204 |
|
* @param name
|
205 |
|
*/
|
206 |
|
public boolean checkRegistrationExistsFor(TaxonName name) {
|
207 |
|
|
208 |
|
for(Registration reg : name.getRegistrations()){
|
209 |
|
if(minter.isFromOwnRegistration(reg.getIdentifier())){
|
210 |
|
return true;
|
211 |
|
}
|
212 |
|
}
|
213 |
|
return false;
|
214 |
|
}
|
215 |
|
|
216 |
|
|
217 |
|
|
218 |
|
/**
|
219 |
|
* @param taxonNameId
|
220 |
|
* @return
|
221 |
|
*/
|
222 |
|
protected Registration createNewRegistrationForName(UUID taxonNameUuid) {
|
223 |
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
224 |
|
// move into RegistrationWorkflowStateMachine
|
225 |
|
TransactionStatus txStatus = getRepo().startTransaction();
|
226 |
|
|
227 |
|
Identifier<String> identifiers = minter.mint();
|
228 |
|
if(identifiers.getIdentifier() == null){
|
229 |
|
throw new RuntimeException("RegistrationIdentifierMinter configuration incomplete.");
|
230 |
|
}
|
231 |
|
Registration reg = Registration.NewInstance(
|
232 |
|
identifiers.getIdentifier(),
|
233 |
|
identifiers.getLocalId(),
|
234 |
|
taxonNameUuid != null ? getRepo().getNameService().load(taxonNameUuid, Arrays.asList("nomenclaturalReference.inReference")) : null,
|
235 |
|
null);
|
236 |
|
Authentication authentication = currentSecurityContext().getAuthentication();
|
237 |
|
reg.setSubmitter((User)authentication.getPrincipal());
|
238 |
|
EntityChangeEvent event = getRegistrationStore().saveBean(reg, (AbstractView) getView());
|
239 |
|
UserHelperAccess.userHelper().createAuthorityForCurrentUser(Registration.class, event.getEntityUuid(), Operation.UPDATE, RegistrationStatus.PREPARATION.name());
|
240 |
|
getRepo().commitTransaction(txStatus);
|
241 |
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
242 |
|
return getRepo().getRegistrationService().load(event.getEntityUuid(), Arrays.asList(new String []{"blockedBy"}));
|
243 |
|
}
|
244 |
|
|
245 |
196 |
/**
|
246 |
197 |
* @param doReload TODO
|
247 |
198 |
*
|
... | ... | |
387 |
338 |
|
388 |
339 |
private void saveRegistrationStatusChange(UUID uuid, Object value) {
|
389 |
340 |
Registration reg = getRepo().getRegistrationService().load(uuid);
|
|
341 |
if(reg == null){
|
|
342 |
// registration was not yet persisted, ignore
|
|
343 |
return;
|
|
344 |
}
|
390 |
345 |
if(value != null && value instanceof RegistrationStatus){
|
391 |
346 |
if(!Objects.equals(value, reg.getStatus())){
|
392 |
347 |
reg.setStatus((RegistrationStatus)value);
|
... | ... | |
525 |
480 |
if(newTaxonNameForRegistration != null){
|
526 |
481 |
UUID taxonNameUuid = newTaxonNameForRegistration.getUuid();
|
527 |
482 |
getRepo().getSession().refresh(newTaxonNameForRegistration);
|
528 |
|
Registration reg = createNewRegistrationForName(taxonNameUuid);
|
|
483 |
Registration reg = getRepo().getRegistrationService().createRegistrationForName(taxonNameUuid);
|
529 |
484 |
// reload workingset into current session
|
530 |
485 |
loadWorkingSet(workingset.getCitationUuid());
|
531 |
486 |
workingset.add(reg);
|
... | ... | |
544 |
499 |
|
545 |
500 |
|
546 |
501 |
/**
|
547 |
|
* Creates a new Registration for an exiting (previously published name).
|
|
502 |
* Creates a new Registration for an exiting (previously published) name.
|
548 |
503 |
*
|
549 |
504 |
* @param event
|
550 |
505 |
* @throws RegistrationValidationException
|
... | ... | |
559 |
514 |
getView().getAddExistingNameCombobox().commit(); // update the chosen value in the datasource
|
560 |
515 |
TaxonName typifiedName = getView().getAddExistingNameCombobox().getValue();
|
561 |
516 |
if(typifiedName != null){
|
562 |
|
boolean reloadWorkingSet = false;
|
|
517 |
boolean doReloadWorkingSet = false;
|
563 |
518 |
Reference citation = getRepo().getReferenceService().find(workingset.getCitationUuid());
|
564 |
519 |
// here we completely ignore the ExistingNameRegistrationType since the user should not have the choice
|
565 |
520 |
// to create a typification only registration in the working (publication) set which contains
|
... | ... | |
568 |
523 |
// the citation which is the base for workingset contains the protologe of the name and the name has not
|
569 |
524 |
// been registered before:
|
570 |
525 |
// create a registration for the name and the first typifications
|
571 |
|
Registration newRegistrationWithExistingName = createNewRegistrationForName(typifiedName.getUuid());
|
572 |
|
newRegistrationDTOWithExistingName = new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation);
|
573 |
|
reloadWorkingSet = true;
|
|
526 |
Registration newRegistrationWithExistingName = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
|
|
527 |
workingset.add(new RegistrationDTO(newRegistrationWithExistingName, typifiedName, citation));
|
|
528 |
doReloadWorkingSet = true;
|
574 |
529 |
} else {
|
575 |
530 |
if(!checkWokingsetContainsProtologe(typifiedName)){
|
576 |
|
// create a typification only registration
|
577 |
|
Registration typificationOnlyRegistration = createNewRegistrationForName(null);
|
578 |
|
if(!checkRegistrationExistsFor(typifiedName)){
|
579 |
|
// oops, yet no registration for this name, so we create it as blocking registration:
|
580 |
|
Registration blockingNameRegistration = createNewRegistrationForName(typifiedName.getUuid());
|
581 |
|
typificationOnlyRegistration.getBlockedBy().add(blockingNameRegistration);
|
|
531 |
if(typeDesignationTarget != null){
|
|
532 |
Notification.show("Can't create a new \"typification only\" registration as long as another new one exists.", Type.WARNING_MESSAGE);
|
|
533 |
} else {
|
|
534 |
// create a typification only registration
|
|
535 |
Registration typificationOnlyRegistration = getRepo().getRegistrationService().newRegistration();
|
|
536 |
// FIXME must only be done on save ----------------
|
|
537 |
if(!getRepo().getRegistrationService().checkRegistrationExistsFor(typifiedName)){
|
|
538 |
// oops, yet no registration for this name, so we create it as blocking registration:
|
|
539 |
Registration blockingNameRegistration = getRepo().getRegistrationService().createRegistrationForName(typifiedName.getUuid());
|
|
540 |
typificationOnlyRegistration.getBlockedBy().add(blockingNameRegistration);
|
|
541 |
}
|
|
542 |
// ----------------------------------------------------
|
|
543 |
typeDesignationTarget = new RegistrationDTO(typificationOnlyRegistration, typifiedName, citation);
|
|
544 |
workingset.add(typeDesignationTarget);
|
582 |
545 |
}
|
583 |
|
newRegistrationDTOWithExistingName = new RegistrationDTO(typificationOnlyRegistration, typifiedName, citation);
|
584 |
546 |
}
|
585 |
547 |
}
|
586 |
|
workingset.add(newRegistrationDTOWithExistingName);
|
587 |
548 |
// tell the view to update the workingset
|
588 |
|
refreshView(reloadWorkingSet);
|
|
549 |
refreshView(doReloadWorkingSet);
|
589 |
550 |
getView().getAddExistingNameRegistrationButton().setEnabled(false);
|
590 |
|
if(newRegistrationDTOWithExistingName.registration().getName() == null){
|
|
551 |
if(typeDesignationTarget.registration().getName() == null){
|
591 |
552 |
getView().getAddExistingNameCombobox().setEnabled(false);
|
592 |
553 |
getView().getAddNewNameRegistrationButton().setEnabled(false);
|
593 |
554 |
getView().getAddNewNameRegistrationButton().setDescription("You first need to add a type designation to the previously created registration.");
|
... | ... | |
630 |
591 |
// propagate readonly state from source button to popup
|
631 |
592 |
popup.setReadOnly(event.getSource().isReadOnly());
|
632 |
593 |
}
|
633 |
|
newNameTypeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
|
|
594 |
typeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
|
634 |
595 |
}
|
635 |
596 |
}
|
636 |
597 |
|
... | ... | |
646 |
607 |
popup.setParentEditorActionContext(event.getContext());
|
647 |
608 |
TypeDesignationWorkingsetEditorIdSet identifierSet;
|
648 |
609 |
UUID typifiedNameUuid;
|
649 |
|
if(newRegistrationDTOWithExistingName != null){
|
650 |
|
typifiedNameUuid = newRegistrationDTOWithExistingName.getTypifiedNameRef().getUuid();
|
|
610 |
if(typeDesignationTarget != null){
|
|
611 |
typifiedNameUuid = typeDesignationTarget.getTypifiedNameRef().getUuid();
|
651 |
612 |
} else {
|
652 |
613 |
RegistrationDTO registrationDTO = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
|
653 |
614 |
EntityReference typifiedNameRef = registrationDTO.getTypifiedNameRef();
|
... | ... | |
676 |
637 |
popup.setParentEditorActionContext(event.getContext());
|
677 |
638 |
popup.withDeleteButton(true);
|
678 |
639 |
popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
|
679 |
|
newNameTypeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
|
|
640 |
typeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationUuid()).get();
|
680 |
641 |
popup.setBeanInstantiator(new BeanInstantiator<NameTypeDesignation>() {
|
681 |
642 |
|
682 |
643 |
@Override
|
... | ... | |
684 |
645 |
|
685 |
646 |
TaxonName typifiedName = getRepo().getNameService().load(event.getTypifiedNameUuid(), Arrays.asList(new String[]{"typeDesignations", "homotypicalGroup"}));
|
686 |
647 |
NameTypeDesignation nameTypeDesignation = NameTypeDesignation.NewInstance();
|
687 |
|
nameTypeDesignation.setCitation(newNameTypeDesignationTarget.getCitation());
|
|
648 |
nameTypeDesignation.setCitation(typeDesignationTarget.getCitation());
|
688 |
649 |
nameTypeDesignation.getTypifiedNames().add(typifiedName);
|
689 |
650 |
return nameTypeDesignation;
|
690 |
651 |
}
|
... | ... | |
716 |
677 |
public void onDoneWithTypeDesignationEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
|
717 |
678 |
if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
|
718 |
679 |
if(event.getReason().equals(Reason.SAVE)){
|
|
680 |
// NOTE: adding the SpecimenTypeDesignations to the registration is done in the
|
|
681 |
// SpecimenTypeDesignationWorkingSetServiceImpl.save(SpecimenTypeDesignationWorkingSetDTO dto) method
|
719 |
682 |
refreshView(true);
|
720 |
683 |
} else if(event.getReason().equals(Reason.CANCEL)){
|
721 |
684 |
// noting to do
|
722 |
685 |
}
|
723 |
|
newRegistrationDTOWithExistingName = null;
|
724 |
686 |
} else if(event.getPopup() instanceof NameTypeDesignationPopupEditor){
|
725 |
687 |
if(event.getReason().equals(Reason.SAVE)){
|
726 |
|
UUID uuid = ((NameTypeDesignationPopupEditor)event.getPopup()).getBean().getUuid();
|
727 |
|
|
728 |
|
Session session = getRepo().getSessionFactory().openSession();
|
729 |
|
Transaction txstate = session.beginTransaction();
|
730 |
|
TypeDesignationBase<?> nameTypeDesignation = getRepo().getNameService().loadTypeDesignation(uuid, Arrays.asList(""));
|
731 |
|
// only load the typeDesignations with the registration so that the typified name can not be twice in the session
|
732 |
|
// otherwise multiple representation problems might occur
|
733 |
|
Registration registration = getRepo().getRegistrationService().load(newNameTypeDesignationTarget.getUuid(), Arrays.asList("typeDesignations"));
|
734 |
|
registration.getTypeDesignations().add(nameTypeDesignation);
|
735 |
|
session.merge(registration);
|
736 |
|
txstate.commit();
|
737 |
|
session.close();
|
738 |
|
|
|
688 |
UUID typeDesignationUuid = ((NameTypeDesignationPopupEditor)event.getPopup()).getBean().getUuid();
|
|
689 |
getRepo().getSession().clear();
|
|
690 |
getRepo().getRegistrationService().addTypeDesignation(typeDesignationTarget.registration(), typeDesignationUuid);
|
|
691 |
getRepo().getSession().clear();
|
|
692 |
typeDesignationTarget = null;
|
739 |
693 |
refreshView(true);
|
740 |
694 |
} else if(event.getReason().equals(Reason.CANCEL)){
|
741 |
695 |
// noting to do
|
742 |
696 |
}
|
743 |
|
newNameTypeDesignationTarget = null;
|
|
697 |
typeDesignationTarget = null;
|
744 |
698 |
}
|
745 |
699 |
// ignore other editors
|
746 |
700 |
}
|
... | ... | |
786 |
740 |
Stack<EditorActionContext>context = ((AbstractPopupEditor)event.getSourceView()).getEditorActionContext();
|
787 |
741 |
EditorActionContext rootContext = context.get(0);
|
788 |
742 |
if(rootContext.getParentView().equals(getView())){
|
789 |
|
Registration blockingRegistration = createNewRegistrationForName(event.getEntityUuid());
|
|
743 |
Registration blockingRegistration = getRepo().getRegistrationService().createRegistrationForName(event.getEntityUuid());
|
790 |
744 |
TypedEntityReference<Registration> regReference = (TypedEntityReference<Registration>)rootContext.getParentEntity();
|
791 |
745 |
Registration registration = getRepo().getRegistrationService().load(regReference.getUuid(), REGISTRATION_INIT_STRATEGY);
|
792 |
746 |
registration.getBlockedBy().add(blockingRegistration);
|
ref #7622 persisting new registrations only when typeDesignations have been added