2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.common
;
12 import java
.util
.HashSet
;
13 import java
.util
.Iterator
;
14 import java
.util
.List
;
17 import java
.util
.UUID
;
19 import javax
.persistence
.Entity
;
20 import javax
.persistence
.FetchType
;
21 import javax
.persistence
.JoinTable
;
22 import javax
.persistence
.OneToMany
;
23 import javax
.persistence
.Transient
;
24 import javax
.xml
.bind
.annotation
.XmlAccessType
;
25 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
26 import javax
.xml
.bind
.annotation
.XmlElement
;
27 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
28 import javax
.xml
.bind
.annotation
.XmlIDREF
;
29 import javax
.xml
.bind
.annotation
.XmlRootElement
;
30 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
31 import javax
.xml
.bind
.annotation
.XmlSeeAlso
;
32 import javax
.xml
.bind
.annotation
.XmlType
;
34 import org
.apache
.log4j
.Logger
;
35 import org
.hibernate
.annotations
.Cascade
;
36 import org
.hibernate
.annotations
.CascadeType
;
37 import org
.hibernate
.envers
.Audited
;
38 import org
.hibernate
.search
.annotations
.Field
;
39 import org
.hibernate
.search
.annotations
.Index
;
40 import org
.hibernate
.search
.annotations
.Indexed
;
41 import org
.hibernate
.search
.annotations
.IndexedEmbedded
;
43 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
44 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationshipType
;
45 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
46 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
49 import au
.com
.bytecode
.opencsv
.CSVWriter
;
51 @XmlAccessorType(XmlAccessType
.FIELD
)
52 @XmlType(name
= "RelationshipTermBase", propOrder
= {
55 "inverseRepresentations"
58 HybridRelationshipType
.class,
59 NameRelationshipType
.class,
60 SynonymRelationshipType
.class,
61 TaxonRelationshipType
.class
64 @Indexed(index
= "eu.etaxonomy.cdm.model.common.DefinedTermBase")
66 public abstract class RelationshipTermBase
<T
extends RelationshipTermBase
> extends OrderedTermBase
<T
> {
67 private static final long serialVersionUID
= 5497187985269083971L;
68 @SuppressWarnings("unused")
69 private static final Logger logger
= Logger
.getLogger(RelationshipTermBase
.class);
71 @XmlElement(name
= "Symmetric")
72 @Field(index
=Index
.UN_TOKENIZED
)
73 private boolean symmetric
;
75 @XmlElement(name
= "Transitive")
76 @Field(index
=Index
.UN_TOKENIZED
)
77 private boolean transitive
;
79 @XmlElementWrapper(name
= "InverseRepresentations")
80 @XmlElement(name
= "Representation")
81 @OneToMany(fetch
= FetchType
.LAZY
)
82 @JoinTable(name
="RelationshipTermBase_inverseRepresentation")
83 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
84 @IndexedEmbedded(depth
= 2)
85 private Set
<Representation
> inverseRepresentations
= new HashSet
<Representation
>();
87 public RelationshipTermBase() {
89 public RelationshipTermBase(String term
, String label
, String labelAbbrev
, boolean symmetric
, boolean transitive
) {
90 super(term
, label
, labelAbbrev
);
91 setSymmetric(symmetric
);
92 setTransitive(transitive
);
96 public boolean isSymmetric() {
99 public void setSymmetric(boolean symmetric
) {
100 this.symmetric
= symmetric
;
103 public boolean isTransitive() {
106 public void setTransitive(boolean transitive
) {
107 this.transitive
= transitive
;
110 public Set
<Representation
> getInverseRepresentations() {
111 return inverseRepresentations
;
114 public void addInverseRepresentation(Representation inverseRepresentation
) {
115 this.inverseRepresentations
.add(inverseRepresentation
);
117 public void removeInverseRepresentation(Representation inverseRepresentation
) {
118 this.inverseRepresentations
.remove(inverseRepresentation
);
120 public void addRepresentation(Representation representation
, Representation inverseRepresentation
) {
121 this.addRepresentation(representation
);
122 this.addInverseRepresentation(inverseRepresentation
);
125 public Representation
getInverseRepresentation(Language lang
) {
126 Representation result
= null;
127 if (this.isSymmetric()){
128 for (Representation repr
: this.getRepresentations()){
129 if (repr
.getLanguage() == lang
){
134 for (Representation repr
: this.getInverseRepresentations()){
135 if (repr
.getLanguage() == lang
){
144 * Returns the InverseRepresentation in the preferred language. Preferred languages
145 * are specified by the parameter languages, which receives a list of
146 * Language instances in the order of preference. If no representation in
147 * any preferred languages is found the method falls back to return the
148 * Representation in Language.DEFAULT() and if necessary further falls back
149 * to return the first element found if any.
151 * TODO think about this fall-back strategy &
152 * see also {@link TextData#getPreferredLanguageString(List)}
153 * see also {@link TermBase#getPreferredRepresentation(List)}
158 public Representation
getPreferredInverseRepresentation(List
<Language
> languages
) {
159 Representation repr
= null;
160 if(languages
!= null){
161 for(Language language
: languages
) {
162 repr
= getInverseRepresentation(language
);
169 repr
= getInverseRepresentation(Language
.DEFAULT());
172 Iterator
<Representation
> it
= getInverseRepresentations().iterator();
174 repr
= getInverseRepresentations().iterator().next();
181 * Inverse representation convenience methods similar to TermBase.xxx
182 * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
185 public String
getInverseLabel() {
186 if(getInverseLabel(Language
.DEFAULT())!=null){
187 return this.getInverseRepresentation(Language
.DEFAULT()).getLabel();
189 for (Representation r
: inverseRepresentations
){
193 return super.getUuid().toString();
196 public String
getInverseLabel(Language lang
) {
197 Representation r
= this.getInverseRepresentation(lang
);
206 public String
getInverseDescription() {
207 return this.getInverseRepresentation(Language
.DEFAULT()).getDescription();
210 public String
getInverseDescription(Language lang
) {
211 return this.getInverseRepresentation(lang
).getDescription();
215 public T
readCsvLine(Class
<T
> termClass
, List
<String
> csvLine
, Map
<UUID
,DefinedTermBase
> terms
) {
216 T newInstance
= super.readCsvLine(termClass
, csvLine
, terms
);
218 String inverseText
= csvLine
.get(5).trim();
219 String inverseLabel
= csvLine
.get(4).trim();
220 String inverseLabelAbbrev
= null;
221 newInstance
.addInverseRepresentation(new Representation(inverseText
, inverseLabel
, inverseLabelAbbrev
, Language
.ENGLISH()) );
222 newInstance
.setSymmetric(Boolean
.parseBoolean(csvLine
.get(6)));
223 newInstance
.setTransitive(Boolean
.parseBoolean(csvLine
.get(7)));
228 public void writeCsvLine(CSVWriter writer
,T term
) {
229 String
[] line
= new String
[8];
230 line
[0] = term
.getUuid().toString();
231 line
[1] = term
.getUri();
232 line
[2] = term
.getLabel();
233 line
[3] = term
.getDescription();
234 line
[4] = term
.getInverseLabel();
235 line
[5] = term
.getInverseDescription();
236 line
[6] = String
.valueOf(term
.isSymmetric());
237 line
[7] = String
.valueOf(term
.isTransitive());
238 writer
.writeNext(line
);