Project

General

Profile

Revision 76463827

ID7646382768282404c14b12c81acad40e55b1151f
Parent 3af337bb
Child 10ae9cf0

Added by Andreas Müller 12 months ago

ref #6794 rename TermTreeNode -> TermNode

View differences:

cdmlib-cache/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml
217 217
      <mapping class="eu.etaxonomy.cdm.model.term.TermRelationshipType"/>
218 218
      <mapping class="eu.etaxonomy.cdm.model.term.TermTree"/>
219 219
      <mapping class="eu.etaxonomy.cdm.model.term.TermGraph"/>
220
      <mapping class="eu.etaxonomy.cdm.model.term.TermTreeNode"/>
220
      <mapping class="eu.etaxonomy.cdm.model.term.TermNode"/>
221 221
      <mapping class="eu.etaxonomy.cdm.model.term.TermRelation"/>
222 222
      <mapping class="eu.etaxonomy.cdm.model.term.TermVocabulary"/>
223 223
      
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/owl/in/OwlImportUtil.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.io.descriptive.owl.in;
10

  
11
import java.net.URI;
12
import java.util.Collections;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

  
18
import com.hp.hpl.jena.rdf.model.Model;
19
import com.hp.hpl.jena.rdf.model.Resource;
20
import com.hp.hpl.jena.rdf.model.Statement;
21

  
22
import eu.etaxonomy.cdm.api.application.ICdmRepository;
23
import eu.etaxonomy.cdm.common.CdmUtils;
24
import eu.etaxonomy.cdm.io.descriptive.owl.OwlUtil;
25
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
26
import eu.etaxonomy.cdm.model.common.Language;
27
import eu.etaxonomy.cdm.model.description.Character;
28
import eu.etaxonomy.cdm.model.description.Feature;
29
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
30
import eu.etaxonomy.cdm.model.description.State;
31
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
32
import eu.etaxonomy.cdm.model.media.Media;
33
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
34
import eu.etaxonomy.cdm.model.reference.Reference;
35
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
36
import eu.etaxonomy.cdm.model.term.DefinedTerm;
37
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
38
import eu.etaxonomy.cdm.model.term.Representation;
39
import eu.etaxonomy.cdm.model.term.TermTreeNode;
40
import eu.etaxonomy.cdm.model.term.TermType;
41
import eu.etaxonomy.cdm.model.term.TermVocabulary;
42

  
43
/**
44
 * @author pplitzner
45
 * @since May 26, 2019
46
 *
47
 */
48
public class OwlImportUtil {
49

  
50
    static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(OwlImportUtil.class);
51

  
52
    private static void addFeatureProperties(Feature feature, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
53
        if(termResource.hasProperty(OwlUtil.propFeatureIsCategorical)){
54
            feature.setSupportsCategoricalData(termResource.getProperty(OwlUtil.propFeatureIsCategorical).getBoolean());
55
        }
56
        if(termResource.hasProperty(OwlUtil.propFeatureIsQuantitative)){
57
            feature.setSupportsQuantitativeData(termResource.getProperty(OwlUtil.propFeatureIsQuantitative).getBoolean());
58
        }
59
        // import measurement units
60
        Set<MeasurementUnit> measurementUnits = new HashSet<>();
61
        List<Statement> measurementUnitStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedMeasurementUnit).toList();
62
        for (Statement statement : measurementUnitStatements) {
63
            Resource measurementUnitResource = model.createResource(statement.getObject().toString());
64
            MeasurementUnit measurementUnit = findTerm(MeasurementUnit.class, measurementUnitResource, repo, model, state);
65
            if(measurementUnit==null){
66
                measurementUnit = MeasurementUnit.NewInstance();
67
                addTermProperties(measurementUnit, measurementUnitResource, repo, model, state);
68
            }
69
            measurementUnits.add(measurementUnit);
70
        }
71
        measurementUnits.forEach(unit->feature.addRecommendedMeasurementUnit(unit));
72
        // import modifier TODO: create entire vocabulary if it cannot be found
73
        Set<TermVocabulary<DefinedTerm>> modifierVocs = new HashSet<>();
74
        List<Statement> modifierEnumStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedModifierEnumeration).toList();
75
        for (Statement statement : modifierEnumStatements) {
76
            Resource modifierEnumResource = model.createResource(statement.getObject().toString());
77
            TermVocabulary modifierVoc = findVocabulary(modifierEnumResource, repo, model, state);
78
            if(modifierVoc!=null){
79
                modifierVocs.add(modifierVoc);
80
            }
81
        }
82
        modifierVocs.forEach(modiferVoc->feature.addRecommendedModifierEnumeration(modiferVoc));
83
        // import statistical measures
84
        Set<StatisticalMeasure> statisticalMeasures = new HashSet<>();
85
        List<Statement> statisticalMeasureStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedStatisticalMeasure).toList();
86
        for (Statement statement : statisticalMeasureStatements) {
87
            Resource statisticalMeasureResource = model.createResource(statement.getObject().toString());
88
            StatisticalMeasure statisticalMeasure = findTerm(StatisticalMeasure.class, statisticalMeasureResource, repo, model, state);
89
            if(statisticalMeasure==null){
90
                statisticalMeasure = StatisticalMeasure.NewInstance();
91
                addTermProperties(statisticalMeasure, statisticalMeasureResource, repo, model, state);
92
            }
93
            statisticalMeasures.add(statisticalMeasure);
94
        }
95
        statisticalMeasures.forEach(statisticalMeasure->feature.addRecommendedStatisticalMeasure(statisticalMeasure));
96
        // import categorical enums TODO: create entire vocabulary if it cannot be found
97
        Set<TermVocabulary<State>> stateVocs = new HashSet<>();
98
        List<Statement> stateVocStatements = termResource.listProperties(OwlUtil.propFeatureHasSupportedCategoricalEnumeration).toList();
99
        for (Statement statement : stateVocStatements) {
100
            Resource stateVocResource = model.createResource(statement.getObject().toString());
101
            TermVocabulary stateVoc = findVocabulary(stateVocResource, repo, model, state);
102
            if(stateVoc!=null){
103
                stateVocs.add(stateVoc);
104
            }
105
        }
106
        stateVocs.forEach(stateVoc->feature.addSupportedCategoricalEnumeration(stateVoc));
107
    }
108

  
109
    private static void addCharacterProperties(Character character, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
110
        addFeatureProperties(character, termResource, repo, model, state);
111
        // TODO import/export of complete term tree of structures and properties belonging to a character is necessary
112
        // import structure
113
        Statement structureStatement = termResource.getProperty(OwlUtil.propCharacterHasStructure);
114
        Resource structureResource = model.createResource(structureStatement.getObject().toString());
115
        TermTreeNode structureNode = findNode(structureResource, repo, model, state);
116
        if(structureNode!=null){
117
            character.setStructure(structureNode);
118
        }
119
        // import property
120
        Statement propertyStatement = termResource.getProperty(OwlUtil.propCharacterHasProperty);
121
        Resource propertyResource = model.createResource(propertyStatement.getObject().toString());
122
        TermTreeNode propertyNode = findNode(propertyResource, repo, model, state);
123
        if(propertyNode!=null){
124
            character.setProperty(propertyNode);
125
        }
126
        // import structure modifier
127
        if(termResource.hasProperty(OwlUtil.propCharacterHasStructureModfier)){
128
            Statement structureModifierStatement = termResource.getProperty(OwlUtil.propCharacterHasStructureModfier);
129
            Resource structureModifierResource = model.createResource(structureModifierStatement.getObject().toString());
130
            DefinedTerm structureModifier = findTerm(DefinedTerm.class, structureModifierResource, repo, model, state);
131
            character.setStructureModifier(structureModifier);
132
        }
133
    }
134

  
135
    private static void addTermProperties(DefinedTermBase term, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
136
        term.setUuid(UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString()));
137

  
138
        // term URI
139
        String uriString = termResource.hasProperty(OwlUtil.propUri)?termResource.getProperty(OwlUtil.propUri).getString():null;
140
        if(CdmUtils.isNotBlank(uriString)){
141
            term.setUri(URI.create(uriString));
142
        }
143
        // symbol
144
        String symbolString = termResource.hasProperty(OwlUtil.propTermSymbol)?termResource.getProperty(OwlUtil.propTermSymbol).getString():null;
145
        if(CdmUtils.isNotBlank(symbolString)){
146
            term.setSymbol(symbolString);
147
        }
148
        // symbol2
149
        String symbol2String = termResource.hasProperty(OwlUtil.propTermSymbol2)?termResource.getProperty(OwlUtil.propTermSymbol2).getString():null;
150
        if(CdmUtils.isNotBlank(symbol2String)){
151
            term.setSymbol2(symbol2String);
152
        }
153
        // idInVocabulary
154
        String idInVocabularyString = termResource.hasProperty(OwlUtil.propTermIdInVocabulary)?termResource.getProperty(OwlUtil.propTermIdInVocabulary).getString():null;
