import java.util.HashSet;
import java.util.List;
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;
import org.springframework.transaction.annotation.Transactional;
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
+import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
+import eu.etaxonomy.cdm.api.service.dto.TaxonRowWrapperDTO;
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
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;
import eu.etaxonomy.cdm.model.description.QuantitativeData;
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
import eu.etaxonomy.cdm.model.description.TextData;
import eu.etaxonomy.cdm.model.location.NamedArea;
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.taxon.Classification;
import eu.etaxonomy.cdm.model.taxon.Taxon;
-import eu.etaxonomy.cdm.model.taxon.TaxonBase;
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptiveDataSetDao;
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
@Autowired
private IOccurrenceService occurrenceService;
+ @Autowired
+ private ITaxonService taxonService;
+
@Autowired
private IDescriptionService descriptionService;
if(monitor.isCanceled()){
return new ArrayList<>();
}
- wrappers.add(createRowWrapper(null, description, null, descriptiveDataSet));
+ RowWrapperDTO rowWrapper = null;
+ if(HibernateProxyHelper.isInstanceOf(description, TaxonDescription.class)){
+ rowWrapper = createTaxonRowWrapper(HibernateProxyHelper.deproxy(description, TaxonDescription.class), descriptiveDataSet);
+ }
+ else if (HibernateProxyHelper.isInstanceOf(description, SpecimenDescription.class)){
+ rowWrapper = createSpecimenRowWrapper(HibernateProxyHelper.deproxy(description, SpecimenDescription.class), descriptiveDataSet, false);
+ }
+ if(rowWrapper!=null){
+ wrappers.add(rowWrapper);
+ }
monitor.worked(1);
}
return wrappers;
@Override
public Collection<SpecimenNodeWrapper> loadSpecimens(DescriptiveDataSet descriptiveDataSet){
- //set filter parameters
+ List<UUID> filteredNodes = findFilteredTaxonNodes(descriptiveDataSet);
+ return occurrenceService.listUuidAndTitleCacheByAssociatedTaxon(filteredNodes, null, null);
+ }
+
+ @Override
+ public List<UUID> findFilteredTaxonNodes(DescriptiveDataSet descriptiveDataSet){
TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(descriptiveDataSet.getMinRank(), descriptiveDataSet.getMaxRank());
descriptiveDataSet.getGeoFilter().forEach(area -> filter.orArea(area.getUuid()));
descriptiveDataSet.getTaxonSubtreeFilter().forEach(node -> filter.orSubtree(node));
filter.setIncludeUnpublished(true);
- List<UUID> filteredNodes = taxonNodeService.uuidList(filter);
- return occurrenceService.listUuidAndTitleCacheByAssociatedTaxon(filteredNodes, null, null);
+ return taxonNodeService.uuidList(filter);
}
@Override
- public RowWrapperDTO createRowWrapper(DescriptionBase description, DescriptiveDataSet descriptiveDataSet){
- return createRowWrapper(null, description, null, descriptiveDataSet);
+ public List<TaxonNode> loadFilteredTaxonNodes(DescriptiveDataSet descriptiveDataSet, List<String> propertyPaths){
+ return taxonNodeService.load(findFilteredTaxonNodes(descriptiveDataSet), propertyPaths);
+ }
+
+ private TaxonNode findTaxonNodeForDescription(TaxonNode taxonNode, SpecimenOrObservationBase specimen){
+ Collection<SpecimenNodeWrapper> nodeWrapper = occurrenceService.listUuidAndTitleCacheByAssociatedTaxon(Arrays.asList(taxonNode.getUuid()), null, null);
+ for (SpecimenNodeWrapper specimenNodeWrapper : nodeWrapper) {
+ if(specimenNodeWrapper.getUuidAndTitleCache().getId().equals(specimen.getId())){
+ return taxonNode;
+ }
+ }
+ return null;
}
@Override
- public RowWrapperDTO createRowWrapper(SpecimenOrObservationBase specimen, DescriptiveDataSet descriptiveDataSet){
- return createRowWrapper(specimen, null, null, descriptiveDataSet);
+ public TaxonRowWrapperDTO createTaxonRowWrapper(TaxonDescription description,
+ DescriptiveDataSet descriptiveDataSet) {
+ TaxonNode taxonNode = null;
+ Classification classification = null;
+ Optional<TaxonNode> first = descriptiveDataSet.getTaxonSubtreeFilter().stream()
+ .filter(node->node.getClassification()!=null).findFirst();
+ Optional<Classification> classificationOptional = first.map(node->node.getClassification());
+ if(classificationOptional.isPresent()){
+ classification = classificationOptional.get();
+ Taxon taxon = (Taxon) taxonService.load(description.getTaxon().getId(), Arrays.asList("taxonNodes", "taxonNodes.classification"));
+ taxonNode = taxon.getTaxonNode(classification);
+ }
+ return new TaxonRowWrapperDTO(description, taxonNode);
}
- private RowWrapperDTO createRowWrapper(SpecimenOrObservationBase specimen, DescriptionBase description, TaxonNode taxonNode, DescriptiveDataSet descriptiveDataSet){
- if(description!=null){
- specimen = description.getDescribedSpecimenOrObservation();
- }
+ @Override
+ 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){
- if(taxonNode==null){
- Collection<TaxonBase<?>> associatedTaxa = occurrenceService.listAssociatedTaxa(specimen, null, null, null,
- Arrays.asList(new String[]{
- "taxonNodes",
- "taxonNodes.classification",
- }));
- if(associatedTaxa!=null && !associatedTaxa.isEmpty()){
- //FIXME: what about multiple associated taxa
- Set<TaxonNode> taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter();
- if(taxonSubtreeFilter!=null && !taxonSubtreeFilter.isEmpty()){
- Taxon taxon = HibernateProxyHelper.deproxy(associatedTaxa.iterator().next(), Taxon.class);
- taxonNode = taxon.getTaxonNode(taxonSubtreeFilter.iterator().next().getClassification());
- }
- }
- }
- Collection<FieldUnit> 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$
+ //get taxon node
+ Set<TaxonNode> 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<TaxonNode> allChildren = taxonNodeService.loadChildNodesOfTaxonNode(node, Arrays.asList("taxon"), true, true, null);
+ for (TaxonNode child : allChildren) {
+ taxonNode = findTaxonNodeForDescription(child, specimen);
+ if(taxonNode!=null){
+ break;
+ }
+ }
}
}
- return new RowWrapperDTO(description, specimen, taxonNode, fieldUnit, identifier, country);
+ if(taxonNode==null){
+ return null;
+ }
+ //taxon node was found
+
+ //get field unit
+ Collection<FieldUnit> 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
}
@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<DescriptionBase> dataSetDescriptions = dataSet.getDescriptions();
+ //filter out COMPUTED descriptions
+ List<TaxonDescription> 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);