Revision b6b3cb35
Added by Andreas Müller about 5 years ago
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") |
Also available in: Unified diff
ref #8162 move FeatureTree and FeatureNode to term package