Project

General

Profile

Download (9.07 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.cdm.model.description;
12

    
13
import java.util.HashSet;
14
import java.util.Iterator;
15
import java.util.List;
16
import java.util.Set;
17

    
18
import javax.persistence.Entity;
19
import javax.persistence.FetchType;
20
import javax.persistence.JoinColumn;
21
import javax.persistence.JoinTable;
22
import javax.persistence.ManyToMany;
23
import javax.persistence.ManyToOne;
24
import javax.persistence.OneToMany;
25
import javax.persistence.Transient;
26
import javax.validation.constraints.NotNull;
27
import javax.xml.bind.annotation.XmlAccessType;
28
import javax.xml.bind.annotation.XmlAccessorType;
29
import javax.xml.bind.annotation.XmlElement;
30
import javax.xml.bind.annotation.XmlElementWrapper;
31
import javax.xml.bind.annotation.XmlIDREF;
32
import javax.xml.bind.annotation.XmlRootElement;
33
import javax.xml.bind.annotation.XmlSchemaType;
34
import javax.xml.bind.annotation.XmlType;
35

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

    
41
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
42
import eu.etaxonomy.cdm.model.common.Language;
43
import eu.etaxonomy.cdm.model.common.Representation;
44

    
45
/**
46
 * 
47
 * The working set class allows the demarcation of a set of descriptions
48
 * associated with representations and a set of features and their
49
 * dependencies.
50
 * 
51
 * @author h.fradin
52
 * @created 12.08.2009
53
 * @version 1.0
54
 */
55

    
56
@XmlAccessorType(XmlAccessType.FIELD)
57
@XmlType(name = "WorkingSet", propOrder = {
58
    "representations",
59
    "descriptiveSystem",
60
    "descriptions"
61
})
62
@XmlRootElement(name = "WorkingSet")
63
@Entity
64
@Audited
65

    
66
public class WorkingSet extends AnnotatableEntity {
67
	private static final long serialVersionUID = 3256448866757415686L;
68
	private static final Logger logger = Logger.getLogger(WorkingSet.class);
69
	
70
	@XmlElementWrapper(name = "Representations")
71
	@XmlElement(name = "Representation")
72
    @OneToMany(fetch=FetchType.EAGER)
73
	@Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE })
74
	private Set<Representation> representations = new HashSet<Representation>();
75
	
76
	@XmlElement(name = "DescriptiveSystem")
77
	@XmlIDREF
78
	@XmlSchemaType(name = "IDREF")
79
	@ManyToOne(fetch = FetchType.LAZY)
80
	@Cascade({CascadeType.SAVE_UPDATE})
81
	private FeatureTree descriptiveSystem;
82
	
83
	@XmlElementWrapper(name = "Descriptions")
84
	@XmlElement(name = "Description")
85
    @XmlIDREF
86
    @XmlSchemaType(name = "IDREF")
87
    @ManyToMany(fetch = FetchType.LAZY)
88
    @JoinTable(
89
        name="WorkingSet_DescriptionBase",
90
        joinColumns=@JoinColumn(name="WorkingSet_id"),
91
        inverseJoinColumns=@JoinColumn(name="descriptions_id")
92
    )
93
	@Cascade(CascadeType.SAVE_UPDATE)
94
	@NotNull
95
	private Set<DescriptionBase> descriptions = new HashSet<DescriptionBase>();
96
	
97
	/** 
98
	 * Class constructor: creates a new empty working set instance.
99
	 */
100
	protected WorkingSet() {
101
		super();
102
	}
103
	
104
	/** 
105
	 * Creates a new empty working set instance.
106
	 */
107
	public static WorkingSet NewInstance(){
108
		return new WorkingSet();
109
	}
110
	
111
	public Set<Representation> getRepresentations() {
112
		return this.representations;
113
	}
114

    
115
	public void addRepresentation(Representation representation) {
116
		this.representations.add(representation);
117
	}
118

    
119
	public void removeRepresentation(Representation representation) {
120
		this.representations.remove(representation);
121
	}
122

    
123
	public Representation getRepresentation(Language lang) {
124
		for (Representation repr : representations){
125
			Language reprLanguage = repr.getLanguage();
126
			if (reprLanguage != null && reprLanguage.equals(lang)){
127
				return repr;
128
			}
129
		}
130
		return null;
131
	}
132
	
133
	/**
134
	 * @see #getPreferredRepresentation(Language)
135
	 * @param language
136
	 * @return
137
	 */
138
	public Representation getPreferredRepresentation(Language language) {
139
		Representation repr = getRepresentation(language); 
140
		if(repr == null){
141
			repr = getRepresentation(Language.DEFAULT());
142
		}
143
		if(repr == null){
144
			repr = getRepresentations().iterator().next();
145
		}
146
		return repr;
147
	}
148
	
149
	/**
150
	 * Returns the Representation in the preferred language. Preferred languages
151
	 * are specified by the parameter languages, which receives a list of
152
	 * Language instances in the order of preference. If no representation in
153
	 * any preferred languages is found the method falls back to return the
154
	 * Representation in Language.DEFAULT() and if necessary further falls back
155
	 * to return the first element found if any.
156
	 * 
157
	 * TODO think about this fall-back strategy & 
158
	 * see also {@link TextData#getPreferredLanguageString(List)}
159
	 * 
160
	 * @param languages
161
	 * @return
162
	 */
