2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.description
;
12 import java
.util
.ArrayList
;
13 import java
.util
.HashSet
;
14 import java
.util
.List
;
16 import java
.util
.UUID
;
18 import javax
.persistence
.Entity
;
19 import javax
.persistence
.FetchType
;
20 import javax
.persistence
.OneToOne
;
21 import javax
.persistence
.Transient
;
22 import javax
.xml
.bind
.annotation
.XmlAccessType
;
23 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
24 import javax
.xml
.bind
.annotation
.XmlElement
;
25 import javax
.xml
.bind
.annotation
.XmlRootElement
;
26 import javax
.xml
.bind
.annotation
.XmlType
;
28 import org
.apache
.log4j
.Logger
;
29 import org
.hibernate
.annotations
.Cascade
;
30 import org
.hibernate
.annotations
.CascadeType
;
31 import org
.hibernate
.envers
.Audited
;
32 import org
.hibernate
.search
.annotations
.Indexed
;
34 import eu
.etaxonomy
.cdm
.model
.common
.TermBase
;
37 * The class to arrange {@link Feature features} (characters) in a tree structure.
38 * Feature trees are essential as interactive multiple-access keys for
39 * determination process and for systematical output arrangement of
40 * {@link DescriptionElementBase description elements} according to different goals but may also be used
41 * to define flat feature subsets for filtering purposes.<BR>
42 * A feature tree is build on {@link FeatureNode feature nodes}.
44 * This class corresponds partially to ConceptTreeDefType according to the SDD
47 * Note: The tree structure of features used for purposes described above has
48 * nothing in common with the possible hierarchical structure of features
49 * depending on their grade of precision.
54 * @created 08-Nov-2007 13:06:16
56 @XmlAccessorType(XmlAccessType
.FIELD
)
57 @XmlType(name
= "FeatureTree", propOrder
= {
58 "descriptionSeparated",
61 @XmlRootElement(name
= "FeatureTree")
63 @Indexed(index
= "eu.etaxonomy.cdm.model.description.FeatureTree")
65 public class FeatureTree
extends TermBase
implements Cloneable
{
66 private static final long serialVersionUID
= -6713834139003172735L;
67 @SuppressWarnings("unused")
68 private static final Logger logger
= Logger
.getLogger(FeatureTree
.class);
69 //private Set<FeatureNode> nodes = new HashSet<FeatureNode>();
71 @XmlElement(name
= "Root")
72 @OneToOne(fetch
= FetchType
.LAZY
)
73 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
})
74 private FeatureNode root
;
76 @XmlElement(name
= "IsDescriptionSeparated")
77 private boolean descriptionSeparated
= false;
80 * Class constructor: creates a new feature tree instance with an empty
81 * {@link #getRoot() root node}.
83 protected FeatureTree() {
85 root
= FeatureNode
.NewInstance();
86 root
.setFeatureTree(this);
90 * Creates a new feature tree instance with an empty {@link #getRoot() root node}.
92 * @see #NewInstance(UUID)
93 * @see #NewInstance(List)
95 public static FeatureTree
NewInstance(){
96 return new FeatureTree();
100 * Creates a new feature tree instance with an empty {@link #getRoot() root node}
101 * and assigns to the new feature tree the given
102 * UUID (universally unique identifier).
104 * @param uuid the universally unique identifier
105 * @see #NewInstance()
106 * @see #NewInstance(List)
108 public static FeatureTree
NewInstance(UUID uuid
){
109 FeatureTree result
= new FeatureTree();
110 result
.setUuid(uuid
);
115 * Creates a new feature tree instance with a {@link #getRoot() root node}
116 * the children of which are the feature nodes build on the base of the
117 * given list of {@link Feature features}. This corresponds to a flat feature tree.
118 * For each feature within the list a new {@link FeatureNode feature node} without
119 * children nodes will be created.
121 * @param featureList the feature list
122 * @see #NewInstance()
123 * @see #NewInstance(UUID)
125 public static FeatureTree
NewInstance(List
<Feature
> featureList
){
126 FeatureTree result
= new FeatureTree();
127 FeatureNode root
= result
.getRoot();
129 for (Feature feature
: featureList
){
130 FeatureNode child
= FeatureNode
.NewInstance(feature
);
131 root
.addChild(child
);
137 // Delete the isDescriptionSeparated flag ??
139 * Returns the boolean value of the flag indicating whether the
140 * {@link DescriptionElementBase description elements} associated with the {@link Feature features}
141 * belonging to <i>this</i> feature tree should be treated separately (true)
144 * @return the boolean value of the isDescriptionSeparated flag
146 public boolean isDescriptionSeparated() {
147 return descriptionSeparated
;
151 * @see #isDescriptionSeparated()
153 public void setDescriptionSeparated(boolean descriptionSeperated
) {
154 this.descriptionSeparated
= descriptionSeperated
;
158 // @Cascade({CascadeType.SAVE_UPDATE})
159 // public Set<FeatureNode> getNodes() {
162 // public void setNodes(Set<FeatureNode> nodes) {
163 // this.nodes = nodes;
167 * Returns the topmost {@link FeatureNode feature node} (root node) of <i>this</i>
168 * feature tree. The root node does not have any parent. Since feature nodes
169 * recursively point to their child nodes the complete feature tree is
170 * defined by its root node.
172 public FeatureNode
getRoot() {
178 public void setRoot(FeatureNode root
) {
183 * Returns the (ordered) list of {@link FeatureNode feature nodes} which are immediate
184 * children of the root node of <i>this</i> feature tree.
187 public List
<FeatureNode
> getRootChildren(){
188 List
<FeatureNode
> result
= new ArrayList
<FeatureNode
>();
189 result
.addAll(root
.getChildren());
194 * Computes a set of distinct features that are present in this feature tree
199 public Set
<Feature
> getDistinctFeatures(){
200 Set
<Feature
> features
= new HashSet
<Feature
>();
202 return root
.getDistinctFeaturesRecursive(features
);
205 //*********************** CLONE ********************************************************/
208 * Clones <i>this</i> FeatureTree. This is a shortcut that enables to create
209 * a new instance that differs only slightly from <i>this</i> FeatureTree by
210 * modifying only some of the attributes.
211 * FeatureNodes always belong only to one tree, so all FeatureNodes are cloned to build
212 * the new FeatureTree
215 * @see eu.etaxonomy.cdm.model.common.TermBase#clone()
216 * @see java.lang.Object#clone()
220 public Object
clone() {
223 result
= (FeatureTree
)super.clone();
224 }catch (CloneNotSupportedException e
) {
225 logger
.warn("Object does not implement cloneable");
229 FeatureNode rootClone
= (FeatureNode
)this.getRoot().cloneDescendants();
230 result
.root
= rootClone
;