warning clean cdmlib-model agent and jaxb
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / IdentifiableEntity.java
1 /**
2 * Copyright (C) 2007 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
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import javax.persistence.Column;
17 import javax.persistence.ManyToMany;
18 import javax.persistence.MappedSuperclass;
19 import javax.persistence.OneToMany;
20 import javax.persistence.Transient;
21 import javax.xml.bind.annotation.XmlAccessType;
22 import javax.xml.bind.annotation.XmlAccessorType;
23 import javax.xml.bind.annotation.XmlElement;
24 import javax.xml.bind.annotation.XmlElementWrapper;
25 import javax.xml.bind.annotation.XmlTransient;
26 import javax.xml.bind.annotation.XmlType;
27
28 import org.apache.log4j.Logger;
29 import org.hibernate.annotations.Cascade;
30 import org.hibernate.annotations.CascadeType;
31
32 import eu.etaxonomy.cdm.model.media.Rights;
33
34 /**
35 * Superclass for the primary CDM classes that can be referenced from outside via LSIDs and contain a simple generated title string as a label for human reading.
36 * All subclasses inherit the ability to store additional properties that are stored as {@link Extension Extensions}, basically a string value with a type term.
37 * Any number of right statements can be attached as well as multiple {@link OriginalSource} objects.
38 * Original sources carry a reference to the source, an ID within that source and the original title/label of this object as it was used in that source (originalNameString).
39 * A Taxon for example that was taken from 2 sources like FaunaEuropaea and IPNI would have two originalSource objects.
40 * The originalSource representing that taxon as it was found in IPNI would contain IPNI as the reference, the IPNI id of the taxon and the name of the taxon exactly as it was used in IPNI.
41 *
42 * @author m.doering
43 * @version 1.0
44 * @created 08-Nov-2007 13:06:27
45 */
46 @XmlAccessorType(XmlAccessType.FIELD)
47 @XmlType(name = "IdentifiableEntity", propOrder = {
48 "lsid",
49 "titleCache",
50 "protectedTitleCache",
51 "rights",
52 "extensions",
53 "sources"
54 })
55 @MappedSuperclass
56 public abstract class IdentifiableEntity<T extends IdentifiableEntity<?>> extends AnnotatableEntity<T> implements ISourceable, IIdentifiableEntity {
57 private static final long serialVersionUID = -5610995424730659058L;
58 private static final Logger logger = Logger.getLogger(IdentifiableEntity.class);
59
60 @XmlTransient
61 public final boolean PROTECTED = true;
62 @XmlTransient
63 public final boolean NOT_PROTECTED = false;
64
65 @XmlElement(name = "LSID")
66 private String lsid;
67
68 @XmlElement(name = "TitleCache", required = true)
69 private String titleCache;
70
71 //if true titleCache will not be automatically generated/updated
72 @XmlElement(name = "ProtectedTitleCache")
73 private boolean protectedTitleCache;
74
75 @XmlElementWrapper(name = "Rights")
76 @XmlElement(name = "Rights")
77 private Set<Rights> rights = getNewRightsSet();
78
79 @XmlElementWrapper(name = "Extensions")
80 @XmlElement(name = "Extension")
81 private Set<Extension> extensions = getNewExtensionSet();
82
83 @XmlElementWrapper(name = "Sources")
84 @XmlElement(name = "OriginalSource")
85 private Set<OriginalSource> sources = getNewOriginalSourcesSet();
86
87
88 /* (non-Javadoc)
89 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getLsid()
90 */
91 public String getLsid(){
92 return this.lsid;
93 }
94 /* (non-Javadoc)
95 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#setLsid(java.lang.String)
96 */
97 public void setLsid(String lsid){
98 this.lsid = lsid;
99 }
100
101 /* (non-Javadoc)
102 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#generateTitle()
103 */
104 public abstract String generateTitle();
105
106 /* (non-Javadoc)
107 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getTitleCache()
108 */
109 @Transient
110 public String getTitleCache(){
111 if (protectedTitleCache){
112 return this.titleCache;
113 }
114 // is title dirty, i.e. equal NULL?
115 if (titleCache == null){
116 this.setTitleCache(generateTitle(),protectedTitleCache) ; //for truncating
117 }
118 return titleCache;
119 }
120 /* (non-Javadoc)
121 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#setTitleCache(java.lang.String)
122 */
123 public void setTitleCache(String titleCache){
124 setTitleCache(titleCache, PROTECTED);
125 }
126
127 //@Index(name="titleCacheIndex")
128 /* (non-Javadoc)
129 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getTitleCache()
130 */
131 @Column(length=255, name="titleCache")
132 @Deprecated //for hibernate use only
133 protected String getPersistentTitleCache(){
134 return getTitleCache();
135 }
136 @Deprecated //for hibernate use only
137 protected void setPersistentTitleCache(String titleCache){
138 this.titleCache = titleCache;
139 }
140
141
142
143 /* (non-Javadoc)
144 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#setTitleCache(java.lang.String, boolean)
145 */
146 public void setTitleCache(String titleCache, boolean protectCache){
147 //TODO truncation of title cache
148 if (titleCache != null && titleCache.length() > 254){
149 logger.warn("Truncation of title cache: " + this.toString() + "/" + titleCache);
150 titleCache = titleCache.substring(0, 249) + "...";
151 }
152 this.titleCache = titleCache;
153 this.setProtectedTitleCache(protectCache);
154 }
155
156 /* (non-Javadoc)
157 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getRights()
158 */
159 @ManyToMany
160 @Cascade({CascadeType.SAVE_UPDATE})
161 public Set<Rights> getRights(){
162 return this.rights;
163 }
164
165 protected void setRights(Set<Rights> rights) {
166 this.rights = rights;
167 }
168 /* (non-Javadoc)
169 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#addRights(eu.etaxonomy.cdm.model.media.Rights)
170 */
171 public void addRights(Rights right){
172 this.rights.add(right);
173 }
174 /* (non-Javadoc)
175 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#removeRights(eu.etaxonomy.cdm.model.media.Rights)
176 */
177 public void removeRights(Rights right){
178 this.rights.remove(right);
179 }
180
181 /* (non-Javadoc)
182 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getExtensions()
183 */
184 @OneToMany//(mappedBy="extendedObj")
185 @Cascade({CascadeType.SAVE_UPDATE})
186 public Set<Extension> getExtensions(){
187 return this.extensions;
188 }
189 protected void setExtensions(Set<Extension> extensions) {
190 this.extensions = extensions;
191 }
192 /* (non-Javadoc)
193 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#addExtension(eu.etaxonomy.cdm.model.common.Extension)
194 */
195 public void addExtension(Extension extension){
196 this.extensions.add(extension);
197 }
198 /* (non-Javadoc)
199 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#removeExtension(eu.etaxonomy.cdm.model.common.Extension)
200 */
201 public void removeExtension(Extension extension){
202 this.extensions.remove(extension);
203 }
204
205
206 /* (non-Javadoc)
207 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#isProtectedTitleCache()
208 */
209 public boolean isProtectedTitleCache() {
210 return protectedTitleCache;
211 }
212
213 /* (non-Javadoc)
214 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#setProtectedTitleCache(boolean)
215 */
216 public void setProtectedTitleCache(boolean protectedTitleCache) {
217 this.protectedTitleCache = protectedTitleCache;
218 }
219
220 /* (non-Javadoc)
221 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#getSources()
222 */
223 @OneToMany //(mappedBy="sourcedObj")
224 @Cascade({CascadeType.SAVE_UPDATE})
225 public Set<OriginalSource> getSources() {
226 return this.sources;
227 }
228 protected void setSources(Set<OriginalSource> sources) {
229 this.sources = sources;
230 }
231 /* (non-Javadoc)
232 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#addSource(eu.etaxonomy.cdm.model.common.OriginalSource)
233 */
234 public void addSource(OriginalSource source) {
235 if (source != null){
236 IdentifiableEntity oldSourcedObj = source.getSourcedObj();
237 if (oldSourcedObj != null && oldSourcedObj != this){
238 oldSourcedObj.getSources().remove(source);
239 }
240 this.sources.add(source);
241 source.setSourcedObj(this);
242 }
243 }
244 /* (non-Javadoc)
245 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#removeSource(eu.etaxonomy.cdm.model.common.OriginalSource)
246 */
247 public void removeSource(OriginalSource source) {
248 this.sources.remove(source);
249 }
250
251 /* (non-Javadoc)
252 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntity#toString()
253 */
254 @Override
255 public String toString() {
256 String result;
257 if (titleCache == null){
258 result = super.toString();
259 }else{
260 result = this.titleCache;
261 }
262 return result;
263 }
264
265 //****************** CLONE ************************************************/
266
267 /* (non-Javadoc)
268 * @see eu.etaxonomy.cdm.model.common.AnnotatableEntity#clone()
269 */
270 @Override
271 public Object clone() throws CloneNotSupportedException{
272 IdentifiableEntity result = (IdentifiableEntity)super.clone();
273
274 //Extensions
275 Set<Extension> newExtensions = getNewExtensionSet();
276 for (Extension extension : this.extensions ){
277 Extension newExtension = extension.clone(this);
278 newExtensions.add(newExtension);
279 }
280 result.setExtensions(newExtensions);
281
282 //OriginalSources
283 Set<OriginalSource> newOriginalSources = getNewOriginalSourcesSet();
284 for (OriginalSource originalSource : this.sources){
285 OriginalSource newSource = originalSource.clone(this);
286 newOriginalSources.add(newSource);
287 }
288 result.setSources(newOriginalSources);
289
290 //Rights
291 Set<Rights> rights = getNewRightsSet();
292 rights.addAll(this.rights);
293 result.setRights(rights);
294
295 //result.setLsid(lsid);
296 //result.setTitleCache(titleCache);
297 //result.setProtectedTitleCache(protectedTitleCache); //must be after setTitleCache
298
299 //no changes to: lsid, titleCache, protectedTitleCache
300
301 //empty titleCache
302 if (! protectedTitleCache){
303 titleCache = null;
304 }
305 return result;
306 }
307
308 @Transient
309 private Set<Extension> getNewExtensionSet(){
310 return new HashSet<Extension>();
311 }
312
313 @Transient
314 private Set<OriginalSource> getNewOriginalSourcesSet(){
315 return new HashSet<OriginalSource>();
316 }
317
318 @Transient
319 private Set<Rights> getNewRightsSet(){
320 return new HashSet<Rights>();
321 }
322
323 }