155
        if(CdmUtils.isNotBlank(idInVocabularyString)){
156
            term.setIdInVocabulary(idInVocabularyString);
157
        }
158

  
159
        // import representations
160
        Set<Representation> representations = new HashSet<>();
161
        termResource.listProperties(OwlUtil.propHasRepresentation).forEachRemaining(r->representations.add(OwlImportUtil.createRepresentation(repo, r, model)));
162
        if(representations.isEmpty()){
163
            logger.error("No representations found for term: "+termResource.getProperty(OwlUtil.propUuid));
164
        }
165
        representations.forEach(rep->term.addRepresentation(rep));
166

  
167
        // import sources
168
        Set<IdentifiableSource> sources = new HashSet<>();
169
        termResource.listProperties(OwlUtil.propTermHasSource).forEachRemaining(sourceStatement->sources.add(OwlImportUtil.createSource(sourceStatement, repo, model)));
170
        sources.forEach(source->term.addSource(source));
171

  
172
        // add import source
173
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(termResource.getURI());
174
        importSource.setCitation(state.getConfig().getSourceReference());
175
        term.addSource(importSource);
176
    }
177

  
178
    private static <T extends DefinedTermBase> T findTerm(Class<T> clazz, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
179
        UUID termUuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
180
        List<T> terms = repo.getTermService().find(clazz, Collections.singleton(termUuid));
181
        if(!terms.isEmpty()){
182
            return terms.iterator().next();
183
        }
184
        return null;
185
    }
186

  
187
    private static TermVocabulary findVocabulary(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
188
        UUID termUuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
189
        return repo.getVocabularyService().find(termUuid);
190
    }
191

  
192
    private static TermTreeNode findNode(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
193
        UUID uuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
194
        return repo.getFeatureNodeService().find(uuid);
195
    }
196

  
197
    private static Reference findReference(Resource resource, ICdmRepository repo){
198
        UUID uuid = UUID.fromString(resource.getProperty(OwlUtil.propUuid).getString());
199
        return repo.getReferenceService().find(uuid);
200
    }
201

  
202
    static Media findMedia(Resource resource, ICdmRepository repo){
203
        UUID uuid = UUID.fromString(resource.getProperty(OwlUtil.propUuid).getString());
204
        return repo.getMediaService().find(uuid);
205
    }
206

  
207
    static Feature createFeature(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
208
        Feature feature = findTerm(Feature.class, termResource, repo, model, state);
209
        if(feature==null){
210
            feature = Feature.NewInstance();
211
            addFeatureProperties(feature, termResource, repo, model, state);
212
        }
213
        return feature;
214
    }
215

  
216
    private static Character createCharacter(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
217
        Character character = findTerm(Character.class, termResource, repo, model, state);
218
        if(character==null){
219
            character = Character.NewInstance();
220
            addCharacterProperties(character, termResource, repo, model, state);
221
        }
222
        return character;
223
    }
224

  
225
    static DefinedTermBase createTerm(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
226
        TermType termType = TermType.getByKey(termResource.getProperty(OwlUtil.propType).getString());
227
        DefinedTermBase term = null;
228
        // create new term
229
        if(termType.equals(TermType.Feature)){
230
            term = createFeature(termResource, repo, model, state);
231
        }
232
        else if(termType.equals(TermType.Character)){
233
            term = createCharacter(termResource, repo, model, state);
234
        }
235
        else{
236
            term = DefinedTerm.NewInstance(termType);
237
        }
238
        addTermProperties(term, termResource, repo, model, state);
239
        return term;
240
    }
241

  
242
    static IdentifiableSource createSource(Statement sourceStatement, ICdmRepository repo, Model model) {
243
        Resource sourceResource = model.createResource(sourceStatement.getObject().toString());
244

  
245
        String typeString = sourceResource.getProperty(OwlUtil.propSourceType).getString();
246
        IdentifiableSource source = IdentifiableSource.NewInstance(OriginalSourceType.getByKey(typeString));
247

  
248
        if(sourceResource.hasProperty(OwlUtil.propSourceIdInSource)){
249
            String idInSource = sourceResource.getProperty(OwlUtil.propSourceIdInSource).getString();
250
            source.setIdInSource(idInSource);
251
        }
252

  
253
        // import citation
254
        List<Statement> citationStatements = sourceResource.listProperties(OwlUtil.propSourceHasCitation).toList();
255
        if(citationStatements.size()>1){
256
            logger.error("More than one citations found for source. Choosing one arbitrarily. - "+sourceResource.toString());
257
        }
258
        if(!citationStatements.isEmpty()){
259
            Statement citationStatement = citationStatements.iterator().next();
260
            Resource citationResource = model.createResource(citationStatement.getObject().toString());
261
            Reference reference = findReference(citationResource, repo);
262
            if(reference==null){
263
                reference = createReference(citationResource, model);
264
            }
265
            source.setCitation(reference);
266
        }
267
        return source;
268
    }
269

  
270
    static Reference createReference(Resource citationResource, Model model){
271
        String titleString = citationResource.getProperty(OwlUtil.propReferenceTitle).getString();
272
        Reference citation = ReferenceFactory.newGeneric();
273
        citation.setTitle(titleString);
274
        return citation;
275
    }
276

  
277
    static TermVocabulary createVocabulary(Resource vocabularyResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
278
        TermType termType = TermType.getByKey(vocabularyResource.getProperty(OwlUtil.propType).getString());
279
        // create new vocabulary
280
        TermVocabulary vocabulary = TermVocabulary.NewInstance(termType);
281
        vocabulary.setUuid(UUID.fromString(vocabularyResource.getProperty(OwlUtil.propUuid).getString()));
282

  
283
        // voc URI
284
        String vocUriString = vocabularyResource.hasProperty(OwlUtil.propUri)?vocabularyResource.getProperty(OwlUtil.propUri).getString():null;
285
        if(CdmUtils.isNotBlank(vocUriString)){
286
            vocabulary.setUri(URI.create(vocUriString));
287
        }
288

  
289
        // voc representations
290
        Set<Representation> vocRepresentations = new HashSet<>();
291
        vocabularyResource.listProperties(OwlUtil.propHasRepresentation).forEachRemaining(r->vocRepresentations.add(OwlImportUtil.createRepresentation(repo, r, model)));
292
        if(vocRepresentations.isEmpty()){
293
            logger.error("No representations found for vocabulary: "+vocabularyResource.getProperty(OwlUtil.propUuid));
294
        }
295
        vocRepresentations.forEach(rep->vocabulary.addRepresentation(rep));
296

  
297
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(vocabularyResource.getURI());
298
        importSource.setCitation(state.getConfig().getSourceReference());
299
        vocabulary.addSource(importSource);
300

  
301

  
302
        return vocabulary;
303
    }
304

  
305
    static Media createMedia(Resource mediaResource, StructureTreeOwlImportState state){
306
        URI mediaUri = URI.create(mediaResource.getProperty(OwlUtil.propMediaUri).getString());
307
        // create new media
308
        Media media = Media.NewInstance(mediaUri, null, null, null);
309
        media.setUuid(UUID.fromString(mediaResource.getProperty(OwlUtil.propUuid).getString()));
310

  
311
        if(mediaResource.hasProperty(OwlUtil.propMediaTitle)){
312
            // TODO: support multiple language titles
313
            media.putTitle(Language.DEFAULT(), mediaResource.getProperty(OwlUtil.propMediaTitle).getString());
314
        }
315

  
316
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(mediaResource.getURI());
317
        importSource.setCitation(state.getConfig().getSourceReference());
318
        media.addSource(importSource);
319

  
320
        return media;
321
    }
322

  
323
    static Representation createRepresentation(ICdmRepository repo, Statement repr, Model model) {
324
        Resource repsentationResource = model.createResource(repr.getObject().toString());
325

  
326
        String languageLabel = repsentationResource.getProperty(OwlUtil.propLanguage).getString();
327
        UUID languageUuid = UUID.fromString(repsentationResource.getProperty(OwlUtil.propLanguageUuid).getString());
328
        Language language = Language.getLanguageFromUuid(languageUuid);
329
        if(language==null){
330
            language = repo.getTermService().getLanguageByLabel(languageLabel);
331
        }
332
        if(language==null){
333
            language = Language.getDefaultLanguage();
334
        }
335

  
336
        String abbreviatedLabel = repsentationResource.hasProperty(OwlUtil.propLabelAbbrev)?repsentationResource.getProperty(OwlUtil.propLabelAbbrev).getString():null;
337
        String plural = repsentationResource.hasProperty(OwlUtil.propLabelPlural)?repsentationResource.getProperty(OwlUtil.propLabelPlural).getString():null;
338
        String label = repsentationResource.getProperty(OwlUtil.propLabel).getString();
339
        String description = repsentationResource.hasProperty(OwlUtil.propDescription)?repsentationResource.getProperty(OwlUtil.propDescription).getString():null;
340
        Representation representation = Representation.NewInstance(description, label, abbreviatedLabel, language);
341
        representation.setPlural(plural);
342

  
343
        return representation;
344
    }
