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