Marshall/unmarshall Representations explicitly
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / agent / Person.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.agent;
11
12 import eu.etaxonomy.cdm.model.common.TimePeriod;
13 import eu.etaxonomy.cdm.model.common.Keyword;
14 import eu.etaxonomy.cdm.strategy.cache.agent.PersonDefaultCacheStrategy;
15
16 import org.apache.log4j.Logger;
17 import org.hibernate.annotations.Cascade;
18 import org.hibernate.annotations.CascadeType;
19 import java.util.*;
20 import javax.persistence.*;
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.XmlIDREF;
26 import javax.xml.bind.annotation.XmlRootElement;
27 import javax.xml.bind.annotation.XmlSchemaType;
28 import javax.xml.bind.annotation.XmlType;
29
30 /**
31 * This class represents human beings, living or dead.<BR>
32 * It includes name parts, {@link Contact contact} details, {@link InstitutionalMembership institutional membership},
33 * and other possible information such as life {@link TimePeriod time period},
34 * taxonomic and/or geographical {@link Keyword specialization}.
35 * For a short abbreviated name the inherited attribute {@link TeamOrPersonBase#getNomenclaturalTitle() nomenclaturalTitle}
36 * is to be used.<BR>
37 * For other alternative (string-)names {@link eu.etaxonomy.cdm.model.common.OriginalSource OriginalSource} instances must be created
38 * and the inherited attribute {@link eu.etaxonomy.cdm.model.common.ReferencedEntityBase#getOriginalNameString() originalNameString} must be used.
39 * <P>
40 * This class corresponds to: <ul>
41 * <li> Person according to the TDWG ontology
42 * <li> AgentName (partially) according to the TCS
43 * <li> Person (PersonName partially) according to the ABCD schema
44 * </ul>
45 *
46 * @author m.doering
47 * @version 1.0
48 * @created 08-Nov-2007 13:06:42
49 */
50 @XmlAccessorType(XmlAccessType.FIELD)
51 @XmlType(name = "Person", propOrder = {
52 "prefix",
53 "firstname",
54 "lastname",
55 "suffix",
56 "lifespan",
57 "institutionalMemberships",
58 "contact",
59 "keywords"
60 })
61 @XmlRootElement(name = "Person")
62 @Entity
63 public class Person extends TeamOrPersonBase {
64 static Logger logger = Logger.getLogger(Person.class);
65
66 @XmlElement(name = "Prefix")
67 private String prefix;
68
69 @XmlElement(name = "FirstName")
70 private String firstname;
71
72 @XmlElement(name = "LastName")
73 private String lastname;
74
75 @XmlElement(name = "Suffix")
76 private String suffix;
77
78 @XmlElement(name = "Lifespan")
79 //@XmlJavaTypeAdapter(IntervalAdapter.class)
80 private TimePeriod lifespan;
81
82 @XmlElementWrapper(name = "InstitutionalMemberships")
83 @XmlElement(name = "InstitutionalMembership")
84 protected Set<InstitutionalMembership> institutionalMemberships;
85
86 @XmlElement(name = "Contact")
87 private Contact contact;
88
89 @XmlElementWrapper(name = "Keywords")
90 @XmlElement(name = "Keyword")
91 @XmlIDREF
92 @XmlSchemaType(name="IDREF")
93 private Set<Keyword> keywords = new HashSet<Keyword>();
94
95 /**
96 * Creates a new empty instance for a person whose existence is all what is known.
97 * This can be a provisional solution until more information about <i>this</i> person
98 * can be gathered, for instance in case a member of a nomenclatural author team
99 * is not explicitly mentioned. It also includes the cache strategy defined in
100 * {@link eu.etaxonomy.cdm.strategy.cache.agent.PersonDefaultCacheStrategy PersonDefaultCacheStrategy}.
101 */
102 public static Person NewInstance(){
103 return new Person();
104 }
105
106 /**
107 * Creates a new instance for a person for whom an "identification" string
108 * is all what is known. This string is generally a short or a complete name.
109 * As this string is kept in the {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache}
110 * attribute and should not be overwritten by the {@link #generateTitle() generateTitle} method
111 * the {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#isProtectedTitleCache() protectedTitleCache} flag will be turned on.
112 */
113 public static Person NewTitledInstance(String titleCache){
114 Person result = new Person();
115 result.setTitleCache(titleCache);
116 return result;
117 }
118
119
120 /**
121 * Class constructor.
122 *
123 * @see #Person(String, String, String)
124 */
125 private Person() {
126 super();
127 this.cacheStrategy = PersonDefaultCacheStrategy.NewInstance();
128
129 }
130
131 /**
132 * Class constructor using a "forenames" string (including initials),
133 * a surname (family name) and an abbreviated name as used in nomenclature.
134 * For the abbreviated name the inherited attribute {@link TeamOrPersonBase#getNomenclaturalTitle() nomenclaturalTitle}
135 * is used.
136 *
137 * @param firstname the given name
138 * @param lastname the hereditary name
139 * @param nomenclaturalTitel the abbreviated name
140 * @see #Person()
141 * @see #NewInstance()
142 */
143 public Person(String firstname, String lastname, String nomenclaturalTitel) {
144 this.setFirstname(firstname);
145 this.setLastname(lastname);
146 this.setNomenclaturalTitle(nomenclaturalTitel);
147 }
148
149
150 /**
151 * Returns the set of {@link InstitutionalMembership institution memberships} corresponding to <i>this</i> person.
152 *
153 * @see InstitutionalMembership
154 */
155 @OneToMany(fetch=FetchType.LAZY)
156 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
157 public Set<InstitutionalMembership> getInstitutionalMemberships(){
158 return this.institutionalMemberships;
159 }
160 /**
161 * @see #getInstitutionalMemberships()
162 */
163 protected void setInstitutionalMemberships(Set<InstitutionalMembership> institutionalMemberships){
164 this.institutionalMemberships = institutionalMemberships;
165 }
166
167 /**
168 * Adds a new {@link InstitutionalMembership membership} of <i>this</i> person in an {@link Institution institution}
169 * to the set of his institution memberships.
170 * This method also creates a new institutional membership instance.
171 *
172 * @param institution the institution <i>this</i> person belongs to
173 * @param period the time period for which <i>this</i> person has been a member of the institution
174 * @param department the string label for the department <i>this</i> person belongs to,
175 * within the institution
176 * @param role the string label for the persons's role within the department or institution
177 * @see #getInstitutionalMemberships()
178 * @see InstitutionalMembership#InstitutionalMembership(Institution, Person, TimePeriod, String, String)
179 */
180 public void addInstitutionalMembership(Institution institution, TimePeriod period, String department, String role){
181 //TODO to be implemented?
182 logger.warn("not yet fully implemented?");
183 InstitutionalMembership ims = new InstitutionalMembership(institution, this, period, department, role);
184 institutionalMemberships.add(ims);
185 }
186
187 /**
188 * Removes one element from the set of institutional memberships of <i>this</i> person.
189 * Institute and person attributes of the institutional membership object
190 * will be nullified.
191 *
192 * @param ims the institutional membership of <i>this</i> person which should be deleted
193 * @see #getInstitutionalMemberships()
194 */
195 public void removeInstitutionalMembership(InstitutionalMembership ims){
196 //TODO to be implemented?
197 logger.warn("not yet fully implemented?");
198 ims.setInstitute(null);
199 ims.setPerson(null);
200 this.institutionalMemberships.remove(ims);
201 }
202
203
204 /**
205 * Returns the set of {@link eu.etaxonomy.cdm.model.common.Keyword keywords} mostly representing a taxonomic or
206 * a geographical specialization of <i>this</i> person.
207 * Keywords are items of a controlled {@link eu.etaxonomy.cdm.model.common.TermVocabulary vocabulary}.
208 *
209 * @see Keyword
210 */
211 @ManyToMany(fetch=FetchType.LAZY,
212 targetEntity=eu.etaxonomy.cdm.model.common.Keyword.class
213 )
214 @JoinTable(
215 name="Person_Keyword",
216 joinColumns=@JoinColumn(name="person_fk"),
217 inverseJoinColumns=@JoinColumn(name="keyword_fk")
218 )
219 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
220 public Set<Keyword> getKeywords(){
221 return this.keywords;
222 }
223 /**
224 * @see #getKeywords()
225 */
226 public void setKeywords(Set<Keyword> keywords){
227 this.keywords = keywords;
228 }
229 /**
230 * Adds a new keyword from the keyword vocabulary to the set of keywords
231 * describing or circumscribing <i>this</i> person's activities.
232 *
233 * @param keyword any keyword
234 * @see #getKeywords()
235 * @see eu.etaxonomy.cdm.model.common.Keyword
236 */
237 public void addKeyword(Keyword keyword){
238 this.keywords.add(keyword);
239 }
240 /**
241 * Removes one element from the set of keywords for <i>this</i> person.
242 *
243 * @param keyword the keyword which should be deleted
244 * @see #getKeywords()
245 */
246 public void removeKeyword(Keyword keyword){
247 this.keywords.remove(keyword);
248 }
249
250
251
252 /**
253 * Returns the {@link Contact contact} of <i>this</i> person.
254 * The contact contains several ways to approach <i>this</i> person.
255 *
256 * @see Contact
257 */
258 @ManyToOne(fetch=FetchType.LAZY)
259 @Cascade({CascadeType.SAVE_UPDATE})
260 public Contact getContact(){
261 return this.contact;
262 }
263 /**
264 * @see #getContact()
265 */
266 public void setContact(Contact contact){
267 this.contact = contact;
268 }
269
270
271 /**
272 * Returns the string representing the prefix (for instance "Prof.&nbsp;Dr.<!-- -->")
273 * to <i>this</i> person's name.
274 */
275 public String getPrefix(){
276 return this.prefix;
277 }
278 /**
279 * @see #getPrefix()
280 */
281 public void setPrefix(String prefix){
282 this.prefix = prefix;
283 }
284
285
286 /**
287 * Returns the string representing the given name or forename
288 * (for instance "John") of <i>this</i> person.
289 * This is the part of his name which is not shared with other
290 * family members. Actually it may be just initials (for instance "G.&nbsp;Jr."),
291 * all forenames in full or a combination of expanded names and initials.
292 */
293 public String getFirstname(){
294 return this.firstname;
295 }
296 /**
297 * @see #getFirstname()
298 */
299 public void setFirstname(String firstname){
300 this.firstname = firstname;
301 }
302
303
304 /**
305 * Returns the string representing the hereditary name (surname or family name)
306 * (for instance "Smith") of <i>this</i> person.
307 * This is the part of his name which is common to (all) other
308 * members of his family, as distinct from the given name or forename.
309 */
310 public String getLastname(){
311 return this.lastname;
312 }
313 /**
314 * @see #getLastname()
315 */
316 public void setLastname(String lastname){
317 this.lastname = lastname;
318 }
319
320
321 /**
322 * Returns the string representing the suffix (for instance "Junior")
323 * of <i>this</i> person's name.
324 */
325 public String getSuffix(){
326 return this.suffix;
327 }
328 /**
329 * @see #getSuffix()
330 */
331 public void setSuffix(String suffix){
332 this.suffix = suffix;
333 }
334
335
336 /**
337 * Returns the {@link eu.etaxonomy.cdm.model.common.TimePeriod period of time}
338 * in which <i>this</i> person was alive (life span).
339 * The general form is birth date - death date
340 * (XXXX - YYYY; XXXX - or - YYYY as appropriate),
341 * but a simple flourished date (fl. XXXX) is also possible
342 * if that is all what is known.
343 *
344 * @see eu.etaxonomy.cdm.model.common.TimePeriod
345 */
346 public TimePeriod getLifespan(){
347 return this.lifespan;
348 }
349 /**
350 * @see #getLifespan()
351 */
352 public void setLifespan(TimePeriod lifespan){
353 this.lifespan = lifespan;
354 }
355
356 /**
357 * Generates the "full" name string of <i>this</i> person according to the strategy
358 * defined in {@link eu.etaxonomy.cdm.strategy.cache.agent.PersonDefaultCacheStrategy PersonDefaultCacheStrategy}.
359 * The used attributes are:
360 * {@link #getPrefix() prefix}, {@link #getFirstname() firstname}, {@link #getLastname() lastname} and {@link #getSuffix() suffix}.
361 * This method overrides {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle() generateTitle}.
362 * The result might be kept as {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#setTitleCache(String) titleCache} if the
363 * flag {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#protectedTitleCache protectedTitleCache} is not set.
364 *
365 * @return the string with the full name of <i>this</i> person
366 */
367 @Override
368 public String generateTitle() {
369 String title = null;
370 if (cacheStrategy != null) {
371 title = cacheStrategy.getTitleCache(this);
372 }
373 return title;
374 }
375
376 }