Project

General

Profile

« Previous | Next » 

Revision b6b3cb35

Added by Andreas Müller about 5 years ago

ref #8162 move FeatureTree and FeatureNode to term package

View differences:

cdmlib-cache/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml
103 103
      <mapping class="eu.etaxonomy.cdm.model.description.Distribution"/>
104 104
      <mapping class="eu.etaxonomy.cdm.model.description.Feature"/>
105 105
      <mapping class="eu.etaxonomy.cdm.model.description.Character"/>
106
      <mapping class="eu.etaxonomy.cdm.model.description.FeatureNode"/>
107
      <mapping class="eu.etaxonomy.cdm.model.description.FeatureTree"/>
106
      <mapping class="eu.etaxonomy.cdm.model.term.FeatureNode"/>
107
      <mapping class="eu.etaxonomy.cdm.model.term.FeatureTree"/>
108 108
      <mapping class="eu.etaxonomy.cdm.model.description.KeyStatement"/>
109 109
      <mapping class="eu.etaxonomy.cdm.model.description.MediaKey"/>
110 110
      <mapping class="eu.etaxonomy.cdm.model.description.IndividualsAssociation"/>
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/owl/out/OwlExport.java
22 22

  
23 23
import eu.etaxonomy.cdm.io.common.CdmExportBase;
24 24
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
25
import eu.etaxonomy.cdm.model.description.FeatureNode;
26
import eu.etaxonomy.cdm.model.description.FeatureTree;
27 25
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
26
import eu.etaxonomy.cdm.model.term.FeatureNode;
27
import eu.etaxonomy.cdm.model.term.FeatureTree;
28 28

  
29 29
/**
30 30
 * @author pplitzner
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/owl/out/OwlExportConfigurator.java
15 15

  
16 16
import eu.etaxonomy.cdm.database.ICdmDataSource;
17 17
import eu.etaxonomy.cdm.io.common.XmlExportConfiguratorBase;
18
import eu.etaxonomy.cdm.model.description.FeatureTree;
18
import eu.etaxonomy.cdm.model.term.FeatureTree;
19 19

  
20 20

  
21 21
/**
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/word/out/WordExport.java
19 19

  
20 20
import eu.etaxonomy.cdm.io.common.CdmExportBase;
21 21
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
22
import eu.etaxonomy.cdm.model.description.FeatureNode;
23
import eu.etaxonomy.cdm.model.description.FeatureTree;
24 22
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
23
import eu.etaxonomy.cdm.model.term.FeatureNode;
24
import eu.etaxonomy.cdm.model.term.FeatureTree;
25 25

  
26 26
/**
27 27
 *
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/word/out/WordExportConfigurator.java
15 15

  
16 16
import eu.etaxonomy.cdm.database.ICdmDataSource;
17 17
import eu.etaxonomy.cdm.io.common.XmlExportConfiguratorBase;
18
import eu.etaxonomy.cdm.model.description.FeatureTree;
18
import eu.etaxonomy.cdm.model.term.FeatureTree;
19 19

  
20 20

  
21 21
/**
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/CdmIDResolver.java
30 30
import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
31 31
import eu.etaxonomy.cdm.model.common.User;
32 32
import eu.etaxonomy.cdm.model.description.DescriptionBase;
33
import eu.etaxonomy.cdm.model.description.FeatureTree;
34 33
import eu.etaxonomy.cdm.model.media.Media;
35 34
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
36 35
import eu.etaxonomy.cdm.model.name.TaxonName;
......
39 38
import eu.etaxonomy.cdm.model.reference.Reference;
40 39
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
41 40
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
41
import eu.etaxonomy.cdm.model.term.FeatureTree;
42 42
import eu.etaxonomy.cdm.model.term.TermVocabulary;
43 43

  
44 44
public class CdmIDResolver extends IDResolver {
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/DataSet.java
38 38
import eu.etaxonomy.cdm.model.common.MarkerType;
39 39
import eu.etaxonomy.cdm.model.common.User;
40 40
import eu.etaxonomy.cdm.model.description.Feature;
41
import eu.etaxonomy.cdm.model.description.FeatureTree;
42 41
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
43 42
import eu.etaxonomy.cdm.model.description.MediaKey;
44 43
import eu.etaxonomy.cdm.model.description.PolytomousKey;
......
84 83
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
85 84
import eu.etaxonomy.cdm.model.term.DefinedTerm;
86 85
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
86
import eu.etaxonomy.cdm.model.term.FeatureTree;
87 87
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
88 88
import eu.etaxonomy.cdm.model.term.TermVocabulary;
89 89

  
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/JaxbExport.java
32 32
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
33 33
import eu.etaxonomy.cdm.model.agent.AgentBase;
34 34
import eu.etaxonomy.cdm.model.common.User;
35
import eu.etaxonomy.cdm.model.description.FeatureTree;
36 35
import eu.etaxonomy.cdm.model.name.TaxonName;
37 36
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
38 37
import eu.etaxonomy.cdm.model.reference.Reference;
......
40 39
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
41 40
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
42 41
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
42
import eu.etaxonomy.cdm.model.term.FeatureTree;
43 43

  
44 44
/**
45 45
 * @author a.babadshanjan
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/JaxbImport.java
27 27
import eu.etaxonomy.cdm.model.common.LanguageStringBase;
28 28
import eu.etaxonomy.cdm.model.common.User;
29 29
import eu.etaxonomy.cdm.model.description.DescriptionBase;
30
import eu.etaxonomy.cdm.model.description.FeatureNode;
31
import eu.etaxonomy.cdm.model.description.FeatureTree;
32 30
import eu.etaxonomy.cdm.model.media.Media;
33 31
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
34 32
import eu.etaxonomy.cdm.model.name.TaxonName;
......
39 37
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40 38
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
41 39
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
40
import eu.etaxonomy.cdm.model.term.FeatureNode;
41
import eu.etaxonomy.cdm.model.term.FeatureTree;
42 42
import eu.etaxonomy.cdm.model.term.TermVocabulary;
43 43

  
44 44
/**
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupImportState.java
28 28
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
29 29
import eu.etaxonomy.cdm.model.common.Language;
30 30
import eu.etaxonomy.cdm.model.description.Feature;
31
import eu.etaxonomy.cdm.model.description.FeatureNode;
32 31
import eu.etaxonomy.cdm.model.description.PolytomousKey;
33 32
import eu.etaxonomy.cdm.model.description.PolytomousKeyNode;
34 33
import eu.etaxonomy.cdm.model.location.NamedArea;
......
36 35
import eu.etaxonomy.cdm.model.occurrence.Collection;
37 36
import eu.etaxonomy.cdm.model.reference.Reference;
38 37
import eu.etaxonomy.cdm.model.taxon.Taxon;
38
import eu.etaxonomy.cdm.model.term.FeatureNode;
39 39

  
40 40
/**
41 41
 * @author a.mueller
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/in/SDDImport.java
54 54
import eu.etaxonomy.cdm.model.description.CategoricalData;
55 55
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
56 56
import eu.etaxonomy.cdm.model.description.Feature;
57
import eu.etaxonomy.cdm.model.description.FeatureNode;
58
import eu.etaxonomy.cdm.model.description.FeatureTree;
59 57
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
60 58
import eu.etaxonomy.cdm.model.description.QuantitativeData;
61 59
import eu.etaxonomy.cdm.model.description.State;
......
85 83
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
86 84
import eu.etaxonomy.cdm.model.term.DefinedTerm;
87 85
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
86
import eu.etaxonomy.cdm.model.term.FeatureNode;
87
import eu.etaxonomy.cdm.model.term.FeatureTree;
88 88
import eu.etaxonomy.cdm.model.term.Representation;
89 89
import eu.etaxonomy.cdm.model.term.TermBase;
90 90
import eu.etaxonomy.cdm.model.term.TermType;
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/out/SDDDataSet.java
41 41
import eu.etaxonomy.cdm.model.common.SourcedEntityBase;
42 42
import eu.etaxonomy.cdm.model.common.VersionableEntity;
43 43
import eu.etaxonomy.cdm.model.description.Feature;
44
import eu.etaxonomy.cdm.model.description.FeatureNode;
45
import eu.etaxonomy.cdm.model.description.FeatureTree;
46 44
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
47 45
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
48 46
import eu.etaxonomy.cdm.model.description.State;
......
81 79
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
82 80
import eu.etaxonomy.cdm.model.term.DefinedTerm;
83 81
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
82
import eu.etaxonomy.cdm.model.term.FeatureNode;
83
import eu.etaxonomy.cdm.model.term.FeatureTree;
84 84
import eu.etaxonomy.cdm.model.term.Representation;
85 85
import eu.etaxonomy.cdm.model.term.TermVocabulary;
86 86

  
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/out/SDDDocumentBuilder.java
53 53
import eu.etaxonomy.cdm.model.description.CategoricalData;
54 54
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
55 55
import eu.etaxonomy.cdm.model.description.Feature;
56
import eu.etaxonomy.cdm.model.description.FeatureNode;
57
import eu.etaxonomy.cdm.model.description.FeatureTree;
58 56
import eu.etaxonomy.cdm.model.description.QuantitativeData;
59 57
import eu.etaxonomy.cdm.model.description.State;
60 58
import eu.etaxonomy.cdm.model.description.StateData;
......
80 78
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
81 79
import eu.etaxonomy.cdm.model.term.DefinedTerm;
82 80
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
81
import eu.etaxonomy.cdm.model.term.FeatureNode;
82
import eu.etaxonomy.cdm.model.term.FeatureTree;
83 83
import eu.etaxonomy.cdm.model.term.Representation;
84 84
import eu.etaxonomy.cdm.model.term.TermBase;
85 85
import eu.etaxonomy.cdm.model.term.TermVocabulary;
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/taxonx2013/TaxonXTreatmentExtractor.java
42 42
import eu.etaxonomy.cdm.model.common.LSID;
43 43
import eu.etaxonomy.cdm.model.common.Language;
44 44
import eu.etaxonomy.cdm.model.description.Feature;
45
import eu.etaxonomy.cdm.model.description.FeatureNode;
46
import eu.etaxonomy.cdm.model.description.FeatureTree;
47 45
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
48 46
import eu.etaxonomy.cdm.model.description.TaxonDescription;
49 47
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
......
65 63
import eu.etaxonomy.cdm.model.taxon.Taxon;
66 64
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
67 65
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
66
import eu.etaxonomy.cdm.model.term.FeatureNode;
67
import eu.etaxonomy.cdm.model.term.FeatureTree;
68 68
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
69 69
import eu.etaxonomy.cdm.persistence.query.MatchMode;
70 70
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/jaxb/FeatureTest.java
18 18
import org.junit.Test;
19 19

  
20 20
import eu.etaxonomy.cdm.model.description.Feature;
21
import eu.etaxonomy.cdm.model.description.FeatureNode;
22
import eu.etaxonomy.cdm.model.description.FeatureTree;
21
import eu.etaxonomy.cdm.model.term.FeatureNode;
22
import eu.etaxonomy.cdm.model.term.FeatureTree;
23 23

  
24 24
public class FeatureTest {
25 25

  
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/owl/out/OwlExportTest.java
27 27
import eu.etaxonomy.cdm.io.descriptive.owl.out.OwlExportConfigurator;
28 28
import eu.etaxonomy.cdm.model.common.CdmBase;
29 29
import eu.etaxonomy.cdm.model.description.Feature;
30
import eu.etaxonomy.cdm.model.description.FeatureNode;
31
import eu.etaxonomy.cdm.model.description.FeatureTree;
30
import eu.etaxonomy.cdm.model.term.FeatureNode;
31
import eu.etaxonomy.cdm.model.term.FeatureTree;
32 32
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
33 33
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
34 34

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/TreeIndex.java
16 16
import java.util.Map;
17 17
import java.util.regex.Pattern;
18 18

  
19
import eu.etaxonomy.cdm.model.description.FeatureNode;
20 19
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
20
import eu.etaxonomy.cdm.model.term.FeatureNode;
21 21

  
22 22
/**
23 23
 * A class to handle tree indexes as used in {@link TaxonNode}, {@link FeatureNode}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/package-info.java
232 232
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
233 233
import eu.etaxonomy.cdm.model.description.Distribution;
234 234
import eu.etaxonomy.cdm.model.description.Feature;
235
import eu.etaxonomy.cdm.model.description.FeatureTree;
236 235
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
237 236
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
238 237
import eu.etaxonomy.cdm.model.description.MediaKey;
......
298 297
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
299 298
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
300 299
import eu.etaxonomy.cdm.model.term.DefinedTerm;
300
import eu.etaxonomy.cdm.model.term.FeatureTree;
301 301
import eu.etaxonomy.cdm.model.term.OrderedTerm;
302 302
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
303 303
import eu.etaxonomy.cdm.model.term.Representation;
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/Character.java
25 25

  
26 26
import eu.etaxonomy.cdm.model.common.Language;
27 27
import eu.etaxonomy.cdm.model.term.DefinedTerm;
28
import eu.etaxonomy.cdm.model.term.FeatureNode;
28 29
import eu.etaxonomy.cdm.model.term.TermType;
29 30

  
30 31
/**
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/DescriptiveDataSet.java
41 41
import eu.etaxonomy.cdm.model.location.NamedArea;
42 42
import eu.etaxonomy.cdm.model.name.Rank;
43 43
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44
import eu.etaxonomy.cdm.model.term.FeatureTree;
44 45
import eu.etaxonomy.cdm.model.term.Representation;
45 46
import eu.etaxonomy.cdm.strategy.cache.description.DescriptiveDataSetDefaultCacheStrategy;
46 47

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/DescriptiveSystemRole.java
14 14
import javax.xml.bind.annotation.XmlEnumValue;
15 15

  
16 16
import eu.etaxonomy.cdm.model.common.Language;
17
import eu.etaxonomy.cdm.model.term.FeatureTree;
17 18

  
18 19
/**
19 20
 * The role of the descriptive system of type {@link FeatureTree}.<BR>
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/Feature.java
45 45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46 46
import eu.etaxonomy.cdm.model.term.DefinedTerm;
47 47
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
48
import eu.etaxonomy.cdm.model.term.FeatureTree;
48 49
import eu.etaxonomy.cdm.model.term.Representation;
49 50
import eu.etaxonomy.cdm.model.term.TermType;
50 51
import eu.etaxonomy.cdm.model.term.TermVocabulary;
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/FeatureNode.java
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

  
10
package eu.etaxonomy.cdm.model.description;
11

  
12
import java.util.ArrayList;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16

  
17
import javax.persistence.Column;
18
import javax.persistence.Entity;
19
import javax.persistence.FetchType;
20
import javax.persistence.Index;
21
import javax.persistence.JoinColumn;
22
import javax.persistence.JoinTable;
23
import javax.persistence.ManyToMany;
24
import javax.persistence.ManyToOne;
25
import javax.persistence.OneToMany;
26
import javax.persistence.OrderBy;
27
import javax.persistence.OrderColumn;
28
import javax.persistence.Table;
29
import javax.persistence.Transient;
30
import javax.validation.constraints.NotNull;
31
import javax.xml.bind.annotation.XmlAccessType;
32
import javax.xml.bind.annotation.XmlAccessorType;
33
import javax.xml.bind.annotation.XmlAttribute;
34
import javax.xml.bind.annotation.XmlElement;
35
import javax.xml.bind.annotation.XmlElementWrapper;
36
import javax.xml.bind.annotation.XmlIDREF;
37
import javax.xml.bind.annotation.XmlRootElement;
38
import javax.xml.bind.annotation.XmlSchemaType;
39
import javax.xml.bind.annotation.XmlType;
40

  
41
import org.apache.log4j.Logger;
42
import org.hibernate.annotations.Cascade;
43
import org.hibernate.annotations.CascadeType;
44
import org.hibernate.annotations.Type;
45
import org.hibernate.envers.Audited;
46

  
47
import eu.etaxonomy.cdm.hibernate.HHH_9751_Util;
48
import eu.etaxonomy.cdm.model.common.CdmBase;
49
import eu.etaxonomy.cdm.model.common.ITreeNode;
50
import eu.etaxonomy.cdm.model.common.VersionableEntity;
51
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
52
import eu.etaxonomy.cdm.model.term.IHasTermType;
53
import eu.etaxonomy.cdm.model.term.TermType;
54

  
55
/**
56
 * The class for tree nodes within a {@link FeatureTree feature tree} structure.
57
 * Feature nodes are the elementary components of such a tree since they might
58
 * be related to other nodes as a parent or as a child. A feature node belongs
59
 * at most to one feature tree. It cannot have more than one parent node but
60
 * may have several child nodes. Parent/child relations are bidirectional:
61
 * a node N1 is the parent of a node N2 if and only if the node N2 is a child of
62
 * the node N1.
63
 *
64
 * @author  m.doering
65
 * @since 08-Nov-2007 13:06:16
66
 */
