Project

General

Profile

Download (11.8 KB) Statistics
| Branch: | Tag: | Revision:
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.net.URI;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Set;
19

    
20
import javax.persistence.Column;
21
import javax.persistence.ElementCollection;
22
import javax.persistence.Embeddable;
23
import javax.persistence.FetchType;
24
import javax.persistence.OneToMany;
25
import javax.persistence.Transient;
26
import javax.xml.bind.annotation.XmlAccessType;
27
import javax.xml.bind.annotation.XmlAccessorType;
28
import javax.xml.bind.annotation.XmlElement;
29
import javax.xml.bind.annotation.XmlElementWrapper;
30
import javax.xml.bind.annotation.XmlRootElement;
31
import javax.xml.bind.annotation.XmlSchemaType;
32
import javax.xml.bind.annotation.XmlType;
33

    
34
import org.apache.commons.lang3.StringUtils;
35
import org.apache.log4j.Logger;
36
import org.hibernate.annotations.Cascade;
37
import org.hibernate.annotations.CascadeType;
38
import org.hibernate.envers.Audited;
39

    
40
import eu.etaxonomy.cdm.model.location.Country;
41
import eu.etaxonomy.cdm.model.location.Point;
42
import eu.etaxonomy.cdm.strategy.merge.MergeException;
43

    
44
/**
45
 * The class for information on how to approach a {@link Person person} or an {@link Institution institution}.
46
 * It includes telecommunication data and an electronic as well as
47
 * multiple postal addresses.
48
* <P>
49
 * This class corresponds to: <ul>
50
 * <li> ContactDetails according to the TDWG ontology
51
 * <li> Contact (partially) according to the ABCD schema
52
 * </ul>
53
 *
54
 * @author m.doering
55
 * @version 1.0
56
 * @since 08-Nov-2007 13:06:18
57
 */
58
@XmlAccessorType(XmlAccessType.FIELD)
59
@XmlType(name = "Contact", propOrder = {
60
    "emailAddresses",
61
    "urls",
62
    "phoneNumbers",
63
    "faxNumbers",
64
    "addresses"
65
})
66
@XmlRootElement(name = "Contact")
67
@Embeddable
68
@Audited
69
public class Contact implements Serializable, Cloneable {
70
	private static final long serialVersionUID = -1851305307069277625L;
71
	private static final Logger logger = Logger.getLogger(Contact.class);
72

    
73

    
74
	@XmlElementWrapper(name = "EmailAddresses", nillable = true)
75
	@XmlElement(name = "EmailAddress")
76
	@ElementCollection(fetch = FetchType.LAZY)
77
	@Column(name = "contact_emailaddresses_element")
78
	private List<String> emailAddresses = new ArrayList<>();
79

    
80
	@XmlElementWrapper(name = "URLs", nillable = true)
81
	@XmlElement(name = "URL")
82
    @XmlSchemaType(name = "anyURI")
83
	@ElementCollection(fetch = FetchType.LAZY)
84
    @Column(name = "contact_urls_element" /*, length=330  */)  //length >255 does not work in InnoDB AUD tables for Key length of (REV, id, url) key
85
	private final List<String> urls = new ArrayList<>();
86

    
87
	@XmlElementWrapper(name = "PhoneNumbers", nillable = true)
88
	@XmlElement(name = "PhoneNumber")
89
	@ElementCollection(fetch = FetchType.LAZY)
90
    @Column(name = "contact_phonenumbers_element")
91
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE, CascadeType.DELETE})
92
	private List<String> phoneNumbers = new ArrayList<>();
93

    
94
	@XmlElementWrapper(name = "FaxNumbers", nillable = true)
95
	@XmlElement(name = "FaxNumber")
96
	@ElementCollection(fetch = FetchType.LAZY)
97
    @Column(name = "contact_faxnumbers_element")
98
	private List<String> faxNumbers = new ArrayList<>();
99

    
100
    @XmlElementWrapper(name = "Addresses", nillable = true)
101
    @XmlElement(name = "Address")
102
    @OneToMany(fetch = FetchType.LAZY, orphanRemoval=true)
103
	@Cascade({CascadeType.SAVE_UPDATE, CascadeType.MERGE})
104
	protected Set<Address> addresses = new HashSet<>();
105

    
106
	public static Contact NewInstance() {
107
		return new Contact();
108
	}
109

    
110
	/**
111
	 * Creates a new contact
112
	 * @param street
113
	 * @param postcode
114
	 * @param locality
115
	 * @param country
116
	 * @param pobox
117
	 * @param region
118
	 * @param email
119
	 * @param faxNumber
120
	 * @param phoneNumber
121
	 * @param url
122
	 * @param location
123
	 * @return
124
	 */
