Revision c693e3b1
Added by Patrick Plitzner about 5 years ago
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/word/out/WordExport.java | ||
---|---|---|
110 | 110 |
// return new JAXBElement( new QName(Namespaces.NS_WORD12, "fldChar"), org.docx4j.wml.FldChar.class, fldchar); |
111 | 111 |
// } |
112 | 112 |
|
113 |
private void addChildNode(FeatureNode node, MainDocumentPart mainDocumentPart, int indent) throws Exception{ |
|
113 |
private void addChildNode(FeatureNode<?> node, MainDocumentPart mainDocumentPart, int indent) throws Exception{
|
|
114 | 114 |
String styleId = "Heading"+indent; |
115 | 115 |
|
116 | 116 |
for (FeatureNode childNode : node.getChildNodes()) { |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/in/SDDImport.java | ||
---|---|---|
106 | 106 |
private Map<String,String> citations = new HashMap<>(); |
107 | 107 |
private Map<String,String> defaultUnitPrefixes = new HashMap<>(); |
108 | 108 |
private Map<String,Person> editors = new HashMap<>(); |
109 |
private Map<String,FeatureNode> featureNodes = new HashMap<>(); |
|
109 |
private Map<String,FeatureNode<Feature>> featureNodes = new HashMap<>();
|
|
110 | 110 |
private Map<String,Feature> features = new HashMap<>(); |
111 | 111 |
private Map<String,String> locations = new HashMap<>(); |
112 | 112 |
private Map<String,List<CdmBase>> mediaObject_ListCdmBase = new HashMap<>(); |
... | ... | |
1753 | 1753 |
|
1754 | 1754 |
FeatureTree featureTree = FeatureTree.NewInstance(); |
1755 | 1755 |
importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState); |
1756 |
FeatureNode root = featureTree.getRoot(); |
|
1756 |
FeatureNode<Feature> root = featureTree.getRoot();
|
|
1757 | 1757 |
List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace); |
1758 | 1758 |
|
1759 | 1759 |
//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts |
... | ... | |
1785 | 1785 |
* @param root |
1786 | 1786 |
* @param elNodes |
1787 | 1787 |
*/ |
1788 |
private void handleCharacterNodes(Namespace sddNamespace, FeatureNode root, Element elNodes) { |
|
1788 |
private void handleCharacterNodes(Namespace sddNamespace, FeatureNode<Feature> root, Element elNodes) {
|
|
1789 | 1789 |
List<Element> listNodes = elNodes.getChildren("Node", sddNamespace); |
1790 | 1790 |
if (listNodes != null) { |
1791 | 1791 |
for (Element elNode : listNodes){ |
1792 | 1792 |
String idN = elNode.getAttributeValue("id"); |
1793 |
FeatureNode fn = null; |
|
1793 |
FeatureNode<Feature> fn = null;
|
|
1794 | 1794 |
Feature dc = null; |
1795 | 1795 |
if (idN!=null) { |
1796 | 1796 |
// DescriptiveConcepts are used as nodes in CharacterTrees |
... | ... | |
1808 | 1808 |
if (elParent!=null){ |
1809 | 1809 |
String refP = elParent.getAttributeValue("ref"); |
1810 | 1810 |
if (refP!=null) { |
1811 |
FeatureNode parent = featureNodes.get(refP); |
|
1811 |
FeatureNode<Feature> parent = featureNodes.get(refP);
|
|
1812 | 1812 |
if (parent==null){ |
1813 | 1813 |
root.addChild(fn); // if no parent found or the reference is broken, add the node to the root of the tree |
1814 | 1814 |
} |
... | ... | |
1832 | 1832 |
Element elParent = elCharNode.getChild("Parent", sddNamespace); |
1833 | 1833 |
Element elCharacter = elCharNode.getChild("Character", sddNamespace); |
1834 | 1834 |
Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace); |
1835 |
FeatureNode fn = FeatureNode.NewInstance(); |
|
1835 |
FeatureNode<Feature> fn = FeatureNode.NewInstance();
|
|
1836 | 1836 |
|
1837 | 1837 |
if (elDependencyRules!=null){ |
1838 | 1838 |
Element elInapplicableIf = elCharNode.getChild("InapplicableIf", sddNamespace); |
... | ... | |
1862 | 1862 |
if (elParent!=null){ |
1863 | 1863 |
String refP = elParent.getAttributeValue("ref"); |
1864 | 1864 |
if ((refP!=null)&&(!refP.equals(""))) { |
1865 |
FeatureNode parent = featureNodes.get(refP); |
|
1865 |
FeatureNode<Feature> parent = featureNodes.get(refP);
|
|
1866 | 1866 |
if (parent==null){ |
1867 | 1867 |
parent = root; // if no parent found or the reference is broken, add the node to the root of the tree |
1868 | 1868 |
} |
... | ... | |
1872 | 1872 |
String refC = elCharacter.getAttributeValue("ref"); |
1873 | 1873 |
if ((refC!=null)&&(!refC.equals(""))){ |
1874 | 1874 |
Feature character = features.get(refC); |
1875 |
fn.setFeature(character);
|
|
1875 |
fn.setTerm(character);
|
|
1876 | 1876 |
featureNodes.put(refC, fn); |
1877 | 1877 |
} |
1878 | 1878 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/out/SDDDocumentBuilder.java | ||
---|---|---|
1272 | 1272 |
} |
1273 | 1273 |
} |
1274 | 1274 |
|
1275 |
public void buildBranches(FeatureNode parent, ElementImpl element, |
|
1275 |
public void buildBranches(FeatureNode<Feature> parent, ElementImpl element,
|
|
1276 | 1276 |
boolean isRoot) { |
1277 |
List<FeatureNode> children = parent.getChildNodes(); |
|
1277 |
List<FeatureNode<Feature>> children = parent.getChildNodes();
|
|
1278 | 1278 |
if (!parent.isLeaf()) { |
1279 | 1279 |
ElementImpl elCharNode = new ElementImpl(document, NODE); |
1280 | 1280 |
charnodeCount = buildReference(parent, featuretrees, ID, |
... | ... | |
1288 | 1288 |
} |
1289 | 1289 |
ElementImpl elDescriptiveConcept = new ElementImpl(document, |
1290 | 1290 |
DESCRIPTIVE_CONCEPT); |
1291 |
Feature fref = parent.getFeature();
|
|
1291 |
Feature fref = parent.getTerm();
|
|
1292 | 1292 |
descriptiveConceptCount = buildReference(fref, descriptiveConcepts, |
1293 | 1293 |
REF, elDescriptiveConcept, "dc", descriptiveConceptCount); |
1294 | 1294 |
elCharNode.appendChild(elDescriptiveConcept); |
1295 | 1295 |
element.appendChild(elCharNode); |
1296 |
for (Iterator<FeatureNode> ifn = children.iterator(); ifn.hasNext();) { |
|
1296 |
for (Iterator<FeatureNode<Feature>> ifn = children.iterator(); ifn.hasNext();) {
|
|
1297 | 1297 |
FeatureNode fn = ifn.next(); |
1298 | 1298 |
buildBranches(fn, element, false); |
1299 | 1299 |
} |
... | ... | |
1306 | 1306 |
charnodeCount = buildReference(parent, featuretrees, ID, |
1307 | 1307 |
elCharNode, "cn", charnodeCount); |
1308 | 1308 |
ElementImpl elCharacter = new ElementImpl(document, CHARACTER); |
1309 |
Feature fref = parent.getFeature();
|
|
1309 |
Feature fref = parent.getTerm();
|
|
1310 | 1310 |
boolean dependencies = false; |
1311 | 1311 |
ElementImpl elDependecyRules = new ElementImpl(document, |
1312 | 1312 |
"DependecyRules"); |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/taxonx2013/TaxonXTreatmentExtractor.java | ||
---|---|---|
308 | 308 |
if (proibiospheretree == null){ |
309 | 309 |
List<FeatureTree> trees = importer.getFeatureTreeService().list(FeatureTree.class, null, null, null, null); |
310 | 310 |
if (trees.size()==1) { |
311 |
FeatureTree ft = trees.get(0); |
|
311 |
FeatureTree<Feature> ft = trees.get(0);
|
|
312 | 312 |
if (featuresMap==null) { |
313 | 313 |
featuresMap=new HashMap<String, Feature>(); |
314 | 314 |
} |
... | ... | |
2145 | 2145 |
//System.out.println("NEW ACCEPTED HERE "+nameToBeFilled); |
2146 | 2146 |
} |
2147 | 2147 |
else { |
2148 |
acceptedTaxon= Taxon.NewInstance(nameToBeFilled,(Reference) nameToBeFilled.getNomenclaturalReference() );//TODO TOFIX reference
|
|
2148 |
acceptedTaxon= Taxon.NewInstance(nameToBeFilled,nameToBeFilled.getNomenclaturalReference() );//TODO TOFIX reference |
|
2149 | 2149 |
//System.out.println("NEW ACCEPTED HERE2 "+nameToBeFilled); |
2150 | 2150 |
} |
2151 | 2151 |
|
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/jaxb/FeatureTest.java | ||
---|---|---|
1 | 1 |
/** |
2 | 2 |
* Copyright (C) 2009 EDIT |
3 |
* European Distributed Institute of Taxonomy
|
|
3 |
* European Distributed Institute of Taxonomy |
|
4 | 4 |
* http://www.e-taxonomy.eu |
5 |
*
|
|
5 |
* |
|
6 | 6 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
7 | 7 |
* See LICENSE.TXT at the top of this package for the full license terms. |
8 | 8 |
*/ |
... | ... | |
22 | 22 |
import eu.etaxonomy.cdm.model.description.FeatureTree; |
23 | 23 |
|
24 | 24 |
public class FeatureTest { |
25 |
|
|
25 |
|
|
26 | 26 |
private String resource = "/eu/etaxonomy/cdm/io/jaxb/FeatureTest.xml"; |
27 |
|
|
27 |
|
|
28 | 28 |
@Test |
29 | 29 |
public void testUnmarshalFeatureTree() throws Exception { |
30 | 30 |
CdmDocumentBuilder cdmDocumentBuilder = new CdmDocumentBuilder(); |
31 | 31 |
URI uri = new URI(URIEncoder.encode(this.getClass().getResource(resource).toString())); |
32 | 32 |
DataSet dataSet = cdmDocumentBuilder.unmarshal(DataSet.class, new InputStreamReader(this.getClass().getResourceAsStream(resource)),uri.toString()); |
33 |
|
|
34 |
FeatureTree featureTree = (FeatureTree)dataSet.getFeatureTrees().get(0);
|
|
33 |
|
|
34 |
FeatureTree featureTree = dataSet.getFeatureTrees().get(0); |
|
35 | 35 |
Feature feature = (Feature)dataSet.getTerms().get(1); |
36 |
|
|
36 |
|
|
37 | 37 |
assertNotNull("FeatureTree must not be null",featureTree); |
38 | 38 |
assertNotNull("Feature must not be null",feature); |
39 |
|
|
39 |
|
|
40 | 40 |
assertNotNull("FeatureTree.root must not be null",featureTree.getRoot()); |
41 | 41 |
FeatureNode featureNode = featureTree.getRoot(); |
42 |
assertNotNull("FeatureNode.feature must not be null",featureNode.getFeature());
|
|
43 |
assertEquals("FeatureNode.feature must equal Feature",feature,featureNode.getFeature());
|
|
44 |
|
|
42 |
assertNotNull("FeatureNode.feature must not be null",featureNode.getTerm());
|
|
43 |
assertEquals("FeatureNode.feature must equal Feature",feature,featureNode.getTerm());
|
|
44 |
|
|
45 | 45 |
assertNotNull("FeatureNode.children must not be null",featureNode.getChildNodes()); |
46 | 46 |
assertFalse("FeatureNode.children must not be empty",featureNode.getChildNodes().isEmpty()); |
47 | 47 |
assertEquals("FeatureNode.children must have 4 child nodes",4,featureNode.getChildNodes().size()); |
48 |
|
|
48 |
|
|
49 | 49 |
} |
50 | 50 |
} |
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/DescriptiveDataSet.java | ||
---|---|---|
82 | 82 |
@XmlSchemaType(name = "IDREF") |
83 | 83 |
@ManyToOne(fetch = FetchType.LAZY) |
84 | 84 |
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) |
85 |
private FeatureTree descriptiveSystem; |
|
85 |
private FeatureTree<Character> descriptiveSystem;
|
|
86 | 86 |
|
87 | 87 |
@XmlElementWrapper(name = "Descriptions") |
88 | 88 |
@XmlElement(name = "Description") |
... | ... | |
306 | 306 |
} |
307 | 307 |
} |
308 | 308 |
|
309 |
public FeatureTree getDescriptiveSystem() { |
|
309 |
public FeatureTree<Character> getDescriptiveSystem() {
|
|
310 | 310 |
return descriptiveSystem; |
311 | 311 |
} |
312 |
public void setDescriptiveSystem(FeatureTree descriptiveSystem) { |
|
312 |
public void setDescriptiveSystem(FeatureTree<Character> descriptiveSystem) {
|
|
313 | 313 |
this.descriptiveSystem = descriptiveSystem; |
314 | 314 |
} |
315 | 315 |
|
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/FeatureNode.java | ||
---|---|---|
45 | 45 |
import org.hibernate.envers.Audited; |
46 | 46 |
|
47 | 47 |
import eu.etaxonomy.cdm.hibernate.HHH_9751_Util; |
48 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
49 | 48 |
import eu.etaxonomy.cdm.model.common.DefinedTermBase; |
50 | 49 |
import eu.etaxonomy.cdm.model.common.IHasTermType; |
51 | 50 |
import eu.etaxonomy.cdm.model.common.ITreeNode; |
... | ... | |
81 | 80 |
@Entity |
82 | 81 |
@Audited |
83 | 82 |
@Table(name="FeatureNode", indexes = { @Index(name = "featureNodeTreeIndex", columnList = "treeIndex") }) |
84 |
public class FeatureNode extends VersionableEntity |
|
85 |
implements ITreeNode<FeatureNode>, IHasTermType, Cloneable { |
|
83 |
public class FeatureNode <T extends DefinedTermBase> extends VersionableEntity
|
|
84 |
implements ITreeNode<FeatureNode<T>>, IHasTermType, Cloneable {
|
|
86 | 85 |
private static final Logger logger = Logger.getLogger(FeatureNode.class); |
87 | 86 |
|
88 | 87 |
//This is the main key a node belongs to. Although other keys may also reference |
... | ... | |
90 | 89 |
@XmlElement(name = "FeatureTree") |
91 | 90 |
@XmlIDREF |
92 | 91 |
@XmlSchemaType(name = "IDREF") |
93 |
@ManyToOne(fetch = FetchType.LAZY) |
|
92 |
@ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureTree.class)
|
|
94 | 93 |
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) //TODO this usage is incorrect, needed only for OneToMany, check why it is here, can it be removed?? |
95 | 94 |
//TODO Val #3379 |
96 | 95 |
// @NotNull |
97 |
private FeatureTree featureTree; |
|
96 |
private FeatureTree<T> featureTree;
|
|
98 | 97 |
|
99 | 98 |
/** |
100 | 99 |
* The {@link TermType type} of this term node. |
... | ... | |
113 | 112 |
@XmlElement(name = "Feature") |
114 | 113 |
@XmlIDREF |
115 | 114 |
@XmlSchemaType(name = "IDREF") |
116 |
@ManyToOne(fetch = FetchType.LAZY) |
|
117 |
private DefinedTermBase feature;
|
|
115 |
@ManyToOne(fetch = FetchType.LAZY, targetEntity=DefinedTermBase.class)
|
|
116 |
private T feature;
|
|
118 | 117 |
|
119 | 118 |
@XmlElement(name = "Parent") |
120 | 119 |
@XmlIDREF |
... | ... | |
122 | 121 |
@ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureNode.class) |
123 | 122 |
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) |
124 | 123 |
@JoinColumn(name="parent_id") |
125 |
private FeatureNode parent; |
|
124 |
private FeatureNode<T> parent;
|
|
126 | 125 |
|
127 | 126 |
|
128 | 127 |
@XmlElement(name = "treeIndex") |
... | ... | |
134 | 133 |
//see https://dev.e-taxonomy.eu/trac/ticket/3722 |
135 | 134 |
@OrderColumn(name="sortIndex") |
136 | 135 |
@OrderBy("sortIndex") |
137 |
@OneToMany(fetch = FetchType.LAZY, mappedBy="parent") |
|
136 |
@OneToMany(fetch = FetchType.LAZY, mappedBy="parent", targetEntity=FeatureNode.class)
|
|
138 | 137 |
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE}) |
139 |
private List<FeatureNode> children = new ArrayList<FeatureNode>();
|
|
138 |
private List<FeatureNode<T>> children = new ArrayList<>();
|
|
140 | 139 |
|
141 | 140 |
//see https://dev.e-taxonomy.eu/trac/ticket/3722 |
142 | 141 |
private Integer sortIndex; |
... | ... | |
166 | 165 |
* |
167 | 166 |
* @see #NewInstance(Feature) |
168 | 167 |
*/ |
169 |
public static FeatureNode NewInstance(TermType termType){
|
|
170 |
return new FeatureNode(termType); |
|
168 |
public static <T extends DefinedTermBase<T>> FeatureNode<T> NewInstance(TermType termType){
|
|
169 |
return new FeatureNode<>(termType);
|
|
171 | 170 |
} |
172 | 171 |
|
173 | 172 |
/** |
... | ... | |
175 | 174 |
* |
176 | 175 |
* @see #NewInstance(Feature) |
177 | 176 |
*/ |
178 |
public static FeatureNode NewInstance(){ |
|
179 |
return new FeatureNode(TermType.Feature); |
|
180 |
} |
|
181 |
|
|
182 |
/** |
|
183 |
* Creates a new feature node instance only with the given {@link Feature feature} |
|
184 |
* (without parent and children). |
|
185 |
* |
|
186 |
* @param feature the feature assigned to the new feature node |
|
187 |
* @see #NewInstance() |
|
188 |
*/ |
|
189 |
public static FeatureNode NewInstance(Feature feature){ |
|
190 |
FeatureNode result = new FeatureNode(TermType.Feature); |
|
191 |
result.setTerm(feature); |
|
192 |
return result; |
|
177 |
public static FeatureNode<Feature> NewInstance(){ |
|
178 |
return new FeatureNode<>(TermType.Feature); |
|
193 | 179 |
} |
194 | 180 |
|
195 | 181 |
/** |
... | ... | |
200 | 186 |
* @param term the term assigned to the new feature node |
201 | 187 |
* @see #NewInstance() |
202 | 188 |
*/ |
203 |
public static FeatureNode NewInstance(DefinedTermBase term){
|
|
204 |
FeatureNode result = new FeatureNode(term.getTermType());
|
|
189 |
public static <T extends DefinedTermBase<T>> FeatureNode<T> NewInstance(T term){
|
|
190 |
FeatureNode<T> result = new FeatureNode<>(term.getTermType());
|
|
205 | 191 |
result.setTerm(term); |
206 | 192 |
return result; |
207 | 193 |
} |
... | ... | |
227 | 213 |
|
228 | 214 |
//*************************** TREE ************************************/ |
229 | 215 |
|
230 |
public FeatureTree getFeatureTree() { |
|
216 |
public FeatureTree<T> getFeatureTree() {
|
|
231 | 217 |
return featureTree; |
232 | 218 |
} |
233 | 219 |
|
234 |
protected void setFeatureTree(FeatureTree featureTree) { |
|
220 |
protected void setFeatureTree(FeatureTree<T> featureTree) {
|
|
235 | 221 |
checkTermType(featureTree); |
236 | 222 |
this.featureTree = featureTree; |
237 | 223 |
} |
... | ... | |
239 | 225 |
//** ********************** FEATURE ******************************/ |
240 | 226 |
|
241 | 227 |
/** |
242 |
* Returns the {@link Feature feature} <i>this</i> feature node is based on. |
|
243 |
*/ |
|
244 |
@Deprecated |
|
245 |
public Feature getFeature() { |
|
246 |
return CdmBase.deproxy(feature, Feature.class); |
|
247 |
} |
|
248 |
/** |
|
249 |
* @see #getFeature() |
|
250 |
*/ |
|
251 |
@Deprecated |
|
252 |
public void setFeature(Feature feature) { |
|
253 |
checkTermType(feature); |
|
254 |
this.feature = feature; |
|
255 |
} |
|
256 |
|
|
257 |
/** |
|
258 | 228 |
* Returns the {@link Feature feature} <i>this</i> feature node is based on. |
259 | 229 |
*/ |
260 |
public DefinedTermBase getTerm() {
|
|
230 |
public T getTerm() {
|
|
261 | 231 |
return feature; |
262 | 232 |
} |
263 | 233 |
/** |
264 | 234 |
* @see #getFeature() |
265 | 235 |
*/ |
266 |
public void setTerm(DefinedTermBase term) {
|
|
236 |
public void setTerm(T term) {
|
|
267 | 237 |
checkTermType(term); |
268 | 238 |
this.feature = term; |
269 | 239 |
} |
... | ... | |
276 | 246 |
* @see #getChildNodes() |
277 | 247 |
*/ |
278 | 248 |
@Override |
279 |
public FeatureNode getParent() { |
|
249 |
public FeatureNode<T> getParent() {
|
|
280 | 250 |
return parent; |
281 | 251 |
} |
282 | 252 |
/** |
... | ... | |
287 | 257 |
* @param parent the feature node to be set as parent |
288 | 258 |
* @see #getParent() |
289 | 259 |
*/ |
290 |
protected void setParent(FeatureNode parent) { |
|
260 |
protected void setParent(FeatureNode<T> parent) {
|
|
291 | 261 |
checkTermType(parent); |
292 | 262 |
this.parent = parent; |
293 | 263 |
} |
... | ... | |
309 | 279 |
* <i>this</i> feature node. |
310 | 280 |
*/ |
311 | 281 |
@Override |
312 |
public List<FeatureNode> getChildNodes() { |
|
282 |
public List<FeatureNode<T>> getChildNodes() {
|
|
313 | 283 |
return children; |
314 | 284 |
} |
315 | 285 |
|
... | ... | |
325 | 295 |
* @see #removeChild(FeatureNode) |
326 | 296 |
* @see #removeChild(int) |
327 | 297 |
*/ |
328 |
public void addChild(FeatureNode child){ |
|
298 |
public void addChild(FeatureNode<T> child){
|
|
329 | 299 |
addChild(child, children.size()); |
330 | 300 |
} |
331 | 301 |
/** |
... | ... | |
344 | 314 |
* @see #removeChild(FeatureNode) |
345 | 315 |
* @see #removeChild(int) |
346 | 316 |
*/ |
347 |
public void addChild(FeatureNode child, int index){ |
|
317 |
public void addChild(FeatureNode<T> child, int index){
|
|
348 | 318 |
checkTermType(child); |
349 |
List<FeatureNode> children = this.getChildNodes(); |
|
319 |
List<FeatureNode<T>> children = this.getChildNodes();
|
|
350 | 320 |
if (index < 0 || index > children.size() + 1){ |
351 | 321 |
throw new IndexOutOfBoundsException("Wrong index: " + index); |
352 | 322 |
} |
... | ... | |
374 | 344 |
* @see #addChild(FeatureNode) |
375 | 345 |
* @see #removeChild(int) |
376 | 346 |
*/ |
377 |
public void removeChild(FeatureNode child){ |
|
347 |
public void removeChild(FeatureNode<T> child){
|
|
378 | 348 |
|
379 | 349 |
int index = children.indexOf(child); |
380 | 350 |
if (index >= 0){ |
... | ... | |
394 | 364 |
* @see #removeChild(FeatureNode) |
395 | 365 |
*/ |
396 | 366 |
public void removeChild(int index){ |
397 |
FeatureNode child = children.get(index); |
|
367 |
FeatureNode<T> child = children.get(index);
|
|
398 | 368 |
if (child != null){ |
399 | 369 |
children.remove(index); |
400 | 370 |
child.setParent(null); |
401 | 371 |
child.setFeatureTree(null); |
402 | 372 |
//TODO workaround (see sortIndex doc) |
403 | 373 |
for(int i = 0; i < children.size(); i++){ |
404 |
FeatureNode childAt = children.get(i); |
|
374 |
FeatureNode<T> childAt = children.get(i);
|
|
405 | 375 |
childAt.setSortIndex(i); |
406 | 376 |
} |
407 | 377 |
child.setSortIndex(null); |
... | ... | |
418 | 388 |
* @see #addChild(FeatureNode, int) |
419 | 389 |
* @see #removeChild(int) |
420 | 390 |
*/ |
421 |
public FeatureNode getChildAt(int childIndex) { |
|
391 |
public FeatureNode<T> getChildAt(int childIndex) {
|
|
422 | 392 |
return children.get(childIndex); |
423 | 393 |
} |
424 | 394 |
|
... | ... | |
441 | 411 |
* @see #addChild(FeatureNode, int) |
442 | 412 |
* @see #removeChild(int) |
443 | 413 |
*/ |
444 |
public int getIndex(FeatureNode node) { |
|
414 |
public int getIndex(FeatureNode<T> node) {
|
|
445 | 415 |
if (! children.contains(node)){ |
446 | 416 |
return -1; |
447 | 417 |
}else{ |
... | ... | |
603 | 573 |
} |
604 | 574 |
|
605 | 575 |
/** |
606 |
* Returns all features that are contained in this node or a child node
|
|
576 |
* Returns all terms that are contained in this node or a child node
|
|
607 | 577 |
* |
608 | 578 |
* @param featureNode |
609 | 579 |
* @param features |
610 | 580 |
* @return |
611 | 581 |
*/ |
612 | 582 |
@Transient |
613 |
public Set<Feature> getDistinctFeaturesRecursive(Set<Feature> features){
|
|
614 |
Feature feature = this.getFeature();
|
|
583 |
public Set<T> getDistinctFeaturesRecursive(Set<T> features){
|
|
584 |
T term = this.getTerm();
|
|
615 | 585 |
|
616 |
if(feature!=null){
|
|
617 |
features.add(feature);
|
|
586 |
if(term!=null){
|
|
587 |
features.add(term);
|
|
618 | 588 |
} |
619 | 589 |
|
620 |
for(FeatureNode childNode : this.getChildNodes()){ |
|
590 |
for(FeatureNode<T> childNode : this.getChildNodes()){
|
|
621 | 591 |
features.addAll(childNode.getDistinctFeaturesRecursive(features)); |
622 | 592 |
} |
623 | 593 |
|
624 | 594 |
return features; |
625 | 595 |
} |
626 | 596 |
|
627 |
public FeatureNode cloneDescendants(){ |
|
628 |
FeatureNode clone = (FeatureNode)this.clone();
|
|
629 |
FeatureNode childClone; |
|
597 |
public FeatureNode<T> cloneDescendants(){
|
|
598 |
FeatureNode<T> clone = (FeatureNode<T>)this.clone();
|
|
599 |
FeatureNode<T> childClone;
|
|
630 | 600 |
|
631 |
for(FeatureNode childNode : this.getChildNodes()){ |
|
632 |
childClone = (FeatureNode) childNode.clone(); |
|
633 |
for (FeatureNode childChild:childNode.getChildNodes()){ |
|
601 |
for(FeatureNode<T> childNode : this.getChildNodes()){
|
|
602 |
childClone = (FeatureNode<T>) childNode.clone();
|
|
603 |
for (FeatureNode<T> childChild:childNode.getChildNodes()){
|
|
634 | 604 |
childClone.addChild(childChild.cloneDescendants()); |
635 | 605 |
} |
636 | 606 |
clone.addChild(childClone); |
... | ... | |
653 | 623 |
*/ |
654 | 624 |
@Override |
655 | 625 |
public Object clone() { |
656 |
FeatureNode result; |
|
626 |
FeatureNode<T> result;
|
|
657 | 627 |
try { |
658 |
result = (FeatureNode)super.clone(); |
|
628 |
result = (FeatureNode<T>)super.clone();
|
|
659 | 629 |
result.children = new ArrayList<>(); |
660 | 630 |
return result; |
661 | 631 |
}catch (CloneNotSupportedException e) { |
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/FeatureTree.java | ||
---|---|---|
37 | 37 |
import org.hibernate.annotations.Type; |
38 | 38 |
import org.hibernate.envers.Audited; |
39 | 39 |
|
40 |
import eu.etaxonomy.cdm.model.common.DefinedTermBase; |
|
40 | 41 |
import eu.etaxonomy.cdm.model.common.IHasTermType; |
41 | 42 |
import eu.etaxonomy.cdm.model.common.IdentifiableEntity; |
42 | 43 |
import eu.etaxonomy.cdm.model.common.Representation; |
... | ... | |
76 | 77 |
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search |
77 | 78 |
//@Indexed(index = "eu.etaxonomy.cdm.model.description.FeatureTree") |
78 | 79 |
@Audited |
79 |
public class FeatureTree |
|
80 |
public class FeatureTree <T extends DefinedTermBase>
|
|
80 | 81 |
extends IdentifiableEntity<IIdentifiableEntityCacheStrategy> |
81 | 82 |
implements IHasTermType, Cloneable{ |
82 | 83 |
|
... | ... | |
84 | 85 |
private static final Logger logger = Logger.getLogger(FeatureTree.class); |
85 | 86 |
|
86 | 87 |
@XmlElement(name = "Root") |
87 |
@OneToOne(fetch = FetchType.LAZY) |
|
88 |
@OneToOne(fetch = FetchType.LAZY, targetEntity=FeatureNode.class)
|
|
88 | 89 |
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE}) |
89 |
private FeatureNode root; |
|
90 |
private FeatureNode<T> root;
|
|
90 | 91 |
|
91 | 92 |
/** |
92 | 93 |
* The {@link TermType type} of this term collection. All nodes in the graph must refer to a term of the same type. |
... | ... | |
126 | 127 |
* with an empty {@link #getRoot() root node}. |
127 | 128 |
* @param termType the {@link TermType term type}, must not be null |
128 | 129 |
*/ |
129 |
public static FeatureTree NewInstance(@NotNull TermType termType){
|
|
130 |
return new FeatureTree(termType); |
|
130 |
public static <T extends DefinedTermBase<T>> FeatureTree<T> NewInstance(@NotNull TermType termType){
|
|
131 |
return new FeatureTree<>(termType);
|
|
131 | 132 |
} |
132 | 133 |
|
133 | 134 |
/** |
... | ... | |
136 | 137 |
* @see #NewInstance(UUID) |
137 | 138 |
* @see #NewInstance(List) |
138 | 139 |
*/ |
139 |
public static FeatureTree NewInstance(){ |
|
140 |
return new FeatureTree(TermType.Feature); |
|
140 |
public static FeatureTree<Feature> NewInstance(){
|
|
141 |
return new FeatureTree<>(TermType.Feature);
|
|
141 | 142 |
} |
142 | 143 |
|
143 | 144 |
/** |
... | ... | |
149 | 150 |
* @see #NewInstance() |
150 | 151 |
* @see #NewInstance(List) |
151 | 152 |
*/ |
152 |
public static FeatureTree NewInstance(UUID uuid){
|
|
153 |
FeatureTree result = new FeatureTree(TermType.Feature);
|
|
153 |
public static <T extends DefinedTermBase<T>> FeatureTree<T> NewInstance(UUID uuid){
|
|
154 |
FeatureTree<T> result = new FeatureTree<>(TermType.Feature);
|
|
154 | 155 |
result.setUuid(uuid); |
155 | 156 |
return result; |
156 | 157 |
} |
... | ... | |
166 | 167 |
* @see #NewInstance() |
167 | 168 |
* @see #NewInstance(UUID) |
168 | 169 |
*/ |
169 |
public static FeatureTree NewInstance(List<Feature> featureList){ |
|
170 |
FeatureTree result = new FeatureTree(TermType.Feature);
|
|
171 |
FeatureNode root = result.getRoot(); |
|
170 |
public static FeatureTree<Feature> NewInstance(List<Feature> featureList){
|
|
171 |
FeatureTree<Feature> result = new FeatureTree<>(TermType.Feature);
|
|
172 |
FeatureNode<Feature> root = result.getRoot();
|
|
172 | 173 |
|
173 | 174 |
for (Feature feature : featureList){ |
174 |
FeatureNode child = FeatureNode.NewInstance(feature); |
|
175 |
FeatureNode<Feature> child = FeatureNode.NewInstance(feature);
|
|
175 | 176 |
root.addChild(child); |
176 | 177 |
} |
177 | 178 |
|
... | ... | |
208 | 209 |
* recursively point to their child nodes the complete feature tree is |
209 | 210 |
* defined by its root node. |
210 | 211 |
*/ |
211 |
public FeatureNode getRoot() { |
|
212 |
public FeatureNode<T> getRoot() {
|
|
212 | 213 |
return root; |
213 | 214 |
} |
214 | 215 |
|
... | ... | |
226 | 227 |
* children of the root node of <i>this</i> feature tree. |
227 | 228 |
*/ |
228 | 229 |
@Transient |
229 |
public List<FeatureNode> getRootChildren(){ |
|
230 |
List<FeatureNode> result = new ArrayList<>(); |
|
230 |
public List<FeatureNode<T>> getRootChildren(){
|
|
231 |
List<FeatureNode<T>> result = new ArrayList<>();
|
|
231 | 232 |
result.addAll(root.getChildNodes()); |
232 | 233 |
return result; |
233 | 234 |
} |
... | ... | |
251 | 252 |
//******************** METHODS ***********************************************/ |
252 | 253 |
|
253 | 254 |
/** |
254 |
* Computes a set of distinct features that are present in this feature tree
|
|
255 |
* Computes a set of distinct terms that are present in this feature tree
|
|
255 | 256 |
* |
256 | 257 |
* @return |
257 | 258 |
*/ |
258 | 259 |
@Transient |
259 |
public Set<Feature> getDistinctFeatures(){
|
|
260 |
public Set<T> getDistinctFeatures(){
|
|
260 | 261 |
if(termType.equals(TermType.Feature) || termType.isKindOf(TermType.Feature)){ |
261 |
Set<Feature> features = new HashSet<>();
|
|
262 |
Set<T> features = new HashSet<>();
|
|
262 | 263 |
return root.getDistinctFeaturesRecursive(features); |
263 | 264 |
} |
264 | 265 |
String message = "FeatureTree is not of type FEATURE."; |
... | ... | |
281 | 282 |
*/ |
282 | 283 |
@Override |
283 | 284 |
public Object clone() { |
284 |
FeatureTree result; |
|
285 |
FeatureTree<T> result;
|
|
285 | 286 |
try { |
286 |
result = (FeatureTree)super.clone(); |
|
287 |
result = (FeatureTree<T>)super.clone();
|
|
287 | 288 |
}catch (CloneNotSupportedException e) { |
288 | 289 |
logger.warn("Object does not implement cloneable"); |
289 | 290 |
e.printStackTrace(); |
290 | 291 |
return null; |
291 | 292 |
} |
292 |
FeatureNode rootClone = this.getRoot().cloneDescendants(); |
|
293 |
FeatureNode<T> rootClone = this.getRoot().cloneDescendants();
|
|
293 | 294 |
result.root = rootClone; |
294 | 295 |
|
295 | 296 |
return result; |
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/generate/PolytomousKeyGenerator.java | ||
---|---|---|
806 | 806 |
* |
807 | 807 |
* @param node |
808 | 808 |
*/ |
809 |
private void checkDependencies(FeatureNode node){ |
|
809 |
private void checkDependencies(FeatureNode<Feature> node){
|
|
810 | 810 |
if (node.getOnlyApplicableIf()!=null){ |
811 | 811 |
Set<State> addToOAI = node.getOnlyApplicableIf(); |
812 | 812 |
for (State state : addToOAI){ |
813 | 813 |
if (oAIdependencies.containsKey(state)) { |
814 | 814 |
oAIdependencies.put(state, new HashSet<Feature>()); |
815 | 815 |
} |
816 |
oAIdependencies.get(state).add(node.getFeature());
|
|
816 |
oAIdependencies.get(state).add(node.getTerm());
|
|
817 | 817 |
} |
818 | 818 |
} |
819 | 819 |
if (node.getInapplicableIf()!=null){ |
... | ... | |
822 | 822 |
if (iIdependencies.containsKey(state)) { |
823 | 823 |
iIdependencies.put(state, new HashSet<Feature>()); |
824 | 824 |
} |
825 |
iIdependencies.get(state).add(node.getFeature());
|
|
825 |
iIdependencies.get(state).add(node.getTerm());
|
|
826 | 826 |
} |
827 | 827 |
} |
828 | 828 |
if (node.getChildNodes()!=null) { |
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/PostMergeEntityListener.java | ||
---|---|---|
102 | 102 |
|
103 | 103 |
} else if(FeatureTree.class.isAssignableFrom(entityClazz)){ |
104 | 104 |
|
105 |
FeatureTree tree = (FeatureTree)entity; |
|
106 |
for (FeatureNode node:tree.getRootChildren()){ |
|
105 |
FeatureTree<?> tree = (FeatureTree)entity;
|
|
106 |
for (FeatureNode<?> node:tree.getRootChildren()){
|
|
107 | 107 |
node.removeNullValueFromChildren(); |
108 | 108 |
if (node.getChildNodes() != null){ |
109 | 109 |
for (FeatureNode childNode: node.getChildNodes()){ |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/DescriptiveDataSetService.java | ||
---|---|---|
452 | 452 |
DescriptiveDataSet dataSet = load(descriptiveDataSetUuid); |
453 | 453 |
SpecimenOrObservationBase specimen = occurrenceService.load(specimenUuid); |
454 | 454 |
|
455 |
Set<Feature> datasetFeatures = dataSet.getDescriptiveSystem().getDistinctFeatures();
|
|
455 |
Set<Character> datasetFeatures = dataSet.getDescriptiveSystem().getDistinctFeatures();
|
|
456 | 456 |
List<DescriptionElementBase> matchingDescriptionElements = new ArrayList<>(); |
457 | 457 |
|
458 | 458 |
for (SpecimenDescription specimenDescription : (Set<SpecimenDescription>) specimen.getDescriptions()) { |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/NaturalLanguageGenerator.java | ||
---|---|---|
11 | 11 |
import org.apache.log4j.Logger; |
12 | 12 |
import org.springframework.stereotype.Component; |
13 | 13 |
|
14 |
import eu.etaxonomy.cdm.model.common.Annotation; |
|
15 |
import eu.etaxonomy.cdm.model.common.AnnotationType; |
|
16 |
import eu.etaxonomy.cdm.model.common.Language; |
|
14 | 17 |
import eu.etaxonomy.cdm.model.description.CategoricalData; |
15 | 18 |
import eu.etaxonomy.cdm.model.description.DescriptionElementBase; |
16 | 19 |
import eu.etaxonomy.cdm.model.description.Feature; |
... | ... | |
20 | 23 |
import eu.etaxonomy.cdm.model.description.TaxonDescription; |
21 | 24 |
import eu.etaxonomy.cdm.model.description.TextData; |
22 | 25 |
import eu.etaxonomy.cdm.model.description.TextFormat; |
23 |
import eu.etaxonomy.cdm.model.common.Annotation; |
|
24 |
import eu.etaxonomy.cdm.model.common.AnnotationType; |
|
25 |
import eu.etaxonomy.cdm.model.common.Language; |
|
26 | 26 |
|
27 | 27 |
|
28 | 28 |
/** |
29 | 29 |
* Generator of natural language descriptions from TaxonDescriptions. |
30 |
*
|
|
30 |
* |
|
31 | 31 |
* @author m.venin |
32 | 32 |
* @since 13.04.2010 |
33 | 33 |
* @version 1.0 |
... | ... | |
45 | 45 |
private DescriptionBuilder<CategoricalData> categoricalDescriptionBuilder = new DefaultCategoricalDescriptionBuilder(); |
46 | 46 |
|
47 | 47 |
private TextData previousTextData; |
48 |
|
|
48 |
|
|
49 | 49 |
DeltaTextDataProcessor deltaTextDataProcessor = new DeltaTextDataProcessor(); |
50 | 50 |
|
51 | 51 |
private Map<String, INaturalLanguageTextDataProcessor> elementProcessors; |
... | ... | |
54 | 54 |
|
55 | 55 |
/** |
56 | 56 |
* Change the first separator used by generateSingleTextData. By default ",". |
57 |
*
|
|
57 |
* |
|
58 | 58 |
* @param separator |
59 | 59 |
*/ |
60 | 60 |
public void setFirstSeparator(String separator){ |
... | ... | |
67 | 67 |
|
68 | 68 |
/** |
69 | 69 |
* Change the second separator used by generateSingleTextData. By default ".". |
70 |
*
|
|
70 |
* |
|
71 | 71 |
* @param separator |
72 | 72 |
*/ |
73 | 73 |
public void setSecondSeparator(String separator){ |
... | ... | |
103 | 103 |
* The keys of the elementProcessors map are regular expressions which are |
104 | 104 |
* being used to identify the those Descriptions to which the mapped |
105 | 105 |
* NaturalLanguageTextDataProcessor is applicable. |
106 |
*
|
|
106 |
* |
|
107 | 107 |
* @param elementProcessors |
108 | 108 |
*/ |
109 | 109 |
public void setElementProcessors( |
... | ... | |
115 | 115 |
* Looks for technical annotations, if one matches a regular expression of the element processors |
116 | 116 |
* the associated processor is added to the applicable element processors which will then be applied |
117 | 117 |
* when generating the description. |
118 |
*
|
|
118 |
* |
|
119 | 119 |
* @param annotations the set of annotations of the description |
120 | 120 |
*/ |
121 | 121 |
private void initNaturalLanguageDescriptionElementProcessors(Set<Annotation> annotations) { |
... | ... | |
138 | 138 |
|
139 | 139 |
/** |
140 | 140 |
* Applies the list of applicable processors to a TextData. |
141 |
*
|
|
141 |
* |
|
142 | 142 |
* @param textData the TextData to be modified |
143 | 143 |
* @param previousTextData the TextData corresponding to the feature of the previous level in the tree |
144 | 144 |
*/ |
... | ... | |
151 | 151 |
|
152 | 152 |
/** |
153 | 153 |
* The most simple function to generate a description. The language used is the default one. |
154 |
*
|
|
154 |
* |
|
155 | 155 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
156 | 156 |
* @param description the TaxonDescription with all the data |
157 |
*
|
|
157 |
* |
|
158 | 158 |
* @return a list of TextData, each one being a basic element of the natural language description |
159 | 159 |
*/ |
160 |
public List<TextData> generateNaturalLanguageDescription(FeatureTree featureTree,TaxonDescription description) { |
|
160 |
@Override |
|
161 |
public List<TextData> generateNaturalLanguageDescription(FeatureTree featureTree,TaxonDescription description) { |
|
161 | 162 |
return generateNaturalLanguageDescription(featureTree,description,Language.DEFAULT()); |
162 | 163 |
} |
163 | 164 |
|
... | ... | |
165 | 166 |
|
166 | 167 |
/** |
167 | 168 |
* Generate a description in a specified language. |
168 |
*
|
|
169 |
* |
|
169 | 170 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
170 | 171 |
* @param description the TaxonDescription with all the data |
171 | 172 |
* @param language the language in which the description has to be printed |
172 |
*
|
|
173 |
* |
|
173 | 174 |
* @return a list of TextData, each one being a basic element of the natural language description |
174 | 175 |
*/ |
175 |
public List<TextData> generateNaturalLanguageDescription(FeatureTree featureTree, TaxonDescription description, Language language) { |
|
176 |
@Override |
|
177 |
public List<TextData> generateNaturalLanguageDescription(FeatureTree featureTree, TaxonDescription description, Language language) { |
|
176 | 178 |
List<Language> languages = new ArrayList<Language>(); |
177 | 179 |
languages.add(language); |
178 | 180 |
initNaturalLanguageDescriptionElementProcessors(description.getAnnotations()); |
... | ... | |
181 | 183 |
|
182 | 184 |
/** |
183 | 185 |
* Generate a description with a specified list of preferred languages. |
184 |
*
|
|
186 |
* |
|
185 | 187 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
186 | 188 |
* @param description the TaxonDescription with all the data |
187 | 189 |
* @param languages the ordered list of languages preferred for printing the description |
188 |
*
|
|
190 |
* |
|
189 | 191 |
* @return a list of TextData, each one being a basic element of the natural language description |
190 | 192 |
*/ |
191 |
public List<TextData> generatePreferredNaturalLanguageDescription(FeatureTree featureTree,TaxonDescription description, List<Language> languages) { |
|
193 |
@Override |
|
194 |
public List<TextData> generatePreferredNaturalLanguageDescription(FeatureTree featureTree,TaxonDescription description, List<Language> languages) { |
|
192 | 195 |
initNaturalLanguageDescriptionElementProcessors(description.getAnnotations()); |
193 | 196 |
return buildBranchesDescr(featureTree.getRootChildren(), featureTree.getRoot(), description, languages,0); |
194 | 197 |
} |
195 | 198 |
|
196 | 199 |
/** |
197 | 200 |
* Generate a description as a single paragraph in a TextData. |
198 |
*
|
|
201 |
* |
|
199 | 202 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
200 | 203 |
* @param description the TaxonDescription with all the data |
201 |
*
|
|
204 |
* |
|
202 | 205 |
* @return a TextData in the default language. |
203 | 206 |
*/ |
204 |
public TextData generateSingleTextData(FeatureTree featureTree, TaxonDescription description) { |
|
207 |
@Override |
|
208 |
public TextData generateSingleTextData(FeatureTree featureTree, TaxonDescription description) { |
|
205 | 209 |
return generateSingleTextData(featureTree,description,Language.DEFAULT()); |
206 | 210 |
} |
207 | 211 |
|
208 | 212 |
/** |
209 | 213 |
* Generate a description as a single paragraph in a TextData. |
210 |
*
|
|
214 |
* |
|
211 | 215 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
212 | 216 |
* @param description the TaxonDescription with all the data |
213 | 217 |
* @param language the language in which the description has to be printed |
214 |
*
|
|
218 |
* |
|
215 | 219 |
* @return a TextData in the specified language. |
216 | 220 |
*/ |
217 |
public TextData generateSingleTextData(FeatureTree featureTree, TaxonDescription description, Language language) { |
|
221 |
@Override |
|
222 |
public TextData generateSingleTextData(FeatureTree featureTree, TaxonDescription description, Language language) { |
|
218 | 223 |
List<Language> languages = new ArrayList<Language>(); |
219 | 224 |
languages.add(language); |
220 | 225 |
return generatePreferredSingleTextData(featureTree,description,languages); |
... | ... | |
222 | 227 |
|
223 | 228 |
/** |
224 | 229 |
* Generate a description with a specified list of preferred languages. |
225 |
*
|
|
230 |
* |
|
226 | 231 |
* @param featureTree the FeatureTree holding the order in which features and their states must be printed |
227 | 232 |
* @param description the TaxonDescription with all the data |
228 | 233 |
* @param languages the ordered list of languages preferred for printing the description |
229 |
*
|
|
234 |
* |
|
230 | 235 |
* @return a TextData using the languages (in the given order of preference) |
231 | 236 |
*/ |
232 |
public TextData generatePreferredSingleTextData(FeatureTree featureTree, TaxonDescription description, List<Language> languages) { |
|
237 |
@Override |
|
238 |
public TextData generatePreferredSingleTextData(FeatureTree featureTree, TaxonDescription description, List<Language> languages) { |
|
233 | 239 |
levels.clear(); // before the start, the table containing the levels of each node must be cleared |
234 | 240 |
// Note: this is not the most efficient way to keep track of the levels of the nodes but it allows some flexibility |
235 | 241 |
List<TextData> texts = generatePreferredNaturalLanguageDescription(featureTree,description, languages);// first get the description as a raw list of TextData |
... | ... | |
246 | 252 |
startSentence=true; |
247 | 253 |
firstOne=false; |
248 | 254 |
String asString = texts.get(i).getText(Language.DEFAULT()).toString(); |
249 |
if (asString.length()>1) descriptionStringBuilder.append(asString.substring(0,1).toUpperCase() + asString.substring(1)); |
|
255 |
if (asString.length()>1) { |
|
256 |
descriptionStringBuilder.append(asString.substring(0,1).toUpperCase() + asString.substring(1)); |
|
257 |
} |
|
250 | 258 |
} |
251 | 259 |
i++; |
252 | 260 |
} |
253 | 261 |
else if (level==0) { // if this node is a leaf |
254 |
if (startSentence) descriptionStringBuilder.append(texts.get(i).getText(Language.DEFAULT())); |
|
255 |
else descriptionStringBuilder.append(firstSeparator + texts.get(i).getText(Language.DEFAULT())); |
|
262 |
if (startSentence) { |
|
263 |
descriptionStringBuilder.append(texts.get(i).getText(Language.DEFAULT())); |
|
264 |
} else { |
|
265 |
descriptionStringBuilder.append(firstSeparator + texts.get(i).getText(Language.DEFAULT())); |
|
266 |
} |
|
256 | 267 |
startSentence=false; |
257 | 268 |
i++; |
258 | 269 |
} |
259 | 270 |
else { |
260 | 271 |
if (!firstOne && levels.get(j-1).equals(0)){ // if this node corresponds to the states linked to the previous leaf |
261 |
if (i<texts.size()) descriptionStringBuilder.append(texts.get(i).getText(Language.DEFAULT())); |
|
272 |
if (i<texts.size()) { |
|
273 |
descriptionStringBuilder.append(texts.get(i).getText(Language.DEFAULT())); |
|
274 |
} |
|
262 | 275 |
i++; |
263 | 276 |
} |
264 | 277 |
} |
... | ... | |
274 | 287 |
|
275 | 288 |
/** recursive function that goes through a tree containing the order in which the description has to be generated, |
276 | 289 |
* if an element of this tree matches one of the TaxonDescription, a DescriptionBuilder is called which returns a TextData with the corresponding description. |
277 |
*
|
|
290 |
* |
|
278 | 291 |
* @param children the children of the feature node considered |
279 | 292 |
* @param parent the feature node considered |
280 | 293 |
* @param description the TaxonDescription element for which we want a natural language output |
... | ... | |
282 | 295 |
* @param floor integer to keep track of the level in the tree |
283 | 296 |
* @return a list of TextData elements containing the part of description corresponding to the feature node considered |
284 | 297 |
*/ |
285 |
private List<TextData> buildBranchesDescr(List<FeatureNode> children, FeatureNode parent, TaxonDescription description, List<Language> languages, int floor) { |
|
298 |
private List<TextData> buildBranchesDescr(List<FeatureNode> children, FeatureNode<Feature> parent, TaxonDescription description, List<Language> languages, int floor) {
|
|
286 | 299 |
List<TextData> listTextData = new ArrayList<TextData>(); |
287 | 300 |
floor++; // counter to know the current level in the tree |
288 | 301 |
|
289 | 302 |
if (!parent.isLeaf()){ // if this node is not a leaf, continue recursively (only the leaves of a FeatureTree contain states) |
290 | 303 |
levels.add(new Integer(floor)); // the level of the different nodes in the tree are kept, thus it is easier to build a structured text out of the List<TextData> |
291 |
Feature feature = parent.getFeature();
|
|
304 |
Feature feature = parent.getTerm();
|
|
292 | 305 |
TextData featureName; |
293 | 306 |
if (feature!=null && feature.getLabel()!=null){ // if a node is associated to a feature |
294 | 307 |
featureName = categoricalDescriptionBuilder.buildTextDataFeature(feature, languages); |
295 | 308 |
levels.add(new Integer(-1)); // it is indicated by a '-1' after its level |
296 | 309 |
listTextData.add(featureName); // the TextData representing the name of the feature is concatenated to the list |
297 | 310 |
} |
298 |
else featureName = new TextData(); // else an empty TextData is created (because we keep track of the features, it is useful to inform when the upper node has no feature attached) |
|
311 |
else { |
|
312 |
featureName = new TextData(); // else an empty TextData is created (because we keep track of the features, it is useful to inform when the upper node has no feature attached) |
|
313 |
} |
|
299 | 314 |
|
300 | 315 |
for (Iterator<FeatureNode> ifn = children.iterator() ; ifn.hasNext() ;){ |
301 | 316 |
previousTextData = featureName; // this allows to keep track of the name of the feature one level up in the tree |
... | ... | |
304 | 319 |
} |
305 | 320 |
} |
306 | 321 |
else { //once a leaf is reached |
307 |
Feature feature = parent.getFeature();
|
|
322 |
Feature feature = parent.getTerm();
|
|
308 | 323 |
if (feature!=null && (feature.isSupportsQuantitativeData() || feature.isSupportsCategoricalData())) { |
309 | 324 |
Set<DescriptionElementBase> elements = description.getElements(); |
310 | 325 |
for (Iterator<DescriptionElementBase> deb = elements.iterator() ; deb.hasNext() ;){ // iterates over all the descriptions enclosed in the TaxonDescription |
... | ... | |
334 | 349 |
} |
335 | 350 |
} |
336 | 351 |
return listTextData; |
337 |
}
|
|
352 |
} |
|
338 | 353 |
|
339 | 354 |
} |
Also available in: Unified diff
ref #6794 Add generics to FeatureNode and FeatureTree