Project

General

Profile

Revision 11df83d8

ID11df83d8c639501a554a28d3cd812f6cedde580c
Parent b3340748
Child 1cc29785

Added by Andreas Müller 12 months ago

ref #6794 add TermCollection and subclasses including TermTree

View differences:

cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/OrderedTermVocabulary.java
36 36
@XmlType(name = "OrderedTermVocabulary")
37 37
@XmlRootElement(name = "OrderedTermVocabulary")
38 38
@Entity
39
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
40
//@Indexed(index = "eu.etaxonomy.cdm.model.term.TermVocabulary")
41 39
@Audited
42 40
public class OrderedTermVocabulary<T extends OrderedTermBase> extends TermVocabulary<T> {
43 41
	private static final long serialVersionUID = 7871741306306371242L;
......
102 100

  
103 101
	@Transient
104 102
	@Override
105
	public Set<T> getNewTermSet() {
103
	protected Set<T> newTermSet() {
106 104
		return new TreeSet<T>();
107 105
	}
108 106

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermCollection.java
1
/**
2
* Copyright (C) 2019 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
package eu.etaxonomy.cdm.model.term;
10

  
11
import javax.persistence.Entity;
12
import javax.persistence.Inheritance;
13
import javax.persistence.InheritanceType;
14
import javax.persistence.Table;
15
import javax.xml.bind.annotation.XmlAccessType;
16
import javax.xml.bind.annotation.XmlAccessorType;
17
import javax.xml.bind.annotation.XmlType;
18

  
19
import org.hibernate.envers.Audited;
20

  
21
/**
22
 * @author a.mueller
23
 * @since 06.03.2019
24
 */
25
@XmlAccessorType(XmlAccessType.FIELD)
26
@XmlType(name = "TermCollection", propOrder = {
27
//    "termSourceUri",
28
//    "terms"
29
})
30
@Entity
31
@Audited
32
@Table(name="TermCollection")
33
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
34
public abstract class TermCollection<T extends DefinedTermBase>
35
            extends TermBase{
36

  
37
    private static final long serialVersionUID = 6102175902060054329L;
38

  
39
    @SuppressWarnings("deprecation")
40
    protected TermCollection(){}
41

  
42
    protected TermCollection(TermType type){
43
        super(type);
44
    }
45

  
46
    protected TermCollection(TermType type, String term, String label, String labelAbbrev) {
47
        super(type, term, label, labelAbbrev);
48
    }
49
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermGraph.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.HashSet;
13
import java.util.Set;
14
import java.util.UUID;
15

  
16
import javax.persistence.Entity;
17
import javax.persistence.Transient;
18
import javax.validation.constraints.NotNull;
19
import javax.xml.bind.annotation.XmlAccessType;
20
import javax.xml.bind.annotation.XmlAccessorType;
21
import javax.xml.bind.annotation.XmlRootElement;
22
import javax.xml.bind.annotation.XmlType;
23

  
24
import org.apache.log4j.Logger;
25
import org.hibernate.envers.Audited;
26

  
27

  
28
/**
29
 * @author a.mueller
30
 * @since 07.03.2019
31
 *
32
 * @param <T>
33
 */
34
@XmlAccessorType(XmlAccessType.FIELD)
35
@XmlType(name = "TermTree", propOrder = {
36

  
37
})
38
@XmlRootElement(name = "TermTree")
39
@Entity
40
@Audited
41
public class TermGraph <T extends DefinedTermBase>
42
            extends TermGraphBase<T, TermRelation<T>> {
43

  
44
	private static final long serialVersionUID = -6713834139003172735L;
45
	private static final Logger logger = Logger.getLogger(TermGraph.class);
46

  
47

  
48
//******************** FACTORY METHODS ******************************************/
49

  
50
    /**
51
     * Creates a new term collection instance for the given term type
52
     * with an empty {@link #getRoot() root node}.
53
     * @param termType the {@link TermType term type}, must not be null
54
     */
55
    public static <T extends DefinedTermBase<T>> TermGraph<T> NewInstance(@NotNull TermType termType){
56
        return new TermGraph<>(termType);
57
    }
58

  
59

  
60
	/**
61
	 * Creates a new TermGraph instance with a given uuid.
62
	 * @param termType
63
	 * @param uuid
64
	 * @return
65
	 */
66
	public static <T extends DefinedTermBase<T>> TermGraph<T> NewInstance(@NotNull TermType termType, UUID uuid){
67
		TermGraph<T> result =  new TermGraph<>(termType);
68
		result.setUuid(uuid);
69
		return result;
70
	}
71

  
72

  
73

  
74
// ******************** CONSTRUCTOR *************************************/
75

  
76
    //TODO needed?
77
    @Deprecated
78
    protected TermGraph(){}
79

  
80
	/**
81
	 * Class constructor: creates a new feature tree instance with an empty
82
	 * {@link #getRoot() root node}.
83
	 */
84
	protected TermGraph(TermType termType) {
85
        super(termType);
86
	}
87

  
88
// ****************** GETTER / SETTER **********************************/
89

  
90

  
91

  
92

  
93
//******************** METHODS ***********************************************/
94

  
95
	/**
96
	 * Computes a set of distinct terms that are present in this term tree
97
	 *
98
	 * @return
99
	 */
100
	@Override
101
    @Transient
102
	public Set<T> getDistinctTerms(){
103
	    Set<T> result = new HashSet<>();
104
	    for (TermRelation<T> rel : getTermRelations()){
105
	        result.add(rel.getTerm());
106
	        result.add(rel.getToTerm());
107
	    }
108
	    result.remove(null);  //just in case
109
	    return result;
110
	}
111

  
112
//*********************** CLONE ********************************************************/
113

  
114
	/**
115
	 * Clones <i>this</i> {@link TermGraph}. This is a shortcut that enables to create
116
	 * a new instance that differs only slightly from <i>this</i> graph by
117
	 * modifying only some of the attributes.
118
	 * {@link TermRelation Term relations} always belong only to one tree, so all
119
	 * {@link TermRelation Term relations} are cloned to build
120
	 * the new {@link TermGraph}
121
	 *
122
	 * @see java.lang.Object#clone()
123
	 */
124
	@Override
125
	public Object clone() {
126
		TermGraph<T> result;
127
		try {
128
			result = (TermGraph<T>)super.clone();
129

  
130
		}catch (CloneNotSupportedException e) {
131
			logger.warn("Object does not implement cloneable");
132
			e.printStackTrace();
133
			return null;
134
		}
135

  
136
		return result;
137

  
138
	}
139

  
140

  
141
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermGraphBase.java
1
/**
2
* Copyright (C) 2019 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
package eu.etaxonomy.cdm.model.term;
10

  
11
import java.util.HashSet;
12
import java.util.Set;
13

  
14
import javax.persistence.Entity;
15
import javax.persistence.FetchType;
16
import javax.persistence.OneToMany;
17
import javax.xml.bind.annotation.XmlAccessType;
18
import javax.xml.bind.annotation.XmlAccessorType;
19
import javax.xml.bind.annotation.XmlElement;
20
import javax.xml.bind.annotation.XmlElementWrapper;
21
import javax.xml.bind.annotation.XmlIDREF;
22
import javax.xml.bind.annotation.XmlSchemaType;
23
import javax.xml.bind.annotation.XmlType;
24

  
25
import org.apache.log4j.Logger;
26
import org.hibernate.annotations.Cascade;
27
import org.hibernate.annotations.CascadeType;
28
import org.hibernate.envers.Audited;
29
import org.hibernate.search.annotations.IndexedEmbedded;
30

  
31
/**
32
 * @author a.mueller
33
 * @since 07.03.2019
34
 */
35
@XmlAccessorType(XmlAccessType.FIELD)
36
@XmlType(name = "TermGraph", propOrder = {
37
      "allowDuplicates",
38
      "orderRelevant",
39
      "isFlat"
40
})
41
@Entity
42
@Audited
43
public abstract class TermGraphBase<TERM extends DefinedTermBase, REL extends TermRelationBase> //<TERM, REL, TermGraphBase>
44
            extends TermCollection<TERM> {
45

  
46
    private static final long serialVersionUID = -704169783744494023L;
47

  
48
    @SuppressWarnings("unused")
49
    private static final Logger logger = Logger.getLogger(TermGraphBase.class);
50

  
51

  
52
    @XmlElementWrapper(name = "TermRelations")
53
    @XmlElement(name = "TermRelation")
54
    @XmlIDREF
55
    @XmlSchemaType(name = "IDREF")
56
    @OneToMany(mappedBy="graph", fetch=FetchType.LAZY, targetEntity = TermRelationBase.class)
57
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
58
    @IndexedEmbedded(depth = 2)
59
    private Set<REL> termRelations = new HashSet<>();
60

  
61
    //#7372 indicates if this tree/graph allows duplicated terms/features
62
    private boolean allowDuplicates = false;
63

  
64
    private boolean orderRelevant = false;
65

  
66
    private boolean isFlat = false;
67

  
68
 // ******************** CONSTRUCTOR *************************************/
69

  
70
    @Deprecated
71
    protected TermGraphBase(){}
72

  
73
    protected TermGraphBase(TermType termType) {
74
        super(termType);
75
    }
76

  
77
 // ****************** GETTER / SETTER **********************************/
78

  
79
    public boolean isAllowDuplicates() {
80
        return allowDuplicates;
81
    }
82
    public void setAllowDuplicates(boolean allowDuplicates) {
83
        this.allowDuplicates = allowDuplicates;
84
    }
85

  
86
    public boolean isOrderRelevant() {
87
        return orderRelevant;
88
    }
89
    public void setOrderRelevant(boolean orderRelevant) {
90
        this.orderRelevant = orderRelevant;
91
    }
92

  
93
    public boolean isFlat() {
94
        return isFlat;
95
    }
96
    public void setFlat(boolean isFlat) {
97
        this.isFlat = isFlat;
98
    }
99

  
100

  
101

  
102
    public Set<REL> getTermRelations() {
103
        return termRelations;
104
    }
105
    /**
106
     * For now protected to avoid type checking etc. Might become
107
     * public in future
108
     * @param termRelations
109
     */
110
    protected void setTermRelations(Set<REL> termRelations) {
111
        this.termRelations = termRelations;
112
    }
113

  
114
    public abstract Set<TERM> getDistinctTerms();
115
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermRelation.java
38 38
@Entity
39 39
@Audited
40 40
public abstract class TermRelation<T extends DefinedTermBase>
41
        extends TermRelationBase<T> {
41
        extends TermRelationBase<T, TermRelation<T>, TermGraph<T>> {
42 42

  
43 43
    private static final long serialVersionUID = -7835146268318871033L;
44 44

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermRelationBase.java
49 49
@Audited
50 50
@Table(name="TermRelation", indexes = { @Index(name = "termTreeNodeTreeIndex", columnList = "treeIndex") })  //was feature NodeTreeIndex before
51 51
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
52
public abstract class TermRelationBase<T extends DefinedTermBase>
52
public abstract class TermRelationBase<TERM extends DefinedTermBase, REL extends TermRelationBase, GRAPH extends TermGraphBase>
53 53
        extends VersionableEntity
54 54
        implements IHasTermType {
55 55

  
......
57 57
    @SuppressWarnings("unused")
58 58
    private static final Logger logger = Logger.getLogger(TermRelationBase.class);
59 59

  
60
    @XmlElement(name = "TermTree")
60
    @XmlElement(name = "TermGraph")
61 61
    @XmlIDREF
62 62
    @XmlSchemaType(name = "IDREF")
63
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=FeatureTree.class)
63
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=TermTree.class)
64 64
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE}) //TODO this usage is incorrect, needed only for OneToMany, check why it is here, can it be removed??
65 65
     //TODO Val #3379
66 66
//    @NotNull
67
    private FeatureTree<T> termTree;
67
    private GRAPH graph;
68 68

  
69 69
    /**
70 70
     * The {@link TermType type} of this term relation.
71
     * Must be the same type as for the {@link FeatureTree term collection}
71
     * Must be the same type as for the {@link TermTree term collection}
72 72
     * this node belongs to and as the term type of the term this node links to.
73 73
     */
74 74
    @XmlAttribute(name ="TermType")
......
84 84
    @XmlIDREF
85 85
    @XmlSchemaType(name = "IDREF")
86 86
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=DefinedTermBase.class)
87
    private T term;
87
    private TERM term;
88 88

  
89 89
 // ******************** CONSTRUCTOR ***************************************/
90 90

  
......
107 107
    /**
108 108
     * Returns the {@link DefinedTermBase term} <i>this</i> term tree node is based on.
109 109
     */
110
    public T getTerm() {
110
    public TERM getTerm() {
111 111
        return CdmBase.deproxy(term);
112 112
    }
113
    public void setTerm(T term) {
113
    public void setTerm(TERM term) {
114 114
        checkTermType(term);
115 115
        this.term = term;
116 116
    }
117 117

  
118 118

  
119
//*************************** TREE ************************************/
119
//*************************** GRAPH ************************************/
120 120

  
121
    public FeatureTree<T> getFeatureTree() {
122
        return termTree;
121
    public GRAPH getGraph() {
122
        return graph;
123 123
    }
124 124

  
125
    protected void setFeatureTree(FeatureTree<T> featureTree) {
126
        checkTermType(featureTree);
127
        this.termTree = featureTree;
125
    protected void setGraph(GRAPH graph) {
126
        checkTermType(graph);
127
        this.graph = graph;
128 128
    }
129 129

  
130 130

  
......
142 142
    @SuppressWarnings("unchecked")
143 143
    @Override
144 144
    public Object clone() throws CloneNotSupportedException{
145
        TermRelationBase<T> result;
146
        result = (TermRelationBase<T>)super.clone();
145
        TermRelationBase<TERM, REL, GRAPH> result;
146
        result = (TermRelationBase<TERM, REL, GRAPH>)super.clone();
147 147
        return result;
148 148
    }
149 149
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermTree.java
15 15
import java.util.Set;
16 16
import java.util.UUID;
17 17

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

  
33 29
import org.apache.log4j.Logger;
34 30
import org.hibernate.annotations.Cascade;
35 31
import org.hibernate.annotations.CascadeType;
36
import org.hibernate.annotations.Type;
37 32
import org.hibernate.envers.Audited;
38 33

  
39 34
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
......
60 55
@XmlAccessorType(XmlAccessType.FIELD)
61 56
@XmlType(name = "TermTree", propOrder = {
62 57
    "root",
63
    "termType",
64
    "allowDuplicates",
65
    "representations"
66

  
67 58
})
68 59
@XmlRootElement(name = "TermTree")
69 60
@Entity
......
88 79
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
89 80
	private TermTreeNode<T> root;
90 81

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

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

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

  
122 83
//******************** FACTORY METHODS ******************************************/
123 84

  
......
189 150
	 * {@link #getRoot() root node}.
190 151
	 */
191 152
	protected TermTree(TermType termType) {
192
        this.termType = termType;
193
        checkTermType(this);  //check not null
153
        super(termType);
194 154
		root = new TermTreeNode<>(termType);
195
		root.setFeatureTree(this);
155
		root.setGraph((TermTree)this);
196 156
	}
197 157

  
198 158
// ****************** GETTER / SETTER **********************************/
199 159

  
200
	@Override
201
    public TermType getTermType() {
202
        return termType;
203
    }
204 160
    /**
205 161
	 * Returns the topmost {@link TermTreeNode feature node} (root node) of <i>this</i>
206 162
	 * feature tree. The root node does not have any parent. Since feature nodes
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermTreeNode.java
72 72
@Entity
73 73
@Audited
74 74
public class TermTreeNode <T extends DefinedTermBase>
75
            extends TermRelationBase<T>
75
            extends TermRelationBase<T, TermTreeNode<T>, TermTree>
76 76
            implements ITreeNode<TermTreeNode<T>> {
77 77

  
78 78
    private static final Logger logger = Logger.getLogger(TermTreeNode.class);
79 79

  
80

  
81 80
    @XmlElement(name = "Parent")
82 81
    @XmlIDREF
83 82
    @XmlSchemaType(name = "IDREF")
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermVocabulary.java
25 25
import javax.persistence.InheritanceType;
26 26
import javax.persistence.OneToMany;
27 27
import javax.persistence.Table;
28
import javax.persistence.Transient;
29 28
import javax.xml.bind.annotation.XmlAccessType;
30 29
import javax.xml.bind.annotation.XmlAccessorType;
31 30
import javax.xml.bind.annotation.XmlElement;
......
66 65
@Audited
67 66
@Table(name="TermCollection")
68 67
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
69
public class TermVocabulary<T extends DefinedTermBase> extends TermBase implements Iterable<T> {
70
	private static final long serialVersionUID = 1925052321596648672L;
68
public class TermVocabulary<T extends DefinedTermBase>
69
        extends TermCollection<T>
70
        implements Iterable<T> {
71

  
72
    private static final long serialVersionUID = 1925052321596648672L;
71 73
	private static final Logger logger = Logger.getLogger(TermVocabulary.class);
72 74

  
73
	//The vocabulary source (e.g. ontology) defining the terms to be loaded when a database is created for the first time.
74
	// Software can go and grap these terms incl labels and description.
75
	//The vocabulary source (e.g. ontology) defining the terms to be loaded when a database
76
	//is created for the first time.
77
	// Software can go and grap these terms incl. labels and description.
75 78
	// UUID needed? Further vocs can be setup through our own ontology.
76 79
	@XmlElement(name = "TermSourceURI")
77 80
	@Type(type="uriUserType")
78 81
	@Field(analyze = Analyze.NO)
79 82
	private URI termSourceUri;
80 83

  
81

  
82
	//TODO Changed
83 84
	@XmlElementWrapper(name = "Terms")
84 85
	@XmlElement(name = "Term")
85 86
    @XmlIDREF
......
88 89
	@Type(type="DefinedTermBase")
89 90
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
90 91
	@IndexedEmbedded(depth = 2)
91
	protected Set<T> terms = getNewTermSet();
92
	protected Set<T> terms = newTermSet();
92 93

  
93 94
// ********************************* FACTORY METHODS *****************************************/
94 95

  
......
123 124
	}
124 125

  
125 126

  
127
	protected Set<T> newTermSet(){
128
	    return new HashSet<>();
129
	}
130

  
126 131
// ******************* METHODS *************************************************/
127 132

  
128 133
	public T findTermByUuid(UUID uuid){
......
134 139
		return null;
135 140
	}
136 141

  
137
	@Transient
138
	Set<T> getNewTermSet() {
139
		return new HashSet<T>();
140
	}
141 142

  
142 143
	public Set<T> getTerms() {
143 144
		return terms;
cdmlib-model/src/test/java/eu/etaxonomy/cdm/model/term/OrderedTermVocabularyTest.java
22 22
import org.junit.Ignore;
23 23
import org.junit.Test;
24 24

  
25
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
26
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
27
import eu.etaxonomy.cdm.model.term.TermType;
28
import eu.etaxonomy.cdm.model.term.TermVocabulary;
29 25
import eu.etaxonomy.cdm.test.unit.EntityTestBase;
30 26

  
31 27

  
......
81 77

  
82 78
	@Test
83 79
	public final void testGetNewTermSet() {
84
		assertNotNull(oVoc1.getNewTermSet());
85
		assertTrue(SortedSet.class.isAssignableFrom(oVoc1.getNewTermSet().getClass()));
80
		assertNotNull(oVoc1.newTermSet());
81
		assertTrue(SortedSet.class.isAssignableFrom(oVoc1.newTermSet().getClass()));
86 82
	}
87 83

  
88 84

  

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)