67
@SuppressWarnings("serial")
68
@XmlAccessorType(XmlAccessType.FIELD)
69
@XmlType(name = "FeatureNode", propOrder = {
70
		"featureTree",
71
		"termType",
72
		"feature",
73
		"parent",
74
		"treeIndex",
75
		"sortIndex",
76
		"children",
77
		"onlyApplicableIf",
78
		"inapplicableIf"
79
})
80
@XmlRootElement(name = "FeatureNode")
81
@Entity
82
@Audited
83
@Table(name="FeatureNode", indexes = { @Index(name = "featureNodeTreeIndex", columnList = "treeIndex") })
84
public class FeatureNode <T extends DefinedTermBase> extends VersionableEntity
85
            implements ITreeNode<FeatureNode<T>>, IHasTermType, Cloneable {
86
	private static final Logger logger = Logger.getLogger(FeatureNode.class);
87

  
88
    //This is the main key a node belongs to. Although other keys may also reference
89
	//<code>this</code> node, a node usually belongs to a given key.
90
	@XmlElement(name = "FeatureTree")
91
    @XmlIDREF
92
    @XmlSchemaType(name = "IDREF")
93
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureTree.class)
94
    @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
	 //TODO Val #3379
96
//    @NotNull
97
	private FeatureTree<T> featureTree;
