Project

General

Profile

Download (8.51 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.ManyToMany;
21
import javax.persistence.ManyToOne;
22
import javax.persistence.OneToMany;
23
import javax.persistence.Transient;
24
import javax.validation.constraints.NotNull;
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.XmlIDREF;
30
import javax.xml.bind.annotation.XmlRootElement;
31
import javax.xml.bind.annotation.XmlSchemaType;
32
import javax.xml.bind.annotation.XmlType;
33

    
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

    
39
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
40
import eu.etaxonomy.cdm.model.common.Language;
41
import eu.etaxonomy.cdm.model.common.Representation;
42

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

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

    
64
public class WorkingSet extends AnnotatableEntity {
65
	private static final long serialVersionUID = 3256448866757415686L;
66
	private static final Logger logger = Logger.getLogger(WorkingSet.class);
67

    
68
	@XmlElementWrapper(name = "Representations")
69
	@XmlElement(name = "Representation")
70
    @OneToMany(fetch=FetchType.EAGER)
71
	@Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE })
72
	private Set<Representation> representations = new HashSet<Representation>();
73

    
74
	@XmlElement(name = "DescriptiveSystem")
75
	@XmlIDREF
76
	@XmlSchemaType(name = "IDREF")
77
	@ManyToOne(fetch = FetchType.LAZY)
78
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
79
	private FeatureTree descriptiveSystem;
80

    
81
	@XmlElementWrapper(name = "Descriptions")
82
	@XmlElement(name = "Description")
83
    @XmlIDREF
84
    @XmlSchemaType(name = "IDREF")
85
    @ManyToMany(fetch = FetchType.LAZY)
86
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
87
	@NotNull
88
	private Set<DescriptionBase> descriptions = new HashSet<DescriptionBase>();
89

    
90
	/**
91
	 * Class constructor: creates a new empty working set instance.
92
	 */
93
	protected WorkingSet() {
94
		super();
95
	}
96

    
97
	/**
98
	 * Creates a new empty working set instance.
99
	 */
100
	public static WorkingSet NewInstance(){
101
		return new WorkingSet();
102
	}
103

    
104
	public Set<Representation> getRepresentations() {
105
		return this.representations;
106
	}
107

    
108
	public void addRepresentation(Representation representation) {
109
		this.representations.add(representation);
110
	}
111

    
112
	public void removeRepresentation(Representation representation) {
113
		this.representations.remove(representation);
114
	}
115

    
116
	public Representation getRepresentation(Language lang) {
117
		for (Representation repr : representations){
118
			Language reprLanguage = repr.getLanguage();
119
			if (reprLanguage != null && reprLanguage.equals(lang)){
120
				return repr;
121
			}
122
		}
123
		return null;
124
	}
125

    
126
	/**
127
	 * @see #getPreferredRepresentation(Language)
128
	 * @param language
129
	 * @return
130
	 */
131
	public Representation getPreferredRepresentation(Language language) {
132
		Representation repr = getRepresentation(language);
133
		if(repr == null){
134
			repr = getRepresentation(Language.DEFAULT());
135
		}
136
		if(repr == null){
137
			repr = getRepresentations().iterator().next();
138
		}
139
		return repr;
140
	}
141

    
142
	/**
143
	 * Returns the Representation 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
	 *
153
	 * @param languages
154
	 * @return
155
	 */
156
	public Representation getPreferredRepresentation(List<Language> languages) {
157
		Representation repr = null;
158
		if(languages != null){
159
			for(Language language : languages) {
160
				repr = getRepresentation(language);
161
				if(repr != null){
162
					return repr;
163
				}
164
			}
165
		}
166
		if(repr == null){
167
			repr = getRepresentation(Language.DEFAULT());
168
		}
169
		if(repr == null){
170
			Iterator<Representation> it = getRepresentations().iterator();
171
			if(it.hasNext()){
172
				repr = getRepresentations().iterator().next();
173
			}
174
		}
175
		return repr;
176
	}
177

    
178
	@Transient
