(no commit message)
[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 IOriginalSource, IIdentifiableEntitiy<T> {
57 static Logger logger = Logger.getLogger(IdentifiableEntity.class);
58
59 @XmlTransient
60 public final boolean PROTECTED = true;
61 @XmlTransient
62 public final boolean NOT_PROTECTED = false;
63
64 @XmlElement(name = "LSID")
65 private String lsid;
66
67 @XmlElement(name = "TitleCache", required = true)
68 private String titleCache;
69
70 //if true titleCache will not be automatically generated/updated
71 @XmlElement(name = "ProtectedTitleCache")
72 private boolean protectedTitleCache;
73
74 @XmlElementWrapper(name = "Rights")
75 @XmlElement(name = "Rights")
76 private Set<Rights> rights = getNewRightsSet();
77
78 @XmlElementWrapper(name = "Extensions")
79 @XmlElement(name = "Extension")
80 private Set<Extension> extensions = getNewExtensionSet();
81
82 @XmlElementWrapper(name = "Sources")
83 @XmlElement(name = "OriginalSource")
84 private Set<OriginalSource> sources = getNewOriginalSourcesSet();
85
86
87 /* (non-Javadoc)
88 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getLsid()
89 */
90 public String getLsid(){
91 return this.lsid;
92 }
93 /* (non-Javadoc)
94 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#setLsid(java.lang.String)
95 */
96 public void setLsid(String lsid){
97 this.lsid = lsid;
98 }
99
100 /* (non-Javadoc)
101 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#generateTitle()
102 */
103 public abstract String generateTitle();
104
105 /* (non-Javadoc)
106 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getTitleCache()
107 */
108 @Transient
109 public String getTitleCache(){
110 if (protectedTitleCache){
111 return this.titleCache;
112 }
113 // is title dirty, i.e. equal NULL?
114 if (titleCache == null){
115 this.setTitleCache(generateTitle(),protectedTitleCache) ; //for truncating
116 }
117 return titleCache;
118 }
119 /* (non-Javadoc)
120 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#setTitleCache(java.lang.String)
121 */
122 public void setTitleCache(String titleCache){
123 setTitleCache(titleCache, PROTECTED);
124 }
125
126 //@Index(name="titleCacheIndex")
127 /* (non-Javadoc)
128 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getTitleCache()
129 */
130 @Column(length=254)
131 @Deprecated //for hibernate use only
132 protected String getPersistentTitleCache(){
133 return getTitleCache();
134 }
135 @Deprecated //for hibernate use only
136 protected void setPersistentTitleCache(String titleCache){
137 this.titleCache = titleCache;
138 }
139
140
141
142 /* (non-Javadoc)
143 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#setTitleCache(java.lang.String, boolean)
144 */
145 public void setTitleCache(String titleCache, boolean protectCache){
146 //TODO truncation of title cache
147 if (titleCache != null && titleCache.length() > 250){
148 logger.warn("Truncation of title cache: " + this.toString());
149 titleCache = titleCache.substring(0, 249) + "...";
150 }
151 this.titleCache = titleCache;
152 this.setProtectedTitleCache(protectCache);
153 }
154
155 /* (non-Javadoc)
156 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getRights()
157 */
158 @ManyToMany
159 @Cascade({CascadeType.SAVE_UPDATE})
160 public Set<Rights> getRights(){
161 return this.rights;
162 }
163
164 protected void setRights(Set<Rights> rights) {
165 this.rights = rights;
166 }
167 /* (non-Javadoc)
168 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#addRights(eu.etaxonomy.cdm.model.media.Rights)
169 */
170 public void addRights(Rights right){
171 this.rights.add(right);
172 }
173 /* (non-Javadoc)
174 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#removeRights(eu.etaxonomy.cdm.model.media.Rights)
175 */
176 public void removeRights(Rights right){
177 this.rights.remove(right);
178 }
179
180 /* (non-Javadoc)
181 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getExtensions()
182 */
183 @OneToMany//(mappedBy="extendedObj")
184 @Cascade({CascadeType.SAVE_UPDATE})
185 public Set<Extension> getExtensions(){
186 return this.extensions;
187 }
188 protected void setExtensions(Set<Extension> extensions) {
189 this.extensions = extensions;
190 }
191 /* (non-Javadoc)
192 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#addExtension(eu.etaxonomy.cdm.model.common.Extension)
193 */
194 public void addExtension(Extension extension){
195 this.extensions.add(extension);
196 }
197 /* (non-Javadoc)
198 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#removeExtension(eu.etaxonomy.cdm.model.common.Extension)
199 */
200 public void removeExtension(Extension extension){
201 this.extensions.remove(extension);
202 }
203
204
205 /* (non-Javadoc)
206 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#isProtectedTitleCache()
207 */
208 public boolean isProtectedTitleCache() {
209 return protectedTitleCache;
210 }
211
212 /* (non-Javadoc)
213 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#setProtectedTitleCache(boolean)
214 */
215 public void setProtectedTitleCache(boolean protectedTitleCache) {
216 this.protectedTitleCache = protectedTitleCache;
217 }
218
219 /* (non-Javadoc)
220 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#getSources()
221 */
222 @OneToMany //(mappedBy="sourcedObj")
223 @Cascade({CascadeType.SAVE_UPDATE})
224 public Set<OriginalSource> getSources() {
225 return this.sources;
226 }
227 protected void setSources(Set<OriginalSource> sources) {
228 this.sources = sources;
229 }
230 /* (non-Javadoc)
231 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#addSource(eu.etaxonomy.cdm.model.common.OriginalSource)
232 */
233 public void addSource(OriginalSource source) {
234 if (source != null){
235 IdentifiableEntity oldSourcedObj = source.getSourcedObj();
236 if (oldSourcedObj != null && oldSourcedObj != this){
237 oldSourcedObj.getSources().remove(source);
238 }
239 this.sources.add(source);
240 source.setSourcedObj(this);
241 }
242 }
243 /* (non-Javadoc)
244 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#removeSource(eu.etaxonomy.cdm.model.common.OriginalSource)
245 */
246 public void removeSource(OriginalSource source) {
247 this.sources.remove(source);
248 }
249
250 /* (non-Javadoc)
251 * @see eu.etaxonomy.cdm.model.common.IIdentifiableEntitiy#toString()
252 */
253 @Override
254 public String toString() {
255 String result;
256 if (titleCache == null){
257 result = super.toString();
258 }else{
259 result = this.titleCache;
260 }
261 return result;
262 }
263
264 //****************** CLONE ************************************************/
265
266 /* (non-Javadoc)
267 * @see eu.etaxonomy.cdm.model.common.AnnotatableEntity#clone()
268 */
269 public Object clone() throws CloneNotSupportedException{
270 IdentifiableEntity result = (IdentifiableEntity)super.clone();
271
272 //Extensions
273 Set<Extension> newExtensions = getNewExtensionSet();
274 for (Extension extension : this.extensions ){
275 Extension newExtension = (Extension)extension.clone(this);
276 newExtensions.add(newExtension);
277 }
278 result.setExtensions(newExtensions);
279
280 //OriginalSources
281 Set<OriginalSource> newOriginalSources = getNewOriginalSourcesSet();
282 for (OriginalSource originalSource : this.sources){
283 OriginalSource newSource = (OriginalSource)originalSource.clone(this);
284 newOriginalSources.add(newSource);
285 }
286 result.setSources(newOriginalSources);
287
288 //Rights
289 Set<Rights> rights = getNewRightsSet();
290 rights.addAll(this.rights);
291 result.setRights(rights);
292
293 //result.setLsid(lsid);
294 //result.setTitleCache(titleCache);
295 //result.setProtectedTitleCache(protectedTitleCache); //must be after setTitleCache
296
297 //no changes to: lsid, titleCache, protectedTitleCache
298 return result;
299 }
300
301 @Transient
302 private Set<Extension> getNewExtensionSet(){
303 return new HashSet<Extension>();
304 }
305
306 @Transient
307 private Set<OriginalSource> getNewOriginalSourcesSet(){
308 return new HashSet<OriginalSource>();
309 }
310
311 @Transient
312 private Set<Rights> getNewRightsSet(){
313 return new HashSet<Rights>();
314 }
315
316 }