98

  
99
    /**
100
     * The {@link TermType type} of this term node.
101
     * Must be the same type as for the {@link FeatureTree term collection}
102
     * this node belongs to and as the term type of the term this node links to.
103
     */
104
    @XmlAttribute(name ="TermType")
105
    @Column(name="termType")
106
    @NotNull
107
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
108
        parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.term.TermType")}
109
    )
110
    @Audited
111
    private TermType termType;
112

  
113
    @XmlElement(name = "Feature")
114
    @XmlIDREF
115
    @XmlSchemaType(name = "IDREF")
116
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=DefinedTermBase.class)
117
	private T feature;
118

  
119
    @XmlElement(name = "Parent")
120
    @XmlIDREF
121
    @XmlSchemaType(name = "IDREF")
122
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureNode.class)
123
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
124
	@JoinColumn(name="parent_id")
125
	private FeatureNode<T> parent;
126

  
127

  
128
    @XmlElement(name = "treeIndex")
129
    @Column(length=255)
130
    private String treeIndex;
131

  
132
    @XmlElementWrapper(name = "Children")
133
    @XmlElement(name = "Child")
134
    //see https://dev.e-taxonomy.eu/trac/ticket/3722
135
    @OrderColumn(name="sortIndex")
136
    @OrderBy("sortIndex")
137
	@OneToMany(fetch = FetchType.LAZY, mappedBy="parent", targetEntity=FeatureNode.class)
138
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
139
	private List<FeatureNode<T>> children = new ArrayList<>();
140

  
141
    //see https://dev.e-taxonomy.eu/trac/ticket/3722
142
    private Integer sortIndex;
143

  
144
	@XmlElementWrapper(name = "OnlyApplicableIf")
145
	@XmlElement(name = "OnlyApplicableIf")
146
	@XmlIDREF
147
	@XmlSchemaType(name="IDREF")
148
	@ManyToMany(fetch = FetchType.LAZY)
149
//	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})  remove cascade #5755
150
	@JoinTable(name="FeatureNode_DefinedTermBase_OnlyApplicable")
151
	private final Set<State> onlyApplicableIf = new HashSet<>();
152

  
153
	@XmlElementWrapper(name = "InapplicableIf")
