2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.common
;
13 import java
.util
.HashSet
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
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
;
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
;
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
;
45 @XmlAccessorType(XmlAccessType
.FIELD
)
46 @XmlType(name
= "TermBase", propOrder
= {
51 DefinedTermBase
.class,
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);
61 @XmlElement(name
= "URI")
62 @Field(index
=org
.hibernate
.search
.annotations
.Index
.UN_TOKENIZED
)
65 // @Pattern(regexp = "^([a-z0-9+.-]+):(?://(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*)@)?((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*)(?::(\\d*))?(/(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?|(/?(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})+(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?)(?:\\?((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.uri.message}")
66 @Type(type
="uriUserType")
69 @XmlElementWrapper(name
= "Representations")
70 @XmlElement(name
= "Representation")
71 @OneToMany(fetch
=FetchType
.EAGER
)
72 @Cascade( { CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
, CascadeType
.DELETE_ORPHAN
})
73 @IndexedEmbedded(depth
= 2)
74 private Set
<Representation
> representations
= new HashSet
<Representation
>();
81 private void initCacheStrategy() {
82 this.cacheStrategy
= new TermDefaultCacheStrategy
<TermBase
>();
84 public TermBase(String term
, String label
, String labelAbbrev
) {
86 this.addRepresentation(new Representation(term
, label
, labelAbbrev
, Language
.DEFAULT()) );
90 public Set
<Representation
> getRepresentations() {
91 return this.representations
;
94 public void addRepresentation(Representation representation
) {
95 this.representations
.add(representation
);
98 public void removeRepresentation(Representation representation
) {
99 this.representations
.remove(representation
);
102 public Representation
getRepresentation(Language lang
) {
103 for (Representation repr
: representations
){
104 Language reprLanguage
= repr
.getLanguage();
105 if (reprLanguage
!= null && reprLanguage
.equals(lang
)){
113 * @see #getPreferredRepresentation(Language)
117 public Representation
getPreferredRepresentation(Language language
) {
118 Representation repr
= getRepresentation(language
);
120 repr
= getRepresentation(Language
.DEFAULT());
123 repr
= getRepresentations().iterator().next();
129 * Returns the Representation in the preferred language. Preferred languages
130 * are specified by the parameter languages, which receives a list of
131 * Language instances in the order of preference. If no representation in
132 * any preferred languages is found the method falls back to return the
133 * Representation in Language.DEFAULT() and if necessary further falls back
134 * to return the first element found if any.
136 * TODO think about this fall-back strategy &
137 * see also {@link TextData#getPreferredLanguageString(List)}
142 public Representation
getPreferredRepresentation(List
<Language
> languages
) {
143 Representation repr
= null;
144 if(languages
!= null){
145 for(Language language
: languages
) {
146 repr
= getRepresentation(language
);
153 repr
= getRepresentation(Language
.DEFAULT());
156 Iterator
<Representation
> it
= getRepresentations().iterator();
158 repr
= getRepresentations().iterator().next();
164 public URI
getUri() {
168 public void setUri(URI uri
) {
173 public String
getLabel() {
174 if(getLabel(Language
.DEFAULT())!=null){
175 Representation repr
= getRepresentation(Language
.DEFAULT());
176 return (repr
== null)?
null :repr
.getLabel();
178 for (Representation r
: representations
){
182 return super.getUuid().toString();
185 public String
getLabel(Language lang
) {
186 Representation repr
= this.getRepresentation(lang
);
187 return (repr
== null) ?
null : repr
.getLabel();
190 public void setLabel(String label
){
191 Language lang
= Language
.DEFAULT();
192 setLabel(label
, lang
);
195 public void setLabel(String label
, Language language
){
196 if (language
!= null){
197 Representation repr
= getRepresentation(language
);
199 repr
.setLabel(label
);
201 repr
= Representation
.NewInstance(null, label
, null, language
);
203 this.addRepresentation(repr
);
208 public String
getDescription() {
209 return this.getDescription(Language
.DEFAULT());
212 public String
getDescription(Language lang
) {
213 Representation repr
= this.getRepresentation(lang
);
214 return (repr
== null) ?
null :repr
.getDescription();
218 public boolean equals(Object obj
) {
222 if (TermBase
.class.isAssignableFrom(obj
.getClass())){
223 TermBase dtb
= (TermBase
)obj
;
224 if (dtb
.getUuid().equals(this.getUuid())){
232 public String
toString() {
233 //TODO eliminate nasty LazyInitializationException loggings
235 return super.toString();
236 } catch (LazyInitializationException e
) {
237 return super.toString()+" "+this.getUuid();
241 //*********************** CLONE ********************************************************/
244 * Clones <i>this</i> TermBase. This is a shortcut that enables to create
245 * a new instance that differs only slightly from <i>this</i> TermBase by
246 * modifying only some of the attributes.
248 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#clone()
249 * @see java.lang.Object#clone()
252 public Object
clone()throws CloneNotSupportedException
{
254 TermBase result
= (TermBase
) super.clone();
256 result
.representations
= new HashSet
<Representation
>();
257 for (Representation rep
: this.representations
){
258 result
.representations
.add((Representation
)rep
.clone());