345

  
346
}
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.io.descriptive.owl.in;
10

  
11
import java.net.URI;
12
import java.util.Collections;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

  
18
import com.hp.hpl.jena.rdf.model.Model;
19
import com.hp.hpl.jena.rdf.model.Resource;
20
import com.hp.hpl.jena.rdf.model.Statement;
21

  
22
import eu.etaxonomy.cdm.api.application.ICdmRepository;
23
import eu.etaxonomy.cdm.common.CdmUtils;
24
import eu.etaxonomy.cdm.io.descriptive.owl.OwlUtil;
25
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
26
import eu.etaxonomy.cdm.model.common.Language;
27
import eu.etaxonomy.cdm.model.description.Character;
28
import eu.etaxonomy.cdm.model.description.Feature;
29
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
30
import eu.etaxonomy.cdm.model.description.State;
31
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
32
import eu.etaxonomy.cdm.model.media.Media;
33
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
34
import eu.etaxonomy.cdm.model.reference.Reference;
35
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
36
import eu.etaxonomy.cdm.model.term.DefinedTerm;
37
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
38
import eu.etaxonomy.cdm.model.term.Representation;
39
import eu.etaxonomy.cdm.model.term.TermNode;
40
import eu.etaxonomy.cdm.model.term.TermType;
41
import eu.etaxonomy.cdm.model.term.TermVocabulary;
42

  
43
/**
44
 * @author pplitzner
45
 * @since May 26, 2019
46
 *
47
 */
48
public class OwlImportUtil {
49

  
50
    static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(OwlImportUtil.class);
51

  
52
    private static void addFeatureProperties(Feature feature, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
53
        if(termResource.hasProperty(OwlUtil.propFeatureIsCategorical)){
54
            feature.setSupportsCategoricalData(termResource.getProperty(OwlUtil.propFeatureIsCategorical).getBoolean());
55
        }
56
        if(termResource.hasProperty(OwlUtil.propFeatureIsQuantitative)){
57
            feature.setSupportsQuantitativeData(termResource.getProperty(OwlUtil.propFeatureIsQuantitative).getBoolean());
58
        }
59
        // import measurement units
60
        Set<MeasurementUnit> measurementUnits = new HashSet<>();
61
        List<Statement> measurementUnitStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedMeasurementUnit).toList();
62
        for (Statement statement : measurementUnitStatements) {
63
            Resource measurementUnitResource = model.createResource(statement.getObject().toString());
64
            MeasurementUnit measurementUnit = findTerm(MeasurementUnit.class, measurementUnitResource, repo, model, state);
65
            if(measurementUnit==null){
66
                measurementUnit = MeasurementUnit.NewInstance();
67
                addTermProperties(measurementUnit, measurementUnitResource, repo, model, state);
68
            }
69
            measurementUnits.add(measurementUnit);
70
        }
71
        measurementUnits.forEach(unit->feature.addRecommendedMeasurementUnit(unit));
72
        // import modifier TODO: create entire vocabulary if it cannot be found
73
        Set<TermVocabulary<DefinedTerm>> modifierVocs = new HashSet<>();
74
        List<Statement> modifierEnumStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedModifierEnumeration).toList();
75
        for (Statement statement : modifierEnumStatements) {
76
            Resource modifierEnumResource = model.createResource(statement.getObject().toString());
77
            TermVocabulary modifierVoc = findVocabulary(modifierEnumResource, repo, model, state);
78
            if(modifierVoc!=null){
79
                modifierVocs.add(modifierVoc);
80
            }
81
        }
82
        modifierVocs.forEach(modiferVoc->feature.addRecommendedModifierEnumeration(modiferVoc));
83
        // import statistical measures
84
        Set<StatisticalMeasure> statisticalMeasures = new HashSet<>();
85
        List<Statement> statisticalMeasureStatements = termResource.listProperties(OwlUtil.propFeatureHasRecommendedStatisticalMeasure).toList();
86
        for (Statement statement : statisticalMeasureStatements) {
87
            Resource statisticalMeasureResource = model.createResource(statement.getObject().toString());
88
            StatisticalMeasure statisticalMeasure = findTerm(StatisticalMeasure.class, statisticalMeasureResource, repo, model, state);
89
            if(statisticalMeasure==null){
90
                statisticalMeasure = StatisticalMeasure.NewInstance();
91
                addTermProperties(statisticalMeasure, statisticalMeasureResource, repo, model, state);
92
            }
93
            statisticalMeasures.add(statisticalMeasure);
94
        }
95
        statisticalMeasures.forEach(statisticalMeasure->feature.addRecommendedStatisticalMeasure(statisticalMeasure));
96
        // import categorical enums TODO: create entire vocabulary if it cannot be found
97
        Set<TermVocabulary<State>> stateVocs = new HashSet<>();
98
        List<Statement> stateVocStatements = termResource.listProperties(OwlUtil.propFeatureHasSupportedCategoricalEnumeration).toList();
99
        for (Statement statement : stateVocStatements) {
100
            Resource stateVocResource = model.createResource(statement.getObject().toString());
101
            TermVocabulary stateVoc = findVocabulary(stateVocResource, repo, model, state);
102
            if(stateVoc!=null){
103
                stateVocs.add(stateVoc);
104
            }
105
        }
106
        stateVocs.forEach(stateVoc->feature.addSupportedCategoricalEnumeration(stateVoc));
107
    }
108

  
109
    private static void addCharacterProperties(Character character, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
110
        addFeatureProperties(character, termResource, repo, model, state);
111
        // TODO import/export of complete term tree of structures and properties belonging to a character is necessary
112
        // import structure
113
        Statement structureStatement = termResource.getProperty(OwlUtil.propCharacterHasStructure);
114
        Resource structureResource = model.createResource(structureStatement.getObject().toString());
115
        TermNode structureNode = findNode(structureResource, repo, model, state);
116
        if(structureNode!=null){
117
            character.setStructure(structureNode);
118
        }
119
        // import property
120
        Statement propertyStatement = termResource.getProperty(OwlUtil.propCharacterHasProperty);
121
        Resource propertyResource = model.createResource(propertyStatement.getObject().toString());
122
        TermNode propertyNode = findNode(propertyResource, repo, model, state);
123
        if(propertyNode!=null){
124
            character.setProperty(propertyNode);
125
        }
126
        // import structure modifier
127
        if(termResource.hasProperty(OwlUtil.propCharacterHasStructureModfier)){
128
            Statement structureModifierStatement = termResource.getProperty(OwlUtil.propCharacterHasStructureModfier);
129
            Resource structureModifierResource = model.createResource(structureModifierStatement.getObject().toString());
130
            DefinedTerm structureModifier = findTerm(DefinedTerm.class, structureModifierResource, repo, model, state);
131
            character.setStructureModifier(structureModifier);
132
        }
133
    }
134

  
135
    private static void addTermProperties(DefinedTermBase term, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
136
        term.setUuid(UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString()));
137

  
138
        // term URI
139
        String uriString = termResource.hasProperty(OwlUtil.propUri)?termResource.getProperty(OwlUtil.propUri).getString():null;
140
        if(CdmUtils.isNotBlank(uriString)){
141
            term.setUri(URI.create(uriString));
142
        }
143
        // symbol
144
        String symbolString = termResource.hasProperty(OwlUtil.propTermSymbol)?termResource.getProperty(OwlUtil.propTermSymbol).getString():null;
145
        if(CdmUtils.isNotBlank(symbolString)){
146
            term.setSymbol(symbolString);
147
        }
148
        // symbol2
149
        String symbol2String = termResource.hasProperty(OwlUtil.propTermSymbol2)?termResource.getProperty(OwlUtil.propTermSymbol2).getString():null;
150
        if(CdmUtils.isNotBlank(symbol2String)){
151
            term.setSymbol2(symbol2String);
152
        }
153
        // idInVocabulary
154
        String idInVocabularyString = termResource.hasProperty(OwlUtil.propTermIdInVocabulary)?termResource.getProperty(OwlUtil.propTermIdInVocabulary).getString():null;
155
        if(CdmUtils.isNotBlank(idInVocabularyString)){
156
            term.setIdInVocabulary(idInVocabularyString);
157
        }
158

  
159
        // import representations
160
        Set<Representation> representations = new HashSet<>();
161
        termResource.listProperties(OwlUtil.propHasRepresentation).forEachRemaining(r->representations.add(OwlImportUtil.createRepresentation(repo, r, model)));
162
        if(representations.isEmpty()){
163
            logger.error("No representations found for term: "+termResource.getProperty(OwlUtil.propUuid));
164
        }
165
        representations.forEach(rep->term.addRepresentation(rep));
166

  
167
        // import sources