154
	@XmlElement(name = "InapplicableIf")
155
	@XmlIDREF
156
	@XmlSchemaType(name="IDREF")
157
	@ManyToMany(fetch = FetchType.LAZY)
158
//	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})  remove cascade #5755
159
	@JoinTable(name="FeatureNode_DefinedTermBase_InapplicableIf")
160
	private final Set<State> inapplicableIf = new HashSet<>();
161

  
162
// ***************************** FACTORY *********************************/
163

  
164
	/**
165
     * Creates a new empty term node instance.
166
     *
167
     * @see #NewInstance(Feature)
168
     */
169
    public static <T extends DefinedTermBase<T>> FeatureNode<T> NewInstance(TermType termType){
170
        return new FeatureNode<>(termType);
171
    }
172

  
173
	/**
174
	 * Creates a new empty feature node instance.
175
	 *
176
	 * @see #NewInstance(Feature)
177
	 */
178
	public static FeatureNode<Feature> NewInstance(){
179
		return new FeatureNode<>(TermType.Feature);
180
	}
181

  
182
	/**
183
	 * Creates a new feature node instance only with the given {@link DefinedTermBase term}
184
	 * (without parent and children). The termType of the feature node is the termType of
185
	 * the given term
186
	 *
187
	 * @param	term	the term assigned to the new feature node
188
	 * @see 			#NewInstance()
189
	 */
190
	public static <T extends DefinedTermBase<T>> FeatureNode<T> NewInstance(T term){
191
	    FeatureNode<T> result = new FeatureNode<>(term.getTermType());
192
	    result.setTerm(term);
193
	    return result;
194
	}
195

  
196
// ******************** CONSTRUCTOR ***************************************/
197

  
198
	//TODO needed?
199
    @Deprecated
200
    protected FeatureNode(){}
201

  
202
	/**
203
	 * Class constructor: creates a new empty feature node instance.
204
	 */
205
	protected FeatureNode(TermType termType) {
206
	    this.termType = termType;
207
	    IHasTermType.checkTermTypeNull(this);
208
	}
209

  
210
    @Override
211
    public TermType getTermType() {
212
        return termType;
213
    }
214

  
215
//*************************** TREE ************************************/
216

  
217
	public FeatureTree<T> getFeatureTree() {
218
		return featureTree;
219
	}
220

  
221
	protected void setFeatureTree(FeatureTree<T> featureTree) {
222
		checkTermType(featureTree);
223
	    this.featureTree = featureTree;
224
	}
225

  
226
//** ********************** FEATURE ******************************/
227

  
228
	/**
229
     * Returns the {@link Feature feature} <i>this</i> feature node is based on.
230
     */
231
    public T getTerm() {
232
        return CdmBase.deproxy(feature);
233
    }
234
    /**
235
     * @see #getFeature()
236
     */
237
    public void setTerm(T term) {
238
        checkTermType(term);
239
        this.feature = term;
240
    }
241

  
242
//** ********************** PARENT ******************************/
243

  
244
	/**
245
	 * Returns the feature node <i>this</i> feature node is a child of.
246
	 *
247
	 * @see	#getChildNodes()
248
	 */
249
	@Override
250
    public FeatureNode<T> getParent() {
251
		return parent;
252
	}
253
	/**
254
	 * Assigns the given feature node as the parent of <i>this</i> feature node.
255
	 * Due to bidirectionality this method must also add <i>this</i> feature node
256
	 * to the list of children of the given parent.
257
	 *
258
	 * @param	parent	the feature node to be set as parent
259
	 * @see				#getParent()
260
	 */
261
	protected void setParent(FeatureNode<T> parent) {
262
		checkTermType(parent);
263
	    this.parent = parent;
264
	}
265

  
266
//** ********************** CHILDREN ******************************/
267

  
268

  
269
	/**
270
	 * @deprecated for internal use only.
271
	 */
272
	//see #4278 , #4200
273
	@Deprecated
274
    protected void setSortIndex(Integer sortIndex) {
275
		this.sortIndex = sortIndex;
276
	}
277

  
278
	/**
279
	 * Returns the (ordered) list of feature nodes which are children nodes of
280
	 * <i>this</i> feature node.
281
	 */
282
	@Override
283
    public List<FeatureNode<T>> getChildNodes() {
284
	    return children;
285
	}
286

  
287
	/**
288
	 * Adds the given feature node at the end of the list of children of
289
	 * <i>this</i> feature node. Due to bidirectionality this method must also
290
	 * assign <i>this</i> feature node as the parent of the given child.
291
	 *
292
	 * @param	child	the feature node to be added
293
	 * @see				#getChildNodes()
294
	 * @see				#setChildren(List)
295
	 * @see				#addChild(FeatureNode, int)
296
	 * @see				#removeChild(FeatureNode)
297
	 * @see				#removeChild(int)
298
	 */
299
	public void addChild(FeatureNode<T> child){
300
		addChild(child, children.size());
301
	}
302
	/**
303
	 * Inserts the given feature node in the list of children of <i>this</i> feature node
304
	 * at the given (index + 1) position. If the given index is out of bounds
305
	 * an exception will arise.<BR>
306
	 * Due to bidirectionality this method must also assign <i>this</i> feature node
307
	 * as the parent of the given child.
308
	 *
309
	 * @param	child	the feature node to be added
310
	 * @param	index	the integer indicating the position at which the child
311
	 * 					should be added
312
	 * @see				#getChildNodes()
313
	 * @see				#setChildren(List)
314
	 * @see				#addChild(FeatureNode)
315
	 * @see				#removeChild(FeatureNode)
316
	 * @see				#removeChild(int)
317
	 */
318
	public void addChild(FeatureNode<T> child, int index){
319
	    checkTermType(child);
320
	    List<FeatureNode<T>> children = this.getChildNodes();
321
		if (index < 0 || index > children.size() + 1){
322
			throw new IndexOutOfBoundsException("Wrong index: " + index);
323
		}
324
		if (child.getParent() != null){
325
			child.getParent().removeChild(child);
326
		}
327
		child.setParent(this);
328
		child.setFeatureTree(this.getFeatureTree());
329
		children.add(index, child);
330
		//TODO workaround (see sortIndex doc)
331
		for(int i = 0; i < children.size(); i++){
332
			children.get(i).setSortIndex(i);
333
		}
334
		child.setSortIndex(index);
335
	}
336

  
337

  
338
    /**
339
	 * Removes the given feature node from the list of {@link #getChildNodes() children}
340
	 * of <i>this</i> feature node.
341
	 *
342
	 * @param  child	the feature node which should be removed
343
	 * @see     		#getChildNodes()
344
	 * @see				#addChild(FeatureNode, int)
345
	 * @see				#addChild(FeatureNode)
346
	 * @see				#removeChild(int)
347
	 */