163
	public Representation getPreferredRepresentation(List<Language> languages) {
164
		Representation repr = null;
165
		if(languages != null){
166
			for(Language language : languages) {
167
				repr = getRepresentation(language); 
168
				if(repr != null){
169
					return repr;
170
				}
171
			}
172
		}
173
		if(repr == null){
174
			repr = getRepresentation(Language.DEFAULT());
175
		}
176
		if(repr == null){
177
			Iterator<Representation> it = getRepresentations().iterator();
178
			if(it.hasNext()){
179
				repr = getRepresentations().iterator().next();
180
			}
181
		}
182
		return repr;
183
	}
184
	
185
	@Transient
186
	public String getLabel() {
187
		if(getLabel(Language.DEFAULT())!=null){
188
			Representation repr = getRepresentation(Language.DEFAULT());
189
			return (repr == null)? null :repr.getLabel();
190
		}else{
191
			for (Representation r : representations){
192
				return r.getLabel();
193
			}			
194
		}
195
		return super.getUuid().toString();
196
	}
197
	
198
	public String getLabel(Language lang) {
199
		Representation repr = this.getRepresentation(lang);
200
		return (repr == null) ? null : repr.getLabel();
201
	}	
202
	
203
	public void setLabel(String label){
204
		Language lang = Language.DEFAULT();
205
		setLabel(label, lang);
206
	}
207

    
208
	public void setLabel(String label, Language language){
209
		if (language != null){
210
			Representation repr = getRepresentation(language);
211
			if (repr != null){
212
				repr.setLabel(label);
213
			}else{
214
				repr = Representation.NewInstance(null, label, null, language);
215
			}
216
			this.addRepresentation(repr);
217
		}
218
	}
219
	
220
	public FeatureTree getDescriptiveSystem() {
221
		return descriptiveSystem;
222
	}
223
	public void setDescriptiveSystem(FeatureTree descriptiveSystem) {
224
		this.descriptiveSystem = descriptiveSystem;
225
	}
226
	
227
	/**
228
	 * Returns the {@link DescriptionBase descriptions} of
229
	 * <i>this</i> working set.
230
	 * 
231
	 * @see    #addDescription(DescriptionBase)
232
	 * @see    #removeDescription(DescriptionBase)
233
	 */
234
	public Set<DescriptionBase> getDescriptions() {
235
		return descriptions;
236
	}
237
	
238
	/**
239
	 * Adds an existing {@link DescriptionBase description} to the set of
240
	 * {@link #getDescriptions() descriptions} of <i>this</i>
241
	 * working set.
242
	 * 
243
	 * @param description	the description to be added to <i>this</i> working set
244
	 * @see    	   			#getDescriptions()
245
	 * @see    	   			WorkingSet#addDescription(DescriptionBase)
246
	 */
247
	public boolean addDescription(DescriptionBase description) {
248
		boolean result = this.descriptions.add(description);
249
		if (! description.getWorkingSets().contains(this)){
250
			description.addWorkingSet(this);
251
		}
252
		return result;
253
	}
254
	
255
	/** 
256
	 * Removes one element from the set of {@link #getDescriptions() descriptions} involved
257
	 * in <i>this</i> working set.<BR>
258
	 *
259
	 * @param  description	the description which should be removed
260
	 * @see     		 	#getDescriptions()
261
	 * @see     		  	#addDescription(DescriptionBase)
262
	 * @see     		  	WorkingSet#removeDescription(DescriptionBase)
263
	 */
264
	public boolean removeDescription(DescriptionBase description) {
265
		boolean result = this.descriptions.remove(description);
266
		if (description.getWorkingSets().contains(this)){
267
			description.removeWorkingSet(this);
268
		}
269
		return result;
270
	}
271
	
272
	//*********************** CLONE ********************************************************/
273
	
274
	/** 
275
	 * Clones <i>this</i> WorkingSet. This is a shortcut that enables to create
276
	 * a new instance that differs only slightly from <i>this</i> WorkingSet by
277
	 * modifying only some of the attributes.
278
	 * The descriptions and the descriptive system are the same, the representations 
279
	 * are cloned.
280
	 * 
281
	 * @see eu.etaxonomy.cdm.model.common.AnnotatableEntity#clone()
282
	 * @see java.lang.Object#clone()
283
	 */
284
	@Override
285
	public Object clone() {
286
		WorkingSet result;
287
		try {
288
			result = (WorkingSet)super.clone();
289
			result.descriptions = new HashSet<DescriptionBase>();
290
			
291
			for (DescriptionBase desc: this.descriptions){
292
				result.addDescription(desc);
293
			}
294
			
295
			result.representations = new HashSet<Representation>();
296
			for (Representation rep : this.representations){
297
				result.addRepresentation((Representation)rep.clone());
298
			}
299
			
300
			return result;
301
		}catch (CloneNotSupportedException e) {
302
			logger.warn("Object does not implement cloneable");
303
			e.printStackTrace();
304
			return null;
305
		}
306
	}
307
	
308
}
(34-34/36)