168
        Set<IdentifiableSource> sources = new HashSet<>();
169
        termResource.listProperties(OwlUtil.propTermHasSource).forEachRemaining(sourceStatement->sources.add(OwlImportUtil.createSource(sourceStatement, repo, model)));
170
        sources.forEach(source->term.addSource(source));
171

  
172
        // add import source
173
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(termResource.getURI());
174
        importSource.setCitation(state.getConfig().getSourceReference());
175
        term.addSource(importSource);
176
    }
177

  
178
    private static <T extends DefinedTermBase> T findTerm(Class<T> clazz, Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
179
        UUID termUuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
180
        List<T> terms = repo.getTermService().find(clazz, Collections.singleton(termUuid));
181
        if(!terms.isEmpty()){
182
            return terms.iterator().next();
183
        }
184
        return null;
185
    }
186

  
187
    private static TermVocabulary findVocabulary(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
188
        UUID termUuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
189
        return repo.getVocabularyService().find(termUuid);
190
    }
191

  
192
    private static TermNode findNode(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
193
        UUID uuid = UUID.fromString(termResource.getProperty(OwlUtil.propUuid).getString());
194
        return repo.getFeatureNodeService().find(uuid);
195
    }
196

  
197
    private static Reference findReference(Resource resource, ICdmRepository repo){
198
        UUID uuid = UUID.fromString(resource.getProperty(OwlUtil.propUuid).getString());
199
        return repo.getReferenceService().find(uuid);
200
    }
201

  
202
    static Media findMedia(Resource resource, ICdmRepository repo){
203
        UUID uuid = UUID.fromString(resource.getProperty(OwlUtil.propUuid).getString());
204
        return repo.getMediaService().find(uuid);
205
    }
206

  
207
    static Feature createFeature(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
208
        Feature feature = findTerm(Feature.class, termResource, repo, model, state);
209
        if(feature==null){
210
            feature = Feature.NewInstance();
211
            addFeatureProperties(feature, termResource, repo, model, state);
212
        }
213
        return feature;
214
    }
215

  
216
    private static Character createCharacter(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
217
        Character character = findTerm(Character.class, termResource, repo, model, state);
218
        if(character==null){
219
            character = Character.NewInstance();
220
            addCharacterProperties(character, termResource, repo, model, state);
221
        }
222
        return character;
223
    }
224

  
225
    static DefinedTermBase createTerm(Resource termResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
226
        TermType termType = TermType.getByKey(termResource.getProperty(OwlUtil.propType).getString());
227
        DefinedTermBase term = null;
228
        // create new term
229
        if(termType.equals(TermType.Feature)){
230
            term = createFeature(termResource, repo, model, state);
231
        }
232
        else if(termType.equals(TermType.Character)){
233
            term = createCharacter(termResource, repo, model, state);
234
        }
235
        else{
236
            term = DefinedTerm.NewInstance(termType);
237
        }
238
        addTermProperties(term, termResource, repo, model, state);
239
        return term;
240
    }
241

  
242
    static IdentifiableSource createSource(Statement sourceStatement, ICdmRepository repo, Model model) {
243
        Resource sourceResource = model.createResource(sourceStatement.getObject().toString());
244

  
245
        String typeString = sourceResource.getProperty(OwlUtil.propSourceType).getString();
246
        IdentifiableSource source = IdentifiableSource.NewInstance(OriginalSourceType.getByKey(typeString));
247

  
248
        if(sourceResource.hasProperty(OwlUtil.propSourceIdInSource)){
249
            String idInSource = sourceResource.getProperty(OwlUtil.propSourceIdInSource).getString();
250
            source.setIdInSource(idInSource);
251
        }
252

  
253
        // import citation
254
        List<Statement> citationStatements = sourceResource.listProperties(OwlUtil.propSourceHasCitation).toList();
255
        if(citationStatements.size()>1){
256
            logger.error("More than one citations found for source. Choosing one arbitrarily. - "+sourceResource.toString());
257
        }
258
        if(!citationStatements.isEmpty()){
259
            Statement citationStatement = citationStatements.iterator().next();
260
            Resource citationResource = model.createResource(citationStatement.getObject().toString());
261
            Reference reference = findReference(citationResource, repo);
262
            if(reference==null){
263
                reference = createReference(citationResource, model);
264
            }
265
            source.setCitation(reference);
266
        }
267
        return source;
268
    }
269

  
270
    static Reference createReference(Resource citationResource, Model model){
271
        String titleString = citationResource.getProperty(OwlUtil.propReferenceTitle).getString();
272
        Reference citation = ReferenceFactory.newGeneric();
273
        citation.setTitle(titleString);
274
        return citation;
275
    }
276

  
277
    static TermVocabulary createVocabulary(Resource vocabularyResource, ICdmRepository repo, Model model, StructureTreeOwlImportState state){
278
        TermType termType = TermType.getByKey(vocabularyResource.getProperty(OwlUtil.propType).getString());
279
        // create new vocabulary
280
        TermVocabulary vocabulary = TermVocabulary.NewInstance(termType);
281
        vocabulary.setUuid(UUID.fromString(vocabularyResource.getProperty(OwlUtil.propUuid).getString()));
282

  
283
        // voc URI
284
        String vocUriString = vocabularyResource.hasProperty(OwlUtil.propUri)?vocabularyResource.getProperty(OwlUtil.propUri).getString():null;
285
        if(CdmUtils.isNotBlank(vocUriString)){
286
            vocabulary.setUri(URI.create(vocUriString));
287
        }
288

  
289
        // voc representations
290
        Set<Representation> vocRepresentations = new HashSet<>();
291
        vocabularyResource.listProperties(OwlUtil.propHasRepresentation).forEachRemaining(r->vocRepresentations.add(OwlImportUtil.createRepresentation(repo, r, model)));
292
        if(vocRepresentations.isEmpty()){
293
            logger.error("No representations found for vocabulary: "+vocabularyResource.getProperty(OwlUtil.propUuid));
294
        }
295
        vocRepresentations.forEach(rep->vocabulary.addRepresentation(rep));
296

  
297
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(vocabularyResource.getURI());
298
        importSource.setCitation(state.getConfig().getSourceReference());
299
        vocabulary.addSource(importSource);
300

  
301

  
302
        return vocabulary;
303
    }
304

  
305
    static Media createMedia(Resource mediaResource, StructureTreeOwlImportState state){
306
        URI mediaUri = URI.create(mediaResource.getProperty(OwlUtil.propMediaUri).getString());
307
        // create new media
308
        Media media = Media.NewInstance(mediaUri, null, null, null);
309
        media.setUuid(UUID.fromString(mediaResource.getProperty(OwlUtil.propUuid).getString()));
310

  
311
        if(mediaResource.hasProperty(OwlUtil.propMediaTitle)){
312
            // TODO: support multiple language titles
313
            media.putTitle(Language.DEFAULT(), mediaResource.getProperty(OwlUtil.propMediaTitle).getString());
314
        }
315

  
316
        IdentifiableSource importSource = IdentifiableSource.NewDataImportInstance(mediaResource.getURI());
317
        importSource.setCitation(state.getConfig().getSourceReference());
318
        media.addSource(importSource);
319

  
320
        return media;
321
    }
322

  
323
    static Representation createRepresentation(ICdmRepository repo, Statement repr, Model model) {
324
        Resource repsentationResource = model.createResource(repr.getObject().toString());
325

  
326
        String languageLabel = repsentationResource.getProperty(OwlUtil.propLanguage).getString();
327
        UUID languageUuid = UUID.fromString(repsentationResource.getProperty(OwlUtil.propLanguageUuid).getString());
328
        Language language = Language.getLanguageFromUuid(languageUuid);
329
        if(language==null){
330
            language = repo.getTermService().getLanguageByLabel(languageLabel);
331
        }
332
        if(language==null){
333
            language = Language.getDefaultLanguage();
334
        }
335

  
336
        String abbreviatedLabel = repsentationResource.hasProperty(OwlUtil.propLabelAbbrev)?repsentationResource.getProperty(OwlUtil.propLabelAbbrev).getString():null;
337
        String plural = repsentationResource.hasProperty(OwlUtil.propLabelPlural)?repsentationResource.getProperty(OwlUtil.propLabelPlural).getString():null;
338
        String label = repsentationResource.getProperty(OwlUtil.propLabel).getString();
339
        String description = repsentationResource.hasProperty(OwlUtil.propDescription)?repsentationResource.getProperty(OwlUtil.propDescription).getString():null;
340
        Representation representation = Representation.NewInstance(description, label, abbreviatedLabel, language);
341
        representation.setPlural(plural);
342

  
343
        return representation;
344
    }