348
	public void removeChild(FeatureNode<T> child){
349

  
350
	    int index = children.indexOf(child);
351
		if (index >= 0){
352
			removeChild(index);
353
		}
354
	}
355
	/**
356
	 * Removes the feature node placed at the given (index + 1) position from
357
	 * the list of {@link #getChildNodes() children} of <i>this</i> feature node.
358
	 * If the given index is out of bounds no child will be removed.
359
	 *
360
	 * @param  index	the integer indicating the position of the feature node to
361
	 * 					be removed
362
	 * @see     		#getChildNodes()
363
	 * @see				#addChild(FeatureNode, int)
364
	 * @see				#addChild(FeatureNode)
365
	 * @see				#removeChild(FeatureNode)
366
	 */
367
	public void removeChild(int index){
368
	   FeatureNode<T> child = children.get(index);
369
	   if (child != null){
370
			children.remove(index);
371
			child.setParent(null);
372
			child.setFeatureTree(null);
373
			//TODO workaround (see sortIndex doc)
374
			for(int i = 0; i < children.size(); i++){
375
				FeatureNode<T> childAt = children.get(i);
376
				childAt.setSortIndex(i);
377
			}
378
			child.setSortIndex(null);
379
		}
380
	}
381

  
382
	/**
383
	 * Returns the feature node placed at the given (childIndex + 1) position
384
	 * within the list of {@link #getChildNodes() children} of <i>this</i> feature node.
385
	 * If the given index is out of bounds no child will be returned.
386
	 *
387
	 * @param  childIndex	the integer indicating the position of the feature node
388
	 * @see     			#getChildNodes()
389
	 * @see					#addChild(FeatureNode, int)
390
	 * @see					#removeChild(int)
391
	 */
392
	public FeatureNode<T> getChildAt(int childIndex) {
393
	    return children.get(childIndex);
394
	}
395

  
396
	/**
397
	 * Returns the number of children nodes of <i>this</i> feature node.
398
	 *
399
	 * @see	#getChildNodes()
400
	 */
401
	@Transient
402
	public int getChildCount() {
403
		return children.size();
404
	}
405

  
406
	/**
407
	 * Returns the integer indicating the position of the given feature node
408
	 * within the list of {@link #getChildNodes() children} of <i>this</i> feature node.
409
	 * If the list does not contain this node then -1 will be returned.
410
	 *
411
	 * @param  node	the feature node the position of which is being searched
412
	 * @see			#addChild(FeatureNode, int)
413
	 * @see			#removeChild(int)
414
	 */
415
	public int getIndex(FeatureNode<T> node) {
416
	    if (! children.contains(node)){
417
			return -1;
418
		}else{
419
			return children.indexOf(node);
420
		}
421
	}
422

  
423
	/**
424
	 * Returns the boolean value indicating if <i>this</i> feature node has
425
	 * children (false) or not (true). A node without children is at the
426
	 * bottommost level of a tree and is called a leaf.
427
	 *
428
	 * @see	#getChildNodes()
429
	 * @see	#getChildCount()
430
	 */
431
	@Transient
432
	public boolean isLeaf() {
433
		return children.size() < 1;
434
	}
435

  
436
	/**
437
	 * Whether <code>this</code> node is the root node of the associated {@link FeatureTree feature tree}.
438
	 *
439
	 * @return <code>true</code> if <code>this</code> is the feature trees root node, <code>false</code> if not
440
	 */
441
	@Transient
442
	public boolean isRoot(){
443
		if(getFeatureTree() != null){
444
			return this.equals(getFeatureTree().getRoot());
445
		}
446
		return false;
447
	}
448

  
449
	/**
450
	 * Returns the set of {@link State states} implying rendering the
451
	 * concerned {@link Feature feature} applicable.
452
	 * If at least one state is present in this set, in a given description
453
	 * the {@link Feature feature} in <i>this</i> feature node is inapplicable
454
	 * unless any of the listed controlling states is present in the parent
455
	 * {@link Feature feature} description element {@link CategoricalData
456
	 * categoricalData}.
457
	 * This attribute is not equivalent to onlyApplicableIf in SDD as it is
458
	 * attached directly to the child feature rather than the parent, which
459
	 * allow having different applicable states for each child feature.
460
	 *
461
	 * @see    #addApplicableState(State)
462
	 * @see    #removeApplicableState(State)
463
	 */
464
	public Set<State> getOnlyApplicableIf() {
465
		return onlyApplicableIf;
466
	}
467

  
468
	/**
469
	 * Adds an existing {@link State applicable state} to the set of
470
	 * {@link #getOnlyApplicableIf() applicable states} described in
471
	 * <i>this</i> feature node.<BR>
472
	 *
473
	 * @param applicableState	the applicable state to be added to <i>this</i> feature node
474
	 * @see    	   								#getApplicableState()
475
	 */
476
	public void addApplicableState(State applicableState) {
477
		this.onlyApplicableIf.add(applicableState);
478
	}
479

  
480
	/**
481
	 * Removes one element from the set of
482
	 * {@link #getOnlyApplicableIf() applicable states} described in
483
	 * <i>this</i> feature node.<BR>
484
	 *
485
	 * @param  applicableState   the applicable state which should be removed
486
	 * @see    	   								#getApplicableState()
487
	 * @see     		  						#addApplicableState(State)
488
	 */
489
	public void removeApplicableState(State applicableState) {
490
		this.onlyApplicableIf.remove(applicableState);
491
	}
492

  
493
	/**
494
	 * Returns the set of {@link State states} implying rendering the
495
	 * concerned {@link Feature feature} inapplicable.
496
	 * If at least one {@link State inapplicable state} is defined in the set,
497
	 * in a given description the {@link Feature feature} attribute of
498
	 * <i>this</i> feature node is inapplicable when any of the listed
499
	 * controlling states is present.
500
	 * This attribute is not equivalent to inapplicableIf in SDD as it is
501
	 * attached directly to the child feature rather than the parent, which
502
	 * allow having different inapplicability rules for each child feature.
503
	 *
504
	 * @see    #addInapplicableState(State)
505
	 * @see    #removeInapplicableState(State)
506
	 */
507
	public Set<State> getInapplicableIf() {
508
		return inapplicableIf;
509
	}
510

  
511
	/**
512
	 * Adds an existing {@link State inapplicable state} to the set of
513
	 * {@link #getInapplicableIf() inapplicable states} described in
514
	 * <i>this</i> feature node.<BR>
515
	 *
516
	 * @param inapplicableState	the inapplicable state to be added to <i>this</i> feature node
517
	 * @see    	   								#getInapplicableState()
518
	 */
519
	public void addInapplicableState(State inapplicableState) {
520
		this.inapplicableIf.add(inapplicableState);
521
	}
