(no commit message)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / description / WorkingSet.java
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.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.XmlType;
32
33 import org.apache.log4j.Logger;
34 import org.hibernate.annotations.Cascade;
35 import org.hibernate.annotations.CascadeType;
36 import org.hibernate.envers.Audited;
37
38 import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
39 import eu.etaxonomy.cdm.model.common.Language;
40 import eu.etaxonomy.cdm.model.common.Representation;
41 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
42 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
43
44 /**
45 *
46 * The working set class allows the demarcation of a set of descriptions
47 * associated with representations and a set of features and their
48 * dependencies.
49 *
50 * @author h.fradin
51 * @created 12.08.2009
52 * @version 1.0
53 */
54
55 @XmlAccessorType(XmlAccessType.FIELD)
56 @XmlType(name = "WorkingSet", propOrder = {
57 "representations",
58 "descriptiveSystem",
59 "descriptions"
60 })
61 @XmlRootElement(name = "WorkingSet")
62 @Entity
63 @Audited
64
65 public class WorkingSet extends AnnotatableEntity {
66 private static final long serialVersionUID = 3256448866757415686L;
67 private static final Logger logger = Logger.getLogger(WorkingSet.class);
68
69 @XmlElementWrapper(name = "Representations")
70 @XmlElement(name = "Representation")
71 @OneToMany(fetch=FetchType.EAGER)
72 @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE })
73 private Set<Representation> representations = new HashSet<Representation>();
74
75 @XmlElement(name = "DescriptiveSystem")
76 @XmlIDREF
77 @XmlSchemaType(name = "IDREF")
78 @ManyToOne(fetch = FetchType.LAZY)
79 @Cascade({CascadeType.SAVE_UPDATE})
80 private FeatureTree descriptiveSystem;
81
82 @XmlElementWrapper(name = "Descriptions")
83 @XmlElement(name = "Description")
84 @XmlIDREF
85 @XmlSchemaType(name = "IDREF")
86 @ManyToMany(fetch = FetchType.LAZY)
87 @Cascade(CascadeType.SAVE_UPDATE)
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 protected 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 void addDescription(DescriptionBase description) {
241 logger.debug("addDescription");
242 this.descriptions.add(description);
243 }
244
245 /**
246 * Removes one element from the set of {@link #getDescriptions() descriptions} involved
247 * in <i>this</i> working set.<BR>
248 *
249 * @param description the description which should be removed
250 * @see #getDescriptions()
251 * @see #addDescription(DescriptionBase)
252 * @see WorkingSet#removeDescription(DescriptionBase)
253 */
254 public void removeDescription(DescriptionBase description) {
255 this.descriptions.remove(description);
256 }
257
258 }