AlgaTerra categorical data and flat classifications
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / agent / Contact.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 java.io.Serializable;
13 import java.util.ArrayList;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17
18 import javax.persistence.Embeddable;
19 import javax.persistence.FetchType;
20 import javax.persistence.OneToMany;
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.XmlRootElement;
26 import javax.xml.bind.annotation.XmlSchemaType;
27 import javax.xml.bind.annotation.XmlType;
28
29 import org.apache.log4j.Logger;
30 import org.hibernate.annotations.Cascade;
31 import org.hibernate.annotations.CascadeType;
32 import org.hibernate.annotations.CollectionOfElements;
33 import org.hibernate.envers.Audited;
34
35 import eu.etaxonomy.cdm.common.CdmUtils;
36 import eu.etaxonomy.cdm.model.location.Point;
37 import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;
38 import eu.etaxonomy.cdm.strategy.merge.MergeException;
39
40 /**
41 * The class for information on how to approach a {@link Person person} or an {@link Institution institution}.
42 * It includes telecommunication data and an electronic as well as
43 * multiple postal addresses.
44 * <P>
45 * This class corresponds to: <ul>
46 * <li> ContactDetails according to the TDWG ontology
47 * <li> Contact (partially) according to the ABCD schema
48 * </ul>
49 *
50 * @author m.doering
51 * @version 1.0
52 * @created 08-Nov-2007 13:06:18
53 */
54 @XmlAccessorType(XmlAccessType.FIELD)
55 @XmlType(name = "Contact", propOrder = {
56 "emailAddresses",
57 "urls",
58 "phoneNumbers",
59 "faxNumbers",
60 "addresses"
61 })
62 @XmlRootElement(name = "Contact")
63 @Embeddable
64 @Audited
65 public class Contact implements Serializable, Cloneable {
66 private static final long serialVersionUID = -1851305307069277625L;
67 @SuppressWarnings("unused")
68 private static final Logger logger = Logger.getLogger(Contact.class);
69
70
71 public static Contact NewInstance() {
72 return new Contact();
73 }
74
75 /**
76 * Creates a new contact
77 * @param street
78 * @param postcode
79 * @param locality
80 * @param country
81 * @param pobox
82 * @param region
83 * @param email
84 * @param faxNumber
85 * @param phoneNumber
86 * @param url
87 * @param location
88 * @return
89 */
90 public static Contact NewInstance(String street, String postcode, String locality,
91 WaterbodyOrCountry country, String pobox, String region,
92 String email, String faxNumber, String phoneNumber, String url, Point location) {
93 Contact result = new Contact();
94 if (country != null || CdmUtils.isNotEmpty(locality) || CdmUtils.isNotEmpty(pobox) || CdmUtils.isNotEmpty(postcode) ||
95 CdmUtils.isNotEmpty(region) || CdmUtils.isNotEmpty(street) ){
96 Address newAddress = Address.NewInstance(country, locality, pobox, postcode, region, street, location);
97 result.addAddress(newAddress);
98 }
99 if (email != null){
100 result.addEmailAddress(email);
101 }
102 if (faxNumber != null){
103 result.addFaxNumber(faxNumber);
104 }
105 if (phoneNumber != null){
106 result.addPhoneNumber(phoneNumber);
107 }
108 if (url != null){
109 result.addUrl(url);
110 }
111 return result;
112 }
113
114
115 public static Contact NewInstance(Set<Address> addresses, List<String> emailAdresses,
116 List<String> faxNumbers, List<String> phoneNumbers, List<String> urls) {
117 Contact result = new Contact();
118 if (addresses != null){
119 result.addresses = addresses;
120 }
121 if (emailAdresses != null){
122 result.emailAddresses = emailAdresses;
123 }
124 if (faxNumbers != null){
125 result.faxNumbers = faxNumbers;
126 }
127 if (phoneNumbers != null){
128 result.phoneNumbers = phoneNumbers;
129 }
130 if (urls != null){
131 result.urls = urls;
132 }
133 return result;
134 }
135
136
137 /**
138 * Class constructor.
139 */
140 public Contact() {
141 }
142
143 @XmlElementWrapper(name = "EmailAddresses", nillable = true)
144 @XmlElement(name = "EmailAddress")
145 @CollectionOfElements(fetch = FetchType.LAZY)
146 private List<String> emailAddresses;
147
148 @XmlElementWrapper(name = "URLs", nillable = true)
149 @XmlElement(name = "URL")
150 @XmlSchemaType(name = "anyURI")
151 @CollectionOfElements(fetch = FetchType.LAZY)
152 private List<String> urls;
153
154 @XmlElementWrapper(name = "PhoneNumbers", nillable = true)
155 @XmlElement(name = "PhoneNumber")
156 @CollectionOfElements(fetch = FetchType.LAZY)
157 private List<String> phoneNumbers;
158
159 @XmlElementWrapper(name = "FaxNumbers", nillable = true)
160 @XmlElement(name = "FaxNumber")
161 @CollectionOfElements(fetch = FetchType.LAZY)
162 private List<String> faxNumbers;
163
164 @XmlElementWrapper(name = "Addresses", nillable = true)
165 @XmlElement(name = "Address")
166 @OneToMany(fetch = FetchType.LAZY)
167 @Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE_ORPHAN})
168 protected Set<Address> addresses;
169
170
171 public void merge(Contact contact2) throws MergeException{
172 if (contact2 != null){
173 mergeList(this.getEmailAddresses(), contact2.getEmailAddresses());
174 mergeList(this.getFaxNumbers(), contact2.getFaxNumbers());
175 mergeList(this.getPhoneNumbers(), contact2.getPhoneNumbers());
176 mergeList(this.getUrls(), contact2.getUrls());
177 for (Address address : contact2.getAddresses()){
178 try {
179 this.addresses.add((Address)address.clone());
180 } catch (CloneNotSupportedException e) {
181 throw new MergeException("Address must implement Cloneable");
182 }
183 }
184 }
185 }
186
187 private void mergeList(List list1, List list2){
188 for (Object obj2 : list2){
189 if (! list1.contains(obj2)){
190 list1.add(obj2);
191 }
192 }
193 }
194
195
196 /**
197 * Returns the set of postal {@link Address addresses} belonging to <i>this</i> contact.
198 * A {@link Person person} or an {@link Institution institution} cannot have more than one contact,
199 * but a contact may include several postal addresses.
200 *
201 * @return the set of postal addresses
202 * @see Address
203 */
204 public Set<Address> getAddresses(){
205 if(this.addresses == null) {
206 this.addresses = new HashSet<Address>();
207 }
208 return this.addresses;
209 }
210
211 /**
212 * Adds a new postal {@link Address address} to the set of postal addresses of <i>this</i> contact.
213 *
214 * @param address the address to be added
215 * @see #getAddresses()
216 * @see Address
217 */
218 public void addAddress(Address address){
219 if (address != null){
220 getAddresses().add(address);
221 }
222 }
223
224 public void addAddress(String street, String postcode, String locality,
225 WaterbodyOrCountry country, String pobox, String region, Point location){
226 Address newAddress = Address.NewInstance(country, locality, pobox, postcode, region, street, location);
227 getAddresses().add(newAddress);
228 }
229
230 /**
231 * Removes one element from the set of postal addresses of <i>this</i> contact.
232 *
233 * @param address the postal address of <i>this</i> contact which should be deleted
234 * @see #getAddresses()
235 */
236 public void removeAddress(Address address){
237 getAddresses().remove(address);
238 }
239
240
241 /**
242 * Returns the List of strings representing the electronic mail addresses
243 * included in <i>this</i> contact.
244 */
245 public List<String> getEmailAddresses(){
246 if(this.emailAddresses == null) {
247 this.emailAddresses = new ArrayList<String>();
248 }
249 return this.emailAddresses;
250 }
251
252 /**
253 * @see #getEmailAddress()
254 */
255 public void addEmailAddress(String emailAddress){
256 getEmailAddresses().add(emailAddress);
257 }
258
259 /**
260 * Removes one element from the list of email addresses of <i>this</i> contact.
261 *
262 * @param emailAddress the email address of <i>this</i> contact which should be deleted
263 * @see #getEmailAddresses()
264 */
265 public void removeEmailAddress(String emailAddress){
266 getEmailAddresses().remove(emailAddress);
267 }
268
269 /**
270 * Returns the list of strings representing the "Uniform Resource Locators" (urls)
271 * included in <i>this</i> contact.
272 */
273 public List<String> getUrls(){
274 if(this.urls == null) {
275 this.urls = new ArrayList<String>();
276 }
277 return this.urls;
278 }
279
280 /**
281 * @see #getUrls()
282 */
283 public void addUrl(String url){
284 getUrls().add(url);
285 }
286
287 /**
288 * Removes one element from the list of urls of <i>this</i> contact.
289 *
290 * @param url the url of <i>this</i> contact which should be deleted
291 * @see #getUrls()
292 */
293 public void removeUrl(String url){
294 getUrls().remove(url);
295 }
296
297 /**
298 * Returns the list of strings representing the phone numbers
299 * included in <i>this</i> contact.
300 */
301 public List<String> getPhoneNumbers(){
302 if(this.phoneNumbers == null) {
303 this.phoneNumbers = new ArrayList<String>();
304 }
305 return this.phoneNumbers;
306 }
307
308 /**
309 * @see #getPhone()
310 */
311 public void addPhoneNumber(String phoneNumber){
312 getPhoneNumbers().add(phoneNumber);
313 }
314
315 /**
316 * Removes one element from the list of phone numbers of <i>this</i> contact.
317 *
318 * @param phoneNumber the phone number of <i>this</i> contact which should be deleted
319 * @see #getPhoneNumber()
320 */
321 public void removePhoneNumber(String phoneNumber){
322 getPhoneNumbers().remove(phoneNumber);
323 }
324
325 /**
326 * Returns the list of strings representing the telefax numbers
327 * included in <i>this</i> contact.
328 */
329 public List<String> getFaxNumbers(){
330 if(this.faxNumbers == null) {
331 this.faxNumbers = new ArrayList<String>();
332 }
333 return this.faxNumbers;
334 }
335
336 /**
337 * @see #getFaxNumbers()
338 */
339 public void addFaxNumber(String faxNumber){
340 getFaxNumbers().add(faxNumber);
341 }
342
343 /**
344 * Removes one element from the list of telefax numbers of <i>this</i> contact.
345 *
346 * @param faxNumber the telefax number of <i>this</i> contact which should be deleted
347 * @see #getFaxNumber()
348 */
349 public void removeFaxNumber(String faxNumber){
350 getFaxNumbers().remove(faxNumber);
351 }
352
353 //*********************** CLONE ********************************************************/
354
355 /**
356 * Clones <i>this</i> Contact. This is a shortcut that enables to create
357 * a new instance that differs only slightly from <i>this</i> Contact.
358 *
359 *
360 * @see java.lang.Object#clone()
361 */
362 @Override
363 public Object clone() {
364 try{
365 Contact result = (Contact) super.clone();
366 result.addresses = new HashSet<Address>();
367 for (Address adr : this.addresses){
368 result.addAddress((Address)adr.clone());
369 }
370 //no changes to emailAdresses, faxNumbers, phoneNumbers, urls
371 return result;
372 }catch (CloneNotSupportedException e){
373 logger.warn("Object does not implement cloneable");
374 e.printStackTrace();
375 return null;
376 }
377 }
378 }