522

  
523
	/**
524
	 * Removes one element from the set of
525
	 * {@link #getInapplicableIf() inapplicable states} described in
526
	 * <i>this</i> feature node.<BR>
527
	 *
528
	 * @param  inapplicableState   the inapplicable state which should be removed
529
	 * @see    	   								#getInapplicableState()
530
	 * @see     		  						#addInapplicableState(State)
531
	 */
532
	public void removeInapplicableState(State inapplicableState) {
533
		this.inapplicableIf.remove(inapplicableState);
534
	}
535

  
536
//	//** ********************** QUESTIONS ******************************/
537
//
538
//	/**
539
//	 * Returns the {@link Representation question} formulation that
540
//	 * corresponds to <i>this</i> feature node and the corresponding
541
//	 * {@link Feature feature} in case it is part of a
542
//	 * {@link PolytomousKey polytomous key}.
543
//	 */
544
//	public Set<Representation> getQuestions() {
545
//		return this.questions;
546
//	}
547
//
548
//	public void addQuestion(Representation question) {
549
//		this.questions.add(question);
550
//	}
551
//
552
//	public void removeQuestion(Representation question) {
553
//		this.questions.remove(question);
554
//	}
555
//
556
//	@Transient
557
//	public Representation getQuestion(Language lang) {
558
//		for (Representation question : questions){
559
//			Language reprLanguage = question.getLanguage();
560
//			if (reprLanguage != null && reprLanguage.equals(lang)){
561
//				return question;
562
//			}
563
//		}
564
//		return null;
565
//	}
566

  
567
	/**
568
     * Throws {@link IllegalArgumentException} if the given
569
     * term has not the same term type as this term or if term type is null.
570
     * @param term
571
     */
572
    private void checkTermType(IHasTermType term) {
573
        IHasTermType.checkTermTypes(term, this);
574
    }
575

  
576
	/**
577
	 * Returns all terms that are contained in this node or a child node
578
	 *
579
	 * @param featureNode
580
	 * @param features
581
	 * @return
582
	 */
583
	@Transient
584
	public Set<T> getDistinctFeaturesRecursive(Set<T> features){
585
		T term = this.getTerm();
586

  
587
		if(term!=null){
588
		    features.add(term);
589
		}
590

  
591
		for(FeatureNode<T> childNode : this.getChildNodes()){
592
			features.addAll(childNode.getDistinctFeaturesRecursive(features));
593
		}
594

  
595
		return features;
596
	}
597

  
598
	public FeatureNode<T> cloneDescendants(){
599
		FeatureNode<T> clone = (FeatureNode<T>)this.clone();
600
		FeatureNode<T> childClone;
601

  
602
		for(FeatureNode<T> childNode : this.getChildNodes()){
603
			childClone = (FeatureNode<T>) childNode.clone();
604
			for (FeatureNode<T> childChild:childNode.getChildNodes()){
605
				childClone.addChild(childChild.cloneDescendants());
606
			}
607
			clone.addChild(childClone);
608

  
609
		}
610
		return clone;
611
	}
612

  
613
//*********************** CLONE ********************************************************/
614

  
615
	/**
616
	 * Clones <i>this</i> FeatureNode. This is a shortcut that enables to create
617
	 * a new instance that differs only slightly from <i>this</i> FeatureNode by
618
	 * modifying only some of the attributes.
619
	 * The parent, the feature and the featureTree are the are the same as for the original feature node
620
	 * the children are removed
621
	 *
622
	 * @see eu.etaxonomy.cdm.model.common.VersionableEntity#clone()
623
	 * @see java.lang.Object#clone()
624
	 */
625
	@Override
626
	public Object clone() {
627
		FeatureNode<T> result;
628
		try {
629
			result = (FeatureNode<T>)super.clone();
630
			result.children = new ArrayList<>();
631
			return result;
632
		}catch (CloneNotSupportedException e) {
633
			logger.warn("Object does not implement cloneable");
634
			e.printStackTrace();
635
			return null;
636
		}
637

  
638

  
639

  
640
	}
641

  
642
// ********************** TREE NODE METHODS ******************************/
643

  
644
	@Override
645
	public String treeIndex() {
646
		return this.treeIndex;
647
	}    @Override
648
    public String treeIndexLike() {
649
        return treeIndex + "%";
650
    }
651
    @Override
652
    public String treeIndexWc() {
653
        return treeIndex + "*";
654
    }
655

  
656
	@Override
657
	@Deprecated
658
	public void setTreeIndex(String newTreeIndex) {
659
		this.treeIndex = newTreeIndex;
660
	}
661

  
662

  
663
	@Override
664
	@Deprecated
665
	public int treeId() {
666
		if (this.featureTree == null){
667
			return -1;
668
		}else{
669
			return this.featureTree.getId();
670
		}
671
	}
672

  
673
	private void updateSortIndex(){
674
	 // TODO workaround (see sortIndex doc)
675
        for (int i = 0; i < children.size(); i++) {
676
            children.get(i).setSortIndex(i);
677
        }
678
	}
679

  
680
	public void removeNullValueFromChildren(){
681
	    HHH_9751_Util.removeAllNull(children);
682
	    updateSortIndex();
683
	}
684

  
685

  
686
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/FeatureTree.java
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

  
10
package eu.etaxonomy.cdm.model.description;
11

  
12
import java.rmi.UnexpectedException;
13
import java.util.ArrayList;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Set;
17
import java.util.UUID;
18

  
19
import javax.persistence.Column;
20
import javax.persistence.Entity;
21
import javax.persistence.FetchType;
22
import javax.persistence.OneToMany;
23
import javax.persistence.OneToOne;
24
import javax.persistence.Transient;
25
import javax.validation.constraints.NotNull;
26
import javax.xml.bind.annotation.XmlAccessType;
27
import javax.xml.bind.annotation.XmlAccessorType;
28
import javax.xml.bind.annotation.XmlAttribute;
29
import javax.xml.bind.annotation.XmlElement;
30
import javax.xml.bind.annotation.XmlElementWrapper;
31
import javax.xml.bind.annotation.XmlRootElement;
32
import javax.xml.bind.annotation.XmlType;
33

  
34
import org.apache.log4j.Logger;
35
import org.hibernate.annotations.Cascade;
36
import org.hibernate.annotations.CascadeType;
37
import org.hibernate.annotations.Type;
38
import org.hibernate.envers.Audited;
39

  
40
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
41
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
42
import eu.etaxonomy.cdm.model.term.IHasTermType;
43
import eu.etaxonomy.cdm.model.term.Representation;
44
import eu.etaxonomy.cdm.model.term.TermType;
45
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
46

  
47
/**
48
 * The class to arrange {@link Feature features} (characters) in a tree structure.
49
 * Feature trees are essential as interactive multiple-access keys for
50
 * determination process and for systematical output arrangement of
51
 * {@link DescriptionElementBase description elements} according to different goals
52
 * but may also be used to define flat feature subsets for filtering purposes.<BR>
53
 * A feature tree is build on {@link FeatureNode feature nodes}.
54
 * <P>
55
 * This class corresponds partially to ConceptTreeDefType according to the SDD
56
 * schema.
57
 * <P>
58
 * Note: The tree structure of features used for purposes described above has
59
 * nothing in common with the possible hierarchical structure of features
60
 * depending on their grade of precision.
61
 *
62
 * @see		MediaKey
63
 *
64
 * @author  m.doering
65
 * @since 08-Nov-2007 13:06:16
66
 */
