+ //TaxonInteraction\r
+ if (ref.isInstanceOf(DeterminationEvent.class)){\r
+ message = "Taxon can't be deleted as it is used in a determination event";\r
+ result.add(message);\r
+ }\r
+\r
+ }\r
+\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public IncludedTaxaDTO listIncludedTaxa(UUID taxonUuid, IncludedTaxonConfiguration config) {\r
+ IncludedTaxaDTO result = new IncludedTaxaDTO(taxonUuid);\r
+\r
+ //preliminary implementation\r
+\r
+ Set<Taxon> taxa = new HashSet<Taxon>();\r
+ TaxonBase taxonBase = find(taxonUuid);\r
+ if (taxonBase == null){\r
+ return new IncludedTaxaDTO();\r
+ }else if (taxonBase.isInstanceOf(Taxon.class)){\r
+ Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);\r
+ taxa.add(taxon);\r
+ }else if (taxonBase.isInstanceOf(Synonym.class)){\r
+ //TODO partial synonyms ??\r
+ //TODO synonyms in general\r
+ Synonym syn = CdmBase.deproxy(taxonBase, Synonym.class);\r
+ taxa.addAll(syn.getAcceptedTaxa());\r
+ }else{\r
+ throw new IllegalArgumentException("Unhandled class " + taxonBase.getClass().getSimpleName());\r
+ }\r
+\r
+ Set<Taxon> related = makeRelatedIncluded(taxa, result, config);\r
+ int i = 0;\r
+ while((! related.isEmpty()) && i++ < 100){ //to avoid\r
+ related = makeRelatedIncluded(related, result, config);\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Computes all children and conceptually congruent and included taxa and adds them to the existingTaxa\r
+ * data structure.\r
+ * @return the set of conceptually related taxa for further use\r
+ */\r
+ /**\r
+ * @param uncheckedTaxa\r
+ * @param existingTaxa\r
+ * @param config\r
+ * @return\r
+ */\r
+ private Set<Taxon> makeRelatedIncluded(Set<Taxon> uncheckedTaxa, IncludedTaxaDTO existingTaxa, IncludedTaxonConfiguration config) {\r
+\r
+ //children\r
+ Set<TaxonNode> taxonNodes = new HashSet<TaxonNode>();\r
+ for (Taxon taxon: uncheckedTaxa){\r
+ taxonNodes.addAll(taxon.getTaxonNodes());\r
+ }\r
+\r
+ Set<Taxon> children = new HashSet<Taxon>();\r
+ if (! config.onlyCongruent){\r
+ for (TaxonNode node: taxonNodes){\r
+ List<TaxonNode> childNodes = nodeService.loadChildNodesOfTaxonNode(node, null, true, false);\r
+ for (TaxonNode child : childNodes){\r
+ children.add(child.getTaxon());\r
+ }\r
+ }\r
+ children.remove(null); // just to be on the save side\r
+ }\r
+\r
+ Iterator<Taxon> it = children.iterator();\r
+ while(it.hasNext()){\r
+ UUID uuid = it.next().getUuid();\r
+ if (existingTaxa.contains(uuid)){\r
+ it.remove();\r
+ }else{\r
+ existingTaxa.addIncludedTaxon(uuid, new ArrayList<UUID>(), false);\r
+ }\r
+ }\r
+\r
+ //concept relations\r
+ Set<Taxon> uncheckedAndChildren = new HashSet<Taxon>(uncheckedTaxa);\r
+ uncheckedAndChildren.addAll(children);\r
+\r
+ Set<Taxon> relatedTaxa = makeConceptIncludedTaxa(uncheckedAndChildren, existingTaxa, config);\r
+\r
+\r
+ Set<Taxon> result = new HashSet<Taxon>(relatedTaxa);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Computes all conceptually congruent or included taxa and adds them to the existingTaxa data structure.\r
+ * @return the set of these computed taxa\r
+ */\r
+ private Set<Taxon> makeConceptIncludedTaxa(Set<Taxon> unchecked, IncludedTaxaDTO existingTaxa, IncludedTaxonConfiguration config) {\r
+ Set<Taxon> result = new HashSet<Taxon>();\r
+\r
+ for (Taxon taxon : unchecked){\r
+ Set<TaxonRelationship> fromRelations = taxon.getRelationsFromThisTaxon();\r
+ Set<TaxonRelationship> toRelations = taxon.getRelationsToThisTaxon();\r
+\r
+ for (TaxonRelationship fromRel : fromRelations){\r
+ if (config.includeDoubtful == false && fromRel.isDoubtful()){\r
+ continue;\r
+ }\r
+ if (fromRel.getType().equals(TaxonRelationshipType.CONGRUENT_TO()) ||\r
+ !config.onlyCongruent && fromRel.getType().equals(TaxonRelationshipType.INCLUDES()) ||\r
+ !config.onlyCongruent && fromRel.getType().equals(TaxonRelationshipType.CONGRUENT_OR_INCLUDES())\r
+ ){\r
+ result.add(fromRel.getToTaxon());\r
+ }\r
+ }\r
+\r
+ for (TaxonRelationship toRel : toRelations){\r
+ if (config.includeDoubtful == false && toRel.isDoubtful()){\r
+ continue;\r
+ }\r
+ if (toRel.getType().equals(TaxonRelationshipType.CONGRUENT_TO())){\r
+ result.add(toRel.getFromTaxon());\r
+ }\r
+ }\r
+ }\r
+\r
+ Iterator<Taxon> it = result.iterator();\r
+ while(it.hasNext()){\r
+ UUID uuid = it.next().getUuid();\r
+ if (existingTaxa.contains(uuid)){\r
+ it.remove();\r
+ }else{\r
+ existingTaxa.addIncludedTaxon(uuid, new ArrayList<UUID>(), false);\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ @Override\r
+ public List<TaxonBase> findTaxaByName(MatchingTaxonConfigurator config){\r
+ List<TaxonBase> taxonList = dao.getTaxaByName(true, false, false, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, 0, config.getPropertyPath());\r
+ return taxonList;\r
+ }\r