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