67
@XmlAccessorType(XmlAccessType.FIELD)
68
@XmlType(name = "FeatureTree", propOrder = {
69
    "root",
70
    "termType",
71
    "allowDuplicates",
72
    "representations"
73

  
74
})
75
@XmlRootElement(name = "FeatureTree")
76
@Entity
77
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
78
//@Indexed(index = "eu.etaxonomy.cdm.model.description.FeatureTree")
79
@Audited
80
public class FeatureTree <T extends DefinedTermBase>
81
            extends IdentifiableEntity<IIdentifiableEntityCacheStrategy>
82
            implements IHasTermType, Cloneable{
83

  
84
	private static final long serialVersionUID = -6713834139003172735L;
85
	private static final Logger logger = Logger.getLogger(FeatureTree.class);
86

  
87
	@XmlElement(name = "Root")
88
	@OneToOne(fetch = FetchType.LAZY, targetEntity=FeatureNode.class)
89
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
90
	private FeatureNode<T> root;
91

  
92
    /**
93
     * The {@link TermType type} of this term collection. All nodes in the graph must refer to a term of the same type.
94
     */
95
    @XmlAttribute(name ="TermType")
96
    @Column(name="termType")
97
    @NotNull
98
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
99
        parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.term.TermType")}
100
    )
101
    @Audited
102
    private TermType termType;
103

  
104
    // TODO needed? FeatureTree was a TermBase until v3.3 but was removed from
105
	//it as TermBase got the termType which does not apply to FeatureTree.
106
	//We need to check how far representations and uri is still required
107
	//or can be deleted. Current implementations seem all to use the title cache
108
	//instead of representation. This may not be correct.
109
	@XmlElementWrapper(name = "Representations")
110
    @XmlElement(name = "Representation")
111
    @OneToMany(fetch=FetchType.EAGER, orphanRemoval=true)
112
    @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
113
    // @IndexedEmbedded no need for embedding since we are using the DefinedTermBaseClassBridge
114
    private Set<Representation> representations = new HashSet<>();
115
    //make them private for now as we may delete representations in future
116
	//otherwise if we decide to use representations we can make the getters public
117
	private Set<Representation> getRepresentations() {return representations;}
118
    private void setRepresentations(Set<Representation> representations) {this.representations = representations;}
119

  
120
    //#7372 indicates if this tree/graph allows duplicated terms/features
121
    private boolean allowDuplicates = false;
122

  
123
//******************** FACTORY METHODS ******************************************/
124

  
125
    /**
126
     * Creates a new term collection instance for the given term type
127
     * with an empty {@link #getRoot() root node}.
128
     * @param termType the {@link TermType term type}, must not be null
129
     */
130
    public static <T extends DefinedTermBase<T>> FeatureTree<T> NewInstance(@NotNull TermType termType){
131
        return new FeatureTree<>(termType);
132
    }
133

  
134
    /**
135
	 * Creates a new feature tree instance with an empty {@link #getRoot() root node}.
136
	 *
137
	 * @see #NewInstance(UUID)
138
	 * @see #NewInstance(List)
139
	 */
140
	public static FeatureTree<Feature> NewInstance(){
141
		return new FeatureTree<>(TermType.Feature);
142
	}
143

  
144
	/**
145
	 * Creates a new feature tree instance with an empty {@link #getRoot() root node}
146
	 * and assigns to the new feature tree the given
147
	 * UUID (universally unique identifier).
148
	 *
149
	 * @param	uuid	the universally unique identifier
150
	 * @see 			#NewInstance()
151
	 * @see 			#NewInstance(List)
152
	 */
153
	public static <T extends DefinedTermBase<T>> FeatureTree<T> NewInstance(UUID uuid){
154
		FeatureTree<T> result =  new FeatureTree<>(TermType.Feature);
155
		result.setUuid(uuid);
156
		return result;
157
	}
158

  
159
	/**
160
	 * Creates a new feature tree instance with a {@link #getRoot() root node}
161
	 * the children of which are the feature nodes build on the base of the
162
	 * given list of {@link Feature features}. This corresponds to a flat feature tree.
163
	 * For each feature within the list a new {@link FeatureNode feature node} without
164
	 * children nodes will be created.
165
	 *
166
	 * @param	featureList	the feature list
167
	 * @see 				#NewInstance()
168
	 * @see 				#NewInstance(UUID)
169
	 */
170
	public static FeatureTree<Feature> NewInstance(List<Feature> featureList){
171
		FeatureTree<Feature> result =  new FeatureTree<>(TermType.Feature);
172
		FeatureNode<Feature> root = result.getRoot();
173

  
174
		for (Feature feature : featureList){
175
			FeatureNode<Feature> child = FeatureNode.NewInstance(feature);
176
			root.addChild(child);
177
		}
178

  
179
		return result;
180
	}
181

  
182

  
183
// ******************** CONSTRUCTOR *************************************/
184

  
185
    //for JAXB only, TODO needed?
186
    @Deprecated
187
    protected FeatureTree(){}
188

  
189
	/**
190
	 * Class constructor: creates a new feature tree instance with an empty
191
	 * {@link #getRoot() root node}.
192
	 */
193
	protected FeatureTree(TermType termType) {
194
        this.termType = termType;
195
        checkTermType(this);
196
		root = FeatureNode.NewInstance(termType);
197
		root.setFeatureTree(this);
198
	}
199

  
200
// ****************** GETTER / SETTER **********************************/
201

  
202
	@Override
203
    public TermType getTermType() {
204
        return termType;
205
    }
206
    /**
207
	 * Returns the topmost {@link FeatureNode feature node} (root node) of <i>this</i>
208
	 * feature tree. The root node does not have any parent. Since feature nodes
209
	 * recursively point to their child nodes the complete feature tree is
210
	 * defined by its root node.
211
	 */
212
	public FeatureNode<T> getRoot() {
213
		return root;
214
	}
215

  
216
    /**
217
     * @deprecated this method is only for internal use when deleting a {@link FeatureTree}
218
     * from a database. It should never be called for other reasons.
219
     */
220
    @Deprecated
221
    public void removeRootNode() {
222
        this.root = null;
223
    }
224

  
225
	/**
226
	 * Returns the (ordered) list of {@link FeatureNode feature nodes} which are immediate
227
	 * children of the root node of <i>this</i> feature tree.
228
	 */
229
	@Transient
230
	public List<FeatureNode<T>> getRootChildren(){
231
		List<FeatureNode<T>> result = new ArrayList<>();
232
		result.addAll(root.getChildNodes());
233
		return result;
234
	}
