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