125
	public static Contact NewInstance(String street, String postcode, String locality,
126
			Country country, String pobox, String region,
127
			String email, String faxNumber, String phoneNumber, URI url, Point location) {
128
		Contact result = new Contact();
129
		if (country != null || StringUtils.isNotBlank(locality) || StringUtils.isNotBlank(pobox) || StringUtils.isNotBlank(postcode) ||
130
				StringUtils.isNotBlank(region) || StringUtils.isNotBlank(street) ){
131
			Address newAddress = Address.NewInstance(country, locality, pobox, postcode, region, street, location);
132
			result.addAddress(newAddress);
133
		}
134
		if (email != null){
135
			result.addEmailAddress(email);
136
		}
137
		if (faxNumber != null){
138
			result.addFaxNumber(faxNumber);
139
		}
140
		if (phoneNumber != null){
141
			result.addPhoneNumber(phoneNumber);
142
		}
143
		if (url != null){
144
			result.addUrl(url);
145
		}
146
		return result;
147
	}
148

    
149

    
150
	public static Contact NewInstance(Set<Address> addresses, List<String> emailAddresses,
151
			List<String> faxNumbers, List<String> phoneNumbers, List<URI> urls) {
152
		Contact result = new Contact();
153
		if (addresses != null){
154
			result.addresses = addresses;
155
		}
156
		if (emailAddresses != null){
157
			result.emailAddresses = emailAddresses;
158
		}
159
		if (faxNumbers != null){
160
			result.faxNumbers = faxNumbers;
161
		}
162
		if (phoneNumbers != null){
163
			result.phoneNumbers = phoneNumbers;
164
		}
165
		if (urls != null){
166
			for (URI uri : urls){
167
				result.urls.add(uri.toString());
168
			}
169
		}
170
		return result;
171
	}
172

    
173
// ************************ CONSTRUCTOR **************************/
174
	/**
175
	 * Class constructor.
176
	 */
177
	public Contact() {
178
	}
179

    
180
// ************************ MERGE /MATCH ***************************/
181

    
182
	public void merge(Contact contact2) throws MergeException{
183
		if (contact2 != null){
184
			mergeList(this.getEmailAddresses(), contact2.getEmailAddresses());
185
			mergeList(this.getFaxNumbers(), contact2.getFaxNumbers());
186
			mergeList(this.getPhoneNumbers(), contact2.getPhoneNumbers());
187
			mergeList(this.getUrls(), contact2.getUrls());
188
			for (Address address : contact2.getAddresses()){
189
				try {
190
					if (this.addresses == null){
191
						this.addresses = new HashSet<>();
192
					}
193
					this.addresses.add(address.clone());
194
				} catch (CloneNotSupportedException e) {
195
					throw new MergeException("Address must implement Cloneable");
196
				}
197
			}
198
		}
199
	}
200

    
201
	private void mergeList(List list1, List list2){
202
		for (Object obj2 : list2){
203
			if (! list1.contains(obj2)){
204
				list1.add(obj2);
205
			}
206
		}
207
	}
208

    
209
    /**
210
     * True, if no contact data exists in any of the lists (email, phone, ...).
211
     */
212
    @Transient
213
    public boolean isEmpty(){
214
        if (isEmpty(emailAddresses) && isEmpty(faxNumbers) && isEmpty(phoneNumbers)
215
                && isEmpty(urls) && isEmpty(addresses)){
216
            return true;
217
        }else{
218
            return false;
219
        }
220
    }
221

    
222
    private boolean isEmpty(Collection<? extends Object> collection) {
223
        return collection == null || collection.isEmpty();
224
    }
225

    
226
    /**
227
	 * Returns the set of postal {@link Address addresses} belonging to <i>this</i> contact.
228
	 * A {@link Person person} or an {@link Institution institution} cannot have more than one contact,
229
	 * but a contact may include several postal addresses.
230
	 *
231
	 * @return	the set of postal addresses
232
	 * @see     Address
233
	 */
234
	public Set<Address> getAddresses(){
235
		return this.addresses;
236
	}
237

    
238
	/**
239
	 * Adds a new postal {@link Address address} to the set of postal addresses of <i>this</i> contact.
240
	 *
241
	 * @param  address  the address to be added
242
	 * @see     		#getAddresses()
243
	 * @see 			Address
244
	 */
245
	public void addAddress(Address address){
246
		if (address != null){
247
			getAddresses().add(address);
248
		}
249
	}
250

    
251
	public Address addAddress(String street, String postcode, String locality,
252
			Country country, String pobox, String region, Point location){
253
		Address newAddress = Address.NewInstance(country, locality, pobox, postcode, region, street, location);
254
		getAddresses().add(newAddress);
255
		return newAddress;
256
	}
257

    
258
	/**
259
	 * Removes one element from the set of postal addresses of <i>this</i> contact.
260
	 *
261
	 * @param  address  the postal address of <i>this</i> contact which should be deleted
262
	 * @see     		#getAddresses()
263
	 */
264
	public void removeAddress(Address address){
265
		getAddresses().remove(address);
266
	}
267

    
268

    
269
	/**
270
	 * Returns the List of strings representing the electronic mail addresses
271
	 * included in <i>this</i> contact.
272
	 */