235

  
236
    public boolean isAllowDuplicates() {
237
        return allowDuplicates;
238
    }
239
    public void setAllowDuplicates(boolean allowDuplicates) {
240
        this.allowDuplicates = allowDuplicates;
241
    }
242

  
243
    /**
244
     * Throws {@link IllegalArgumentException} if the given
245
     * term has not the same term type as this term or if term type is null.
246
     * @param term
247
     */
248
    private void checkTermType(IHasTermType term) {
249
        IHasTermType.checkTermTypes(term, this);
250
    }
251

  
252
//******************** METHODS ***********************************************/
253

  
254
	/**
255
	 * Computes a set of distinct terms that are present in this feature tree
256
	 *
257
	 * @return
258
	 */
259
	@Transient
260
	public Set<T> getDistinctFeatures(){
261
	    if(termType.equals(TermType.Feature) || termType.isKindOf(TermType.Feature)){
262
	        Set<T> features = new HashSet<>();
263
	        return root.getDistinctFeaturesRecursive(features);
264
	    }
265
	    String message = "FeatureTree is not of type FEATURE.";
266
	    logger.warn(message, new UnexpectedException(message));
267
	    return new HashSet<>();
268
	}
269

  
270
//*********************** CLONE ********************************************************/
271

  
272
	/**
273
	 * Clones <i>this</i> FeatureTree. This is a shortcut that enables to create
274
	 * a new instance that differs only slightly from <i>this</i> FeatureTree by
275
	 * modifying only some of the attributes.
276
	 * FeatureNodes always belong only to one tree, so all FeatureNodes are cloned to build
277
	 * the new FeatureTree
278
	 *
279
	 *
280
	 * @see eu.etaxonomy.cdm.model.term.TermBase#clone()
281
	 * @see java.lang.Object#clone()
282
	 */
283
	@Override
284
	public Object clone() {
285
		FeatureTree<T> result;
286
		try {
287
			result = (FeatureTree<T>)super.clone();
288
		}catch (CloneNotSupportedException e) {
289
			logger.warn("Object does not implement cloneable");
290
			e.printStackTrace();
291
			return null;
292
		}
293
		FeatureNode<T> rootClone = this.getRoot().cloneDescendants();
294
		result.root = rootClone;
295

  
296
		return result;
297

  
298
	}
299

  
300

  
301
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/FeatureNode.java
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

  
10
package eu.etaxonomy.cdm.model.term;
11

  
12
import java.util.ArrayList;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16

  
17
import javax.persistence.Column;
18
import javax.persistence.Entity;
19
import javax.persistence.FetchType;
20
import javax.persistence.Index;
21
import javax.persistence.JoinColumn;
22
import javax.persistence.JoinTable;
23
import javax.persistence.ManyToMany;
24
import javax.persistence.ManyToOne;
25
import javax.persistence.OneToMany;
26
import javax.persistence.OrderBy;
27
import javax.persistence.OrderColumn;
28
import javax.persistence.Table;
29
import javax.persistence.Transient;
30
import javax.validation.constraints.NotNull;
31
import javax.xml.bind.annotation.XmlAccessType;
32
import javax.xml.bind.annotation.XmlAccessorType;
33
import javax.xml.bind.annotation.XmlAttribute;
34
import javax.xml.bind.annotation.XmlElement;
35
import javax.xml.bind.annotation.XmlElementWrapper;
36
import javax.xml.bind.annotation.XmlIDREF;
37
import javax.xml.bind.annotation.XmlRootElement;
38
import javax.xml.bind.annotation.XmlSchemaType;
39
import javax.xml.bind.annotation.XmlType;
40

  
41
import org.apache.log4j.Logger;
42
import org.hibernate.annotations.Cascade;
43
import org.hibernate.annotations.CascadeType;
44
import org.hibernate.annotations.Type;
45
import org.hibernate.envers.Audited;
46

  
47
import eu.etaxonomy.cdm.hibernate.HHH_9751_Util;
48
import eu.etaxonomy.cdm.model.common.CdmBase;
49
import eu.etaxonomy.cdm.model.common.ITreeNode;
50
import eu.etaxonomy.cdm.model.common.VersionableEntity;
51
import eu.etaxonomy.cdm.model.description.CategoricalData;
52
import eu.etaxonomy.cdm.model.description.Feature;
53
import eu.etaxonomy.cdm.model.description.State;
54

  
55
/**
56
 * The class for tree nodes within a {@link FeatureTree feature tree} structure.
57
 * Feature nodes are the elementary components of such a tree since they might
58
 * be related to other nodes as a parent or as a child. A feature node belongs
59
 * at most to one feature tree. It cannot have more than one parent node but
60
 * may have several child nodes. Parent/child relations are bidirectional:
61
 * a node N1 is the parent of a node N2 if and only if the node N2 is a child of
62
 * the node N1.
63
 *
64
 * @author  m.doering
65
 * @since 08-Nov-2007 13:06:16
66
 */
67
@SuppressWarnings("serial")
68
@XmlAccessorType(XmlAccessType.FIELD)
69
@XmlType(name = "FeatureNode", propOrder = {
70
		"featureTree",
71
		"termType",
72
		"feature",
73
		"parent",
74
		"treeIndex",
75
		"sortIndex",
76
		"children",
77
		"onlyApplicableIf",
78
		"inapplicableIf"
79
})
80
@XmlRootElement(name = "FeatureNode")
81
@Entity
82
@Audited
83
@Table(name="FeatureNode", indexes = { @Index(name = "featureNodeTreeIndex", columnList = "treeIndex") })
84
public class FeatureNode <T extends DefinedTermBase> extends VersionableEntity
85
            implements ITreeNode<FeatureNode<T>>, IHasTermType, Cloneable {
86
	private static final Logger logger = Logger.getLogger(FeatureNode.class);
87

  
88
    //This is the main key a node belongs to. Although other keys may also reference
89
	//<code>this</code> node, a node usually belongs to a given key.
90
	@XmlElement(name = "FeatureTree")
91
    @XmlIDREF
92
    @XmlSchemaType(name = "IDREF")
93
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureTree.class)
94
    @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
	 //TODO Val #3379
96
//    @NotNull
97
	private FeatureTree<T> featureTree;
98

  
99
    /**
100
     * The {@link TermType type} of this term node.
101
     * Must be the same type as for the {@link FeatureTree term collection}
102
     * this node belongs to and as the term type of the term this node links to.
103
     */
104
    @XmlAttribute(name ="TermType")
105
    @Column(name="termType")
106
    @NotNull
107
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
108
        parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.term.TermType")}
109
    )
110
    @Audited
111
    private TermType termType;
112

  
113
    @XmlElement(name = "Feature")
114
    @XmlIDREF
115
    @XmlSchemaType(name = "IDREF")
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff