Revision 59174ab0
Added by Andreas Müller over 3 years ago
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/Classification.java | ||
---|---|---|
350 | 350 |
} |
351 | 351 |
|
352 | 352 |
for (TaxonNode taxonNode: taxon.getTaxonNodes()){ |
353 |
Classification classification = deproxy(taxonNode.getClassification(), Classification.class);
|
|
353 |
Classification classification = deproxy(taxonNode.getClassification()); |
|
354 | 354 |
if (classification.equals(this)){ |
355 | 355 |
return taxonNode; |
356 | 356 |
} |
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/Taxon.java | ||
---|---|---|
1739 | 1739 |
* @see java.lang.Object#clone() |
1740 | 1740 |
*/ |
1741 | 1741 |
@Override |
1742 |
public Object clone() { |
|
1742 |
public Taxon clone() { |
|
1743 |
return clone(true, true, true, true); |
|
1744 |
} |
|
1745 |
|
|
1746 |
public Taxon clone(boolean withSynonyms, boolean withTaxonRelations, boolean withDescriptions, boolean withMedia) { |
|
1743 | 1747 |
Taxon result; |
1744 | 1748 |
result = (Taxon)super.clone(); |
1745 | 1749 |
|
1746 | 1750 |
result.setRelationsFromThisTaxon(new HashSet<>()); |
1747 | 1751 |
|
1748 |
for (TaxonRelationship fromRelationship : this.getRelationsFromThisTaxon()){ |
|
1749 |
TaxonRelationship newRelationship = (TaxonRelationship)fromRelationship.clone(); |
|
1750 |
newRelationship.setRelatedFrom(result); |
|
1751 |
result.relationsFromThisTaxon.add(newRelationship); |
|
1752 |
} |
|
1752 |
if (withTaxonRelations){ |
|
1753 |
for (TaxonRelationship fromRelationship : this.getRelationsFromThisTaxon()){ |
|
1754 |
TaxonRelationship newRelationship = (TaxonRelationship)fromRelationship.clone(); |
|
1755 |
newRelationship.setRelatedFrom(result); |
|
1756 |
result.relationsFromThisTaxon.add(newRelationship); |
|
1757 |
} |
|
1753 | 1758 |
|
1754 |
result.setRelationsToThisTaxon(new HashSet<>()); |
|
1755 |
for (TaxonRelationship toRelationship : this.getRelationsToThisTaxon()){ |
|
1756 |
TaxonRelationship newRelationship = (TaxonRelationship)toRelationship.clone(); |
|
1757 |
newRelationship.setRelatedTo(result); |
|
1758 |
result.relationsToThisTaxon.add(newRelationship); |
|
1759 |
result.setRelationsToThisTaxon(new HashSet<>()); |
|
1760 |
for (TaxonRelationship toRelationship : this.getRelationsToThisTaxon()){ |
|
1761 |
TaxonRelationship newRelationship = (TaxonRelationship)toRelationship.clone(); |
|
1762 |
newRelationship.setRelatedTo(result); |
|
1763 |
result.relationsToThisTaxon.add(newRelationship); |
|
1764 |
} |
|
1759 | 1765 |
} |
1760 | 1766 |
|
1761 | 1767 |
//clone synonyms (is this wanted or should we remove synonyms |
1762 | 1768 |
result.synonyms = new HashSet<>(); |
1763 |
for (Synonym synonym : this.getSynonyms()){ |
|
1764 |
Synonym newSyn = (Synonym)synonym.clone(); |
|
1765 |
newSyn.setAcceptedTaxon(result); |
|
1769 |
if(withSynonyms){ |
|
1770 |
for (Synonym synonym : this.getSynonyms()){ |
|
1771 |
Synonym newSyn = (Synonym)synonym.clone(); |
|
1772 |
newSyn.setAcceptedTaxon(result); |
|
1773 |
} |
|
1766 | 1774 |
} |
1767 | 1775 |
|
1768 | 1776 |
result.descriptions = new HashSet<>(); |
1769 | 1777 |
for (TaxonDescription description : this.getDescriptions()){ |
1770 |
TaxonDescription newDescription = (TaxonDescription)description.clone(); |
|
1771 |
result.addDescription(newDescription); |
|
1778 |
if (description.isImageGallery() && withMedia || |
|
1779 |
!description.isImageGallery() && withDescriptions){ |
|
1780 |
TaxonDescription newDescription = (TaxonDescription)description.clone(); |
|
1781 |
result.addDescription(newDescription); |
|
1782 |
} |
|
1772 | 1783 |
} |
1773 | 1784 |
|
1774 | 1785 |
result.taxonNodes = new HashSet<>(); |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImpl.java | ||
---|---|---|
34 | 34 |
|
35 | 35 |
import eu.etaxonomy.cdm.api.service.config.CreateHierarchyForClassificationConfigurator; |
36 | 36 |
import eu.etaxonomy.cdm.api.service.config.NodeDeletionConfigurator.ChildHandling; |
37 |
import eu.etaxonomy.cdm.api.service.config.SubtreeCloneConfigurator; |
|
37 | 38 |
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator; |
38 | 39 |
import eu.etaxonomy.cdm.api.service.dto.EntityDTO; |
39 | 40 |
import eu.etaxonomy.cdm.api.service.dto.GroupedTaxonDTO; |
... | ... | |
47 | 48 |
import eu.etaxonomy.cdm.exception.FilterException; |
48 | 49 |
import eu.etaxonomy.cdm.exception.UnpublishedException; |
49 | 50 |
import eu.etaxonomy.cdm.hibernate.HHH_9751_Util; |
50 |
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; |
|
51 | 51 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
52 | 52 |
import eu.etaxonomy.cdm.model.common.ITreeNode; |
53 | 53 |
import eu.etaxonomy.cdm.model.common.MarkerType; |
... | ... | |
68 | 68 |
import eu.etaxonomy.cdm.model.taxon.Taxon; |
69 | 69 |
import eu.etaxonomy.cdm.model.taxon.TaxonBase; |
70 | 70 |
import eu.etaxonomy.cdm.model.taxon.TaxonNode; |
71 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
|
|
71 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship; |
|
72 | 72 |
import eu.etaxonomy.cdm.model.term.DefinedTermBase; |
73 | 73 |
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer; |
74 | 74 |
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao; |
... | ... | |
104 | 104 |
@Autowired |
105 | 105 |
private ITaxonNodeService taxonNodeService; |
106 | 106 |
|
107 |
@Autowired |
|
108 |
private IReferenceService referenceService; |
|
109 |
|
|
107 | 110 |
@Autowired |
108 | 111 |
private IDefinedTermDao termDao; |
109 | 112 |
|
... | ... | |
137 | 140 |
|
138 | 141 |
@Override |
139 | 142 |
@Transactional(readOnly = false) |
140 |
public UpdateResult cloneClassification(UUID classificationUuid, |
|
141 |
String name, Reference sec, TaxonRelationshipType relationshipType) { |
|
143 |
public UpdateResult cloneClassification(SubtreeCloneConfigurator config) { |
|
142 | 144 |
UpdateResult result = new UpdateResult(); |
143 |
Classification classification = load(classificationUuid); |
|
144 |
Classification clone = Classification.NewInstance(name); |
|
145 |
clone.setReference(sec); |
|
145 |
|
|
146 |
if (config.getSubTreeUuids().isEmpty()){ |
|
147 |
return result; |
|
148 |
} |
|
149 |
|
|
150 |
//TODO error handling |
|
151 |
Reference taxonSecundum = config.isReuseTaxa() || config.isReuseTaxonSecundum() || config.getTaxonSecundumUuid() == null ? |
|
152 |
null : referenceService.find(config.getTaxonSecundumUuid()); |
|
153 |
config.setTaxonSecundum(taxonSecundum); |
|
154 |
|
|
155 |
Reference parentChildReference = config.isReuseParentChildReference() || config.getParentChildReferenceUuid() == null ? |
|
156 |
null : referenceService.find(config.getParentChildReferenceUuid()); |
|
157 |
config.setParentChildReference(parentChildReference); |
|
158 |
|
|
159 |
Reference taxonRelationshipReference = config.getRelationTypeToOldTaxon() == null ? |
|
160 |
null : referenceService.find(config.getRelationshipReferenceUuid()); |
|
161 |
config.setRelationshipReference(taxonRelationshipReference); |
|
162 |
|
|
163 |
Classification classificationClone = Classification.NewInstance(config.getClassificationName()); |
|
164 |
|
|
165 |
if (config.isReuseClassificationReference()){ |
|
166 |
TaxonNode anyNode = taxonNodeDao.findByUuid(config.getSubTreeUuids().iterator().next()); |
|
167 |
if (anyNode != null){ |
|
168 |
Reference oldClassificationRef = anyNode.getClassification().getReference(); |
|
169 |
classificationClone.setReference(oldClassificationRef); |
|
170 |
} |
|
171 |
}else if (config.getClassificationReferenceUuid() != null) { |
|
172 |
Reference classificationReference = referenceService.find(config.getClassificationReferenceUuid()); |
|
173 |
classificationClone.setReference(classificationReference); |
|
174 |
} |
|
146 | 175 |
|
147 | 176 |
//clone taxa and taxon nodes |
148 |
List<TaxonNode> childNodes = classification.getRootNode().getChildNodes(); |
|
149 |
for (TaxonNode taxonNode : childNodes) { |
|
150 |
addChildTaxa(taxonNode, null, clone, relationshipType); |
|
177 |
// List<Integer> childNodeIds = taxonNodeService.idList(taxonNodeFilter); |
|
178 |
// List<TaxonNode> childNodes = taxonNodeService.loadByIds(childNodeIds, null); |
|
179 |
List<TaxonNode> rootNodes = taxonNodeService.find(config.getSubTreeUuids()); |
|
180 |
for (TaxonNode taxonNode : rootNodes) { |
|
181 |
addChildTaxaToClone(taxonNode, classificationClone.getRootNode(), config); |
|
151 | 182 |
} |
152 |
dao.saveOrUpdate(clone); |
|
153 |
result.setCdmEntity(clone); |
|
183 |
dao.saveOrUpdate(classificationClone);
|
|
184 |
result.setCdmEntity(classificationClone);
|
|
154 | 185 |
return result; |
155 | 186 |
} |
156 | 187 |
|
157 |
private void addChildTaxa(TaxonNode originalParentNode, TaxonNode cloneParentNode, Classification classification, TaxonRelationshipType relationshipType){ |
|
158 |
Reference reference = classification.getReference(); |
|
159 |
Taxon cloneTaxon = (Taxon) HibernateProxyHelper.deproxy(originalParentNode.getTaxon(), Taxon.class).clone(); |
|
160 |
cloneTaxon.setSec(reference); |
|
161 |
String microReference = null; |
|
162 |
List<TaxonNode> originalChildNodes = originalParentNode.getChildNodes(); |
|
163 |
HHH_9751_Util.removeAllNull(originalChildNodes); |
|
164 |
|
|
165 |
//add relation between taxa |
|
166 |
if (relationshipType != null){ |
|
167 |
cloneTaxon.addTaxonRelation(originalParentNode.getTaxon(), relationshipType, reference, microReference); |
|
168 |
} |
|
188 |
private void addChildTaxaToClone(TaxonNode originalParentNode, TaxonNode parentNodeClone, |
|
189 |
SubtreeCloneConfigurator config){ |
|
169 | 190 |
|
170 |
TaxonNode cloneChildNode = null; |
|
171 |
//add taxon node to either parent node or classification (no parent node) |
|
172 |
if(cloneParentNode==null){ |
|
173 |
cloneChildNode = classification.addChildTaxon(cloneTaxon, reference, microReference); |
|
174 |
} |
|
175 |
else{ |
|
176 |
cloneChildNode = cloneParentNode.addChildTaxon(cloneTaxon, reference, microReference); |
|
177 |
} |
|
178 |
taxonNodeDao.saveOrUpdate(cloneChildNode); |
|
179 |
//add children |
|
180 |
for (TaxonNode originalChildNode : originalChildNodes) { |
|
181 |
addChildTaxa(originalChildNode, cloneChildNode, classification, relationshipType); |
|
182 |
} |
|
191 |
Taxon originalTaxon = CdmBase.deproxy(originalParentNode.getTaxon()); |
|
192 |
if (originalTaxon == null){ |
|
193 |
for (TaxonNode originalChildChildNode : originalParentNode.getChildNodes()) { |
|
194 |
addChildTaxaToClone(originalChildChildNode, parentNodeClone, config); |
|
195 |
} |
|
196 |
}else{ |
|
197 |
TaxonNode childNodeClone; |
|
198 |
String microReference = null; |
|
199 |
if (config.isReuseTaxa()){ |
|
200 |
childNodeClone = parentNodeClone.addChildTaxon(originalTaxon, config.getParentChildReference(), microReference); |
|
201 |
}else{ |
|
202 |
Taxon cloneTaxon = originalTaxon.clone(config.isCloneSynonyms(), config.isCloneTaxonRelationships(), |
|
203 |
config.isCloneDescriptiveData(), config.isCloneMedia()); |
|
204 |
// xxx KonzeptClone MAN, ppSyns; |
|
205 |
if (!config.isReuseTaxonSecundum()){ |
|
206 |
cloneTaxon.setSec(config.getTaxonSecundum()); |
|
207 |
} |
|
208 |
|
|
209 |
//add relation between taxa |
|
210 |
if (config.getRelationTypeToOldTaxon() != null){ |
|
211 |
TaxonRelationship rel = cloneTaxon.addTaxonRelation(originalParentNode.getTaxon(), config.getRelationTypeToOldTaxon(), |
|
212 |
config.getRelationshipReference(), microReference); |
|
213 |
rel.setDoubtful(config.isRelationDoubtful()); |
|
214 |
} |
|
215 |
childNodeClone = parentNodeClone.addChildTaxon(cloneTaxon, config.getParentChildReference(), microReference); |
|
216 |
} |
|
217 |
|
|
218 |
//TODO necessary? |
|
219 |
taxonNodeDao.saveOrUpdate(childNodeClone); |
|
220 |
//add children |
|
221 |
List<TaxonNode> originalChildNodes = originalParentNode.getChildNodes(); |
|
222 |
HHH_9751_Util.removeAllNull(originalChildNodes); |
|
223 |
|
|
224 |
for (TaxonNode originalChildNode : originalChildNodes) { |
|
225 |
addChildTaxaToClone(originalChildNode, childNodeClone, config); |
|
226 |
} |
|
227 |
} |
|
183 | 228 |
} |
184 | 229 |
|
185 | 230 |
@Override |
... | ... | |
253 | 298 |
return loadTreeBranch(taxonNode, null, baseRank, includeUnpublished, propertyPaths); |
254 | 299 |
} |
255 | 300 |
|
256 |
/** |
|
257 |
* {@inheritDoc} |
|
258 |
*/ |
|
259 | 301 |
@Override |
260 | 302 |
public List<TaxonNode> loadTreeBranch(TaxonNode taxonNode, TaxonNode subtree, Rank baseRank, |
261 | 303 |
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException{ |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IClassificationService.java | ||
---|---|---|
15 | 15 |
import java.util.UUID; |
16 | 16 |
|
17 | 17 |
import eu.etaxonomy.cdm.api.service.config.CreateHierarchyForClassificationConfigurator; |
18 |
import eu.etaxonomy.cdm.api.service.config.SubtreeCloneConfigurator; |
|
18 | 19 |
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator; |
19 | 20 |
import eu.etaxonomy.cdm.api.service.dto.GroupedTaxonDTO; |
20 | 21 |
import eu.etaxonomy.cdm.api.service.dto.TaxonInContextDTO; |
... | ... | |
24 | 25 |
import eu.etaxonomy.cdm.model.common.MarkerType; |
25 | 26 |
import eu.etaxonomy.cdm.model.media.MediaRepresentation; |
26 | 27 |
import eu.etaxonomy.cdm.model.name.Rank; |
27 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
28 | 28 |
import eu.etaxonomy.cdm.model.taxon.Classification; |
29 | 29 |
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode; |
30 | 30 |
import eu.etaxonomy.cdm.model.taxon.Taxon; |
31 | 31 |
import eu.etaxonomy.cdm.model.taxon.TaxonNode; |
32 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; |
|
33 | 32 |
import eu.etaxonomy.cdm.persistence.dto.ClassificationLookupDTO; |
34 | 33 |
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto; |
35 | 34 |
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache; |
... | ... | |
42 | 41 |
*/ |
43 | 42 |
public interface IClassificationService extends IIdentifiableEntityService<Classification> { |
44 | 43 |
|
45 |
/** |
|
46 |
* |
|
47 |
* @param uuid |
|
48 |
* @return |
|
49 |
*/ |
|
50 | 44 |
public ITaxonTreeNode getTreeNodeByUuid(UUID uuid); |
51 | 45 |
|
52 | 46 |
/** |
53 |
* |
|
54 | 47 |
* Returns the root node of the the given classification (specified by its UUID) |
55 | 48 |
* @param classificationUuid the uuid of the classification |
56 | 49 |
* @return the root node of the classification |
... | ... | |
61 | 54 |
|
62 | 55 |
/** |
63 | 56 |
* Clones an existing classification including all taxa and taxon nodes. |
64 |
* @param name |
|
65 |
* @param sec |
|
66 |
* @param relationshipType |
|
67 |
* @return |
|
57 |
|
|
58 |
* @param config the configurator for the cloning |
|
68 | 59 |
*/ |
69 |
public UpdateResult cloneClassification(UUID classificationUuid, String name, Reference sec, TaxonRelationshipType relationshipType);
|
|
60 |
public UpdateResult cloneClassification(SubtreeCloneConfigurator config);
|
|
70 | 61 |
|
71 | 62 |
/** |
72 | 63 |
* |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/config/SpecimenDeleteConfigurator.java | ||
---|---|---|
19 | 19 |
*/ |
20 | 20 |
public class SpecimenDeleteConfigurator extends DeleteConfiguratorBase { |
21 | 21 |
|
22 |
private static final long serialVersionUID = 5306732384161520246L; |
|
23 |
|
|
22 | 24 |
/** |
23 | 25 |
* If <code>true</code> all sub derivates of the specimen are deleted. |
24 | 26 |
*/ |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/config/SubtreeCloneConfigurator.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2020 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
6 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
|
7 |
* See LICENSE.TXT at the top of this package for the full license terms. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.api.service.config; |
|
10 |
|
|
11 |
import java.io.Serializable; |
|
12 |
import java.util.HashSet; |
|
13 |
import java.util.Set; |
|
14 |
import java.util.UUID; |
|
15 |
|
|
16 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
17 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship; |
|
18 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; |
|
19 |
|
|
20 |
/** |
|
21 |
* @author a.mueller |
|
22 |
* @since 30.11.2020 |
|
23 |
*/ |
|
24 |
public class SubtreeCloneConfigurator implements Serializable { |
|
25 |
|
|
26 |
private static final long serialVersionUID = 5599009171476893297L; |
|
27 |
|
|
28 |
//might be replaced by a TaxonNodeFilter in future (but requires treebuilding and handling for missing inbetween taxa a tree) |
|
29 |
private Set<UUID> subTreeUuids; |
|
30 |
|
|
31 |
private String classificationName = "Taxon subtree clone"; |
|
32 |
|
|
33 |
private boolean reuseClassificationReference = false; |
|
34 |
//used only if reuseClassificationReferenceUuid == false |
|
35 |
private UUID classificationReferenceUuid; |
|
36 |
private Reference classificationReference; |
|
37 |
|
|
38 |
private boolean reuseTaxa = false; |
|
39 |
//used only if reuseTaxa == false |
|
40 |
private boolean cloneSynonyms = true; |
|
41 |
//used only if reuseTaxa == false |
|
42 |
private boolean cloneDescriptiveData = true; |
|
43 |
//used only if reuseTaxa == false |
|
44 |
private boolean cloneMedia = true; |
|
45 |
//used only if reuseTaxa == false |
|
46 |
private boolean cloneTaxonRelationships = false; |
|
47 |
//used only if reuseTaxa == false |
|
48 |
private boolean reuseNames = true; |
|
49 |
//used only if reuseTaxa == false |
|
50 |
private boolean reuseTaxonSecundum = true; |
|
51 |
//used only if reuseTaxa == false AND reuseTaxonSecundum = false |
|
52 |
private UUID taxonSecundumUuid = null; |
|
53 |
private Reference taxonSecundum; |
|
54 |
|
|
55 |
private boolean reuseParentChildReference = true; |
|
56 |
//used only if reuseParentChildReference == false |
|
57 |
private UUID parentChildReferenceUuid = null; |
|
58 |
private Reference parentChildReference; |
|
59 |
|
|
60 |
private TaxonRelationshipType relationTypeToOldTaxon; |
|
61 |
//used only if relationTypeToOldTaxon != null |
|
62 |
private boolean relationDoubtful = true; |
|
63 |
//used only if relationTypeToOldTaxon != null |
|
64 |
private UUID relationshipReferenceUuid = null; |
|
65 |
private Reference relationshipReference; |
|
66 |
|
|
67 |
|
|
68 |
public static SubtreeCloneConfigurator NewBaseInstance(UUID subTreeUuid, String classificationName |
|
69 |
){ |
|
70 |
Set<UUID> subTreeUuids = new HashSet<>(); |
|
71 |
subTreeUuids.add(subTreeUuid); |
|
72 |
return new SubtreeCloneConfigurator(subTreeUuids, classificationName, |
|
73 |
false, null, |
|
74 |
false, true, null, |
|
75 |
true, null, |
|
76 |
null, |
|
77 |
true |
|
78 |
); |
|
79 |
} |
|
80 |
|
|
81 |
public static SubtreeCloneConfigurator NewInstance(Set<UUID> subTreeUuids, String classificationName, |
|
82 |
boolean reuseClassificationReference, UUID classificationReferenceUuid, boolean reuseTaxa, |
|
83 |
boolean reuseTaxonSecundum, UUID taxonSecundumUuid, boolean reuseParentChildReference, |
|
84 |
UUID parentChildReferenceUuid, TaxonRelationshipType relationTypeToOldTaxon, boolean reuseNames){ |
|
85 |
return new SubtreeCloneConfigurator(subTreeUuids, classificationName, |
|
86 |
reuseClassificationReference, classificationReferenceUuid, |
|
87 |
reuseTaxa, reuseTaxonSecundum, taxonSecundumUuid, |
|
88 |
reuseParentChildReference, parentChildReferenceUuid, |
|
89 |
relationTypeToOldTaxon, |
|
90 |
reuseNames); |
|
91 |
} |
|
92 |
|
|
93 |
|
|
94 |
// ******************************** CONSTRUCTOR ********************************/ |
|
95 |
|
|
96 |
private SubtreeCloneConfigurator(Set<UUID> subTreeUuids, String classificationName, |
|
97 |
boolean reuseClassificationReference, UUID classificationReferenceUuid, |
|
98 |
boolean reuseTaxa, boolean reuseTaxonSecundum, UUID taxonSecundumUuid, |
|
99 |
boolean reuseParentChildReference, UUID parentChildReferenceUuid, |
|
100 |
TaxonRelationshipType relationTypeToOldTaxon, |
|
101 |
boolean reuseNames) { |
|
102 |
this.subTreeUuids = subTreeUuids; |
|
103 |
this.classificationName = classificationName; |
|
104 |
this.reuseClassificationReference = reuseClassificationReference; |
|
105 |
this.classificationReferenceUuid = classificationReferenceUuid; |
|
106 |
this.reuseTaxa = reuseTaxa; |
|
107 |
this.reuseTaxonSecundum = reuseTaxonSecundum; |
|
108 |
this.taxonSecundumUuid = taxonSecundumUuid; |
|
109 |
this.reuseParentChildReference = reuseParentChildReference; |
|
110 |
this.parentChildReferenceUuid = parentChildReferenceUuid; |
|
111 |
this.relationTypeToOldTaxon = relationTypeToOldTaxon; |
|
112 |
this.reuseNames = reuseNames; |
|
113 |
} |
|
114 |
|
|
115 |
// ******************** GETTER / SETTER ********************************/ |
|
116 |
|
|
117 |
public Set<UUID> getSubTreeUuids() { |
|
118 |
return subTreeUuids; |
|
119 |
} |
|
120 |
public void setSubTreeUuids(Set<UUID> subTreeUuid) { |
|
121 |
this.subTreeUuids = subTreeUuid; |
|
122 |
} |
|
123 |
|
|
124 |
public String getClassificationName() { |
|
125 |
return classificationName; |
|
126 |
} |
|
127 |
public void setClassificationName(String classificationName) { |
|
128 |
this.classificationName = classificationName; |
|
129 |
} |
|
130 |
|
|
131 |
public UUID getClassificationReferenceUuid() { |
|
132 |
return classificationReferenceUuid; |
|
133 |
} |
|
134 |
public void setClassificationReferenceUuid(UUID classificationReferenceUuid) { |
|
135 |
this.classificationReferenceUuid = classificationReferenceUuid; |
|
136 |
} |
|
137 |
|
|
138 |
public UUID getTaxonSecundumUuid() { |
|
139 |
return taxonSecundumUuid; |
|
140 |
} |
|
141 |
public void setTaxonSecundumUuid(UUID taxonSecundumUuid) { |
|
142 |
this.taxonSecundumUuid = taxonSecundumUuid; |
|
143 |
} |
|
144 |
|
|
145 |
public UUID getParentChildReferenceUuid() { |
|
146 |
return parentChildReferenceUuid; |
|
147 |
} |
|
148 |
public void setParentChildReferenceUuid(UUID parentChildReferenceUuid) { |
|
149 |
this.parentChildReferenceUuid = parentChildReferenceUuid; |
|
150 |
} |
|
151 |
|
|
152 |
public TaxonRelationshipType getRelationTypeToOldTaxon() { |
|
153 |
return relationTypeToOldTaxon; |
|
154 |
} |
|
155 |
public void setRelationTypeToOldTaxon(TaxonRelationshipType relationTypeToOldTaxon) { |
|
156 |
this.relationTypeToOldTaxon = relationTypeToOldTaxon; |
|
157 |
} |
|
158 |
|
|
159 |
public boolean isReuseTaxa() { |
|
160 |
return reuseTaxa; |
|
161 |
} |
|
162 |
public void setReuseTaxa(boolean reuseTaxa) { |
|
163 |
this.reuseTaxa = reuseTaxa; |
|
164 |
} |
|
165 |
|
|
166 |
public boolean isReuseNames() { |
|
167 |
return reuseNames; |
|
168 |
} |
|
169 |
public void setReuseNames(boolean reuseNames) { |
|
170 |
this.reuseNames = reuseNames; |
|
171 |
} |
|
172 |
public boolean isReuseClassificationReference() { |
|
173 |
return reuseClassificationReference; |
|
174 |
} |
|
175 |
public void setReuseClassificationReference(boolean reuseClassificationReference) { |
|
176 |
this.reuseClassificationReference = reuseClassificationReference; |
|
177 |
} |
|
178 |
public boolean isReuseTaxonSecundum() { |
|
179 |
return reuseTaxonSecundum; |
|
180 |
} |
|
181 |
public void setReuseTaxonSecundum(boolean reuseTaxonSecundum) { |
|
182 |
this.reuseTaxonSecundum = reuseTaxonSecundum; |
|
183 |
} |
|
184 |
public boolean isReuseParentChildReference() { |
|
185 |
return reuseParentChildReference; |
|
186 |
} |
|
187 |
public void setReuseParentChildReference(boolean reuseParentChildReference) { |
|
188 |
this.reuseParentChildReference = reuseParentChildReference; |
|
189 |
} |
|
190 |
|
|
191 |
public boolean isRelationDoubtful() { |
|
192 |
return relationDoubtful; |
|
193 |
} |
|
194 |
|
|
195 |
public void setRelationDoubtful(boolean relationDoubtful) { |
|
196 |
this.relationDoubtful = relationDoubtful; |
|
197 |
} |
|
198 |
|
|
199 |
public UUID getRelationshipReferenceUuid() { |
|
200 |
return relationshipReferenceUuid; |
|
201 |
} |
|
202 |
|
|
203 |
public void setRelationshipReferenceUuid(UUID relationshipReferenceUuid) { |
|
204 |
this.relationshipReferenceUuid = relationshipReferenceUuid; |
|
205 |
} |
|
206 |
|
|
207 |
public Reference getClassificationReference() { |
|
208 |
return classificationReference; |
|
209 |
} |
|
210 |
|
|
211 |
/** |
|
212 |
* Sets the reference for the classification reference. Also the {@link #getClassificationReferenceUuid() |
|
213 |
* classification reference uuid} is set by this method.<BR> |
|
214 |
* This parameter is used only if <code>{@link #isReuseClassificationReference() reuse classification reference} == false</code> |
|
215 |
* <BR> |
|
216 |
* NOTE: Only use persistent references if configurator is not used within a single transaction. |
|
217 |
* @param parentChildReference |
|
218 |
*/ |
|
219 |
public void setClassificationReference(Reference classificationReference) { |
|
220 |
this.classificationReference = classificationReference; |
|
221 |
} |
|
222 |
|
|
223 |
public Reference getTaxonSecundum() { |
|
224 |
return taxonSecundum; |
|
225 |
} |
|
226 |
/** |
|
227 |
* Sets the taxon secundum reference. Also the {@link #getTaxonSecundumUuid() taxon secundum reference uuid} is set by this method.<BR> |
|
228 |
* This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false && {@link #isReuseTaxonSecundum() |
|
229 |
* reuseTaxonSecundum} == false</code> |
|
230 |
* <BR> |
|
231 |
* NOTE: Only use persistent references if configurator is not used within a single transaction. |
|
232 |
* @param taxonSecundum |
|
233 |
*/ |
|
234 |
public void setTaxonSecundum(Reference taxonSecundum) { |
|
235 |
this.taxonSecundum = taxonSecundum; |
|
236 |
this.taxonSecundumUuid = taxonSecundum == null ? null : taxonSecundum.getUuid(); |
|
237 |
} |
|
238 |
|
|
239 |
public Reference getParentChildReference() { |
|
240 |
return parentChildReference; |
|
241 |
} |
|
242 |
|
|
243 |
/** |
|
244 |
* Sets the reference for the parent child relationship. Also the {@link #getParentChildReferenceUuid() |
|
245 |
* parent child reference uuid} is set by this method.<BR> |
|
246 |
* This parameter is used only if <code>{@link #isReuseParentChildReference() reuse parent child reference} == false</code> |
|
247 |
* <BR> |
|
248 |
* NOTE: Only use persistent references if configurator is not used within a single transaction. |
|
249 |
* @param parentChildReference |
|
250 |
*/ |
|
251 |
public void setParentChildReference(Reference parentChildReference) { |
|
252 |
this.parentChildReference = parentChildReference; |
|
253 |
} |
|
254 |
|
|
255 |
public Reference getRelationshipReference() { |
|
256 |
return relationshipReference; |
|
257 |
} |
|
258 |
|
|
259 |
/** |
|
260 |
* Sets the reference for the new taxon to old taxon {@link TaxonRelationship taxon relationship}. |
|
261 |
* Also the {@link #getRelationshipReferenceUuid() relationship reference uuid} is set by this method.<BR> |
|
262 |
* This parameter is used only if <code>{@link #relationTypeToOldTaxon() relationTypeToOldTaxon} != null</code> |
|
263 |
* <BR> |
|
264 |
* NOTE: Only use persistent references if configurator is not used within a single transaction. |
|
265 |
* @param parentChildReference |
|
266 |
*/ |
|
267 |
public void setRelationshipReference(Reference relationshipReference) { |
|
268 |
this.relationshipReference = relationshipReference; |
|
269 |
} |
|
270 |
|
|
271 |
public boolean isCloneSynonyms() { |
|
272 |
return cloneSynonyms; |
|
273 |
} |
|
274 |
/** |
|
275 |
* If <code>true</code> the synonyms relationships of this taxon are cloned and attached to the new taxon. |
|
276 |
* <BR> |
|
277 |
* This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code> |
|
278 |
*/ |
|
279 |
public void setCloneSynonyms(boolean cloneSynonyms) { |
|
280 |
this.cloneSynonyms = cloneSynonyms; |
|
281 |
} |
|
282 |
|
|
283 |
public boolean isCloneDescriptiveData() { |
|
284 |
return cloneDescriptiveData; |
|
285 |
} |
|
286 |
|
|
287 |
/** |
|
288 |
* If <code>true</code> the descriptive data attached to this taxon are also cloned and attached to the new taxon. |
|
289 |
* <BR> |
|
290 |
* This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code> |
|
291 |
*/ |
|
292 |
public void setCloneDescriptiveData(boolean cloneDescriptiveData) { |
|
293 |
this.cloneDescriptiveData = cloneDescriptiveData; |
|
294 |
} |
|
295 |
|
|
296 |
public boolean isCloneMedia() { |
|
297 |
return cloneMedia; |
|
298 |
} |
|
299 |
/** |
|
300 |
* If <code>true</code> the media attached to this taxon are also attached to the new taxon. |
|
301 |
* Media itself are always reused.<BR> |
|
302 |
* This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code> |
|
303 |
*/ |
|
304 |
public void setCloneMedia(boolean cloneMedia) { |
|
305 |
this.cloneMedia = cloneMedia; |
|
306 |
} |
|
307 |
|
|
308 |
public boolean isCloneTaxonRelationships() { |
|
309 |
return cloneTaxonRelationships; |
|
310 |
} |
|
311 |
/** |
|
312 |
* If <code>true</code> the taxon (concept) relationships to and from this taxon are also cloned. |
|
313 |
* <BR> |
|
314 |
* This parameter is used only if <code>{@link #isReuseTaxa() reuseTaxa} == false</code> |
|
315 |
*/ |
|
316 |
public void setCloneTaxonRelationships(boolean cloneTaxonRelationships) { |
|
317 |
this.cloneTaxonRelationships = cloneTaxonRelationships; |
|
318 |
} |
|
319 |
} |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/config/SwitchAgentConfigurator.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2014 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
6 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
|
7 |
* See LICENSE.TXT at the top of this package for the full license terms. |
|
8 |
*/ |
|
1 | 9 |
package eu.etaxonomy.cdm.api.service.config; |
2 | 10 |
|
3 | 11 |
public class SwitchAgentConfigurator { |
... | ... | |
11 | 19 |
public void setDoAddPersonAsMember(boolean doAddPersonAsMember) { |
12 | 20 |
this.doAddPersonAsMember = doAddPersonAsMember; |
13 | 21 |
} |
14 |
|
|
15 |
|
|
16 | 22 |
} |
cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/ClassificationServiceImplTest.java | ||
---|---|---|
10 | 10 |
package eu.etaxonomy.cdm.api.service; |
11 | 11 |
|
12 | 12 |
import static org.junit.Assert.assertEquals; |
13 |
import static org.junit.Assert.assertNotNull; |
|
13 | 14 |
import static org.junit.Assert.assertNull; |
15 |
import static org.junit.Assert.assertTrue; |
|
14 | 16 |
|
15 | 17 |
import java.io.FileNotFoundException; |
16 | 18 |
import java.util.ArrayList; |
... | ... | |
20 | 22 |
import java.util.List; |
21 | 23 |
import java.util.Set; |
22 | 24 |
import java.util.UUID; |
25 |
import java.util.stream.Collectors; |
|
23 | 26 |
|
24 | 27 |
import org.apache.commons.lang.StringUtils; |
25 | 28 |
import org.apache.log4j.Logger; |
... | ... | |
29 | 32 |
import org.unitils.dbunit.annotation.DataSet; |
30 | 33 |
import org.unitils.spring.annotation.SpringBeanByType; |
31 | 34 |
|
35 |
import eu.etaxonomy.cdm.api.service.config.SubtreeCloneConfigurator; |
|
32 | 36 |
import eu.etaxonomy.cdm.api.service.dto.GroupedTaxonDTO; |
33 | 37 |
import eu.etaxonomy.cdm.model.name.IBotanicalName; |
34 | 38 |
import eu.etaxonomy.cdm.model.name.Rank; |
... | ... | |
39 | 43 |
import eu.etaxonomy.cdm.model.taxon.Taxon; |
40 | 44 |
import eu.etaxonomy.cdm.model.taxon.TaxonNode; |
41 | 45 |
import eu.etaxonomy.cdm.model.taxon.TaxonNodeByNameComparator; |
46 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship; |
|
42 | 47 |
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType; |
43 | 48 |
import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao; |
44 | 49 |
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao; |
... | ... | |
288 | 293 |
Assert.assertFalse(StringUtils.isBlank(result.get(2).getGroupTaxonName())); |
289 | 294 |
} |
290 | 295 |
|
291 |
|
|
292 | 296 |
@Test |
293 | 297 |
@DataSet |
294 | 298 |
public final void testCloneClassification(){ |
295 |
Classification classification = classificationDao.load(CLASSIFICATION_UUID); |
|
296 |
Reference sec = ReferenceFactory.newGeneric(); |
|
297 |
sec.setTitle("cloned sec"); |
|
298 |
Classification clone = (Classification) classificationService.cloneClassification(CLASSIFICATION_UUID, "Cloned classification", sec, TaxonRelationshipType.CONGRUENT_TO()).getCdmEntity(); |
|
299 |
|
|
300 |
List<TaxonNode> childNodes = classification.getChildNodes(); |
|
301 |
for (TaxonNode taxonNode : childNodes) { |
|
302 |
System.out.println(taxonNode.getTaxon().getTitleCache()); |
|
303 |
} |
|
304 |
childNodes = clone.getChildNodes(); |
|
305 |
for (TaxonNode taxonNode : childNodes) { |
|
306 |
System.out.println(taxonNode.getTaxon().getTitleCache()); |
|
307 |
} |
|
308 |
Set<TaxonNode> allNodes = classification.getAllNodes(); |
|
309 |
assertEquals("# of direct children does not match", classification.getChildNodes().size(), clone.getChildNodes().size()); |
|
310 |
assertEquals("# of all nodes does not match", allNodes.size(), clone.getAllNodes().size()); |
|
311 | 299 |
|
312 |
//check that original taxon does not appear in cloned classification |
|
313 |
for (TaxonNode taxonNode : allNodes) { |
|
314 |
assertNull(clone.getNode(taxonNode.getTaxon())); |
|
300 |
Classification originalClassification = classificationDao.load(CLASSIFICATION_UUID); |
|
301 |
|
|
302 |
SubtreeCloneConfigurator config = SubtreeCloneConfigurator.NewBaseInstance( |
|
303 |
originalClassification.getRootNode().getUuid(), "Cloned classification"); |
|
304 |
|
|
305 |
Classification classificatonClone = (Classification) classificationService.cloneClassification(config).getCdmEntity(); |
|
306 |
|
|
307 |
assertEquals("# of direct children does not match", originalClassification.getChildNodes().size(), classificatonClone.getChildNodes().size()); |
|
308 |
assertEquals("# of all nodes does not match", originalClassification.getAllNodes().size(), classificatonClone.getAllNodes().size()); |
|
309 |
|
|
310 |
Set<UUID> originalTaxonSecUuids = originalClassification.getAllNodes().stream().map(tn -> tn.getTaxon().getSec().getUuid()).collect(Collectors.toSet()); |
|
311 |
for (TaxonNode clonedTaxonNode : classificatonClone.getChildNodes()) { |
|
312 |
//test no reuse of taxon |
|
313 |
Taxon clonedTaxon = clonedTaxonNode.getTaxon(); |
|
314 |
TaxonNode originalNode = originalClassification.getNode(clonedTaxon); |
|
315 |
assertNull(originalNode); |
|
316 |
|
|
317 |
//check relationship |
|
318 |
assertEquals(0, clonedTaxon.getRelationsFromThisTaxon().size()); |
|
319 |
|
|
320 |
//test taxon sec |
|
321 |
assertTrue(originalTaxonSecUuids.contains(clonedTaxon.getSec().getUuid())); |
|
315 | 322 |
} |
323 |
|
|
324 |
//test reuse taxon |
|
325 |
config.setReuseTaxa(true); |
|
326 |
classificatonClone = (Classification) classificationService.cloneClassification(config).getCdmEntity(); |
|
327 |
assertEquals("# of direct children does not match", originalClassification.getChildNodes().size(), classificatonClone.getChildNodes().size()); |
|
328 |
originalTaxonSecUuids = originalClassification.getAllNodes().stream().map(tn -> tn.getTaxon().getSec().getUuid()).collect(Collectors.toSet()); |
|
329 |
for (TaxonNode taxonNode : classificatonClone.getChildNodes()) { |
|
330 |
//test no reuse of taxon |
|
331 |
Taxon clonedTaxon = taxonNode.getTaxon(); |
|
332 |
TaxonNode originalNode = originalClassification.getNode(clonedTaxon); |
|
333 |
assertNotNull(originalNode); |
|
334 |
Taxon originalTaxon = originalNode.getTaxon(); |
|
335 |
assertNotNull(originalTaxon); |
|
336 |
|
|
337 |
//check relationship |
|
338 |
assertEquals(0, clonedTaxon.getRelationsFromThisTaxon().size()); |
|
339 |
|
|
340 |
//test taxon sec |
|
341 |
assertEquals(originalTaxon.getSec().getUuid(), clonedTaxon.getSec().getUuid()); |
|
342 |
} |
|
343 |
|
|
344 |
config.setReuseTaxa(false); //reset |
|
345 |
config.setRelationTypeToOldTaxon(TaxonRelationshipType.CONGRUENT_TO()); |
|
346 |
Reference sec = referenceDao.findByUuid(UUID.fromString("719d136b-409e-40d0-9561-46f6999465b4")); |
|
347 |
config.setTaxonSecundumUuid(sec.getUuid()); |
|
348 |
classificatonClone = (Classification) classificationService.cloneClassification(config).getCdmEntity(); |
|
349 |
originalTaxonSecUuids = originalClassification.getAllNodes().stream().map(tn -> tn.getTaxon().getSec().getUuid()).collect(Collectors.toSet()); |
|
350 |
for (TaxonNode taxonNode : classificatonClone.getChildNodes()) { |
|
351 |
//test no reuse of taxon |
|
352 |
Taxon clonedTaxon = taxonNode.getTaxon(); |
|
353 |
TaxonNode originalNode = originalClassification.getNode(clonedTaxon); |
|
354 |
assertNull(originalNode); |
|
355 |
|
|
356 |
//check relationship |
|
357 |
TaxonRelationship relShip = clonedTaxon.getRelationsFromThisTaxon().iterator().next(); |
|
358 |
Taxon relatedTaxon = relShip.getToTaxon(); |
|
359 |
Taxon relatedOriginalTaxon = originalClassification.getNode(relatedTaxon).getTaxon(); |
|
360 |
assertEquals(relatedOriginalTaxon.getName(), clonedTaxon.getName()); |
|
361 |
assertTrue(relShip.getType().equals(TaxonRelationshipType.CONGRUENT_TO())); |
|
362 |
|
|
363 |
//test taxon sec |
|
364 |
assertEquals(relatedOriginalTaxon.getSec().getUuid(), clonedTaxon.getSec().getUuid()); |
|
365 |
} |
|
316 | 366 |
} |
317 | 367 |
|
318 | 368 |
|
... | ... | |
320 | 370 |
private UUID acacia_cuspidifolia_uuid = UUID.fromString("94123e4d-da49-4ed0-9d59-f52a9f7a3618"); |
321 | 371 |
private UUID acacia_sect_botrycephalae_uuid = UUID.fromString("2c73a166-35d1-483d-b8e8-209214cb6193"); |
322 | 372 |
|
323 |
|
|
324 |
/** |
|
325 |
* {@inheritDoc} |
|
326 |
*/ |
|
327 | 373 |
@Override |
328 | 374 |
// @Test |
329 | 375 |
public void createTestDataSet() throws FileNotFoundException { |
cdmlib-services/src/test/resources/eu/etaxonomy/cdm/api/service/ClassificationServiceImplTest.xml | ||
---|---|---|
17 | 17 |
<TAXONNAME NAMETYPE="ICNAFP" ID="5006" CREATED="2015-09-03 10:40:10.0" UUID="1de1a72b-aa0a-4d8f-b434-97379a9fc4bf" UPDATED="2015-09-03 10:40:10.848" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Acacia cuspidifolia Maslin" APPENDEDPHRASE="[null]" FULLTITLECACHE="Acacia cuspidifolia Maslin, Sp. Pl." NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="Maslin" BINOMHYBRID="false" GENUSORUNINOMIAL="Acacia" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="Acacia cuspidifolia" PROTECTEDAUTHORSHIPCACHE="true" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="cuspidifolia" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5006" NOMENCLATURALREFERENCE_ID="5000" RANK_ID="765" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/> |
18 | 18 |
<TAXONNAME NAMETYPE="ICNAFP" ID="5007" CREATED="2015-09-03 10:40:10.0" UUID="3498c017-e8d1-43e0-9cb8-9edbdbe6f403" UPDATED="2015-09-03 10:40:10.851" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Acacia acicularis Willd." APPENDEDPHRASE="[null]" FULLTITLECACHE="Acacia acicularis Willd., Sp. Pl." NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="Willd." BINOMHYBRID="false" GENUSORUNINOMIAL="Acacia" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="Acacia acicularis" PROTECTEDAUTHORSHIPCACHE="true" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="acicularis" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5007" NOMENCLATURALREFERENCE_ID="5000" RANK_ID="765" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/> |
19 | 19 |
<REFERENCE ID="5000" CREATED="2015-09-03 10:40:10.0" UUID="d8db2b51-cb22-40ad-90e2-f66fa1306639" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="Sp. Pl." DATEPUBLISHED_END="[null]" DATEPUBLISHED_FREETEXT="[null]" DATEPUBLISHED_START="[null]" EDITION="[null]" EDITOR="[null]" ISBN="[null]" ISSN="[null]" DOI="[null]" NOMENCLATURALLYRELEVANT="false" ORGANIZATION="[null]" PAGES="[null]" PARSINGPROBLEM="0" PLACEPUBLISHED="[null]" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PUBLISHER="[null]" REFERENCEABSTRACT="[null]" SERIESPART="[null]" TITLE="[null]" ABBREVTITLE="[null]" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="BK" URI="[null]" VOLUME="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" AUTHORSHIP_ID="[null]" INREFERENCE_ID="[null]" INSTITUTION_ID="[null]" SCHOOL_ID="[null]"/> |
20 |
<REFERENCE ID="5001" UUID="719d136b-409e-40d0-9561-46f6999465b4" PROTECTEDTITLECACHE="true" TITLECACHE="Classification reference" NOMENCLATURALLYRELEVANT="false" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="BK" /> |
|
21 |
<REFERENCE ID="5002" UUID="b6bda80a-99f8-40a4-a810-21c9f717aa1b" PROTECTEDTITLECACHE="true" TITLECACHE="Taxon relation reference" NOMENCLATURALLYRELEVANT="false" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="BK" /> |
|
20 | 22 |
<CLASSIFICATION ID="5000" CREATED="2015-09-03 10:40:10.0" UUID="6c2bc8d9-ee62-4222-be89-4a8e31770878" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Acacia Classification" MICROREFERENCE="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_FREETEXT="[null]" TIMEPERIOD_END="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" REFERENCE_ID="[null]" ROOTNODE_ID="5000"/> |
21 | 23 |
<TAXONNODE ID="5000" CREATED="2015-09-03 10:40:10.0" UUID="6b4966ae-8815-49e5-849c-7001b29e5ed0" UPDATED="2015-09-03 10:40:10.8" SORTINDEX="-1" TREEINDEX="#t5000#5000#" COUNTCHILDREN="2" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="[null]" REFERENCEFORPARENTCHILDRELATION_ID="[null]" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="[null]"/> |
22 | 24 |
<TAXONNODE ID="5001" CREATED="2015-09-03 10:40:10.0" UUID="26cc5c08-72df-45d4-84ea-ce81e7e53114" UPDATED="2015-09-03 10:40:10.827" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#" COUNTCHILDREN="4" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5000" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5000"/> |
Also available in: Unified diff
ref #4866, ref #9228 implement subtree clone in branch