package eu.etaxonomy.cdm.service;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
import org.apache.log4j.Logger;
+import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import eu.etaxonomy.cdm.api.application.CdmRepository;
+import eu.etaxonomy.cdm.api.service.dto.RegistrationDTO;
+import eu.etaxonomy.cdm.api.service.exception.RegistrationValidationException;
import eu.etaxonomy.cdm.api.service.pager.Pager;
+import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
import eu.etaxonomy.cdm.model.common.User;
import eu.etaxonomy.cdm.model.name.Registration;
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
+import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.model.reference.ReferenceType;
+import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
-import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
-import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
/**
* Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
- * <p>
- * Can create missing registrations for names which have Extensions of the Type <code>IAPTRegdata.json</code>.
- * See https://dev.e-taxonomy.eu/redmine/issues/6621 for further details.
- * This feature can be activated by by supplying one of the following jvm command line arguments:
- * <ul>
- * <li><code>-DregistrationCreate=iapt</code>: create all iapt Registrations if missing</li>
- * <li><code>-DregistrationWipeout=iapt</code>: remove all iapt Registrations</li>
- * <li><code>-DregistrationWipeout=all</code>: remove all Registrations</li>
- * </ul>
- * The <code>-DregistrationWipeout</code> commands are executed before the <code>-DregistrationCreate</code> and will not change the name and type designations.
*
*
* @author a.kohlbecker
@Transactional(readOnly=true)
public class RegistrationWorkingSetService implements IRegistrationWorkingSetService {
+ public static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
+ "blockedBy",
+ // typeDesignation
+ "typeDesignations.typeStatus",
+ "typeDesignations.typifiedNames.typeDesignations", // important !!
+ "typeDesignations.typeSpecimen",
+ "typeDesignations.typeName.$",
+ "typeDesignations.citation",
+ "typeDesignations.citation.authorship.$",
+ "typeDesignations.annotations", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
+ "typeDesignations.markers", // needed for AnnotatableEntity.clone() in DerivedUnitConverter.copyPropertiesTo
+ "typeDesignations.registrations", // DerivedUnitConverter.copyPropertiesTo(TARGET n)
+
+ // name
+ "name.$",
+ "name.nomenclaturalReference.authorship.$",
+ "name.nomenclaturalReference.inReference",
+ "name.rank",
+ "name.homotypicalGroup.typifiedNames",
+ "name.status.type",
+ "name.typeDesignations", // important !!"
+ // institution
+ "institution",
+ }
+ );
+
+ /**
+ *
+ */
+ private List<String> DERIVEDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
+ "*", // initialize all related entities to allow DerivedUnit conversion, see DerivedUnitConverter.copyPropertiesTo()
+ "derivedFrom.$",
+ "derivedFrom.type", // TODO remove?
+ "derivedFrom.originals.derivationEvents", // important!!
+ "specimenTypeDesignations.typifiedNames.typeDesignations", // important!!
+ "mediaSpecimen.sources"
+ });
+
+ /**
+ *
+ */
+ private List<String> FIELDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
+ "$",
+ "annotations.*", // * is needed as log as we are using a table in FilterableAnnotationsField
+ "gatheringEvent.$",
+ "gatheringEvent.country",
+ "gatheringEvent.collectingAreas",
+ "gatheringEvent.actor",
+ "derivationEvents.derivatives" // important, otherwise the DerivedUnits are not included into the graph of initialized entities!!!
+ });
+
+ public static final List<String> BLOCKING_REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
+
+ "blockedBy.blockedBy",
+ // typeDesignation
+ "blockedBy.typeDesignations.typeStatus",
+// "typeDesignations.typifiedNames.typeDesignations", // important !!
+// "typeDesignations.typeSpecimen",
+// "typeDesignations.typeName.$",
+// "typeDesignations.citation",
+// "typeDesignations.citation.authorship.$",
+ // name
+// "blockedBy.name.$",
+ "blockedBy.name.nomenclaturalReference.authorship",
+ "blockedBy.name.nomenclaturalReference.inReference",
+ "blockedBy.name.rank",
+// "name.homotypicalGroup.typifiedNames",
+// "name.status.type",
+// "name.typeDesignations",
+ // institution
+ "blockedBy.institution",
+ }
+ );
+
/**
*
*/
@Qualifier("cdmRepository")
private CdmRepository repo;
+ @Autowired
+ protected IBeanInitializer defaultBeanInitializer;
+
public RegistrationWorkingSetService() {
}
/**
- * @param id the CDM Entity id
+ * @param id the Registration entity id
* @return
*/
@Override
public RegistrationDTO loadDtoById(Integer id) {
- Registration reg = repo.getRegistrationService().find(id);
+ Registration reg = repo.getRegistrationService().load(id, REGISTRATION_INIT_STRATEGY);
+ inititializeSpecimen(reg);
return new RegistrationDTO(reg);
}
+ /**
+ * @param id the Registration entity id
+ * @return
+ */
@Override
- public Collection<RegistrationDTO> listDTOs() {
+ public RegistrationDTO loadDtoByUuid(UUID uuid) {
+ Registration reg = repo.getRegistrationService().load(uuid, REGISTRATION_INIT_STRATEGY);
+ inititializeSpecimen(reg);
+ return new RegistrationDTO(reg);
+ }
- List<Registration> regs = repo.getRegistrationService().list(null, PAGE_SIZE, 0, null, null);
- List<RegistrationDTO> dtos = makeDTOs(regs);
- return dtos;
+ @Override
+ public Pager<RegistrationDTO> pageDTOs(Integer pageSize, Integer pageIndex) {
+
+ return pageDTOs(null, null, null, null, pageSize, pageIndex);
}
/**
* {@inheritDoc}
*/
@Override
- public Collection<RegistrationDTO> listDTOs(User submitter, Collection<RegistrationStatus> includedStatus) {
+ public Pager<RegistrationDTO> pageDTOs(User submitter, Collection<RegistrationStatus> includedStatus,
+ String identifierFilterPattern, String taxonNameFilterPattern,
+ Integer pageSize, Integer pageIndex) {
- Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus, PAGE_SIZE, 0, null, null);
- return makeDTOs(pager.getRecords());
+ if(pageSize == null){
+ pageSize = PAGE_SIZE;
+ }
+
+ Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus,
+ identifierFilterPattern, taxonNameFilterPattern,
+ PAGE_SIZE, 0, null, REGISTRATION_INIT_STRATEGY);
+ List<Registration> registrations = pager.getRecords();
+ Pager<RegistrationDTO> dtoPager = new DefaultPagerImpl(pager.getCurrentIndex(), pager.getCount(), pager.getPageSize(), makeDTOs(registrations));
+ return dtoPager;
}
+
/**
* {@inheritDoc}
* @throws RegistrationValidationException
*/
@Override
- public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID) throws RegistrationValidationException {
- Reference reference = repo.getReferenceService().find(referenceID);
- Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, null);
+ public RegistrationWorkingSet loadWorkingSetByReferenceUuid(UUID referenceUuid, boolean resolveSections) throws RegistrationValidationException {
+
+ Reference reference = repo.getReferenceService().find(referenceUuid); // needed to use load to avoid the problem described in #7331
+ if(resolveSections){
+ reference = resolveSection(reference);
+ }
+
+ Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
+
+ /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
+ // debugIssue7331(pager);
return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
}
+
+ /**
+ * @param reference
+ * @return
+ */
+ protected Reference resolveSection(Reference reference) {
+ repo.getReferenceService().load(reference.getUuid(), Arrays.asList(new String[]{"inReference"})); // needed to avoid the problem described in #7331
+ if(reference.isOfType(ReferenceType.Section) && reference.getInReference() != null) {
+ reference = reference.getInReference();
+ }
+ return reference;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws RegistrationValidationException
+ */
@Override
- public RegistrationWorkingSet loadWorkingSetByCitationID(Integer id) throws RegistrationValidationException {
+ public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID, boolean resolveSections) throws RegistrationValidationException {
+
+ Reference reference = repo.getReferenceService().find(referenceID);
+ if(resolveSections){
+ reference = resolveSection(reference);
+ }
+ repo.getReferenceService().load(reference.getUuid()); // needed to avoid the problem described in #7331
+
+ Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
+
+ /* for debugging https://dev.e-taxonomy.eu/redmine/issues/7331 */
+ // debugIssue7331(pager);
- Reference ref = repo.getReferenceService().find(id);
- Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(ref), null, null, null, null);
return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
}
+ /**
+ * @param pager
+ */
+ @SuppressWarnings("unused")
+ private void debugIssue7331(Pager<Registration> pager) {
+ for(Registration reg : pager.getRecords()){
+ if(reg.getName() != null && reg.getName().getNomenclaturalReference().getAuthorship() != null){
+ Reference ref = reg.getName().getNomenclaturalReference();
+ if(!Hibernate.isInitialized(ref.getAuthorship())){
+ logger.error("UNINITIALIZED");
+ }
+ } else {
+ logger.debug("NO AUTHORS");
+ }
+ }
+ }
+
+ @Override
+ public Set<RegistrationDTO> loadBlockingRegistrations(UUID blockedRegistrationUuid){
+
+ Registration registration = repo.getRegistrationService().load(blockedRegistrationUuid, BLOCKING_REGISTRATION_INIT_STRATEGY);
+ Set<Registration> registrations = registration.getBlockedBy();
+
+ Set<RegistrationDTO> blockingSet = new HashSet<>();
+ for(Registration reg : registrations){
+ blockingSet.add(new RegistrationDTO(reg));
+ }
+ return blockingSet;
+ }
+
/**
* @param regs
* @return
*/
private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
+ initializeSpecimens(regs);
List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
return dtos;
+ /**
+ * @param regs
+ */
+ private void initializeSpecimens(List<Registration> regs) {
+ for(Registration reg : regs){
+ inititializeSpecimen(reg);
+ }
+
+ }
+
+
+ /**
+ * @param reg
+ */
+ protected void inititializeSpecimen(Registration reg) {
+
+ for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
+ if(td instanceof SpecimenTypeDesignation){
+
+ DerivedUnit derivedUnit = ((SpecimenTypeDesignation) td).getTypeSpecimen();
+ @SuppressWarnings("rawtypes")
+ Set<SpecimenOrObservationBase> sobs = new HashSet<>();
+ sobs.add(HibernateProxyHelper.deproxy(derivedUnit));
+
+ while(sobs != null && !sobs.isEmpty()){
+ @SuppressWarnings("rawtypes")
+ Set<SpecimenOrObservationBase> nextSobs = null;
+ for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob : sobs){
+ sob = HibernateProxyHelper.deproxy(sob);
+ if(sob == null){
+ continue;
+ }
+ if(DerivedUnit.class.isAssignableFrom(sob.getClass())) {
+ defaultBeanInitializer.initialize(sob, DERIVEDUNIT_INIT_STRATEGY);
+ nextSobs = ((DerivedUnit)sob).getOriginals();
+ }
+ if(sob instanceof FieldUnit){
+ defaultBeanInitializer.initialize(sob, FIELDUNIT_INIT_STRATEGY);
+ }
+ }
+ sobs = nextSobs;
+ }
+ }
+ }
+ }
+
+
+