package eu.etaxonomy.cdm.api.service;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
+import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
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.IdentifiableSource;
import eu.etaxonomy.cdm.model.common.Language;
-import eu.etaxonomy.cdm.model.common.Marker;
-import eu.etaxonomy.cdm.model.common.MarkerType;
-import eu.etaxonomy.cdm.model.common.OriginalSourceType;
import eu.etaxonomy.cdm.model.description.CategoricalData;
-import eu.etaxonomy.cdm.model.description.Character;
import eu.etaxonomy.cdm.model.description.DescriptionBase;
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
+import eu.etaxonomy.cdm.model.description.DescriptionType;
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
import eu.etaxonomy.cdm.model.description.DescriptiveSystemRole;
import eu.etaxonomy.cdm.model.description.Feature;
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
+import eu.etaxonomy.cdm.model.description.PolytomousKey;
import eu.etaxonomy.cdm.model.description.QuantitativeData;
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
-import eu.etaxonomy.cdm.model.description.StateData;
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
-import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
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.taxon.TaxonBase;
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptiveDataSetDao;
-import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
+import eu.etaxonomy.cdm.persistence.dao.term.IDefinedTermDao;
import eu.etaxonomy.cdm.persistence.dto.SpecimenNodeWrapper;
+import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
+import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGenerator;
+import eu.etaxonomy.cdm.strategy.generate.PolytomousKeyGeneratorConfigurator;
@Service
-@Transactional(readOnly = false)
+@Transactional(readOnly=true)
public class DescriptiveDataSetService
extends IdentifiableServiceBase<DescriptiveDataSet, IDescriptiveDataSetDao>
implements IDescriptiveDataSetService {
private ITaxonService taxonService;
@Autowired
- private IDescriptionService descriptionService;
+ private IPolytomousKeyService polytomousKeyService;
@Autowired
- private ITaxonNodeService taxonNodeService;
+ private IDefinedTermDao termDao;
@Autowired
- private ITaxonNodeDao taxonNodeDao;
+ private IDescriptionService descriptionService;
@Autowired
- private IProgressMonitorService progressMonitorService;
+ private ITaxonNodeService taxonNodeService;
@Override
@Autowired
return dao.getDescriptiveDataSetUuidAndTitleCache( limitOfInitialElements, pattern);
}
-
- @Override
- @Transactional
- public UUID monitGetRowWrapper(DescriptiveDataSet descriptiveDataSet) {
- RemotingProgressMonitorThread monitorThread = new RemotingProgressMonitorThread() {
- @Override
- public Serializable doRun(IRemotingProgressMonitor monitor) {
- return getRowWrapper(descriptiveDataSet, monitor);
- }
- };
- UUID uuid = progressMonitorService.registerNewRemotingMonitor(monitorThread);
- monitorThread.setPriority(3);
- monitorThread.start();
- return uuid;
- }
-
@Override
- public ArrayList<RowWrapperDTO> getRowWrapper(DescriptiveDataSet descriptiveDataSet, IProgressMonitor monitor) {
+ public ArrayList<RowWrapperDTO> getRowWrapper(UUID descriptiveDataSetUuid, IProgressMonitor monitor) {
+ DescriptiveDataSet descriptiveDataSet = load(descriptiveDataSetUuid);
monitor.beginTask("Load row wrapper", descriptiveDataSet.getDescriptions().size());
ArrayList<RowWrapperDTO> wrappers = new ArrayList<>();
Set<DescriptionBase> descriptions = descriptiveDataSet.getDescriptions();
return new ArrayList<>();
}
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);
+ // only viable descriptions are aggregated, literature or default descriptions
+ if(HibernateProxyHelper.isInstanceOf(description, TaxonDescription.class) &&
+ (description.isAggregatedStructuredDescription()
+ || description.getTypes().contains(DescriptionType.DEFAULT_VALUES_FOR_AGGREGATION)
+ || description.getTypes().contains(DescriptionType.SECONDARY_DATA)
+ )){
+ rowWrapper = createTaxonRowWrapper(description.getUuid(), descriptiveDataSet.getUuid());
+ }
+ else if (HibernateProxyHelper.isInstanceOf(description, SpecimenDescription.class)&&
+ !description.getTypes().contains(DescriptionType.CLONE_FOR_SOURCE)){
+ rowWrapper = createSpecimenRowWrapper(HibernateProxyHelper.deproxy(description, SpecimenDescription.class), descriptiveDataSetUuid);
}
if(rowWrapper!=null){
wrappers.add(rowWrapper);
@Override
public Collection<SpecimenNodeWrapper> loadSpecimens(DescriptiveDataSet descriptiveDataSet){
List<UUID> filteredNodes = findFilteredTaxonNodes(descriptiveDataSet);
+ if(filteredNodes.isEmpty()){
+ return Collections.EMPTY_SET;
+ }
return occurrenceService.listUuidAndTitleCacheByAssociatedTaxon(filteredNodes, null, null);
}
+ @Override
+ public Collection<SpecimenNodeWrapper> loadSpecimens(UUID descriptiveDataSetUuid){
+ DescriptiveDataSet dataSet = load(descriptiveDataSetUuid);
+ return loadSpecimens(dataSet);
+ }
+
+
@Override
public List<UUID> findFilteredTaxonNodes(DescriptiveDataSet descriptiveDataSet){
TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(descriptiveDataSet.getMinRank(), descriptiveDataSet.getMaxRank());
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;
+ @Override
+ public TaxonDescription findDefaultDescription(UUID specimenDescriptionUuid, UUID dataSetUuid){
+ SpecimenDescription specimenDescription = (SpecimenDescription) descriptionService.load(specimenDescriptionUuid);
+ DescriptiveDataSet dataSet = load(dataSetUuid);
+ TaxonNode node = findTaxonNodeForDescription(specimenDescription, dataSet);
+ return recurseDefaultDescription(node, dataSet);
+ }
+
+ private TaxonDescription recurseDefaultDescription(TaxonNode node, DescriptiveDataSet dataSet){
+ TaxonDescription defaultDescription = null;
+ if(node!=null && node.getTaxon()!=null){
+ defaultDescription = findTaxonDescriptionByDescriptionType(dataSet, node.getTaxon(), DescriptionType.DEFAULT_VALUES_FOR_AGGREGATION);
+ if(defaultDescription==null && node.getParent()!=null){
+ defaultDescription = recurseDefaultDescription(node.getParent(), dataSet);
+ }
+ }
+ return defaultDescription;
+ }
+
+ private TaxonNode findTaxonNodeForDescription(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet){
+ SpecimenOrObservationBase specimen = description.getDescribedSpecimenOrObservation();
+ //get taxon node
+
+ Set<IndividualsAssociation> associations = (Set<IndividualsAssociation>)descriptiveDataSet.getDescriptions()
+ .stream()
+ .flatMap(desc->desc.getElements().stream())// put all description element in one stream
+ .filter(element->element instanceof IndividualsAssociation)
+ .map(ia->(IndividualsAssociation)ia)
+ .collect(Collectors.toSet());
+ Classification classification = descriptiveDataSet.getTaxonSubtreeFilter().iterator().next().getClassification();
+ for (IndividualsAssociation individualsAssociation : associations) {
+ if(individualsAssociation.getAssociatedSpecimenOrObservation().equals(specimen)){
+ return ((TaxonDescription) individualsAssociation.getInDescription()).getTaxon().getTaxonNode(classification);
}
}
return null;
}
@Override
- public TaxonRowWrapperDTO createTaxonRowWrapper(TaxonDescription description,
- DescriptiveDataSet descriptiveDataSet) {
+ public TaxonRowWrapperDTO createTaxonRowWrapper(UUID taxonDescriptionUuid, UUID descriptiveDataSetUuid) {
TaxonNode taxonNode = null;
Classification classification = null;
+ TaxonDescription description = (TaxonDescription) descriptionService.load(taxonDescriptionUuid,
+ Arrays.asList("taxon", "descriptionElements", "descriptionElements.feature"));
+ DescriptiveDataSet descriptiveDataSet = dao.load(descriptiveDataSetUuid, null);
Optional<TaxonNode> first = descriptiveDataSet.getTaxonSubtreeFilter().stream()
.filter(node->node.getClassification()!=null).findFirst();
Optional<Classification> classificationOptional = first.map(node->node.getClassification());
Taxon taxon = (Taxon) taxonService.load(description.getTaxon().getId(), Arrays.asList("taxonNodes", "taxonNodes.classification"));
taxonNode = taxon.getTaxonNode(classification);
}
- return new TaxonRowWrapperDTO(description, taxonNode);
+ return new TaxonRowWrapperDTO(description, new TaxonNodeDto(taxonNode));
}
@Override
- public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, DescriptiveDataSet descriptiveDataSet,
- boolean createDefaultTaxonDescription){
- SpecimenOrObservationBase specimen = description.getDescribedSpecimenOrObservation();
- TaxonNode taxonNode = null;
+ @Transactional(readOnly=false)
+ public UpdateResult addRowWrapperToDataset(Collection<SpecimenNodeWrapper> wrappers, UUID datasetUuid){
+ UpdateResult result = new UpdateResult();
+ DescriptiveDataSet dataSet = load(datasetUuid);
+ result.setCdmEntity(dataSet);
+
+ List<UUID> taxonUuids = wrappers.stream().map(wrapper->wrapper.getTaxonNode().getTaxon().getUuid()).collect(Collectors.toList());
+ List<TaxonBase> taxa = taxonService.load(taxonUuids, Arrays.asList(new String[]{"descriptions"}));
+
+ for (SpecimenNodeWrapper wrapper : wrappers) {
+ Optional<TaxonBase> findAny = taxa.stream().filter(taxon->taxon.getUuid().equals(wrapper.getTaxonNode().getTaxon().getUuid())).findAny();
+ if(!findAny.isPresent()){
+ result.addException(new IllegalArgumentException("Could not create wrapper for "+wrapper.getUuidAndTitleCache().getTitleCache()));
+ continue;
+ }
+ Taxon taxon = (Taxon) findAny.get();
+ UUID taxonDescriptionUuid = wrapper.getTaxonDescriptionUuid();
+ TaxonDescription taxonDescription = null;
+ if(taxonDescriptionUuid!=null){
+ taxonDescription = (TaxonDescription) descriptionService.load(taxonDescriptionUuid);
+ }
+ if(taxonDescription==null){
+ Optional<TaxonDescription> associationDescriptionOptional = taxon.getDescriptions().stream()
+ .filter(desc->desc.getTypes().contains(DescriptionType.INDIVIDUALS_ASSOCIATION))
+ .findFirst();
+ if(!associationDescriptionOptional.isPresent()){
+ taxonDescription = TaxonDescription.NewInstance(taxon);
+ }
+ else{
+ taxonDescription = associationDescriptionOptional.get();
+ }
+
+ SpecimenOrObservationBase specimen = occurrenceService.load(wrapper.getUuidAndTitleCache().getUuid());
+ IndividualsAssociation association = IndividualsAssociation.NewInstance(specimen);
+ taxonDescription.addElement(association);
+ taxonService.saveOrUpdate(taxon);
+ result.addUpdatedObject(taxon);
+ }
+ SpecimenDescription specimenDescription = findSpecimenDescription(datasetUuid, wrapper.getUuidAndTitleCache().getUuid(), true);
+ SpecimenRowWrapperDTO rowWrapper = createSpecimenRowWrapper(specimenDescription, wrapper.getTaxonNode().getUuid(), datasetUuid);
+ if(rowWrapper==null){
+ result.addException(new IllegalArgumentException("Could not create wrapper for "+specimenDescription));
+ continue;
+ }
+ //add specimen description to data set
+ rowWrapper.getDescription().addDescriptiveDataSet(dataSet);
+ //add taxon description with IndividualsAssociation to the specimen to data set
+ taxonDescription.addDescriptiveDataSet(dataSet);
+
+ result.addUpdatedObject(rowWrapper.getDescription());
+ result.addUpdatedObject(taxonDescription);
+ }
+ saveOrUpdate(dataSet);
+ return result;
+ }
+
+ private SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, UUID taxonNodeUuid,
+ UUID datasetUuid) {
+ TaxonNode taxonNode = taxonNodeService.load(taxonNodeUuid);
+ DescriptiveDataSet descriptiveDataSet = load(datasetUuid);
+ SpecimenOrObservationBase specimen = description.getDescribedSpecimenOrObservation();
+ //supplemental information
+ if(taxonNode==null){
+ taxonNode = findTaxonNodeForDescription(description, descriptiveDataSet);
+ }
FieldUnit fieldUnit = null;
String identifier = null;
NamedArea country = null;
- //supplemental information
- //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{
- //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;
- }
- }
- }
- }
if(taxonNode==null){
return null;
}
country = fieldUnit.getGatheringEvent().getCountry();
}
//get default taxon description
- TaxonDescription defaultTaxonDescription = findDefaultTaxonDescription(descriptiveDataSet.getUuid(),
- taxonNode.getUuid(), createDefaultTaxonDescription);
+ TaxonDescription defaultTaxonDescription = findDefaultDescription(description.getUuid(), descriptiveDataSet.getUuid());
TaxonRowWrapperDTO taxonRowWrapper = defaultTaxonDescription != null
- ? createTaxonRowWrapper(defaultTaxonDescription, descriptiveDataSet) : null;
- return new SpecimenRowWrapperDTO(description, taxonNode, fieldUnit, identifier, country, taxonRowWrapper);
+ ? createTaxonRowWrapper(defaultTaxonDescription.getUuid(), descriptiveDataSet.getUuid()) : null;
+ SpecimenRowWrapperDTO specimenRowWrapperDTO = new SpecimenRowWrapperDTO(description, new TaxonNodeDto(taxonNode), fieldUnit, identifier, country);
+ specimenRowWrapperDTO.setDefaultDescription(taxonRowWrapper);
+ return specimenRowWrapperDTO;
+ }
+
+ @Override
+ public SpecimenRowWrapperDTO createSpecimenRowWrapper(SpecimenDescription description, UUID descriptiveDataSetUuid){
+ return createSpecimenRowWrapper(description, null, descriptiveDataSetUuid);
}
@Override
@Transactional(readOnly = false)
- public void updateTitleCache(Class<? extends DescriptiveDataSet> clazz, Integer stepSize,
+ public UpdateResult updateCaches(Class<? extends DescriptiveDataSet> clazz, Integer stepSize,
IIdentifiableEntityCacheStrategy<DescriptiveDataSet> cacheStrategy, IProgressMonitor monitor) {
if (clazz == null) {
clazz = DescriptiveDataSet.class;
}
- super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
+ return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor);
}
- @Override
- 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()
- .noneMatch(marker -> marker.getMarkerType().equals(MarkerType.COMPUTED())))
- .collect(Collectors.toList());
- for (TaxonDescription taxonDescription : nonComputedDescriptions) {
- for (DescriptionBase description : dataSetDescriptions) {
- if(description.getUuid().equals(taxonDescription.getUuid())){
- return HibernateProxyHelper.deproxy(descriptionService.load(taxonDescription.getUuid(),
- Arrays.asList("taxon", "descriptionElements", "descriptionElements.feature")), TaxonDescription.class);
- }
- }
+ private TaxonDescription findTaxonDescriptionByDescriptionType(DescriptiveDataSet dataSet, Taxon taxon, DescriptionType descriptionType){
+ Optional<TaxonDescription> first = taxon.getDescriptions().stream()
+ .filter(desc -> desc.getTypes().stream().anyMatch(type -> type.equals(descriptionType)))
+ .filter(desc -> dataSet.getDescriptions().contains(desc))
+ .findFirst();
+ if(first.isPresent()){
+ return HibernateProxyHelper.deproxy(descriptionService.load(first.get().getUuid(),
+ Arrays.asList("taxon", "descriptionElements", "descriptionElements.feature")), TaxonDescription.class);
}
- if(!create){
- return null;
- }
- TaxonRowWrapperDTO taxonRowWrapperDTO = createTaxonDescription(descriptiveDataSetUuid, taxonNodeUuid, MarkerType.USE(), true);
- TaxonDescription newTaxonDescription = taxonRowWrapperDTO.getDescription();
- return newTaxonDescription;
+ return null;
}
@Override
- @Transactional(readOnly=false)
- public UpdateResult aggregateTaxonDescription(UUID taxonNodeUuid, UUID descriptiveDataSetUuid,
- IRemotingProgressMonitor monitor){
- UpdateResult result = new UpdateResult();
-
- TaxonNode node = taxonNodeService.load(taxonNodeUuid);
- Taxon taxon = HibernateProxyHelper.deproxy(taxonService.load(node.getTaxon().getUuid()), Taxon.class);
- result.setCdmEntity(taxon);
-
- //get all "computed" descriptions from all sub nodes
- List<TaxonNode> childNodes = taxonNodeDao.listChildrenOf(node, null, null, true, false, null);
- List<TaxonDescription> computedDescriptions = new ArrayList<>();
-
- childNodes.stream().map(childNode -> childNode.getTaxon())
- .forEach(childTaxon -> childTaxon.getDescriptions().stream()
- // filter out non-computed descriptions
- .filter(description -> description.getMarkers().stream()
- .anyMatch(marker -> marker.getMarkerType().equals(MarkerType.COMPUTED())))
- // add them to the list
- .forEach(computedDescription -> computedDescriptions.add(computedDescription)));
-
- UpdateResult aggregateDescription = aggregateDescription(taxon, computedDescriptions,
- "[Taxon Descriptions]"+taxon.getTitleCache(), descriptiveDataSetUuid);
- result.includeResult(aggregateDescription);
- result.setCdmEntity(aggregateDescription.getCdmEntity());
- aggregateDescription.setCdmEntity(null);
- return result;
+ public TaxonDescription findTaxonDescriptionByDescriptionType(UUID dataSetUuid, UUID taxonNodeUuid, DescriptionType descriptionType){
+ DescriptiveDataSet dataSet = load(dataSetUuid);
+ TaxonNode taxonNode = taxonNodeService.load(taxonNodeUuid);
+ return findTaxonDescriptionByDescriptionType(dataSet, taxonNode.getTaxon(), descriptionType);
}
@Override
@Transactional(readOnly=false)
- public UpdateResult aggregateDescription(UUID taxonUuid, List<UUID> descriptionUuids, String descriptionTitle
- , UUID descriptiveDataSetUuid) {
+ public UpdateResult generatePolytomousKey(UUID descriptiveDataSetUuid, UUID taxonUuid) {
UpdateResult result = new UpdateResult();
- TaxonBase taxonBase = taxonService.load(taxonUuid);
- if(!(taxonBase instanceof Taxon)){
- result.addException(new ClassCastException("The given taxonUUID does not belong to a taxon"));
- result.setError();
- return result;
+ PolytomousKeyGeneratorConfigurator keyConfig = new PolytomousKeyGeneratorConfigurator();
+ DescriptiveDataSet descriptiveDataSet = load(descriptiveDataSetUuid);
+ keyConfig.setDataSet(descriptiveDataSet);
+ PolytomousKey key = new PolytomousKeyGenerator().invoke(keyConfig);
+ IdentifiableServiceConfiguratorImpl<PolytomousKey> serviceConfig= new IdentifiableServiceConfiguratorImpl<>();
+ serviceConfig.setTitleSearchString(descriptiveDataSet.getTitleCache());
+ List<PolytomousKey> list = polytomousKeyService.findByTitle(serviceConfig).getRecords();
+ if(list!=null){
+ list.forEach(polytomousKey->polytomousKeyService.delete(polytomousKey));
}
- Taxon taxon = (Taxon)taxonBase;
+ key.setTitleCache(descriptiveDataSet.getTitleCache(), true);
- List<DescriptionBase> descriptions = descriptionService.load(descriptionUuids, null);
+ Taxon taxon = (Taxon) taxonService.load(taxonUuid);
+ key.addTaxonomicScope(taxon);
- UpdateResult aggregateDescriptionResult = aggregateDescription(taxon, descriptions, descriptionTitle, descriptiveDataSetUuid);
- result.setCdmEntity(aggregateDescriptionResult.getCdmEntity());
- aggregateDescriptionResult.setCdmEntity(null);
- result.includeResult(aggregateDescriptionResult);
+ polytomousKeyService.saveOrUpdate(key);
+
+ result.setCdmEntity(key);
+ result.addUpdatedObject(taxon);
return result;
}
- @SuppressWarnings("unchecked")
- private UpdateResult aggregateDescription(Taxon taxon, List<? extends DescriptionBase> descriptions, String descriptionTitle
- , UUID descriptiveDataSetUuid) {
- UpdateResult result = new UpdateResult();
- Map<Character, List<DescriptionElementBase>> featureToElementMap = new HashMap<>();
-
+ @Override
+ @Transactional(readOnly=false)
+ public DeleteResult removeDescription(UUID descriptionUuid, UUID descriptiveDataSetUuid) {
+ DeleteResult result = new DeleteResult();
DescriptiveDataSet dataSet = load(descriptiveDataSetUuid);
- if(dataSet==null){
- result.addException(new IllegalArgumentException("Could not find data set for uuid "+descriptiveDataSetUuid));
- result.setAbort();
- return result;
+ DescriptionBase descriptionBase = descriptionService.load(descriptionUuid);
+ if(dataSet==null || descriptionBase==null){
+ result.setError();
}
-
- //extract all character description elements
- descriptions.forEach(description->{
- description.getElements()
- .stream()
- //filter out elements that do not have a Characters as Feature
- .filter(element->HibernateProxyHelper.isInstanceOf(((DescriptionElementBase)element).getFeature(), Character.class))
- .forEach(ele->{
- DescriptionElementBase descriptionElement = (DescriptionElementBase)ele;
- List<DescriptionElementBase> list = featureToElementMap.get(descriptionElement.getFeature());
- if(list==null){
- list = new ArrayList<>();
+ else{
+ boolean success = dataSet.removeDescription(descriptionBase);
+ result.addDeletedObject(descriptionBase);
+ // remove taxon description with IndividualsAssociation from data set
+ if(descriptionBase instanceof SpecimenDescription){
+ @SuppressWarnings("cast")
+ Set<IndividualsAssociation> associations = (Set<IndividualsAssociation>)dataSet.getDescriptions()
+ .stream()
+ .flatMap(desc->desc.getElements().stream())// put all description element in one stream
+ .filter(element->element instanceof IndividualsAssociation)
+ .map(ia->(IndividualsAssociation)ia)
+ .collect(Collectors.toSet());
+ Classification classification = dataSet.getTaxonSubtreeFilter().iterator().next().getClassification();
+ for (IndividualsAssociation individualsAssociation : associations) {
+ if(individualsAssociation.getAssociatedSpecimenOrObservation().equals(descriptionBase.getDescribedSpecimenOrObservation())){
+ dataSet.removeDescription(individualsAssociation.getInDescription());
+ result.addDeletedObject(individualsAssociation.getInDescription());
+ }
}
- list.add(descriptionElement);
- featureToElementMap.put(HibernateProxyHelper.deproxy(descriptionElement.getFeature(), Character.class), list);
- });
- });
+ }
+ result.addUpdatedObject(dataSet);
+ result.setStatus(success?Status.OK:Status.ERROR);
+ }
+ return result;
+ }
- TaxonDescription description = TaxonDescription.NewInstance(taxon);
- description.setTitleCache("[Aggregation] "+descriptionTitle, true);
- description.addMarker(Marker.NewInstance(MarkerType.COMPUTED(), true));
- IdentifiableSource source = IdentifiableSource.NewInstance(OriginalSourceType.Aggregation);
- description.addSource(source);
- description.addDescriptiveDataSet(dataSet);
-
- featureToElementMap.forEach((feature, elements)->{
- //aggregate categorical data
- if(feature.isSupportsCategoricalData()){
- CategoricalData aggregate = CategoricalData.NewInstance(feature);
- elements.stream()
- .filter(element->element instanceof CategoricalData)
- .forEach(categoricalData->((CategoricalData)categoricalData).getStateData()
- .forEach(stateData->aggregate.addStateData((StateData) stateData.clone())));
- description.addElement(aggregate);
- }
- //aggregate quantitative data
- else if(feature.isSupportsQuantitativeData()){
- QuantitativeData aggregate = QuantitativeData.NewInstance(feature);
- elements.stream()
- .filter(element->element instanceof QuantitativeData)
- .forEach(categoricalData->((QuantitativeData)categoricalData).getStatisticalValues()
- .forEach(statisticalValue->aggregate.addStatisticalValue((StatisticalMeasurementValue) statisticalValue.clone())));
- description.addElement(aggregate);
+ @Override
+ @Transactional(readOnly = false)
+ public DeleteResult delete(UUID datasetUuid){
+ DescriptiveDataSet dataSet = dao.load(datasetUuid);
+ DeleteResult result = new DeleteResult();
+ if (!dataSet.getDescriptions().isEmpty()){
+ Set<DescriptionBase> descriptions = new HashSet();;
+ for (DescriptionBase desc: dataSet.getDescriptions()){
+ descriptions.add(desc);
}
- });
- result.addUpdatedObject(taxon);
- result.setCdmEntity(description);
+ DeleteResult descriptionResult;
+ for (DescriptionBase desc: descriptions){
+ dataSet.removeDescription(desc);
+ descriptionResult = descriptionService.deleteDescription(desc);
+ result.includeResult(descriptionResult);
+ }
+
+
+ }
+ dao.delete(dataSet);
+ result.addDeletedObject(dataSet);
return result;
}
@Override
- public TaxonRowWrapperDTO createTaxonDescription(UUID dataSetUuid, UUID taxonNodeUuid, MarkerType markerType, boolean markerFlag){
+ @Transactional(readOnly=false)
+ public TaxonRowWrapperDTO createTaxonDescription(UUID dataSetUuid, UUID taxonNodeUuid, DescriptionType descriptionType){
DescriptiveDataSet dataSet = load(dataSetUuid);
TaxonNode taxonNode = taxonNodeService.load(taxonNodeUuid, Arrays.asList("taxon"));
TaxonDescription newTaxonDescription = TaxonDescription.NewInstance(taxonNode.getTaxon());
- String tag = "";
- if(markerFlag){
- if(markerType.equals(MarkerType.USE())){
- tag = "[Default]";
- }
- else if(markerType.equals(MarkerType.IN_BIBLIOGRAPHY())){
- tag = "[Literature]";
- }
- }
- newTaxonDescription.setTitleCache(tag+" "+dataSet.getLabel()+": "+newTaxonDescription.generateTitle(), true); //$NON-NLS-2$
- if(markerType!=null){
- newTaxonDescription.addMarker(Marker.NewInstance(markerType, markerFlag));
- }
- dataSet.getDescriptiveSystem().getDistinctFeatures().forEach(wsFeature->{
+ newTaxonDescription.setTitleCache(dataSet.getLabel()+": "+newTaxonDescription.generateTitle(), true); //$NON-NLS-2$
+ newTaxonDescription.getTypes().add(descriptionType);
+
+ dataSet.getDescriptiveSystem().getDistinctTerms().forEach(wsFeature->{
if(wsFeature.isSupportsCategoricalData()){
newTaxonDescription.addElement(CategoricalData.NewInstance(wsFeature));
}
});
dataSet.addDescription(newTaxonDescription);
- return createTaxonRowWrapper(newTaxonDescription, dataSet);
+ return createTaxonRowWrapper(newTaxonDescription.getUuid(), dataSet.getUuid());
}
@Override
- public SpecimenDescription findSpecimenDescription(UUID descriptiveDataSetUuid, UUID specimenUuid){
+ public List<TermDto> getSupportedStatesForFeature(UUID featureUuid){
+ return termDao.getSupportedStatesForFeature(featureUuid);
+ }
+
+ @Override
+ @Transactional(readOnly=false)
+ public SpecimenDescription findSpecimenDescription(UUID descriptiveDataSetUuid, UUID specimenUuid, boolean addDatasetSource){
DescriptiveDataSet dataSet = load(descriptiveDataSetUuid);
SpecimenOrObservationBase specimen = occurrenceService.load(specimenUuid);
- Set<Feature> datasetFeatures = dataSet.getDescriptiveSystem().getDistinctFeatures();
+ Set<? extends Feature> datasetFeatures = dataSet.getDescriptiveSystem().getDistinctTerms();
List<DescriptionElementBase> matchingDescriptionElements = new ArrayList<>();
for (SpecimenDescription specimenDescription : (Set<SpecimenDescription>) specimen.getDescriptions()) {
for (DescriptionElementBase specimenDescriptionElement : specimenDescription.getElements()) {
Feature feature = specimenDescriptionElement.getFeature();
specimenDescriptionFeatures.add(feature);
- if(datasetFeatures.contains(feature)){
+ if(datasetFeatures.contains(feature) && RowWrapperDTO.hasData(specimenDescriptionElement)){
matchingDescriptionElements.add(specimenDescriptionElement);
}
}
}
});
} catch (CloneNotSupportedException e) {
-// MessagingUtils.error(CharacterMatrix.class, e);
+ //nothing
}
}
- //add all remaining description elements to the new description
- for(Feature wsFeature:datasetFeatures){
- boolean featureFound = false;
- for(DescriptionElementBase element:newDesription.getElements()){
- if(element.getFeature().equals(wsFeature)){
- featureFound = true;
- break;
+ //add sources of data set
+ if(addDatasetSource){
+ dataSet.getSources().forEach(source->{
+ try {
+ newDesription.addSource((IdentifiableSource) source.clone());
+ } catch (CloneNotSupportedException e) {
+ //nothing
}
- }
- if(!featureFound){
- if(wsFeature.isSupportsCategoricalData()){
- newDesription.addElement(CategoricalData.NewInstance(wsFeature));
- }
- else if(wsFeature.isSupportsQuantitativeData()){
- newDesription.addElement(QuantitativeData.NewInstance(wsFeature));
- }
- }
+ });
}
return newDesription;
return DescriptiveDataSetService.this;
}
+
+
}
}