273
	public List<String> getEmailAddresses(){
274
		if(this.emailAddresses == null) {
275
			this.emailAddresses = new ArrayList<>();
276
		}
277
		return this.emailAddresses;
278
	}
279

    
280
	/**
281
	 * @see  #getEmailAddress()
282
	 */
283
	public void addEmailAddress(String emailAddress){
284
		getEmailAddresses().add(emailAddress);
285
	}
286

    
287
	/**
288
	 * Removes one element from the list of email addresses of <i>this</i> contact.
289
	 *
290
	 * @param  emailAddress  the email address of <i>this</i> contact which should be deleted
291
	 * @see     		#getEmailAddresses()
292
	 */
293
	public void removeEmailAddress(String emailAddress){
294
		getEmailAddresses().remove(emailAddress);
295
	}
296

    
297
//	/**
298
//	 * Returns the list of {@link URI URIs} representing this contact
299
//	 * included in <i>this</i> contact.
300
//	 */
301
//	@Transient   //TODO preliminary workaround as we get LazyInit Exception in JSON #4444
302
//	public List<URI> getUrls(){
303
//		List<URI> result = new ArrayList<URI>();
304
//		if(this.urls != null) {
305
//			for (String uri : this.urls){
306
//				result.add(URI.create(uri));
307
//			}
308
//		}
309
//		return result;
310
//	}
311

    
312
	/**
313
	 * Returns the list of {@link URI URIs} representing this contact
314
	 * included in <i>this</i> contact.
315
	 */
316
	public List<String> getUrls(){
317
		return this.urls;
318
	}
319

    
320
	/**
321
	 * @see  #getUrls()
322
	 */
323
	public void addUrl(URI url){
324
		this.urls.add(url.toString());
325
	}
326

    
327
	/**
328
	 * Removes one element from the list of urls of <i>this</i> contact.
329
	 *
330
	 * @param  url  the url of <i>this</i> contact which should be deleted
331
	 * @see     		#getUrls()
332
	 */
333
	public void removeUrl(URI url){
334
		this.urls.remove(url.toString());
335
	}
336

    
337

    
338
	/**
339
	 * Returns the list of strings representing the phone numbers
340
	 * included in <i>this</i> contact.
341
	 */
342
	public List<String> getPhoneNumbers(){
343
		if(this.phoneNumbers == null) {
344
			this.phoneNumbers = new ArrayList<>();
345
		}
346
		return this.phoneNumbers;
347
	}
348

    
349
	/**
350
	 * @see  #getPhone()
351
	 */
352
	public void addPhoneNumber(String phoneNumber){
353
		getPhoneNumbers().add(phoneNumber);
354
	}
355

    
356
	/**
357
	 * Removes one element from the list of phone numbers of <i>this</i> contact.
358
	 *
359
	 * @param  phoneNumber  the phone number of <i>this</i> contact which should be deleted
360
	 * @see     		#getPhoneNumber()
361
	 */
362
	public void removePhoneNumber(String phoneNumber){
363
		getPhoneNumbers().remove(phoneNumber);
364
	}
365

    
366
	/**
367
	 * Returns the list of strings representing the telefax numbers
368
	 * included in <i>this</i> contact.
369
	 */
370
	public List<String> getFaxNumbers(){
371
		if(this.faxNumbers == null) {
372
			this.faxNumbers = new ArrayList<>();
373
		}
374
		return this.faxNumbers;
375
	}
376

    
377
	/**
378
	 * @see  #getFaxNumbers()
379
	 */
380
	public void addFaxNumber(String faxNumber){
381
		getFaxNumbers().add(faxNumber);
382
	}
383

    
384
	/**
385
	 * Removes one element from the list of telefax numbers of <i>this</i> contact.
386
	 *
387
	 * @param  faxNumber  the telefax number of <i>this</i> contact which should be deleted
388
	 * @see     		#getFaxNumber()
389
	 */
390
	public void removeFaxNumber(String faxNumber){
391
		getFaxNumbers().remove(faxNumber);
392
	}
393

    
394
//*********************** CLONE ********************************************************/
395

    
396
	/**
397
	 * Clones <i>this</i> Contact. This is a shortcut that enables to create
398
	 * a new instance that differs only slightly from <i>this</i> Contact.
399
	 *
400
	 *
401
	 * @see java.lang.Object#clone()
402
	 */
403
	@Override
404
	public Object clone() {
405
		try{
406
			Contact result = (Contact) super.clone();
407
			result.addresses = new HashSet<>();
408
			for (Address adr : this.addresses){
409
				result.addAddress(adr.clone());
410
			}
411
			//no changes to emailAdresses, faxnumbers, phonenumbers, urls
412
			return result;
413
		}catch (CloneNotSupportedException e){
414
			logger.warn("Object does not implement cloneable");
415
			e.printStackTrace();
416
			return null;
417
		}
418
	}
419
}
(3-3/12)