From 041e26e260df6566ae0737678e20ef06c5caa276 Mon Sep 17 00:00:00 2001 From: Patrick Plitzner Date: Fri, 31 Aug 2018 12:02:37 +0200 Subject: [PATCH] ref #7674 Create default taxon description when adding specimens --- .../service/DescriptiveDataSetService.java | 131 ++++++++++++------ .../service/IDescriptiveDataSetService.java | 30 +++- .../service/dto/SpecimenRowWrapperDTO.java | 8 +- 3 files changed, 119 insertions(+), 50 deletions(-) diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptiveDataSetService.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptiveDataSetService.java index 9e2285755b..d5d97989b0 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptiveDataSetService.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptiveDataSetService.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,7 @@ import eu.etaxonomy.cdm.common.monitor.RemotingProgressMonitorThread; import eu.etaxonomy.cdm.filter.TaxonNodeFilter; import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; import eu.etaxonomy.cdm.model.common.Language; +import eu.etaxonomy.cdm.model.common.MarkerType; import eu.etaxonomy.cdm.model.description.CategoricalData; import eu.etaxonomy.cdm.model.description.DescriptionBase; import eu.etaxonomy.cdm.model.description.DescriptionElementBase; @@ -125,7 +127,7 @@ public class DescriptiveDataSetService rowWrapper = createTaxonRowWrapper(HibernateProxyHelper.deproxy(description, TaxonDescription.class), descriptiveDataSet); } else if (HibernateProxyHelper.isInstanceOf(description, SpecimenDescription.class)){ - rowWrapper = createSpecimenRowWrapper(HibernateProxyHelper.deproxy(description, SpecimenDescription.class), descriptiveDataSet); + rowWrapper = createSpecimenRowWrapper(HibernateProxyHelper.deproxy(description, SpecimenDescription.class), descriptiveDataSet, false); } if(rowWrapper!=null){ wrappers.add(rowWrapper); @@ -183,57 +185,66 @@ public class DescriptiveDataSetService } @Override - public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet){ + public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet, + boolean createDefaultTaxonDescription){ SpecimenOrObservationBase specimen = description.getDescribedSpecimenOrObservation(); TaxonNode taxonNode = null; FieldUnit fieldUnit = null; String identifier = null; NamedArea country = null; //supplemental information - if(specimen!=null){ - //get taxon node - Set taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter(); - for (TaxonNode node : taxonSubtreeFilter) { - //check for node - node = taxonNodeService.load(node.getId(), Arrays.asList("taxon")); - taxonNode = findTaxonNodeForDescription(node, specimen); - if(taxonNode!=null){ - break; - } - else{ - //check for child nodes - List allChildren = taxonNodeService.loadChildNodesOfTaxonNode(node, Arrays.asList("taxon"), true, true, null); - for (TaxonNode child : allChildren) { - taxonNode = findTaxonNodeForDescription(child, specimen); - if(taxonNode!=null){ - break; - } - } - } - } - if(taxonNode==null){ - return null; - } - Collection fieldUnits = occurrenceService.findFieldUnits(specimen.getUuid(), - Arrays.asList(new String[]{ - "gatheringEvent", - "gatheringEvent.country" - })); - if(fieldUnits.size()!=1){ - logger.error("More than one or no field unit found for specimen"); //$NON-NLS-1$ - return null; + //get taxon node + Set taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter(); + for (TaxonNode node : taxonSubtreeFilter) { + //check for node + node = taxonNodeService.load(node.getId(), Arrays.asList("taxon")); + taxonNode = findTaxonNodeForDescription(node, specimen); + if(taxonNode!=null){ + break; } else{ - fieldUnit = fieldUnits.iterator().next(); - } - if(specimen instanceof DerivedUnit){ - identifier = occurrenceService.getMostSignificantIdentifier(HibernateProxyHelper.deproxy(specimen, DerivedUnit.class)); - } - if(fieldUnit!=null && fieldUnit.getGatheringEvent()!=null){ - country = fieldUnit.getGatheringEvent().getCountry(); + //check for child nodes + List allChildren = taxonNodeService.loadChildNodesOfTaxonNode(node, Arrays.asList("taxon"), true, true, null); + for (TaxonNode child : allChildren) { + taxonNode = findTaxonNodeForDescription(child, specimen); + if(taxonNode!=null){ + break; + } + } } } - return new SpecimenRowWrapperDTO(description, taxonNode, fieldUnit, identifier, country); + if(taxonNode==null){ + return null; + } + //taxon node was found + + //get field unit + Collection fieldUnits = occurrenceService.findFieldUnits(specimen.getUuid(), + Arrays.asList(new String[]{ + "gatheringEvent", + "gatheringEvent.country" + })); + if(fieldUnits.size()!=1){ + logger.error("More than one or no field unit found for specimen"); //$NON-NLS-1$ + return null; + } + else{ + fieldUnit = fieldUnits.iterator().next(); + } + //get identifier + if(specimen instanceof DerivedUnit){ + identifier = occurrenceService.getMostSignificantIdentifier(HibernateProxyHelper.deproxy(specimen, DerivedUnit.class)); + } + //get country + if(fieldUnit!=null && fieldUnit.getGatheringEvent()!=null){ + country = fieldUnit.getGatheringEvent().getCountry(); + } + //get default taxon description + TaxonDescription defaultTaxonDescription = findDefaultTaxonDescription(descriptiveDataSet.getUuid(), + taxonNode.getUuid(), createDefaultTaxonDescription); + TaxonRowWrapperDTO taxonRowWrapper = defaultTaxonDescription != null + ? createTaxonRowWrapper(defaultTaxonDescription, descriptiveDataSet) : null; + return new SpecimenRowWrapperDTO(description, taxonNode, fieldUnit, identifier, country, taxonRowWrapper); } @Override @@ -247,7 +258,41 @@ public class DescriptiveDataSetService } @Override - public SpecimenDescription findDescriptionForDescriptiveDataSet(UUID descriptiveDataSetUuid, UUID specimenUuid){ + public TaxonDescription findDefaultTaxonDescription(UUID descriptiveDataSetUuid, UUID taxonNodeUuid, boolean create){ + DescriptiveDataSet dataSet = load(descriptiveDataSetUuid); + TaxonNode taxonNode = taxonNodeService.load(taxonNodeUuid, Arrays.asList("taxon", "taxon.descriptions", "taxon.descriptions.markers")); + Set dataSetDescriptions = dataSet.getDescriptions(); + //filter out COMPUTED descriptions + List nonComputedDescriptions = taxonNode.getTaxon().getDescriptions().stream() + .filter(desc -> desc.getMarkers().stream() + .anyMatch(marker -> marker.getMarkerType().equals(MarkerType.COMPUTED()))) + .collect(Collectors.toList()); + for (TaxonDescription taxonDescription : nonComputedDescriptions) { + for (DescriptionBase description : dataSetDescriptions) { + if(description.getUuid().equals(taxonDescription.getUuid())){ + return taxonDescription; + } + } + } + if(!create){ + return null; + } + //description not yet added to dataset -> create a new one + TaxonDescription newTaxonDescription = TaxonDescription.NewInstance(taxonNode.getTaxon()); + newTaxonDescription.setTitleCache("Dataset "+dataSet.getLabel()+": "+newTaxonDescription.generateTitle(), true); //$NON-NLS-2$ + dataSet.getDescriptiveSystem().getDistinctFeatures().forEach(wsFeature->{ + if(wsFeature.isSupportsCategoricalData()){ + newTaxonDescription.addElement(CategoricalData.NewInstance(wsFeature)); + } + else if(wsFeature.isSupportsQuantitativeData()){ + newTaxonDescription.addElement(QuantitativeData.NewInstance(wsFeature)); + } + }); + return newTaxonDescription; + } + + @Override + public SpecimenDescription findSpecimenDescription(UUID descriptiveDataSetUuid, UUID specimenUuid){ DescriptiveDataSet dataSet = load(descriptiveDataSetUuid); SpecimenOrObservationBase specimen = occurrenceService.load(specimenUuid); diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IDescriptiveDataSetService.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IDescriptiveDataSetService.java index 39dcdd5245..d4da819912 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IDescriptiveDataSetService.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IDescriptiveDataSetService.java @@ -84,9 +84,12 @@ public interface IDescriptiveDataSetService extends IIdentifiableEntityServicetrue a default taxon description will be created for the taxon + * this wrapper belongs to * @return the created row wrapper */ - public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet); + public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet, + boolean createDefaultTaxonDescription); /** * Creates a taxon row wrapper object for the given description @@ -98,12 +101,27 @@ public interface IDescriptiveDataSetService extends IIdentifiableEntityService + * If a description is found that matches all features of the data set this description + * will be returned. A new one will be created otherwise. + * @param descriptiveDataSetUuid the uuid of the dataset defining the features + * @param specimenUuid the uuid of the specimen + * @return either the found specimen description or a newly created one */ - public SpecimenDescription findDescriptionForDescriptiveDataSet(UUID descriptiveDataSetUuid, UUID specimenUuid); + public SpecimenDescription findSpecimenDescription(UUID descriptiveDataSetUuid, UUID specimenUuid); + + /** + * Returns a {@link TaxonDescription} for a given taxon node with corresponding + * features according to the {@link DescriptiveDataSet}.
+ * If a description is found that matches all features of the data set this description + * will be returned. Otherwise a new one will be created if specified. + * @param descriptiveDataSetUuid the uuid of the dataset defining the features + * @param taxonNodeUuid the uuid of the taxon node that links to the taxon + * @param create if true a new description will be created + * if none could be found + * @return either the found taxon description or a newly created one + */ + public TaxonDescription findDefaultTaxonDescription(UUID descriptiveDataSetUuid, UUID taxonNodeUuid, boolean create); /** * Loads all taxon nodes that match the filter set defined in the diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/dto/SpecimenRowWrapperDTO.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/dto/SpecimenRowWrapperDTO.java index 08f3642d61..0622715af5 100644 --- a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/dto/SpecimenRowWrapperDTO.java +++ b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/dto/SpecimenRowWrapperDTO.java @@ -24,17 +24,19 @@ public class SpecimenRowWrapperDTO extends RowWrapperDTO { private static final long serialVersionUID = 5198447592554976471L; + private TaxonRowWrapperDTO defaultTaxonDescription; private SpecimenOrObservationBase specimen; private FieldUnit fieldUnit; private String identifier; private NamedArea country; public SpecimenRowWrapperDTO(SpecimenDescription description, TaxonNode taxonNode, FieldUnit fieldUnit, String identifier, - NamedArea country) { + NamedArea country, TaxonRowWrapperDTO defaultTaxonDescription) { super(description, taxonNode); this.fieldUnit = fieldUnit; this.identifier = identifier; this.country = country; + this.defaultTaxonDescription = defaultTaxonDescription; this.specimen = description.getDescribedSpecimenOrObservation(); } @@ -53,4 +55,8 @@ public class SpecimenRowWrapperDTO extends RowWrapperDTO { public NamedArea getCountry() { return country; } + + public TaxonRowWrapperDTO getDefaultTaxonDescription() { + return defaultTaxonDescription; + } } -- 2.34.1