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