]> git.mxchange.org Git - jcontacts-core.git/blob - src/org/mxchange/jcontacts/model/contact/UserContact.java
Updated copyright year
[jcontacts-core.git] / src / org / mxchange / jcontacts / model / contact / UserContact.java
1 /*
2  * Copyright (C) 2016 - 2024 Free Software Foundation
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 package org.mxchange.jcontacts.model.contact;
18
19 import java.text.MessageFormat;
20 import java.util.Date;
21 import java.util.Objects;
22 import javax.persistence.Basic;
23 import javax.persistence.CascadeType;
24 import javax.persistence.Column;
25 import javax.persistence.Entity;
26 import javax.persistence.EnumType;
27 import javax.persistence.Enumerated;
28 import javax.persistence.GeneratedValue;
29 import javax.persistence.GenerationType;
30 import javax.persistence.Id;
31 import javax.persistence.Index;
32 import javax.persistence.JoinColumn;
33 import javax.persistence.Lob;
34 import javax.persistence.NamedQueries;
35 import javax.persistence.NamedQuery;
36 import javax.persistence.OneToOne;
37 import javax.persistence.Table;
38 import javax.persistence.Temporal;
39 import javax.persistence.TemporalType;
40 import javax.persistence.Transient;
41 import org.apache.commons.lang3.StringUtils;
42 import org.mxchange.jcontacts.model.contact.title.PersonalTitle;
43 import org.mxchange.jcontacts.model.utils.PersonalTitleUtils;
44 import org.mxchange.jcoreutils.bool.BooleanUtils;
45 import org.mxchange.jcoreutils.comparable.ComparableUtils;
46 import org.mxchange.jcoreutils.dates.DateUtils;
47 import org.mxchange.jcoreutils.number.SafeNumberUtils;
48 import org.mxchange.jcountry.model.data.Country;
49 import org.mxchange.jcountry.model.data.CountryData;
50 import org.mxchange.jcountry.model.utils.CountryUtils;
51 import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
52 import org.mxchange.jphone.model.phonenumbers.fax.FaxNumber;
53 import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
54 import org.mxchange.jphone.model.phonenumbers.landline.LandLineNumber;
55 import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
56 import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber;
57
58 /**
59  * A general contact class which serves as an entity.
60  * <p>
61  * @author Roland Häder<roland@mxchange.org>
62  * @version 0.0
63  */
64 @Entity (name = "contacts")
65 @Table (
66                 name = "contacts",
67                 indexes = {
68                         @Index (
69                                         name = "contact_personal_title",
70                                         columnList = "contact_personal_title"
71                         )
72                 }
73 )
74 @NamedQueries (
75                 {
76                         @NamedQuery (name = "AllContacts", query = "SELECT c FROM contacts AS c ORDER BY c.contactId ASC")
77                 }
78 )
79 @SuppressWarnings ("PersistenceUnitPresent")
80 public class UserContact implements Contact {
81
82         /**
83          * Serial number
84          */
85         @Transient
86         private static final long serialVersionUID = 58_744_284_981_863L;
87
88         /**
89          * Birth day
90          */
91         @Column (name = "contact_birthday")
92         @Temporal (TemporalType.DATE)
93         private Date contactBirthday;
94
95         /**
96          * City
97          */
98         @Column (name = "contact_city", length = 100)
99         private String contactCity;
100
101         /**
102          * Optional comments
103          */
104         @Lob
105         @Column (name = "contact_comment")
106         private String contactComment;
107
108         /**
109          * Country code
110          */
111         @JoinColumn (name = "contact_country_id", nullable = false, referencedColumnName = "country_id")
112         @OneToOne (targetEntity = CountryData.class, cascade = CascadeType.REFRESH, optional = false)
113         private Country contactCountry;
114
115         /**
116          * Email address
117          */
118         @Column (name = "contact_email_address", length = 100, unique = true)
119         private String contactEmailAddress;
120
121         /**
122          * When the contact has been created
123          */
124         @Basic (optional = false)
125         @Temporal (TemporalType.TIMESTAMP)
126         @Column (name = "contact_entry_created", updatable = false, nullable = false)
127         private Date contactEntryCreated;
128
129         /**
130          * When the contact has been updated
131          */
132         @Temporal (TemporalType.TIMESTAMP)
133         @Column (name = "contact_entry_updated", insertable = false)
134         private Date contactEntryUpdated;
135
136         /**
137          * Family name
138          */
139         @Basic (optional = false)
140         @Column (name = "contact_family_name", length = 100, nullable = false)
141         private String contactFamilyName;
142
143         /**
144          * Fax number
145          */
146         @JoinColumn (name = "contact_fax_number_id", referencedColumnName = "fax_id", unique = true)
147         @OneToOne (targetEntity = FaxNumber.class, cascade = CascadeType.ALL)
148         private DialableFaxNumber contactFaxNumber;
149
150         /**
151          * First name
152          */
153         @Basic (optional = false)
154         @Column (name = "contact_first_name", length = 100, nullable = false)
155         private String contactFirstName;
156
157         /**
158          * House number
159          */
160         @Column (name = "contact_house_number")
161         private Short contactHouseNumber;
162
163         /**
164          * House number extension
165          */
166         @Column (name = "contact_house_number_extension", length = 5)
167         private String contactHouseNumberExtension;
168
169         /**
170          * Id number
171          */
172         @Id
173         @GeneratedValue (strategy = GenerationType.IDENTITY)
174         @Column (name = "contact_id", nullable = false, updatable = false)
175         private Long contactId;
176
177         /**
178          * Cellphone number
179          */
180         @JoinColumn (name = "contact_mobile_number_id", referencedColumnName = "mobile_id", unique = true)
181         @OneToOne (targetEntity = MobileNumber.class, cascade = CascadeType.ALL)
182         private DialableMobileNumber contactMobileNumber;
183
184         /**
185          * Flag whether this contact is user's own data
186          */
187         @Basic (optional = false)
188         @Column (name = "contact_own_contact", nullable = false)
189         private Boolean contactOwnContact;
190
191         /**
192          * Contact's personal title (Mr./Mrs.)
193          */
194         @Basic (optional = false)
195         @Column (name = "contact_personal_title", nullable = false)
196         @Enumerated (EnumType.STRING)
197         private PersonalTitle contactPersonalTitle;
198
199         /**
200          * Phone number
201          */
202         @JoinColumn (name = "contact_landline_number_id", referencedColumnName = "landline_id", unique = true)
203         @OneToOne (targetEntity = LandLineNumber.class, cascade = CascadeType.ALL)
204         private DialableLandLineNumber contactPhoneNumber;
205
206         /**
207          * Street
208          */
209         @Column (name = "contact_street")
210         private String contactStreet;
211
212         /**
213          * Title (Doctor, etc)
214          */
215         @Column (name = "contact_title")
216         private String contactTitle;
217
218         /**
219          * ZIP code
220          */
221         @Column (name = "contact_zip_code")
222         private Integer contactZipCode;
223
224         /**
225          * Default constructor
226          */
227         public UserContact () {
228         }
229
230         /**
231          * Constructor for title and names
232          * <p>
233          * @param personalTitle Personal title
234          * @param firstName     First name
235          * @param familyName    Family name
236          * @param country       Country instance
237          * @param isOwnContact  Whether this is own contact
238          */
239         public UserContact (final PersonalTitle personalTitle, final String firstName, final String familyName, final Country country, final Boolean isOwnContact) {
240                 // Invoke default constructor
241                 this();
242
243                 // Are all parameter set?
244                 if (null == personalTitle) {
245                         // Throw NPE
246                         throw new NullPointerException("personalTitle is null"); //NOI18N
247                 } else if (null == firstName) {
248                         // Throw NPE
249                         throw new NullPointerException("firstName is null"); //NOI18N
250                 } else if (firstName.isEmpty()) {
251                         // Throw IAE
252                         throw new IllegalArgumentException("firstName is empty"); //NOI18N
253                 } else if (null == familyName) {
254                         // Throw NPE
255                         throw new NullPointerException("familyName is null"); //NOI18N
256                 } else if (familyName.isEmpty()) {
257                         // Throw IAE
258                         throw new IllegalArgumentException("familyName is empty"); //NOI18N
259                 } else if (null == country) {
260                         // Throw NPE
261                         throw new NullPointerException("country is null"); //NOI18N
262                 } else if (country.getCountryId() == null) {
263                         // Throw it again
264                         throw new NullPointerException("country.countryId is null"); //NOI18N
265                 } else if (country.getCountryId() < 1) {
266                         // Throw IAE
267                         throw new IllegalArgumentException(MessageFormat.format("contactCountry.countryId={0} is not valid", country.getCountryId())); //NOI18N
268                 } else if (null == isOwnContact) {
269                         // Throw NPE
270                         throw new NullPointerException("isOwnContact is null"); // NOI18N
271                 }
272
273                 // Set all
274                 this.contactPersonalTitle = personalTitle;
275                 this.contactFirstName = firstName;
276                 this.contactFamilyName = familyName;
277                 this.contactCountry = country;
278                 this.contactOwnContact = isOwnContact;
279         }
280
281         /**
282          * Constructor with all fields, except created/updated and primary key
283          * <p>
284          * @param personalTitle        Personal title (Mr./Mrs.)
285          * @param firstName            First name
286          * @param familyName           Family name
287          * @param country              Country (e.g. current)
288          * @param isOwnContact         Whether this is own contact
289          * @param street               Street name
290          * @param houseNumber          House number
291          * @param houseNumberExtension Extension to house number (e.g. a in 12a)
292          * @param zipCode              ZIP code
293          * @param city                 City
294          * @param emailAddress         email address
295          * @param academicTitle        Academic title
296          * @param birthday             Birthday
297          * @param comment              Comment
298          * <p>
299          * @todo Find a way to stop 0000-00-00 as birthdays to be entered
300          */
301         public UserContact (final PersonalTitle personalTitle, final String firstName, final String familyName, final Country country, final Boolean isOwnContact, final String street, final Short houseNumber, final String houseNumberExtension, final Integer zipCode, final String city, final String emailAddress, final String academicTitle, final Date birthday, final String comment) {
302                 // Call other constructor first
303                 this(personalTitle, firstName, familyName, country, isOwnContact);
304
305                 // Validate parameter
306                 if (street != null && street.isEmpty()) {
307                         // Throw IAE
308                         throw new IllegalArgumentException("street is empty"); // NOI18N
309                 } else if (houseNumber != null && houseNumber < 1) {
310                         // No zero house numbers exist
311                         throw new IllegalArgumentException(MessageFormat.format("houseNumber={0} is not valid", houseNumber)); // NOI18N
312                 } else if (houseNumberExtension != null && houseNumberExtension.isEmpty()) {
313                         // Throw IAE
314                         throw new IllegalArgumentException("houseNumberExtension is empty"); // NOI18N
315                 } else if (zipCode != null && zipCode < 1) {
316                         // No zero house numbers exist
317                         throw new IllegalArgumentException(MessageFormat.format("zipCode={0} is not valid", zipCode)); // NOI18N
318                 } else if (city != null && city.isEmpty()) {
319                         // Throw IAE
320                         throw new IllegalArgumentException("city is empty"); // NOI18N
321                 } else if (emailAddress != null && emailAddress.isEmpty()) {
322                         // Throw IAE
323                         throw new IllegalArgumentException("emailAddress is empty"); // NOI18N
324                 } else if (academicTitle != null && academicTitle.isEmpty()) {
325                         // Throw IAE
326                         throw new IllegalArgumentException("academicTitle is empty"); // NOI18N
327                 } else if (comment != null && comment.isEmpty()) {
328                         // Throw IAE
329                         throw new IllegalArgumentException("comment is empty"); // NOI18N
330                 }
331
332                 // Set all fields
333                 this.contactStreet = street;
334                 this.contactHouseNumber = houseNumber;
335                 this.contactHouseNumberExtension = houseNumberExtension;
336                 this.contactZipCode = zipCode;
337                 this.contactCity = city;
338                 this.contactEmailAddress = emailAddress;
339                 this.contactTitle = academicTitle;
340                 this.contactBirthday = birthday;
341                 this.contactComment = comment;
342         }
343
344         @Override
345         public int compareTo (final Contact contact) {
346                 // Checkparameter and return 0 if equal
347                 if (null == contact) {
348                         // Should not happen
349                         throw new NullPointerException("contact is null"); //NOI18N
350                 } else if (contact.equals(this)) {
351                         // Same object
352                         return 0;
353                 }
354
355                 // Init comparators
356                 final int comparators[] = {
357                         // First check country
358                         CountryUtils.compare(this.getContactCountry(), contact.getContactCountry()),
359                         // ... then ZIP code
360                         SafeNumberUtils.compare(this.getContactZipCode(), contact.getContactZipCode()),
361                         // ... and city
362                         StringUtils.compare(this.getContactCity(), contact.getContactCity()),
363                         // ... street name
364                         StringUtils.compareIgnoreCase(this.getContactStreet(), contact.getContactStreet()),
365                         // ... house number
366                         SafeNumberUtils.compare(this.getContactHouseNumber(), contact.getContactHouseNumber()),
367                         // ... extension
368                         StringUtils.compareIgnoreCase(this.getContactHouseNumberExtension(), contact.getContactHouseNumberExtension()),
369                         // ... now it is sure that address is different/same, continue with personal title
370                         PersonalTitleUtils.compare(this.getContactPersonalTitle(), contact.getContactPersonalTitle()),
371                         // ... academical title
372                         StringUtils.compareIgnoreCase(this.getContactTitle(), contact.getContactTitle()),
373                         // .. family name ...
374                         StringUtils.compareIgnoreCase(this.getContactFamilyName(), contact.getContactFamilyName()),
375                         // .. next is first...
376                         StringUtils.compareIgnoreCase(this.getContactFirstName(), contact.getContactFirstName()),
377                         // ... next is email address
378                         StringUtils.compareIgnoreCase(this.getContactEmailAddress(), contact.getContactEmailAddress()),
379                         // ... next birthday - year
380                         DateUtils.compareYearMonthDay(this.getContactBirthday(), contact.getContactBirthday()),
381                         // ... next "is own" flag
382                         BooleanUtils.compare(this.isOwnContact(), contact.isOwnContact()),
383                         // ... next comment
384                         StringUtils.compare(this.getContactComment(), contact.getContactComment())
385                 };
386
387                 // Check all values
388                 final int comparison = ComparableUtils.checkAll(comparators);
389
390                 // Return value
391                 return comparison;
392         }
393
394         @Override
395         public boolean equals (final Object object) {
396                 if (this == object) {
397                         return true;
398                 } else if (null == object) {
399                         return false;
400                 } else if (this.getClass() != object.getClass()) {
401                         return false;
402                 }
403
404                 final Contact contact = (Contact) object;
405
406                 if (!Objects.equals(this.getContactBirthday(), contact.getContactBirthday())) {
407                         return false;
408                 } else if (!Objects.equals(this.getContactCity(), contact.getContactCity())) {
409                         return false;
410                 } else if (!Objects.equals(this.getContactComment(), contact.getContactComment())) {
411                         return false;
412                 } else if (!Objects.equals(this.getContactCountry(), contact.getContactCountry())) {
413                         return false;
414                 } else if (!Objects.equals(this.getContactEmailAddress(), contact.getContactEmailAddress())) {
415                         return false;
416                 } else if (!Objects.equals(this.getContactFamilyName(), contact.getContactFamilyName())) {
417                         return false;
418                 } else if (!Objects.equals(this.getContactFaxNumber(), contact.getContactFaxNumber())) {
419                         return false;
420                 } else if (!Objects.equals(this.getContactFirstName(), contact.getContactFirstName())) {
421                         return false;
422                 } else if (!Objects.equals(this.getContactHouseNumber(), contact.getContactHouseNumber())) {
423                         return false;
424                 } else if (!Objects.equals(this.getContactHouseNumberExtension(), contact.getContactHouseNumberExtension())) {
425                         return false;
426                 } else if (!Objects.equals(this.getContactId(), contact.getContactId())) {
427                         return false;
428                 } else if (!Objects.equals(this.getContactLandLineNumber(), contact.getContactLandLineNumber())) {
429                         return false;
430                 } else if (!Objects.equals(this.getContactMobileNumber(), contact.getContactMobileNumber())) {
431                         return false;
432                 } else if (this.getContactPersonalTitle() != contact.getContactPersonalTitle()) {
433                         return false;
434                 } else if (!Objects.equals(this.getContactStreet(), contact.getContactStreet())) {
435                         return false;
436                 } else if (!Objects.equals(this.getContactTitle(), contact.getContactTitle())) {
437                         return false;
438                 } else if (!Objects.equals(this.getContactZipCode(), contact.getContactZipCode())) {
439                         return false;
440                 } else if (!Objects.equals(this.isOwnContact(), contact.isOwnContact())) {
441                         return false;
442                 }
443
444                 return true;
445         }
446
447         @Override
448         @SuppressWarnings ("ReturnOfDateField")
449         public Date getContactBirthday () {
450                 return this.contactBirthday;
451         }
452
453         @Override
454         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
455         public void setContactBirthday (final Date contactBirthday) {
456                 this.contactBirthday = contactBirthday;
457         }
458
459         @Override
460         public String getContactCity () {
461                 return this.contactCity;
462         }
463
464         @Override
465         public void setContactCity (final String contactCity) {
466                 this.contactCity = contactCity;
467         }
468
469         @Override
470         public String getContactComment () {
471                 return this.contactComment;
472         }
473
474         @Override
475         public void setContactComment (final String contactComment) {
476                 this.contactComment = contactComment;
477         }
478
479         @Override
480         public Country getContactCountry () {
481                 return this.contactCountry;
482         }
483
484         @Override
485         public void setContactCountry (final Country contactCountry) {
486                 this.contactCountry = contactCountry;
487         }
488
489         @Override
490         public String getContactEmailAddress () {
491                 return this.contactEmailAddress;
492         }
493
494         @Override
495         public void setContactEmailAddress (final String contactEmailAddress) {
496                 this.contactEmailAddress = contactEmailAddress;
497         }
498
499         @Override
500         @SuppressWarnings ("ReturnOfDateField")
501         public Date getContactEntryCreated () {
502                 return this.contactEntryCreated;
503         }
504
505         @Override
506         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
507         public void setContactEntryCreated (final Date contactEntryCreated) {
508                 this.contactEntryCreated = contactEntryCreated;
509         }
510
511         @Override
512         @SuppressWarnings ("ReturnOfDateField")
513         public Date getContactEntryUpdated () {
514                 return this.contactEntryUpdated;
515         }
516
517         @Override
518         @SuppressWarnings ("AssignmentToDateFieldFromParameter")
519         public void setContactEntryUpdated (final Date contactEntryUpdated) {
520                 this.contactEntryUpdated = contactEntryUpdated;
521         }
522
523         @Override
524         public String getContactFamilyName () {
525                 //* NOISY-DEBUG: */ this.getLogger().logTrace("CALLED!");
526                 return this.contactFamilyName;
527         }
528
529         @Override
530         public void setContactFamilyName (final String contactFamilyName) {
531                 this.contactFamilyName = contactFamilyName;
532         }
533
534         @Override
535         public DialableFaxNumber getContactFaxNumber () {
536                 return this.contactFaxNumber;
537         }
538
539         @Override
540         public void setContactFaxNumber (final DialableFaxNumber contactFaxNumber) {
541                 this.contactFaxNumber = contactFaxNumber;
542         }
543
544         @Override
545         public String getContactFirstName () {
546                 return this.contactFirstName;
547         }
548
549         @Override
550         public void setContactFirstName (final String contactFirstName) {
551                 this.contactFirstName = contactFirstName;
552         }
553
554         @Override
555         public Short getContactHouseNumber () {
556                 return this.contactHouseNumber;
557         }
558
559         @Override
560         public void setContactHouseNumber (final Short contactHouseNumber) {
561                 this.contactHouseNumber = contactHouseNumber;
562         }
563
564         @Override
565         public String getContactHouseNumberExtension () {
566                 return this.contactHouseNumberExtension;
567         }
568
569         @Override
570         public void setContactHouseNumberExtension (final String contactHouseNumberExtension) {
571                 this.contactHouseNumberExtension = contactHouseNumberExtension;
572         }
573
574         @Override
575         public Long getContactId () {
576                 return this.contactId;
577         }
578
579         @Override
580         public void setContactId (final Long contactId) {
581                 this.contactId = contactId;
582         }
583
584         @Override
585         public DialableLandLineNumber getContactLandLineNumber () {
586                 return this.contactPhoneNumber;
587         }
588
589         @Override
590         public void setContactLandLineNumber (final DialableLandLineNumber contactPhoneNumber) {
591                 this.contactPhoneNumber = contactPhoneNumber;
592         }
593
594         @Override
595         public DialableMobileNumber getContactMobileNumber () {
596                 return this.contactMobileNumber;
597         }
598
599         @Override
600         public void setContactMobileNumber (final DialableMobileNumber contactMobileNumber) {
601                 this.contactMobileNumber = contactMobileNumber;
602         }
603
604         @Override
605         public void setContactOwnContact (final Boolean contactOwnContact) {
606                 this.contactOwnContact = contactOwnContact;
607         }
608
609         @Override
610         public PersonalTitle getContactPersonalTitle () {
611                 return this.contactPersonalTitle;
612         }
613
614         @Override
615         public void setContactPersonalTitle (final PersonalTitle contactPersonalTitle) {
616                 this.contactPersonalTitle = contactPersonalTitle;
617         }
618
619         @Override
620         public String getContactStreet () {
621                 return this.contactStreet;
622         }
623
624         @Override
625         public void setContactStreet (final String contactStreet) {
626                 this.contactStreet = contactStreet;
627         }
628
629         @Override
630         public String getContactTitle () {
631                 return this.contactTitle;
632         }
633
634         @Override
635         public void setContactTitle (final String contactTitle) {
636                 this.contactTitle = contactTitle;
637         }
638
639         @Override
640         public Integer getContactZipCode () {
641                 return this.contactZipCode;
642         }
643
644         @Override
645         public void setContactZipCode (final Integer contactZipCode) {
646                 this.contactZipCode = contactZipCode;
647         }
648
649         @Override
650         public int hashCode () {
651                 int hash = 5;
652
653                 hash = 29 * hash + Objects.hashCode(this.getContactBirthday());
654                 hash = 29 * hash + Objects.hashCode(this.getContactCity());
655                 hash = 29 * hash + Objects.hashCode(this.getContactComment());
656                 hash = 29 * hash + Objects.hashCode(this.getContactCountry());
657                 hash = 29 * hash + Objects.hashCode(this.getContactEmailAddress());
658                 hash = 29 * hash + Objects.hashCode(this.getContactFamilyName());
659                 hash = 29 * hash + Objects.hashCode(this.getContactFaxNumber());
660                 hash = 29 * hash + Objects.hashCode(this.getContactFirstName());
661                 hash = 29 * hash + Objects.hashCode(this.getContactHouseNumber());
662                 hash = 29 * hash + Objects.hashCode(this.getContactHouseNumberExtension());
663                 hash = 29 * hash + Objects.hashCode(this.getContactId());
664                 hash = 29 * hash + Objects.hashCode(this.getContactLandLineNumber());
665                 hash = 29 * hash + Objects.hashCode(this.getContactMobileNumber());
666                 hash = 29 * hash + Objects.hashCode(this.getContactPersonalTitle());
667                 hash = 29 * hash + Objects.hashCode(this.getContactStreet());
668                 hash = 29 * hash + Objects.hashCode(this.getContactTitle());
669                 hash = 29 * hash + Objects.hashCode(this.getContactZipCode());
670                 hash = 29 * hash + Objects.hashCode(this.isOwnContact());
671
672                 return hash;
673         }
674
675         @Override
676         public Boolean isOwnContact () {
677                 return this.contactOwnContact;
678         }
679
680 }