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
.List
;
15 import javax
.persistence
.Entity
;
16 import javax
.persistence
.JoinColumn
;
17 import javax
.persistence
.ManyToOne
;
18 import javax
.persistence
.OneToMany
;
19 import javax
.persistence
.Transient
;
20 import javax
.swing
.tree
.TreeNode
;
21 import javax
.xml
.bind
.annotation
.XmlAccessType
;
22 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
23 import javax
.xml
.bind
.annotation
.XmlElement
;
24 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
25 import javax
.xml
.bind
.annotation
.XmlIDREF
;
26 import javax
.xml
.bind
.annotation
.XmlRootElement
;
27 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
28 import javax
.xml
.bind
.annotation
.XmlType
;
30 import org
.apache
.log4j
.Logger
;
31 import org
.hibernate
.annotations
.Cascade
;
32 import org
.hibernate
.annotations
.CascadeType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.VersionableEntity
;
35 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
38 * The class for tree nodes within a {@link FeatureTree feature tree} structure.
39 * Feature nodes are the elementary components of such a tree since they might
40 * be related to other nodes as a parent or as a child. A feature node belongs
41 * at most to one feature tree. It cannot have more than one parent node but
42 * may have several child nodes. Parent/child relations are bidirectional:
43 * a node N1 is the parent of a node N2 if and only if the node N2 is a child of
48 * @created 08-Nov-2007 13:06:16
50 @XmlAccessorType(XmlAccessType
.FIELD
)
51 @XmlType(name
= "FeatureNode", propOrder
= {
57 @XmlRootElement(name
= "FeatureNode")
59 public class FeatureNode
extends VersionableEntity
{
60 static Logger logger
= Logger
.getLogger(FeatureNode
.class);
62 @XmlElement(name
= "Feature")
64 @XmlSchemaType(name
= "IDREF")
65 private Feature feature
;
67 // @XmlElement(name = "FeatureType")
69 // @XmlSchemaType(name = "IDREF")
70 // private Feature type;
72 @XmlElement(name
= "Parent")
74 @XmlSchemaType(name
= "IDREF")
75 private FeatureNode parent
;
77 @XmlElementWrapper(name
= "Children")
78 @XmlElement(name
= "Child")
80 @XmlSchemaType(name
= "IDREF")
81 private List
<FeatureNode
> children
= new ArrayList
<FeatureNode
>();
84 * Class constructor: creates a new empty feature node instance.
86 protected FeatureNode() {
91 * Creates a new empty feature node instance.
93 * @see #NewInstance(Feature)
95 public static FeatureNode
NewInstance(){
96 return new FeatureNode();
100 * Creates a new feature node instance only with the given {@link Feature feature}
101 * (without parent and children).
103 * @param feature the feature assigned to the new feature node
104 * @see #NewInstance()
106 public static FeatureNode
NewInstance(Feature feature
){
107 FeatureNode result
= new FeatureNode();
108 result
.setFeature(feature
);
115 //** ********************** FEATURE ******************************/
117 // * Does the same as getFeature
121 // protected Feature getType() {
125 // * Does the same as setFeature
127 // protected void setType(Feature feature) {
128 // this.feature = feature;
132 * Returns the {@link Feature feature} <i>this</i> feature node is based on.
135 public Feature
getFeature() {
141 public void setFeature(Feature feature
) {
142 this.feature
= feature
;
146 //** ********************** PARENT ******************************/
150 * Returns the feature node <i>this</i> feature node is a child of.
152 * @see #getChildren()
155 @JoinColumn(name
="parent_fk")
156 @Cascade({CascadeType
.SAVE_UPDATE
})
157 public FeatureNode
getParent() {
161 * Assigns the given feature node as the parent of <i>this</i> feature node.
162 * Due to bidirectionality this method must also add <i>this</i> feature node
163 * to the list of children of the given parent.
165 * @param parent the feature node to be set as parent
168 protected void setParent(FeatureNode parent
) {
169 this.parent
= parent
;
172 //** ********************** CHILDREN ******************************/
175 * Returns the (ordered) list of feature nodes which are children nodes of
176 * <i>this</i> feature node.
178 @OneToMany(mappedBy
="parent")
179 @Cascade({CascadeType
.SAVE_UPDATE
})
180 public List
<FeatureNode
> getChildren() {
184 * Assigns the given feature node list as the list of children of
185 * <i>this</i> feature node. Due to bidirectionality this method must also
186 * add <i>this</i> feature node to the list of children of the given parent.
188 * @param children the feature node list to be set as child list
189 * @see #getChildren()
190 * @see #addChild(FeatureNode)
191 * @see #addChild(FeatureNode, int)
193 public void setChildren(List
<FeatureNode
> children
) {
194 this.children
= children
;
197 * Adds the given feature node at the end of the list of children of
198 * <i>this</i> feature node. Due to bidirectionality this method must also
199 * assign <i>this</i> feature node as the parent of the given child.
201 * @param child the feature node to be added
202 * @see #getChildren()
203 * @see #setChildren(List)
204 * @see #addChild(FeatureNode, int)
205 * @see #removeChild(FeatureNode)
206 * @see #removeChild(int)
208 public void addChild(FeatureNode child
){
209 addChild(child
, children
.size());
212 * Inserts the given feature node in the list of children of <i>this</i> feature node
213 * at the given (index + 1) position. If the given index is out of bounds
214 * an exception will arise.<BR>
215 * Due to bidirectionality this method must also assign <i>this</i> feature node
216 * as the parent of the given child.
218 * @param child the feature node to be added
219 * @param index the integer indicating the position at which the child
221 * @see #getChildren()
222 * @see #setChildren(List)
223 * @see #addChild(FeatureNode)
224 * @see #removeChild(FeatureNode)
225 * @see #removeChild(int)
227 public void addChild(FeatureNode child
, int index
){
228 if (index
< 0 || index
> children
.size() + 1){
229 throw new IndexOutOfBoundsException("Wrong index");
231 if (child
.getParent() != null){
232 child
.getParent().removeChild(child
);
234 child
.setParent(this);
235 children
.add(index
, child
);
238 * Removes the given feature node from the list of {@link #getChildren() children}
239 * of <i>this</i> feature node.
241 * @param child the feature node which should be removed
242 * @see #getChildren()
243 * @see #addChild(FeatureNode, int)
244 * @see #addChild(FeatureNode)
245 * @see #removeChild(int)
247 public void removeChild(FeatureNode child
){
248 int index
= children
.indexOf(child
);
254 * Removes the feature node placed at the given (index + 1) position from
255 * the list of {@link #getChildren() children} of <i>this</i> feature node.
256 * If the given index is out of bounds no child will be removed.
258 * @param index the integer indicating the position of the feature node to
260 * @see #getChildren()
261 * @see #addChild(FeatureNode, int)
262 * @see #addChild(FeatureNode)
263 * @see #removeChild(FeatureNode)
265 public void removeChild(int index
){
266 FeatureNode child
= children
.get(index
);
268 children
.remove(index
);
269 child
.setParent(child
);
275 * Returns the feature node placed at the given (childIndex + 1) position
276 * within the list of {@link #getChildren() children} of <i>this</i> feature node.
277 * If the given index is out of bounds no child will be returned.
279 * @param childIndex the integer indicating the position of the feature node
280 * @see #getChildren()
281 * @see #addChild(FeatureNode, int)
282 * @see #removeChild(int)
285 public FeatureNode
getChildAt(int childIndex
) {
286 return children
.get(childIndex
);
290 * Returns the number of children nodes of <i>this</i> feature node.
292 * @see #getChildren()
295 public int getChildCount() {
296 return children
.size();
300 * Returns the integer indicating the position of the given feature node
301 * within the list of {@link #getChildren() children} of <i>this</i> feature node.
302 * If the list does not contain this node then -1 will be returned.
304 * @param node the feature node the position of which is being searched
305 * @see #addChild(FeatureNode, int)
306 * @see #removeChild(int)
309 // public int getIndex(TreeNode node) {
310 public int getIndex(FeatureNode node
) {
311 if (! children
.contains(node
)){
314 return children
.indexOf(node
);
319 * Returns the boolean value indicating if <i>this</i> feature node has
320 * children (false) or not (true). A node without children is at the
321 * bottommost level of a tree and is called a leaf.
323 * @see #getChildren()
324 * @see #getChildCount()
327 public boolean isLeaf() {
328 return children
.size() < 1;