Project

General

Profile

Download (8.13 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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.common;
11

    
12
import java.util.HashSet;
13
import java.util.Iterator;
14
import java.util.List;
15
import java.util.Map;
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.JoinTable;
23
import javax.persistence.OneToMany;
24
import javax.persistence.Transient;
25
import javax.xml.bind.annotation.XmlAccessType;
26
import javax.xml.bind.annotation.XmlAccessorType;
27
import javax.xml.bind.annotation.XmlElement;
28
import javax.xml.bind.annotation.XmlElementWrapper;
29
import javax.xml.bind.annotation.XmlSeeAlso;
30
import javax.xml.bind.annotation.XmlType;
31

    
32
import org.apache.log4j.Logger;
33
import org.hibernate.annotations.Cascade;
34
import org.hibernate.annotations.CascadeType;
35
import org.hibernate.envers.Audited;
36
import org.hibernate.search.annotations.Field;
37
import org.hibernate.search.annotations.Index;
38
import org.hibernate.search.annotations.Indexed;
39
import org.hibernate.search.annotations.IndexedEmbedded;
40

    
41
import au.com.bytecode.opencsv.CSVWriter;
42
import eu.etaxonomy.cdm.model.description.TextData;
43
import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
44
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
45
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
46
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
47

    
48
@XmlAccessorType(XmlAccessType.FIELD)
49
@XmlType(name = "RelationshipTermBase", propOrder = {
50
    "symmetric",
51
    "transitive",
52
    "inverseRepresentations"
53
})
54
@XmlSeeAlso({
55
	HybridRelationshipType.class,
56
	NameRelationshipType.class,
57
	SynonymRelationshipType.class,
58
	TaxonRelationshipType.class
59
})
60
@Entity
61
@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
62
@Audited
63
public abstract class RelationshipTermBase<T extends RelationshipTermBase> extends OrderedTermBase<T> {
64
	private static final long serialVersionUID = 5497187985269083971L;
65
	@SuppressWarnings("unused")
66
	private static final Logger logger = Logger.getLogger(RelationshipTermBase.class);
67
	
68
	@XmlElement(name = "Symmetrical")
69
	@Field(index=Index.UN_TOKENIZED)
70
	@Column(name="symmetrical") //to be compatible with PostGreSQL 
71
	private boolean symmetric;
72
	
73
	@XmlElement(name = "Transitive")
74
	@Field(index=Index.UN_TOKENIZED)
75
	private boolean transitive;
76
	
77
	@XmlElementWrapper(name = "InverseRepresentations")
78
	@XmlElement(name = "Representation")
79
	@OneToMany(fetch = FetchType.LAZY)
80
	@JoinTable(name="RelationshipTermBase_inverseRepresentation")
81
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
82
	@IndexedEmbedded(depth = 2)
83
	private Set<Representation> inverseRepresentations = new HashSet<Representation>();
84
	
85
	public RelationshipTermBase() {
86
	}
87
	public RelationshipTermBase(String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
88
		super(term, label, labelAbbrev);
89
		setSymmetric(symmetric);
90
		setTransitive(transitive);		
91
	}
92
	
93
//************************** METHODS ********************************
94
	
95
	public boolean isSymmetric() {
96
		return symmetric;
97
	}
98
	public void setSymmetric(boolean symmetric) {
99
		this.symmetric = symmetric;
100
	}
101
	
102
	public boolean isTransitive() {
103
		return transitive;
104
	}
105
	public void setTransitive(boolean transitive) {
106
		this.transitive = transitive;
107
	}
108
	
109
	public Set<Representation> getInverseRepresentations() {
110
		return inverseRepresentations;
111
	}
112

    
113
	public void addInverseRepresentation(Representation inverseRepresentation) {
114
		this.inverseRepresentations.add(inverseRepresentation);
115
	}
116
	public void removeInverseRepresentation(Representation inverseRepresentation) {
117
		this.inverseRepresentations.remove(inverseRepresentation);
118
	}
119
	public void addRepresentation(Representation representation, Representation inverseRepresentation) {
120
		this.addRepresentation(representation);
121
		this.addInverseRepresentation(inverseRepresentation);
122
	}
123
	
124
	public Representation getInverseRepresentation(Language lang) {
125
		Representation result = null;
126
		if (this.isSymmetric()){
127
			for (Representation repr : this.getRepresentations()){
128
				if (lang.equals(repr.getLanguage())){
129
					result = repr;
130
				}
131
			}
132
		}else{
133
			for (Representation repr : this.getInverseRepresentations()){
134
				if (lang.equals(repr.getLanguage())){
135
					result = repr;
136
				}
137
			}
138
		}
139
		return result;
140
	}
141
	
142
	/**
143
	 * Returns the InverseRepresentation in the preferred language. Preferred languages
144
	 * are specified by the parameter languages, which receives a list of
145
	 * Language instances in the order of preference. If no representation in
146
	 * any preferred languages is found the method falls back to return the
147
	 * Representation in Language.DEFAULT() and if necessary further falls back
148
	 * to return the first element found if any.
149
	 * 
150
	 * TODO think about this fall-back strategy & 
151
	 * see also {@link TextData#getPreferredLanguageString(List)}
152
	 * see also {@link TermBase#getPreferredRepresentation(List)}
153
	 * 
154
	 * @param languages
155
	 * @return
156
	 */
157
	public Representation getPreferredInverseRepresentation(List<Language> languages) {
158
		Representation repr = null;
159
		if(languages != null){
160
			for(Language language : languages) {
161
				repr = getInverseRepresentation(language); 
162
				if(repr != null){
163
					return repr;
164
				}
165
			}
166
		}
167
		if(repr == null){
168
			repr = getInverseRepresentation(Language.DEFAULT());
169
		}
170
		if(repr == null){
171
			Iterator<Representation> it = getInverseRepresentations().iterator();
172
			if(it.hasNext()){
173
				repr = getInverseRepresentations().iterator().next();
174
			}
175
		}
176
		return repr;
177
	}
178
	
179
	/*
180
	 * Inverse representation convenience methods similar to TermBase.xxx 
181
	 * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
182
	 */
183
	@Transient
184
	public String getInverseLabel() {
185
		if(getInverseLabel(Language.DEFAULT())!=null){
186
			return this.getInverseRepresentation(Language.DEFAULT()).getLabel();
187
		}else{
188
			for (Representation r : inverseRepresentations){
189
				return r.getLabel();
190
			}			
191
		}
192
		return super.getUuid().toString();
193
	}
194

    
195
	public String getInverseLabel(Language lang) {
196
		Representation r = this.getInverseRepresentation(lang);
197
		if(r==null){
198
			return null;
199
		}else{
200
			return r.getLabel();
201
		}
202
	}
203
	
204
	@Transient
205
	public String getInverseDescription() {
206
		return this.getInverseRepresentation(Language.DEFAULT()).getDescription();
207
	}
208

    
209
	public String getInverseDescription(Language lang) {
210
		return this.getInverseRepresentation(lang).getDescription();
211
	}
212
	
213
	@Override
214
	public T readCsvLine(Class<T> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
215
		T newInstance = super.readCsvLine(termClass, csvLine, terms);
216

    
217
		String inverseText = csvLine.get(6).trim();
218
		String inverseLabel = csvLine.get(5).trim();
219
		String inverseLabelAbbrev = null;
220
		newInstance.addInverseRepresentation(new Representation(inverseText, inverseLabel, inverseLabelAbbrev, Language.CSV_LANGUAGE()) );
221
		newInstance.setSymmetric(Boolean.parseBoolean(csvLine.get(7)));
222
		newInstance.setTransitive(Boolean.parseBoolean(csvLine.get(8)));
223
		return newInstance;
224
	}
225
	
226
	@Override
227
	public void writeCsvLine(CSVWriter writer,T term) {
228
		String [] line = new String[8];
229
		line[0] = term.getUuid().toString();
230
		line[1] = term.getUri().toString();
231
		line[2] = term.getLabel();
232
		line[3] = term.getDescription();
233
		line[4] = term.getDescription();
234
		line[5] = term.getInverseLabel();
235
		line[6] = term.getInverseDescription();
236
		line[7] = String.valueOf(term.isSymmetric());
237
		line[8] = String.valueOf(term.isTransitive());
238
		writer.writeNext(line);
239
	}
240
	//*********************************** CLONE *********************************************************/
241
	
242
	/* (non-Javadoc)
243
	 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#clone()
244
	 * @see java.lang.Object#clone()
245
	 */
246
	@Override
247
	public Object clone() {
248
		RelationshipTermBase result = (RelationshipTermBase)super.clone();
249
		
250
		result.inverseRepresentations = new HashSet<Representation>();
251
		for (Representation rep: this.inverseRepresentations){
252
			result.addInverseRepresentation((Representation)rep.clone());
253
		}
254
		
255
		//no changes to: symmetric, transitiv
256
		return result;
257
	}
258

    
259
	
260
}
(51-51/63)