345

  
346
}
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/owl/in/StructureTreeOwlImport.java
23 23
import eu.etaxonomy.cdm.model.description.Feature;
24 24
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
25 25
import eu.etaxonomy.cdm.model.term.TermTree;
26
import eu.etaxonomy.cdm.model.term.TermTreeNode;
26
import eu.etaxonomy.cdm.model.term.TermNode;
27 27
import eu.etaxonomy.cdm.model.term.TermType;
28 28
import eu.etaxonomy.cdm.model.term.TermVocabulary;
29 29

  
......
67 67
        }
68 68
    }
69 69

  
70
    private <T extends DefinedTermBase> void createNode(TermTreeNode<T> parent, Statement nodeStatement, String treeLabel, Model model, StructureTreeOwlImportState state) {
70
    private <T extends DefinedTermBase> void createNode(TermNode<T> parent, Statement nodeStatement, String treeLabel, Model model, StructureTreeOwlImportState state) {
71 71
        if(state.getConfig().getProgressMonitor().isCanceled()){
72 72
            return;
73 73
        }
......
95 95

  
96 96
        getVocabularyService().saveOrUpdate(vocabulary);
97 97

  
98
        TermTreeNode<?> childNode = parent.addChild(term);
98
        TermNode<?> childNode = parent.addChild(term);
99 99

  
100 100
        state.getConfig().getProgressMonitor().worked(1);
101 101

  
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/owl/out/OwlExportUtil.java
34 34
import eu.etaxonomy.cdm.model.term.Representation;
35 35
import eu.etaxonomy.cdm.model.term.TermBase;
36 36
import eu.etaxonomy.cdm.model.term.TermTree;
37
import eu.etaxonomy.cdm.model.term.TermTreeNode;
37
import eu.etaxonomy.cdm.model.term.TermNode;
38 38
import eu.etaxonomy.cdm.model.term.TermVocabulary;
39 39
import eu.etaxonomy.cdm.persistence.dto.TermDto;
40 40

  
......
267 267
                .addProperty(OwlUtil.propType, featureTree.getTermType().getKey())
268 268
                ;
269 269

  
270
        TermTreeNode rootNode = featureTree.getRoot();
270
        TermNode rootNode = featureTree.getRoot();
271 271

  
272 272
        Resource resourceRootNode = OwlExportUtil.createNodeResource(rootNode, false, repo, state);
273 273
        featureTreeResource.addProperty(OwlUtil.propHasRootNode, resourceRootNode);
......
277 277
        return featureTreeResource;
278 278
    }
279 279

  
280
    private static void addChildNode(TermTreeNode parentNode, Resource parentResourceNode, ICdmRepository repo, StructureTreeOwlExportState state){
281
        List<TermTreeNode> childNodes = parentNode.getChildNodes();
282
        for (TermTreeNode child : childNodes) {
280
    private static void addChildNode(TermNode parentNode, Resource parentResourceNode, ICdmRepository repo, StructureTreeOwlExportState state){
281
        List<TermNode> childNodes = parentNode.getChildNodes();
282
        for (TermNode child : childNodes) {
283 283
            // create node resource with term
284 284
            Resource nodeResource = OwlExportUtil.createNodeResource(child, false, repo, state);
285 285

  
......
290 290
        }
291 291
    }
292 292

  
293
    static Resource createNodeResource(TermTreeNode<Feature> node, boolean initFeatureTree, ICdmRepository repo, StructureTreeOwlExportState state) {
293
    static Resource createNodeResource(TermNode<Feature> node, boolean initFeatureTree, ICdmRepository repo, StructureTreeOwlExportState state) {
294 294
        if(initFeatureTree){
295 295
            createFeatureTreeResource(node.getGraph(), repo, state);
296 296
            return getNodeResource(node, state);
......
333 333
        return state.getModel().createResource(OwlUtil.RESOURCE_MEDIA+media.getUuid().toString());
334 334
    }
335 335

  
336
    private static Resource getNodeResource(TermTreeNode node, StructureTreeOwlExportState state) {
336
    private static Resource getNodeResource(TermNode node, StructureTreeOwlExportState state) {
337 337
        return state.getModel().createResource(OwlUtil.RESOURCE_NODE + node.getUuid().toString());
338 338
    }
339 339

  
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/descriptive/word/out/WordExport.java
21 21
import eu.etaxonomy.cdm.io.common.mapping.out.IExportTransformer;
22 22
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
23 23
import eu.etaxonomy.cdm.model.term.TermTree;
24
import eu.etaxonomy.cdm.model.term.TermTreeNode;
24
import eu.etaxonomy.cdm.model.term.TermNode;
25 25

  
26 26
/**
27 27
 *
......
46 46

  
47 47
        TermTree featureTree = state.getConfig().getFeatureTree();
48 48
        featureTree = getFeatureTreeService().load(featureTree.getUuid());
49
        TermTreeNode rootNode = featureTree.getRoot();
49
        TermNode rootNode = featureTree.getRoot();
50 50

  
51 51
        try {
52 52
            exportStream = generateDocx4JDocument(rootNode);
......
60 60
        return;
61 61
    }
62 62

  
63
    private ByteArrayOutputStream generateDocx4JDocument(TermTreeNode rootNode) throws Exception {
63
    private ByteArrayOutputStream generateDocx4JDocument(TermNode rootNode) throws Exception {
64 64
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("eu/etaxonomy/cdm/io/word/out/template.docx");
65 65
        WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(resourceAsStream);
66 66
        MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart();
......
110 110
//        return new JAXBElement( new QName(Namespaces.NS_WORD12, "fldChar"), org.docx4j.wml.FldChar.class, fldchar);
111 111
//    }
112 112

  
113
    private void addChildNode(TermTreeNode<?> node, MainDocumentPart mainDocumentPart, int indent) throws Exception{
113
    private void addChildNode(TermNode<?> node, MainDocumentPart mainDocumentPart, int indent) throws Exception{
114 114
        String styleId = "Heading"+indent;
115 115

  
116
        for (TermTreeNode childNode : node.getChildNodes()) {
116
        for (TermNode childNode : node.getChildNodes()) {
117 117
            DefinedTermBase term = childNode.getTerm();
118 118
            mainDocumentPart.addStyledParagraphOfText(styleId, term.getLabel());
119 119
            if(term.getDescription()!=null){
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/jaxb/JaxbImport.java
38 38
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
39 39
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
40 40
import eu.etaxonomy.cdm.model.term.TermTree;
41
import eu.etaxonomy.cdm.model.term.TermTreeNode;
41
import eu.etaxonomy.cdm.model.term.TermNode;
42 42
import eu.etaxonomy.cdm.model.term.TermVocabulary;
43 43

  
44 44
/**
......
118 118
		List<TypeDesignationBase<?>> typeDesignations;
119 119
		List<SpecimenOrObservationBase> occurrences;
120 120
		List<TermTree> featureTrees;
121
		List<TermTreeNode> featureNodes;
121
		List<TermNode> featureNodes;
122 122
		List<Media> media;
123 123
		List<LanguageStringBase> languageData;
124 124
		List<TermVocabulary<DefinedTermBase>> termVocabularies;
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupImportState.java
35 35
import eu.etaxonomy.cdm.model.occurrence.Collection;
36 36
import eu.etaxonomy.cdm.model.reference.Reference;
37 37
import eu.etaxonomy.cdm.model.taxon.Taxon;
38
import eu.etaxonomy.cdm.model.term.TermTreeNode;
38
import eu.etaxonomy.cdm.model.term.TermNode;
39 39

  
40 40
/**
41 41
 * @author a.mueller
......
51 51
	private UnmatchedLeads unmatchedLeads;
52 52
	private boolean onlyNumberedTaxaExist; //attribute in <key>
53 53

  
54
	private Set<TermTreeNode> featureNodesToSave = new HashSet<TermTreeNode>();
54
	private Set<TermNode> featureNodesToSave = new HashSet<TermNode>();
55 55

  
56 56
	private Set<PolytomousKeyNode> polytomousKeyNodesToSave = new HashSet<>();
57 57

  
......
115 115
	 * @see MarkupImportConfigurator#getNewState()
116 116
	 */
117 117
	protected void reset(){
118
		featureNodesToSave = new HashSet<TermTreeNode>();
118
		featureNodesToSave = new HashSet<TermNode>();
119 119
		polytomousKeyNodesToSave = new HashSet<PolytomousKeyNode>();
120 120
		currentKey = null;
121 121
		defaultLanguage = null;
......
154 154
		this.unmatchedLeads = unmatchedKeys;
155 155
	}
156 156

  
157
	public void setFeatureNodesToSave(Set<TermTreeNode> featureNodesToSave) {
157
	public void setFeatureNodesToSave(Set<TermNode> featureNodesToSave) {
158 158
		this.featureNodesToSave = featureNodesToSave;
159 159
	}
160 160

  
161
	public Set<TermTreeNode> getFeatureNodesToSave() {
161
	public Set<TermNode> getFeatureNodesToSave() {
162 162
		return featureNodesToSave;
163 163
	}
164 164

  
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/in/SDDImport.java
86 86
import eu.etaxonomy.cdm.model.term.Representation;
87 87
import eu.etaxonomy.cdm.model.term.TermBase;
88 88
import eu.etaxonomy.cdm.model.term.TermTree;
89
import eu.etaxonomy.cdm.model.term.TermTreeNode;
89
import eu.etaxonomy.cdm.model.term.TermNode;
90 90
import eu.etaxonomy.cdm.model.term.TermType;
91 91
import eu.etaxonomy.cdm.model.term.TermVocabulary;
92 92

  
......
106 106
    private Map<String,String> citations = new HashMap<>();
107 107
    private Map<String,String> defaultUnitPrefixes = new HashMap<>();
108 108
    private Map<String,Person> editors = new HashMap<>();
109
    private Map<String,TermTreeNode<Feature>> featureNodes = new HashMap<>();
109
    private Map<String,TermNode<Feature>> featureNodes = new HashMap<>();
110 110
    private Map<String,Feature> features = new HashMap<>();
111 111
    private Map<String,String> locations = new HashMap<>();
112 112
    private Map<String,List<CdmBase>> mediaObject_ListCdmBase = new HashMap<>();
......
1753 1753

  
1754 1754
					TermTree featureTree =  TermTree.NewInstance();
1755 1755
					importRepresentation(elCharacterTree, sddNamespace, featureTree, "", cdmState);
1756
					TermTreeNode<Feature> root = featureTree.getRoot();
1756
					TermNode<Feature> root = featureTree.getRoot();
1757 1757
					List<Element> listeOfNodes = elCharacterTree.getChildren("Nodes", sddNamespace);
1758 1758

  
1759 1759
					//Nodes of CharacterTrees in SDD always refer to DescriptiveConcepts
......
1784 1784
	 * @param root
1785 1785
	 * @param elNodes
1786 1786
	 */
1787
	private void handleCharacterNodes(Namespace sddNamespace, TermTreeNode<Feature> root, Element elNodes) {
1787
	private void handleCharacterNodes(Namespace sddNamespace, TermNode<Feature> root, Element elNodes) {
1788 1788
		List<Element> listNodes = elNodes.getChildren("Node", sddNamespace);
1789 1789
		if (listNodes != null) {
1790 1790
			for (Element elNode : listNodes){
1791 1791
				String idN = elNode.getAttributeValue("id");
1792
				TermTreeNode<Feature> fn = null;
1792
				TermNode<Feature> fn = null;
1793 1793
				Feature dc = null;
1794 1794
				if (idN!=null) {
1795 1795
					// DescriptiveConcepts are used as nodes in CharacterTrees
......
1803 1803
					if (elParent!=null){
1804 1804
						String refP = elParent.getAttributeValue("ref");
1805 1805
						if (refP!=null) {
1806
							TermTreeNode<Feature> parent = featureNodes.get(refP);
1806
							TermNode<Feature> parent = featureNodes.get(refP);
1807 1807
							if (parent==null){
1808 1808
							    // if no parent found or the reference is broken, add the node to the root of the tree
1809 1809
							    fn = (dc==null)?root.addChild():root.addChild(dc);
......
1830 1830
				Element elParent = elCharNode.getChild("Parent", sddNamespace);
1831 1831
				Element elCharacter = elCharNode.getChild("Character", sddNamespace);
1832 1832
				Element elDependencyRules = elCharNode.getChild("DependencyRules", sddNamespace);
1833
				TermTreeNode<Feature> fn = null;
1833
				TermNode<Feature> fn = null;
1834 1834

  
1835 1835
                if (elParent!=null){
1836 1836
                    String refP = elParent.getAttributeValue("ref");
1837 1837
                    if ((refP!=null)&&(!refP.equals(""))) {
1838
                        TermTreeNode<Feature> parent = featureNodes.get(refP);
1838
                        TermNode<Feature> parent = featureNodes.get(refP);
1839 1839
                        if (parent==null){
1840 1840
                            parent = root; // if no parent found or the reference is broken, add the node to the root of the tree
1841 1841
                        }
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/out/SDDDataSet.java
81 81
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
82 82
import eu.etaxonomy.cdm.model.term.Representation;
83 83
import eu.etaxonomy.cdm.model.term.TermTree;
84
import eu.etaxonomy.cdm.model.term.TermTreeNode;
84
import eu.etaxonomy.cdm.model.term.TermNode;
85 85
import eu.etaxonomy.cdm.model.term.TermVocabulary;
86 86

  
87 87
/**
......
133 133

  
134 134
    @XmlElementWrapper(name = "FeatureData")
135 135
    @XmlElements({
136
        @XmlElement(name = "FeatureNode", namespace = "http://etaxonomy.eu/cdm/model/description/1.0", type = TermTreeNode.class),
136
        @XmlElement(name = "FeatureNode", namespace = "http://etaxonomy.eu/cdm/model/description/1.0", type = TermNode.class),
137 137
        @XmlElement(name = "FeatureTree", namespace = "http://etaxonomy.eu/cdm/model/description/1.0", type = TermTree.class)
138 138
    })
139 139
//    protected List<VersionableEntity> featureData;
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/sdd/out/SDDDocumentBuilder.java
81 81
import eu.etaxonomy.cdm.model.term.Representation;
82 82
import eu.etaxonomy.cdm.model.term.TermBase;
83 83
import eu.etaxonomy.cdm.model.term.TermTree;
84
import eu.etaxonomy.cdm.model.term.TermTreeNode;
84
import eu.etaxonomy.cdm.model.term.TermNode;
85 85
import eu.etaxonomy.cdm.model.term.TermVocabulary;
86 86

  
87 87
/**
......
101 101
	private final Map<Person, String> agents = new HashMap<>();
102 102
	private final Map<TaxonName, String> taxonNames = new HashMap<>();
103 103
	private final Map<Feature, String> characters = new HashMap<>();
104
	private final Map<TermTreeNode, String> featureNodes = new HashMap<>();
104
	private final Map<TermNode, String> featureNodes = new HashMap<>();
105 105
	private final Map<Feature, String> descriptiveConcepts = new HashMap<>();
106 106
	private final Map<TaxonDescription, String> codedDescriptions = new HashMap<>();
107 107
	private final Map<Media, String> medias = new HashMap<>();
......
1197 1197
					elChartrees.appendChild(elChartree);
1198 1198
					ElementImpl elNodes = new ElementImpl(document, NODES);
1199 1199
					elChartree.appendChild(elNodes);
1200
					List<TermTreeNode> roots = ft.getRootChildren();
1201
					for (Iterator<TermTreeNode> fn = roots.iterator(); fn
1200
					List<TermNode> roots = ft.getRootChildren();
1201
					for (Iterator<TermNode> fn = roots.iterator(); fn
1202 1202
							.hasNext();) {
1203
						TermTreeNode featureNode = fn.next();
1203
						TermNode featureNode = fn.next();
1204 1204
						buildBranches(featureNode, elNodes, true);
1205 1205
					}
1206 1206
				}
......
1270 1270
		}
1271 1271
	}
1272 1272

  
1273
	public void buildBranches(TermTreeNode<Feature> parent, ElementImpl element,
1273
	public void buildBranches(TermNode<Feature> parent, ElementImpl element,
1274 1274
			boolean isRoot) {
1275
		List<TermTreeNode<Feature>> children = parent.getChildNodes();
1275
		List<TermNode<Feature>> children = parent.getChildNodes();
1276 1276
		if (!parent.isLeaf()) {
1277 1277
			ElementImpl elCharNode = new ElementImpl(document, NODE);
1278 1278
			charnodeCount = buildReference(parent, featuretrees, ID,
1279 1279
					elCharNode, "cn", charnodeCount);
1280
			TermTreeNode grandparent = parent.getParent();
1280
			TermNode grandparent = parent.getParent();
1281 1281
			if ((grandparent != null) && (!isRoot)) {
1282 1282
				ElementImpl elParent = new ElementImpl(document, PARENT);
1283 1283
				charnodeCount = buildReference(grandparent, featuretrees, REF,
......
1291 1291
					REF, elDescriptiveConcept, "dc", descriptiveConceptCount);
1292 1292
			elCharNode.appendChild(elDescriptiveConcept);
1293 1293
			element.appendChild(elCharNode);
1294
			for (Iterator<TermTreeNode<Feature>> ifn = children.iterator(); ifn.hasNext();) {
1295
				TermTreeNode fn = ifn.next();
1294
			for (Iterator<TermNode<Feature>> ifn = children.iterator(); ifn.hasNext();) {
1295
				TermNode fn = ifn.next();
1296 1296
				buildBranches(fn, element, false);
1297 1297
			}
1298 1298
		} else {
1299 1299
			ElementImpl elCharNode = new ElementImpl(document, CHAR_NODE);
1300 1300
			ElementImpl elParent = new ElementImpl(document, PARENT);
1301
			TermTreeNode grandparent = parent.getParent();
1301
			TermNode grandparent = parent.getParent();
1302 1302
			charnodeCount = buildReference(grandparent, featuretrees, REF,
1303 1303
					elParent, "cn", charnodeCount);
1304 1304
			charnodeCount = buildReference(parent, featuretrees, ID,
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/taxonx2013/TaxonXTreatmentExtractor.java
64 64
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
65 65
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
66 66
import eu.etaxonomy.cdm.model.term.TermTree;
67
import eu.etaxonomy.cdm.model.term.TermTreeNode;
67
import eu.etaxonomy.cdm.model.term.TermNode;
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;
......
322 322
            proibiospheretree.setUuid(proIbioTreeUUID);
323 323
        }
324 324

  
325
        TermTreeNode root2 = proibiospheretree.getRoot();
325
        TermNode root2 = proibiospheretree.getRoot();
326 326
        if (root2 != null){
327 327
            int nbChildren = root2.getChildCount()-1;
328 328
            while (nbChildren>-1){
cdmlib-io/src/main/resources/schema/cdm/description.xsd
35 35

  
36 36
  <xs:element name="Feature" type="description:Feature"/>
37 37

  
38
  <xs:element name="TermTreeNode" type="description:FeatureNode"/>
38
  <xs:element name="TermNode" type="description:FeatureNode"/>
39 39

  
40 40
  <xs:element name="FeatureTree" type="description:FeatureTree"/>
41 41
  
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/owl/in/StructureTreeOwlImportTest.java
46 46
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
47 47
import eu.etaxonomy.cdm.model.term.Representation;
48 48
import eu.etaxonomy.cdm.model.term.TermTree;
49
import eu.etaxonomy.cdm.model.term.TermTreeNode;
49
import eu.etaxonomy.cdm.model.term.TermNode;
50 50
import eu.etaxonomy.cdm.model.term.TermType;
51 51
import eu.etaxonomy.cdm.model.term.TermVocabulary;
52 52
import eu.etaxonomy.cdm.persistence.dto.TermDto;
......
108 108
        List rootChildren = tree.getRootChildren();
109 109
        assertEquals("Wrong number of root children", 1, rootChildren.size());
110 110
        Object entirePlant = rootChildren.iterator().next();
111
        assertTrue("Root is no feature node", entirePlant instanceof TermTreeNode);
112
        assertEquals("Root node has wrong term type", TermType.Structure, ((TermTreeNode)entirePlant).getTermType());
113
        TermTreeNode<DefinedTerm> entirePlantNode = (TermTreeNode<DefinedTerm>) entirePlant;
114
        List<TermTreeNode<DefinedTerm>> childNodes = entirePlantNode.getChildNodes();
111
        assertTrue("Root is no feature node", entirePlant instanceof TermNode);
112
        assertEquals("Root node has wrong term type", TermType.Structure, ((TermNode)entirePlant).getTermType());
113
        TermNode<DefinedTerm> entirePlantNode = (TermNode<DefinedTerm>) entirePlant;
114
        List<TermNode<DefinedTerm>> childNodes = entirePlantNode.getChildNodes();
115 115
        assertEquals("Wrong number of children", 2, childNodes.size());
116 116

  
117 117
        String inflorescenceLabel = "inflorescence";
......
121 121
        DefinedTerm inflorescence = records.iterator().next();
122 122
        assertEquals(inflorescenceLabel, inflorescence.getLabel(Language.ENGLISH()));
123 123

  
124
        for (TermTreeNode<DefinedTerm> featureNode : childNodes) {
124
        for (TermNode<DefinedTerm> featureNode : childNodes) {
125 125
            assertTrue("Child node not found. Found node with term: "+featureNode.getTerm().getLabel(),
126 126
                    featureNode.getTerm().getUuid().equals(inflorescence.getUuid())
127 127
                    || featureNode.getTerm().getLabel(Language.ENGLISH()).equals("Flower"));
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/owl/out/OwlExportTest.java
32 32
import eu.etaxonomy.cdm.model.common.CdmBase;
33 33
import eu.etaxonomy.cdm.model.description.Feature;
34 34
import eu.etaxonomy.cdm.model.term.TermTree;
35
import eu.etaxonomy.cdm.model.term.TermTreeNode;
35
import eu.etaxonomy.cdm.model.term.TermNode;
36 36
import eu.etaxonomy.cdm.model.term.TermType;
37 37
import eu.etaxonomy.cdm.model.term.TermVocabulary;
38 38
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
......
79 79

  
80 80
        Feature featureA = Feature.NewInstance("A", "A", "A");
81 81
        voc.addTerm(featureA);
82
        TermTreeNode<Feature> nodeA = tree.getRoot().addChild(featureA);
82
        TermNode<Feature> nodeA = tree.getRoot().addChild(featureA);
83 83

  
84 84
        Feature featureA1 = Feature.NewInstance("A1", "A1", "A1");
85 85
        voc.addTerm(featureA1);
86
        TermTreeNode<Feature> nodeA1 = nodeA.addChild(featureA1);
86
        TermNode<Feature> nodeA1 = nodeA.addChild(featureA1);
87 87

  
88 88
        Feature featureA2 = Feature.NewInstance("A2", "A2", "A2");
89 89
        voc.addTerm(featureA2);
90
        TermTreeNode<Feature> nodeA2 = nodeA.addChild(featureA2);
90
        TermNode<Feature> nodeA2 = nodeA.addChild(featureA2);
91 91

  
92 92
        Feature featureB = Feature.NewInstance("B", "B", "B");
93 93
        voc.addTerm(featureB);
94
        TermTreeNode<Feature> nodeB = tree.getRoot().addChild(featureB);
94
        TermNode<Feature> nodeB = tree.getRoot().addChild(featureB);
95 95

  
96 96
        Feature featureB1 = Feature.NewInstance("B", "B1", "B1");
97 97
        voc.addTerm(featureB1);
98
        TermTreeNode<Feature> nodeB1 = nodeB.addChild(featureB1);
98
        TermNode<Feature> nodeB1 = nodeB.addChild(featureB1);
99 99

  
100 100
        Feature featureC = Feature.NewInstance("C", "C", "C");
101 101
        voc.addTerm(featureC);
102
        TermTreeNode<Feature> nodeC = tree.getRoot().addChild(featureC);
102
        TermNode<Feature> nodeC = tree.getRoot().addChild(featureC);
103 103

  
104 104
        featureTreeService.save(tree);
105 105
        return Collections.singletonList(tree.getUuid());
cdmlib-io/src/test/resources/eu/etaxonomy/cdm/database/ClearDBDataSet.xml
421 421
  <TAXONRELATIONSHIP_MARKER_AUD/>
422 422
  <TERMRELATION/>
423 423
  <TERMRELATION_AUD/>
424
  <TERMTREENODE_DEFINEDTERMBASE_INAPPLICABLEIF/>
425
  <TERMTREENODE_DEFINEDTERMBASE_INAPPLICABLEIF_AUD/>
426
  <TERMTREENODE_DEFINEDTERMBASE_ONLYAPPLICABLE/>
427
  <TERMTREENODE_DEFINEDTERMBASE_ONLYAPPLICABLE_AUD/>
424
  <TERMNODE_DEFINEDTERMBASE_INAPPLICABLEIF/>
425
  <TERMNODE_DEFINEDTERMBASE_INAPPLICABLEIF_AUD/>
426
  <TERMNODE_DEFINEDTERMBASE_ONLYAPPLICABLE/>
427
  <TERMNODE_DEFINEDTERMBASE_ONLYAPPLICABLE_AUD/>
428 428
  <TERMCOLLECTION_ANNOTATION/>
429 429
  <TERMCOLLECTION_ANNOTATION_AUD/>
430 430
  <TERMCOLLECTION_CREDIT/>
cdmlib-io/src/test/resources/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml
419 419
<TAXONRELATIONSHIP_MARKER_AUD/>
420 420
<TERMRELATION/>
421 421
<TERMRELATION_AUD/>
422
<TERMTREENODE_DEFINEDTERMBASE_INAPPLICABLEIF/>
423
<TERMTREENODE_DEFINEDTERMBASE_INAPPLICABLEIF_AUD/>
424
<TERMTREENODE_DEFINEDTERMBASE_ONLYAPPLICABLE/>
425
<TERMTREENODE_DEFINEDTERMBASE_ONLYAPPLICABLE_AUD/>
422
<TERMNODE_DEFINEDTERMBASE_INAPPLICABLEIF/>
423
<TERMNODE_DEFINEDTERMBASE_INAPPLICABLEIF_AUD/>
424
<TERMNODE_DEFINEDTERMBASE_ONLYAPPLICABLE/>
425
<TERMNODE_DEFINEDTERMBASE_ONLYAPPLICABLE_AUD/>
426 426
<TERMCOLLECTION />
427 427
<TERMCOLLECTION_AUD />
428 428
<TERMCOLLECTION_REPRESENTATION />
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/TreeIndex.java
17 17
import java.util.regex.Pattern;
18 18

  
19 19
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
20
import eu.etaxonomy.cdm.model.term.TermTreeNode;
20
import eu.etaxonomy.cdm.model.term.TermNode;
21 21

  
22 22
/**
23
 * A class to handle tree indexes as used in {@link TaxonNode}, {@link TermTreeNode}
23
 * A class to handle tree indexes as used in {@link TaxonNode}, {@link TermNode}
24 24
 * etc.<BR>
25 25
 * Might be come a hibernate user type in future.
26 26
 *
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.TermTreeNode;
28
import eu.etaxonomy.cdm.model.term.TermNode;
29 29
import eu.etaxonomy.cdm.model.term.TermType;
30 30

  
31 31
/**
......
59 59
    @ManyToOne(fetch = FetchType.LAZY)
60 60
    @IndexedEmbedded
61 61
//    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
62
    private TermTreeNode structure;
62
    private TermNode structure;
63 63

  
64 64
    //#8120
65 65
    @XmlElement(name = "StructureModifier")
......
75 75
    @ManyToOne(fetch = FetchType.LAZY)
76 76
    @IndexedEmbedded
77 77
//    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
78
    private TermTreeNode property;
78
    private TermNode property;
79 79

  
80 80
    //#8120
81 81
    /**
......
107 107
     * @param property The property feature node for this character
108 108
     * @see #Feature()
109 109
     */
110
    public static Character NewInstance(TermTreeNode structure, TermTreeNode property){
110
    public static Character NewInstance(TermNode structure, TermNode property){
111 111
        return new Character(structure, property, null, null, null);
112 112
    }
113 113

  
......
130 130
     *            to be created
131 131
     * @see #Feature()
132 132
     */
133
    public static Character NewInstance(TermTreeNode structure, TermTreeNode property, String term, String label, String labelAbbrev){
133
    public static Character NewInstance(TermNode structure, TermNode property, String term, String label, String labelAbbrev){
134 134
        return new Character(structure, property, term, label, labelAbbrev);
135 135
    }
136 136

  
......
161 161
     *            to be created
162 162
     * @see #Feature()
163 163
     */
164
    protected Character(TermTreeNode structure, TermTreeNode property, String term, String label, String labelAbbrev) {
164
    protected Character(TermNode structure, TermNode property, String term, String label, String labelAbbrev) {
165 165
        super(term, label, labelAbbrev);
166 166
        this.setTermType(TermType.Character);
167 167
        this.structure = structure;
......
170 170

  
171 171
 // ****************** GETTER / SETTER *********************************************/
172 172

  
173
    public TermTreeNode getStructure() {
173
    public TermNode getStructure() {
174 174
        return structure;
175 175
    }
176
    public void setStructure(TermTreeNode structure) {
176
    public void setStructure(TermNode structure) {
177 177
        this.structure = structure;
178 178
    }
179 179

  
180
    public TermTreeNode getProperty() {
180
    public TermNode getProperty() {
181 181
        return property;
182 182
    }
183
    public void setProperty(TermTreeNode property) {
183
    public void setProperty(TermNode property) {
184 184
        this.property = property;
185 185
    }
186 186

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/ITermTree.java
18 18
            extends ITermGraph<TERM, REL> {
19 19

  
20 20
    /**
21
     * Returns the (ordered) list of {@link TermTreeNode feature nodes} which are immediate
21
     * Returns the (ordered) list of {@link TermNode feature nodes} which are immediate
22 22
     * children of the root node of <i>this</i> term tree.
23 23
     */
24
    public abstract List<TermTreeNode<TERM>> getRootChildren();
24
    public abstract List<TermNode<TERM>> getRootChildren();
25 25

  
26 26
    public List<TERM> asTermList();
27 27

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/OrderedTermVocabulary.java
39 39
@Audited
40 40
public class OrderedTermVocabulary<T extends OrderedTermBase>
41 41
        extends TermVocabulary<T>
42
        implements ITermGraph<T, TermTreeNode>    {
42
        implements ITermGraph<T, TermNode>    {
43 43

  
44 44

  
45 45
	private static final long serialVersionUID = 7871741306306371242L;
......
301 301
	}
302 302

  
303 303
    @Override
304
    public Set<TermTreeNode> getTermRelations() {
304
    public Set<TermNode> getTermRelations() {
305 305
        return super.termRelations();
306 306
    }
307 307
    /**
......
310 310
     * @param termRelations
311 311
     */
312 312
//    @Override  //not yet public
313
    protected void setTermRelations(Set<TermTreeNode> termRelations) {
313
    protected void setTermRelations(Set<TermNode> termRelations) {
314 314
        super.termRelations(termRelations);
315 315
    }
316 316

  
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/term/TermNode.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.Collection;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Set;
17

  
18
import javax.persistence.Column;
19
import javax.persistence.Entity;
20
import javax.persistence.FetchType;
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.Transient;
29
import javax.xml.bind.annotation.XmlAccessType;
30
import javax.xml.bind.annotation.XmlAccessorType;
31
import javax.xml.bind.annotation.XmlElement;
32
import javax.xml.bind.annotation.XmlElementWrapper;
33
import javax.xml.bind.annotation.XmlIDREF;
34
import javax.xml.bind.annotation.XmlRootElement;
35
import javax.xml.bind.annotation.XmlSchemaType;
36
import javax.xml.bind.annotation.XmlType;
37

  
38
import org.apache.log4j.Logger;
39
import org.hibernate.annotations.Cascade;
40
import org.hibernate.annotations.CascadeType;
41
import org.hibernate.envers.Audited;
42

  
43
import eu.etaxonomy.cdm.hibernate.HHH_9751_Util;
44
import eu.etaxonomy.cdm.model.common.ITreeNode;
45
import eu.etaxonomy.cdm.model.description.CategoricalData;
46
import eu.etaxonomy.cdm.model.description.Feature;
47
import eu.etaxonomy.cdm.model.description.State;
48

  
49
/**
50
 * The class for tree nodes within a {@link TermTree feature tree} structure.
51
 * Feature nodes are the elementary components of such a tree since they might
52
 * be related to other nodes as a parent or as a child. A feature node belongs
53
 * at most to one feature tree. It cannot have more than one parent node but
54
 * may have several child nodes. Parent/child relations are bidirectional:
55
 * a node N1 is the parent of a node N2 if and only if the node N2 is a child of
56
 * the node N1.
57
 *
58
 * @author  m.doering
59
 * @since 08-Nov-2007 13:06:16
60
 */
61
@SuppressWarnings("serial")
62
@XmlAccessorType(XmlAccessType.FIELD)
63
@XmlType(name = "TermNode", propOrder = {
64
		"parent",
65
		"treeIndex",
66
		"sortIndex",
67
		"children",
68
		"onlyApplicableIf",
69
		"inapplicableIf"
70
})
71
@XmlRootElement(name = "TermNode")
72
@Entity
73
@Audited
74
public class TermNode <T extends DefinedTermBase>
75
            extends TermRelationBase<T, TermNode<T>, TermTree>
76
            implements ITreeNode<TermNode<T>> {
77

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

  
80
    @XmlElement(name = "Parent")
81
    @XmlIDREF
82
    @XmlSchemaType(name = "IDREF")
83
    @ManyToOne(fetch = FetchType.LAZY, targetEntity=TermNode.class)
84
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
85
	@JoinColumn(name="parent_id")
86
	private TermNode<T> parent;
87

  
88

  
89
    @XmlElement(name = "treeIndex")
90
    @Column(length=255)
91
    private String treeIndex;
92

  
93
    @XmlElementWrapper(name = "Children")
94
    @XmlElement(name = "Child")
95
    //see https://dev.e-taxonomy.eu/trac/ticket/3722
96
    @OrderColumn(name="sortIndex")
97
    @OrderBy("sortIndex")
98
	@OneToMany(fetch = FetchType.LAZY, mappedBy="parent", targetEntity=TermNode.class)
99
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
100
	private List<TermNode<T>> children = new ArrayList<>();
101

  
102
    //see https://dev.e-taxonomy.eu/trac/ticket/3722
103
    private Integer sortIndex;
104

  
105
	@XmlElementWrapper(name = "OnlyApplicableIf")
106
	@XmlElement(name = "OnlyApplicableIf")
107
	@XmlIDREF
108
	@XmlSchemaType(name="IDREF")
109
	@ManyToMany(fetch = FetchType.LAZY)
110
//	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})  remove cascade #5755
111
	@JoinTable(name="TermNode_DefinedTermBase_OnlyApplicable")
112
	private final Set<State> onlyApplicableIf = new HashSet<>();
113

  
114
	@XmlElementWrapper(name = "InapplicableIf")
115
	@XmlElement(name = "InapplicableIf")
116
	@XmlIDREF
117
	@XmlSchemaType(name="IDREF")
118
	@ManyToMany(fetch = FetchType.LAZY)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)