179
	public String getLabel() {
180
		if(getLabel(Language.DEFAULT())!=null){
181
			Representation repr = getRepresentation(Language.DEFAULT());
182
			return (repr == null)? null :repr.getLabel();
183
		}else{
184
			for (Representation r : representations){
185
				return r.getLabel();
186
			}
187
		}
188
		return super.getUuid().toString();
189
	}
190

    
191
	public String getLabel(Language lang) {
192
		Representation repr = this.getRepresentation(lang);
193
		return (repr == null) ? null : repr.getLabel();
194
	}
195

    
196
	public void setLabel(String label){
197
		Language lang = Language.DEFAULT();
198
		setLabel(label, lang);
199
	}
200

    
201
	public void setLabel(String label, Language language){
202
		if (language != null){
203
			Representation repr = getRepresentation(language);
204
			if (repr != null){
205
				repr.setLabel(label);
206
			}else{
207
				repr = Representation.NewInstance(null, label, null, language);
208
			}
209
			this.addRepresentation(repr);
210
		}
211
	}
212

    
213
	public FeatureTree getDescriptiveSystem() {
214
		return descriptiveSystem;
215
	}
216
	public void setDescriptiveSystem(FeatureTree descriptiveSystem) {
217
		this.descriptiveSystem = descriptiveSystem;
218
	}
219

    
220
	/**
221
	 * Returns the {@link DescriptionBase descriptions} of
222
	 * <i>this</i> working set.
223
	 *
224
	 * @see    #addDescription(DescriptionBase)
225
	 * @see    #removeDescription(DescriptionBase)
226
	 */
227
	public Set<DescriptionBase> getDescriptions() {
228
		return descriptions;
229
	}
230

    
231
	/**
232
	 * Adds an existing {@link DescriptionBase description} to the set of
233
	 * {@link #getDescriptions() descriptions} of <i>this</i>
234
	 * working set.
235
	 *
236
	 * @param description	the description to be added to <i>this</i> working set
237
	 * @see    	   			#getDescriptions()
238
	 * @see    	   			WorkingSet#addDescription(DescriptionBase)
239
	 */
240
	public boolean addDescription(DescriptionBase description) {
241
		boolean result = this.descriptions.add(description);
242
		if (! description.getWorkingSets().contains(this)){
243
			description.addWorkingSet(this);
244
		}
245
		return result;
246
	}
247

    
248
	/**
249
	 * Removes one element from the set of {@link #getDescriptions() descriptions} involved
250
	 * in <i>this</i> working set.<BR>
251
	 *
252
	 * @param  description	the description which should be removed
253
	 * @see     		 	#getDescriptions()
254
	 * @see     		  	#addDescription(DescriptionBase)
255
	 * @see     		  	WorkingSet#removeDescription(DescriptionBase)
256
	 */
257
	public boolean removeDescription(DescriptionBase description) {
258
		boolean result = this.descriptions.remove(description);
259
		if (description.getWorkingSets().contains(this)){
260
			description.removeWorkingSet(this);
261
		}
262
		return result;
263
	}
264

    
265
	//*********************** CLONE ********************************************************/
266

    
267
	/**
268
	 * Clones <i>this</i> WorkingSet. This is a shortcut that enables to create
269
	 * a new instance that differs only slightly from <i>this</i> WorkingSet by
270
	 * modifying only some of the attributes.
271
	 * The descriptions and the descriptive system are the same, the representations
272
	 * are cloned.
273
	 *
274
	 * @see eu.etaxonomy.cdm.model.common.AnnotatableEntity#clone()
275
	 * @see java.lang.Object#clone()
276
	 */
277
	@Override
278
	public Object clone() {
279
		WorkingSet result;
280
		try {
281
			result = (WorkingSet)super.clone();
282
			result.descriptions = new HashSet<DescriptionBase>();
283

    
284
			for (DescriptionBase desc: this.descriptions){
285
				result.addDescription(desc);
286
			}
287

    
288
			result.representations = new HashSet<Representation>();
289
			for (Representation rep : this.representations){
290
				result.addRepresentation((Representation)rep.clone());
291
			}
292

    
293
			return result;
294
		}catch (CloneNotSupportedException e) {
295
			logger.warn("Object does not implement cloneable");
296
			e.printStackTrace();
297
			return null;
298
		}
299
	}
300

    
301
}
(34-34/36)