bugfix for Coordinate Parser with whitespaces, Dateparsing, etc.
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / TermBase.java
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.net.URI;
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.FetchType;
19 import javax.persistence.MappedSuperclass;
20 import javax.persistence.OneToMany;
21 import javax.persistence.Transient;
22 import javax.validation.constraints.Pattern;
23 import javax.xml.bind.annotation.XmlAccessType;
24 import javax.xml.bind.annotation.XmlAccessorType;
25 import javax.xml.bind.annotation.XmlElement;
26 import javax.xml.bind.annotation.XmlElementWrapper;
27 import javax.xml.bind.annotation.XmlSeeAlso;
28 import javax.xml.bind.annotation.XmlType;
29
30 import org.apache.log4j.Logger;
31 import org.hibernate.LazyInitializationException;
32 import org.hibernate.annotations.Cascade;
33 import org.hibernate.annotations.CascadeType;
34 import org.hibernate.annotations.Type;
35 import org.hibernate.search.annotations.Field;
36 import org.hibernate.search.annotations.IndexedEmbedded;
37 import org.hibernate.validator.constraints.Length;
38
39 import eu.etaxonomy.cdm.model.description.FeatureTree;
40 import eu.etaxonomy.cdm.model.description.TextData;
41 import eu.etaxonomy.cdm.strategy.cache.common.TermDefaultCacheStrategy;
42 import eu.etaxonomy.cdm.validation.Level2;
43 import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
44
45 @XmlAccessorType(XmlAccessType.FIELD)
46 @XmlType(name = "TermBase", propOrder = {
47 "uri",
48 "representations"
49 })
50 @XmlSeeAlso({
51 DefinedTermBase.class,
52 TermVocabulary.class,
53 FeatureTree.class
54 })
55 @MappedSuperclass
56 public abstract class TermBase extends IdentifiableEntity {
57 private static final long serialVersionUID = 1471561531632115822L;
58 @SuppressWarnings("unused")
59 private static final Logger logger = Logger.getLogger(TermBase.class);
60
61 @XmlElement(name = "URI")
62 @Field(index=org.hibernate.search.annotations.Index.UN_TOKENIZED)
63 @NullOrNotEmpty
64 @Length(max = 255)
65 @Type(type="uriUserType")
66 private URI uri;
67
68 @XmlElementWrapper(name = "Representations")
69 @XmlElement(name = "Representation")
70 @OneToMany(fetch=FetchType.EAGER)
71 @Cascade( { CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE, CascadeType.DELETE_ORPHAN})
72 @IndexedEmbedded(depth = 2)
73 private Set<Representation> representations = new HashSet<Representation>();
74
75 public TermBase(){
76 super();
77 initCacheStrategy();
78
79 }
80 private void initCacheStrategy() {
81 this.cacheStrategy = new TermDefaultCacheStrategy<TermBase>();
82 }
83 public TermBase(String term, String label, String labelAbbrev) {
84 super();
85 this.addRepresentation(new Representation(term, label, labelAbbrev, Language.DEFAULT()) );
86 initCacheStrategy();
87 }
88
89 public Set<Representation> getRepresentations() {
90 return this.representations;
91 }
92
93 public void addRepresentation(Representation representation) {
94 this.representations.add(representation);
95 }
96
97 public void removeRepresentation(Representation representation) {
98 this.representations.remove(representation);
99 }
100
101 public Representation getRepresentation(Language lang) {
102 for (Representation repr : representations){
103 Language reprLanguage = repr.getLanguage();
104 if (reprLanguage != null && reprLanguage.equals(lang)){
105 return repr;
106 }
107 }
108 return null;
109 }
110
111 /**
112 * @see #getPreferredRepresentation(Language)
113 * @param language
114 * @return
115 */
116 public Representation getPreferredRepresentation(Language language) {
117 Representation repr = getRepresentation(language);
118 if(repr == null){
119 repr = getRepresentation(Language.DEFAULT());
120 }
121 if(repr == null){
122 repr = getRepresentations().iterator().next();
123 }
124 return repr;
125 }
126
127 /**
128 * Returns the Representation in the preferred language. Preferred languages
129 * are specified by the parameter languages, which receives a list of
130 * Language instances in the order of preference. If no representation in
131 * any preferred languages is found the method falls back to return the
132 * Representation in Language.DEFAULT() and if necessary further falls back
133 * to return the first element found if any.
134 *
135 * TODO think about this fall-back strategy &
136 * see also {@link TextData#getPreferredLanguageString(List)}
137 *
138 * @param languages
139 * @return
140 */
141 public Representation getPreferredRepresentation(List<Language> languages) {
142 Representation repr = null;
143 if(languages != null){
144 for(Language language : languages) {
145 repr = getRepresentation(language);
146 if(repr != null){
147 return repr;
148 }
149 }
150 }
151 if(repr == null){
152 repr = getRepresentation(Language.DEFAULT());
153 }
154 if(repr == null){
155 Iterator<Representation> it = getRepresentations().iterator();
156 if(it.hasNext()){
157 repr = getRepresentations().iterator().next();
158 }
159 }
160 return repr;
161 }
162
163 public URI getUri() {
164 return this.uri;
165 }
166
167 public void setUri(URI uri) {
168 this.uri = uri;
169 }
170
171 @Transient
172 public String getLabel() {
173 if(getLabel(Language.DEFAULT())!=null){
174 Representation repr = getRepresentation(Language.DEFAULT());
175 return (repr == null)? null :repr.getLabel();
176 }else{
177 for (Representation r : representations){
178 return r.getLabel();
179 }
180 }
181 return super.getUuid().toString();
182 }
183
184 public String getLabel(Language lang) {
185 Representation repr = this.getRepresentation(lang);
186 return (repr == null) ? null : repr.getLabel();
187 }
188
189 public void setLabel(String label){
190 Language lang = Language.DEFAULT();
191 setLabel(label, lang);
192 }
193
194 public void setLabel(String label, Language language){
195 if (language != null){
196 Representation repr = getRepresentation(language);
197 if (repr != null){
198 repr.setLabel(label);
199 }else{
200 repr = Representation.NewInstance(null, label, null, language);
201 }
202 this.addRepresentation(repr);
203 }
204 }
205
206 @Transient
207 public String getDescription() {
208 return this.getDescription(Language.DEFAULT());
209 }
210
211 public String getDescription(Language lang) {
212 Representation repr = this.getRepresentation(lang);
213 return (repr == null) ? null :repr.getDescription();
214 }
215
216 @Override
217 public boolean equals(Object obj) {
218 if (obj == null){
219 return false;
220 }
221 if (TermBase.class.isAssignableFrom(obj.getClass())){
222 TermBase dtb = (TermBase)obj;
223 if (dtb.getUuid().equals(this.getUuid())){
224 return true;
225 }
226 }
227 return false;
228 }
229
230 @Override
231 public String toString() {
232 //TODO eliminate nasty LazyInitializationException loggings
233 try {
234 return super.toString();
235 } catch (LazyInitializationException e) {
236 return super.toString()+" "+this.getUuid();
237 }
238 }
239
240 //*********************** CLONE ********************************************************/
241
242 /**
243 * Clones <i>this</i> TermBase. This is a shortcut that enables to create
244 * a new instance that differs only slightly from <i>this</i> TermBase by
245 * modifying only some of the attributes.
246 *
247 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#clone()
248 * @see java.lang.Object#clone()
249 */
250 @Override
251 public Object clone()throws CloneNotSupportedException {
252
253 TermBase result = (TermBase) super.clone();
254
255 result.representations = new HashSet<Representation>();
256 for (Representation rep : this.representations){
257 result.representations.add((Representation)rep.clone());
258 }
259
260
261
262 return result;
263
264 }
265
266 }