root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/FeatureTree.java

Revision 11650, 7.0 kB (checked in by k.luther, 14 months ago)
  • Property svn:keywords set to Id
Line 
1/**
2* Copyright (C) 2007 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
10package eu.etaxonomy.cdm.model.description;
11
12import java.util.ArrayList;
13import java.util.HashSet;
14import java.util.List;
15import java.util.Set;
16import java.util.UUID;
17
18import javax.persistence.Entity;
19import javax.persistence.FetchType;
20import javax.persistence.OneToOne;
21import javax.persistence.Transient;
22import javax.xml.bind.annotation.XmlAccessType;
23import javax.xml.bind.annotation.XmlAccessorType;
24import javax.xml.bind.annotation.XmlElement;
25import javax.xml.bind.annotation.XmlRootElement;
26import javax.xml.bind.annotation.XmlType;
27
28import org.apache.log4j.Logger;
29import org.hibernate.annotations.Cascade;
30import org.hibernate.annotations.CascadeType;
31import org.hibernate.envers.Audited;
32import org.hibernate.search.annotations.Indexed;
33
34import eu.etaxonomy.cdm.model.common.TermBase;
35
36/**
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}.
43 * <P>
44 * This class corresponds partially to ConceptTreeDefType according to the SDD
45 * schema.
46 * <P>
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. 
50 * 
51 * @see         MediaKey
52 * @author  m.doering
53 * @version 1.0
54 * @created 08-Nov-2007 13:06:16
55 */
56@XmlAccessorType(XmlAccessType.FIELD)
57@XmlType(name = "FeatureTree", propOrder = {
58    "descriptionSeparated",
59    "root"
60})
61@XmlRootElement(name = "FeatureTree")
62@Entity
63@Indexed(index = "eu.etaxonomy.cdm.model.description.FeatureTree")
64@Audited
65public 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>();
70       
71        @XmlElement(name = "Root")
72        @OneToOne(fetch = FetchType.LAZY)
73        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
74        private FeatureNode root;
75       
76        @XmlElement(name = "IsDescriptionSeparated")
77        private boolean descriptionSeparated = false;
78               
79        /**
80         * Class constructor: creates a new feature tree instance with an empty
81         * {@link #getRoot() root node}.
82         */
83        protected FeatureTree() {
84                super();
85                root = FeatureNode.NewInstance();
86                root.setFeatureTree(this);
87        }
88
89        /**
90         * Creates a new feature tree instance with an empty {@link #getRoot() root node}.
91         *
92         * @see #NewInstance(UUID)
93         * @see #NewInstance(List)
94         */
95        public static FeatureTree NewInstance(){
96                return new FeatureTree();
97        }
98
99        /**
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).
103         *
104         * @param       uuid    the universally unique identifier
105         * @see                         #NewInstance()
106         * @see                         #NewInstance(List)
107         */
108        public static FeatureTree NewInstance(UUID uuid){
109                FeatureTree result =  new FeatureTree();
110                result.setUuid(uuid);
111                return result;
112        }
113       
114        /**
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.
120         *
121         * @param       featureList     the feature list
122         * @see                                 #NewInstance()
123         * @see                                 #NewInstance(UUID)
124         */
125        public static FeatureTree NewInstance(List<Feature> featureList){
126                FeatureTree result =  new FeatureTree();
127                FeatureNode root = result.getRoot();
128               
129                for (Feature feature : featureList){
130                        FeatureNode child = FeatureNode.NewInstance(feature);
131                        root.addChild(child);   
132                }
133               
134                return result;
135        }
136       
137        // Delete the isDescriptionSeparated flag ??
138        /**
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)
142         * or not (false).
143         * 
144         * @return  the boolean value of the isDescriptionSeparated flag
145         */
146        public boolean isDescriptionSeparated() {
147                return descriptionSeparated;
148        }
149
150        /**
151         * @see #isDescriptionSeparated()
152         */
153        public void setDescriptionSeparated(boolean descriptionSeperated) {
154                this.descriptionSeparated = descriptionSeperated;
155        }
156       
157//      @OneToMany
158//      @Cascade({CascadeType.SAVE_UPDATE})
159//      public Set<FeatureNode> getNodes() {
160//              return nodes;
161//      }
162//      public void setNodes(Set<FeatureNode> nodes) {
163//              this.nodes = nodes;
164//      }
165
166        /**
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.
171         */
172        public FeatureNode getRoot() {
173                return root;
174        }
175        /**
176         * @see #getRoot()
177         */
178        public void setRoot(FeatureNode root) {
179                this.root = root;
180        }
181       
182        /**
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.
185         */
186        @Transient
187        public List<FeatureNode> getRootChildren(){
188                List<FeatureNode> result = new ArrayList<FeatureNode>();
189                result.addAll(root.getChildren());
190                return result;
191        }
192       
193        /**
194         * Computes a set of distinct features that are present in this feature tree
195         *
196         * @return
197         */
198        @Transient
199        public Set<Feature> getDistinctFeatures(){
200                Set<Feature> features = new HashSet<Feature>();
201               
202                return root.getDistinctFeaturesRecursive(features);
203        }
204       
205//*********************** CLONE ********************************************************/
206       
207        /**
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
213         *
214         *
215         * @see eu.etaxonomy.cdm.model.common.TermBase#clone()
216         * @see java.lang.Object#clone()
217         */
218        @Override
219       
220        public Object clone() {
221                FeatureTree result;
222                try {
223                        result = (FeatureTree)super.clone();
224                }catch (CloneNotSupportedException e) {
225                        logger.warn("Object does not implement cloneable");
226                        e.printStackTrace();
227                        return null;
228                }
229                FeatureNode rootClone = (FeatureNode)this.getRoot().cloneDescendants();
230                result.root = rootClone;
231                               
232                return result;
233               
234        }
235       
236       
237}
Note: See TracBrowser for help on using the browser.