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
package eu.etaxonomy.cdm.model.agent;
10

    
11
import java.io.Serializable;
12
import java.net.URI;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Set;
18

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

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

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

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

    
71

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

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

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

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

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

    
104
	public static Contact NewInstance() {
105
		return new Contact();
106
	}
107

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

    
147

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

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

    
178
// ************************ MERGE /MATCH ***************************/
179

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

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

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

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

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

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

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

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

    
266

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

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

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

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

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

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

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

    
335

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

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

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

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

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

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

    
392
//*********************** CLONE ********************************************************/
393

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