Project

General

Profile

Download (8.24 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.Analyze;
37
import org.hibernate.search.annotations.Field;
38
import org.hibernate.search.annotations.IndexedEmbedded;
39

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

    
47
@XmlAccessorType(XmlAccessType.FIELD)
48
@XmlType(name = "RelationshipTermBase", propOrder = {
49
    "symmetric",
50
    "transitive",
51
    "inverseRepresentations"
52
})
53
@XmlSeeAlso({
54
	HybridRelationshipType.class,
55
	NameRelationshipType.class,
56
	SynonymRelationshipType.class,
57
	TaxonRelationshipType.class
58
})
59
@Entity
60
@Audited
61
public abstract class RelationshipTermBase<T extends RelationshipTermBase> extends OrderedTermBase<T> {
62
	private static final long serialVersionUID = 5497187985269083971L;
63
	@SuppressWarnings("unused")
64
	private static final Logger logger = Logger.getLogger(RelationshipTermBase.class);
65

    
66
	@XmlElement(name = "Symmetrical")
67
	@Field(analyze = Analyze.NO)
68
	@Column(name="symmetrical") //to be compatible with PostGreSQL
69
	private boolean symmetric;
70

    
71
	@XmlElement(name = "Transitive")
72
	@Field(analyze = Analyze.NO)
73
	private boolean transitive;
74

    
75
	@XmlElementWrapper(name = "InverseRepresentations")
76
	@XmlElement(name = "Representation")
77
	@OneToMany(fetch = FetchType.LAZY)
78
	@JoinTable(name="RelationshipTermBase_inverseRepresentation")
79
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
80
	@IndexedEmbedded(depth = 2)
81
	private Set<Representation> inverseRepresentations = new HashSet<Representation>();
82

    
83
//******************** CONSTRUCTOR ************************/
84

    
85
    //for JAXB only, TODO needed?
86
    @Deprecated
87
    private RelationshipTermBase(){super();}
88

    
89

    
90
	protected RelationshipTermBase(TermType type) {
91
		super(type);
92
	}
93
	public RelationshipTermBase(TermType type, String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
94
		super(type, term, label, labelAbbrev);
95
		setSymmetric(symmetric);
96
		setTransitive(transitive);
97
	}
98

    
99
//************************** METHODS ********************************
100

    
101
	public boolean isSymmetric() {
102
		return symmetric;
103
	}
104
	public void setSymmetric(boolean symmetric) {
105
		this.symmetric = symmetric;
106
	}
107

    
108
	public boolean isTransitive() {
109
		return transitive;
110
	}
111
	public void setTransitive(boolean transitive) {
112
		this.transitive = transitive;
113
	}
114

    
115
	public Set<Representation> getInverseRepresentations() {
116
		return inverseRepresentations;
117
	}
118

    
119
	public void addInverseRepresentation(Representation inverseRepresentation) {
120
		this.inverseRepresentations.add(inverseRepresentation);
121
	}
122
	public void removeInverseRepresentation(Representation inverseRepresentation) {
123
		this.inverseRepresentations.remove(inverseRepresentation);
124
	}
125
	public void addRepresentation(Representation representation, Representation inverseRepresentation) {
126
		this.addRepresentation(representation);
127
		this.addInverseRepresentation(inverseRepresentation);
128
	}
129

    
130
	public Representation getInverseRepresentation(Language lang) {
131
		Representation result = null;
132
		if (this.isSymmetric()){
133
			for (Representation repr : this.getRepresentations()){
134
				if (lang.equals(repr.getLanguage())){
135
					result = repr;
136
				}
137
			}
138
		}else{
139
			for (Representation repr : this.getInverseRepresentations()){
140
				if (lang.equals(repr.getLanguage())){
141
					result = repr;
142
				}
143
			}
144
		}
145
		return result;
146
	}
147

    
148
	/**
149
	 * Returns the InverseRepresentation in the preferred language. Preferred languages
150
	 * are specified by the parameter languages, which receives a list of
151
	 * Language instances in the order of preference. If no representation in
152
	 * any preferred languages is found the method falls back to return the
153
	 * Representation in Language.DEFAULT() and if necessary further falls back
154
	 * to return the first element found if any.
155
	 *
156
	 * TODO think about this fall-back strategy &
157
	 * see also {@link TextData#getPreferredLanguageString(List)}
158
	 * see also {@link TermBase#getPreferredRepresentation(List)}
159
	 *
160
	 * @param languages
161
	 * @return
162
	 */
163
	public Representation getPreferredInverseRepresentation(List<Language> languages) {
164
		Representation repr = null;
165
		if(languages != null){
166
			for(Language language : languages) {
167
				repr = getInverseRepresentation(language);
168
				if(repr != null){
169
					return repr;
170
				}
171
			}
172
		}
173
		if(repr == null){
174
			repr = getInverseRepresentation(Language.DEFAULT());
175
		}
176
		if(repr == null){
177
			Iterator<Representation> it = getInverseRepresentations().iterator();
178
			if(it.hasNext()){
179
				repr = getInverseRepresentations().iterator().next();
180
			}
181
		}
182
		return repr;
183
	}
184

    
185
	/*
186
	 * Inverse representation convenience methods similar to TermBase.xxx
187
	 * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
188
	 */
189
	@Transient
190
	public String getInverseLabel() {
191
		if(getInverseLabel(Language.DEFAULT())!=null){
192
			return this.getInverseRepresentation(Language.DEFAULT()).getLabel();
193
		}else{
194
			for (Representation r : inverseRepresentations){
195
				return r.getLabel();
196
			}
197
		}
198
		return super.getUuid().toString();
199
	}
200

    
201
	public String getInverseLabel(Language lang) {
202
		Representation r = this.getInverseRepresentation(lang);
203
		if(r==null){
204
			return null;
205
		}else{
206
			return r.getLabel();
207
		}
208
	}
209

    
210
	@Transient
211
	public String getInverseDescription() {
212
		return this.getInverseRepresentation(Language.DEFAULT()).getDescription();
213
	}
214

    
215
	public String getInverseDescription(Language lang) {
216
		return this.getInverseRepresentation(lang).getDescription();
217
	}
218

    
219
	@Override
220
	public T readCsvLine(Class<T> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) {
221
		T newInstance = super.readCsvLine(termClass, csvLine, terms, abbrevAsId);
222

    
223
		String inverseText = csvLine.get(6).trim();
224
		String inverseLabel = csvLine.get(5).trim();
225
		String inverseLabelAbbrev = csvLine.get(7).trim();
226
		newInstance.addInverseRepresentation(new Representation(inverseText, inverseLabel, inverseLabelAbbrev, Language.CSV_LANGUAGE()) );
227
		newInstance.setSymmetric(Boolean.parseBoolean(csvLine.get(8)));
228
		newInstance.setTransitive(Boolean.parseBoolean(csvLine.get(9)));
229
		return newInstance;
230
	}
231

    
232
	@Override
233
	public void writeCsvLine(CSVWriter writer,T term) {
234
		String [] line = new String[8];
235
		line[0] = term.getUuid().toString();
236
		line[1] = term.getUri().toString();
237
		line[2] = term.getLabel();
238
		line[3] = term.getDescription();
239
		line[4] = term.getDescription();
240
		line[5] = term.getInverseLabel();
241
		line[6] = term.getInverseDescription();
242
		line[7] = String.valueOf(term.isSymmetric());
243
		line[8] = String.valueOf(term.isTransitive());
244
		writer.writeNext(line);
245
	}
246
	//*********************************** CLONE *********************************************************/
247

    
248
	/* (non-Javadoc)
249
	 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#clone()
250
	 * @see java.lang.Object#clone()
251
	 */
252
	@Override
253
	public Object clone() {
254
		RelationshipTermBase<?> result = (RelationshipTermBase<?>)super.clone();
255

    
256
		result.inverseRepresentations = new HashSet<Representation>();
257
		for (Representation rep: this.inverseRepresentations){
258
			result.addInverseRepresentation((Representation)rep.clone());
259
		}
260

    
261
		//no changes to: symmetric, transitiv
262
		return result;
263
	}
264

    
265

    
266
}
(60-60/72)