2 * Copyright (C) 2016 Roland Haeder
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.
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.
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/>.
17 package org.mxchange.addressbook.database;
19 import java.text.MessageFormat;
20 import java.util.GregorianCalendar;
21 import java.util.Objects;
22 import org.mxchange.jcontacts.contact.Contact;
23 import org.mxchange.jcoreee.database.BaseDatabaseBean;
24 import org.mxchange.jphone.phonenumbers.cellphone.DialableCellphoneNumber;
25 import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
26 import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
27 import org.mxchange.jphone.utils.PhoneUtils;
30 * A helper class for beans that access the database.
32 * @author Roland Haeder<roland@mxchange.org>
34 public abstract class BaseAddressbookDatabaseBean extends BaseDatabaseBean {
39 private static final long serialVersionUID = 12_895_410_275_811_963L;
42 * Protected constructor
44 protected BaseAddressbookDatabaseBean () {
45 // Call super constructor
50 * Updates all contacts's phone entry's created timestamps
52 * @param contact Contact instance to update
54 protected void setAllContactPhoneEntriesCreated (final Contact contact) {
56 this.getLoggerBeanLocal().logTrace(MessageFormat.format("setAllContactPhoneEntriesCreated: contact={0} - CALLED!", contact)); //NOI18N
58 // The contact instance must be valid
59 if (null == contact) {
61 throw new NullPointerException("contact is null"); //NOI18N
64 // Get all phone instances
65 DialableLandLineNumber landLineNumber = contact.getContactLandLineNumber();
66 DialableFaxNumber faxNumber = contact.getContactFaxNumber();
67 DialableCellphoneNumber cellphoneNumber = contact.getContactCellphoneNumber();
70 this.getLoggerBeanLocal().logDebug(MessageFormat.format("setAllContactPhoneEntriesCreated: landLineNumber={0},faxNumber={1},cellphoneNumber={2}", landLineNumber, faxNumber, cellphoneNumber)); //NOI18N
72 // Is a phone number instance set?
73 if ((landLineNumber instanceof DialableLandLineNumber) && (landLineNumber.getPhoneId() == null)) {
75 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesCreated: Setting created timestamp for land-line number ..."); //NOI18N
77 // Set updated timestamp
78 landLineNumber.setPhoneEntryCreated(new GregorianCalendar());
81 // Is a fax number instance set?
82 if ((faxNumber instanceof DialableFaxNumber) && (faxNumber.getPhoneId() == null)) {
84 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesCreated: Setting created timestamp for fax number ..."); //NOI18N
86 // Set updated timestamp
87 faxNumber.setPhoneEntryCreated(new GregorianCalendar());
90 // Is a mobile number instance set?
91 if ((cellphoneNumber instanceof DialableCellphoneNumber) && (cellphoneNumber.getPhoneId() == null)) {
93 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesCreated: Setting created timestamp for cellphone number ..."); //NOI18N
95 // Set updated timestamp
96 cellphoneNumber.setPhoneEntryCreated(new GregorianCalendar());
100 this.getLoggerBeanLocal().logTrace("setAllContactPhoneEntriesCreated: EXIT!"); //NOI18N
104 * Returnes a detached instance from given cellphone instance
106 * @param cellphoneNumber Cellphone instance
107 * @param fetchedNumber Found cellphone number in database
109 * @return Detached instance
111 protected DialableCellphoneNumber getDetached (final DialableCellphoneNumber cellphoneNumber, final DialableCellphoneNumber fetchedNumber) {
113 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: cellphoneNumber={0},fetchedNumber={1} - CALLED!", cellphoneNumber, fetchedNumber));
116 if (null == cellphoneNumber) {
118 throw new NullPointerException("cellphoneNumber is null");
119 } else if (fetchedNumber.getPhoneId() == null) {
121 throw new NullPointerException("fetchedNumber.phoneId is null");
125 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: fetchedNumber.phoneId={0}", fetchedNumber.getPhoneId()));
127 // Init query instance
128 DialableCellphoneNumber foundNumber = this.getEntityManager().find(fetchedNumber.getClass(), fetchedNumber.getPhoneId());
131 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: foundNumber={0}", foundNumber));
134 DialableCellphoneNumber detachedNumber = null;
136 // Is there a difference?
137 if (!PhoneUtils.isSameCellphoneNumber(cellphoneNumber, fetchedNumber)) {
139 detachedNumber = this.getEntityManager().merge(foundNumber);
145 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: detachedNumber={0} - EXIT!", detachedNumber));
148 return detachedNumber;
152 * Returnes a detached instance from given land-line instance
154 * @param landLineNumber Land-line instance
155 * @param fetchedNumber Found land-line number in database
157 * @return Detached instance
159 protected DialableLandLineNumber getDetached (final DialableLandLineNumber landLineNumber, final DialableLandLineNumber fetchedNumber) {
161 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: landLineNumber={0},fetchedNumber={1} - CALLED!", landLineNumber, fetchedNumber));
164 if (null == landLineNumber) {
166 throw new NullPointerException("landLineNumber is null");
167 } else if (fetchedNumber.getPhoneId() == null) {
169 throw new NullPointerException("landLineNumber.phoneId is null");
173 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: fetchedNumber.phoneId={0}", fetchedNumber.getPhoneId()));
175 // Init query instance
176 DialableLandLineNumber foundNumber = this.getEntityManager().find(fetchedNumber.getClass(), fetchedNumber.getPhoneId());
179 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: foundNumber={0}", foundNumber));
182 DialableLandLineNumber detachedNumber = null;
184 // Is there a difference?
185 if (!PhoneUtils.isSameLandLineNumber(landLineNumber, fetchedNumber)) {
187 detachedNumber = this.getEntityManager().merge(foundNumber);
191 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: detachedNumber={0} - EXIT!", detachedNumber));
194 return detachedNumber;
198 * Returnes a detached instance from given fax instance
200 * @param faxNumber Fax instance
201 * @param fetchedNumber Found fax number in database
203 * @return Detached instance
205 protected DialableFaxNumber getDetached (final DialableFaxNumber faxNumber, final DialableFaxNumber fetchedNumber) {
207 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: faxNumber={0},fetchedNumber={1} - CALLED!", faxNumber, fetchedNumber));
210 if (null == faxNumber) {
212 throw new NullPointerException("faxNumber is null");
213 } else if (fetchedNumber.getPhoneId() == null) {
215 throw new NullPointerException("fetchedNumber.phoneId is null");
219 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: fetchedNumber.phoneId={0}", fetchedNumber.getPhoneId()));
221 // Init query instance
222 DialableFaxNumber foundNumber = this.getEntityManager().find(fetchedNumber.getClass(), fetchedNumber.getPhoneId());
225 this.getLoggerBeanLocal().logDebug(MessageFormat.format("getDetached: foundNumber={0}", foundNumber));
228 DialableFaxNumber detachedNumber = null;
230 // Is there a difference?
231 if (!PhoneUtils.isSameFaxNumber(faxNumber, fetchedNumber)) {
233 detachedNumber = this.getEntityManager().merge(foundNumber);
237 this.getLoggerBeanLocal().logTrace(MessageFormat.format("getDetached: detachedNumber={0} - EXIT!", detachedNumber));
240 return detachedNumber;
244 * Merges given contact's data
246 * @param contact Contact instance to merge
248 * @return Detached contact instance
250 protected Contact mergeContactData (final Contact contact) {
252 this.getLoggerBeanLocal().logTrace(MessageFormat.format("mergeContactData: contact={0} - CALLED!", contact)); //NOI18N
254 // The contact instance must be valid
255 if (null == contact) {
257 throw new NullPointerException("contact is null"); //NOI18N
258 } else if (contact.getContactId() == null) {
260 throw new NullPointerException("contact.contactId is null"); //NOI18N //NOI18N
261 } else if (contact.getContactId() < 1) {
263 throw new IllegalStateException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
266 // Set updated timestamp
267 contact.setContactUpdated(new GregorianCalendar());
269 // Get contact from it and find it
270 Contact foundContact = this.getEntityManager().find(contact.getClass(), contact.getContactId());
273 assert (foundContact instanceof Contact) : MessageFormat.format("Contact with id {0} not found, but should be.", contact.getContactId()); //NOI18N
276 this.getLoggerBeanLocal().logDebug(MessageFormat.format("updateUserPersonalData: contact.contactId={0}", foundContact.getContactId())); //NOI18N
278 // Merge contact instance
279 Contact detachedContact = this.getEntityManager().merge(foundContact);
282 detachedContact.copyAll(contact);
285 this.getLoggerBeanLocal().logTrace(MessageFormat.format("mergeContactData: detachedContact={0} - EXIT!", detachedContact)); //NOI18N
287 // Return detached contact
288 return detachedContact;
292 * Merges given (detached) contact's cellphone, land-line and fax numbers
294 * @param detachedContact Detached contact instance
296 protected void mergeContactsCellphoneLandLineFaxNumbers (final Contact detachedContact) {
298 this.getLoggerBeanLocal().logTrace(MessageFormat.format("mergeContactsCellphoneLandLineFaxNumbers: detachedContact={0} - CALLED!", detachedContact)); //NOI18N
300 // The contact instance must be valid
301 if (null == detachedContact) {
303 throw new NullPointerException("detachedContact is null"); //NOI18N
304 } else if (detachedContact.getContactId() == null) {
306 throw new NullPointerException("detachedContact.contactId is null"); //NOI18N //NOI18N
307 } else if (detachedContact.getContactId() < 1) {
309 throw new IllegalStateException(MessageFormat.format("detachedContact.contactId={0} is not valid.", detachedContact.getContactId())); //NOI18N
313 DialableCellphoneNumber cellphone = detachedContact.getContactCellphoneNumber();
314 DialableLandLineNumber landLine = detachedContact.getContactLandLineNumber();
315 DialableFaxNumber fax = detachedContact.getContactFaxNumber();
317 // Is there a cellphone instance set?
318 if (cellphone instanceof DialableCellphoneNumber) {
320 this.getLoggerBeanLocal().logDebug(MessageFormat.format("updateUserPersonalData: cellphone.phoneId={0} is being updated ...", cellphone.getPhoneId())); //NOI18N
323 DialableCellphoneNumber foundCellphone = this.getEntityManager().find(cellphone.getClass(), cellphone.getPhoneId());
326 assert (foundCellphone instanceof DialableCellphoneNumber) : MessageFormat.format("Cellphone number with id {0} not found but should be.", foundCellphone.getPhoneId()); //NOI18N
328 // Then merge it, too
329 DialableCellphoneNumber detachedCellphone = this.getEntityManager().merge(foundCellphone);
332 assert (detachedCellphone instanceof DialableCellphoneNumber) : MessageFormat.format("Cellphone number with id {0} not found but should be.", detachedCellphone.getPhoneId()); //NOI18N
335 detachedCellphone.copyAll(detachedContact.getContactCellphoneNumber());
338 detachedContact.setContactCellphoneNumber(detachedCellphone);
341 // Is there a fax instance set?
342 if (fax instanceof DialableFaxNumber) {
344 this.getLoggerBeanLocal().logDebug(MessageFormat.format("updateUserPersonalData: fax.phoneId={0} is being updated ...", fax.getPhoneId())); //NOI18N
347 DialableFaxNumber foundFax = this.getEntityManager().find(fax.getClass(), fax.getPhoneId());
350 assert (foundFax instanceof DialableFaxNumber) : MessageFormat.format("Fax number with id {0} not found but should be.", foundFax.getPhoneId()); //NOI18N
352 // Then merge it, too
353 DialableFaxNumber detachedFax = this.getEntityManager().merge(foundFax);
356 assert (detachedFax instanceof DialableFaxNumber) : MessageFormat.format("Fax number with id {0} not found but should be.", detachedFax.getPhoneId()); //NOI18N
359 detachedFax.copyAll(detachedContact.getContactFaxNumber());
362 detachedContact.setContactFaxNumber(detachedFax);
365 // Is there a fax instance set?
366 if (landLine instanceof DialableLandLineNumber) {
368 this.getLoggerBeanLocal().logDebug(MessageFormat.format("updateUserPersonalData: landLine.phoneId={0} is being updated ...", landLine.getPhoneId())); //NOI18N
371 DialableLandLineNumber foundLandLine = this.getEntityManager().find(landLine.getClass(), landLine.getPhoneId());
374 assert (foundLandLine instanceof DialableLandLineNumber) : MessageFormat.format("Land line number with id {0} not found but should be.", foundLandLine.getPhoneId()); //NOI18N
376 // Then merge it, too
377 DialableLandLineNumber detachedLandLine = this.getEntityManager().merge(foundLandLine);
380 assert (detachedLandLine instanceof DialableLandLineNumber) : MessageFormat.format("Land line number with id {0} not found but should be.", detachedLandLine.getPhoneId()); //NOI18N
383 detachedLandLine.copyAll(detachedContact.getContactLandLineNumber());
386 detachedContact.setContactLandLineNumber(detachedLandLine);
390 this.getLoggerBeanLocal().logTrace("mergeContactsCellphoneLandLineFaxNumbers: EXIT!"); //NOI18N
394 * Updates all contact's phone instances from other contact, both contacts
395 * should be the same.
397 * @param contact Contact to set instances
398 * @param other Other contact to get instances from
400 protected void setAllContactPhoneEntries (final Contact contact, final Contact other) {
402 this.getLoggerBeanLocal().logTrace(MessageFormat.format("setAllContactPhoneEntries: contact={0},other={1} - CALLED!", contact, other)); //NOI18N
404 // Both must be the same and not null
405 if (null == contact) {
407 throw new NullPointerException("contact is null"); //NOI18N
408 } else if (null == other) {
410 throw new NullPointerException("other is null"); //NOI18N
411 } else if (!Objects.equals(contact, other)) {
412 // Not same instances
413 throw new IllegalArgumentException(MessageFormat.format("contact={0} and other={1} are not equal!", contact, other)); //NOI18N
417 this.getLoggerBeanLocal().logDebug(MessageFormat.format("setAllContactPhoneEntries: other.contactCellphoneNumber={0}", other.getContactCellphoneNumber())); //NOI18N
419 // Is other cellphone not set?
420 if ((other.getContactCellphoneNumber() == null) || (PhoneUtils.isSameCellphoneNumber(contact.getContactCellphoneNumber(), other.getContactCellphoneNumber()))) {
422 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntries: Copying cellphone entry ..."); //NOI18N
424 // Is the fax number set?
425 if (other.getContactCellphoneNumber() instanceof DialableCellphoneNumber) {
426 // Copy cellphone number
427 contact.setContactCellphoneNumber(this.getDetached(other.getContactCellphoneNumber(), contact.getContactCellphoneNumber()));
430 contact.setContactCellphoneNumber(null);
435 this.getLoggerBeanLocal().logDebug(MessageFormat.format("setAllContactPhoneEntries: other.contactLandLineNumber={0}", other.getContactLandLineNumber())); //NOI18N
437 // Is other cellphone not set?
438 if ((other.getContactLandLineNumber() == null) || (PhoneUtils.isSameLandLineNumber(contact.getContactLandLineNumber(), other.getContactLandLineNumber()))) {
440 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntries: Copying land-line entry ..."); //NOI18N
442 // Is the land-line number set?
443 if (other.getContactLandLineNumber() instanceof DialableLandLineNumber) {
444 // Copy land-line number
445 contact.setContactLandLineNumber(this.getDetached(other.getContactLandLineNumber(), contact.getContactLandLineNumber()));
448 contact.setContactLandLineNumber(null);
453 this.getLoggerBeanLocal().logDebug(MessageFormat.format("setAllContactPhoneEntries: other.contactFaxNumber={0}", other.getContactFaxNumber())); //NOI18N
455 // Is other cellphone not set?
456 if ((other.getContactFaxNumber() == null) || (PhoneUtils.isSameFaxNumber(contact.getContactFaxNumber(), other.getContactFaxNumber()))) {
458 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntries: Copying fax entry ..."); //NOI18N
460 // Is the fax number set?
461 if (other.getContactFaxNumber() instanceof DialableFaxNumber) {
463 contact.setContactFaxNumber(this.getDetached(other.getContactFaxNumber(), contact.getContactFaxNumber()));
466 contact.setContactFaxNumber(null);
471 this.getLoggerBeanLocal().logTrace("setAllContactPhoneEntries: EXIT!"); //NOI18N
475 * Updates all contacts's phone entry's updated timestamps
477 * @param contact Contact instance to update
478 * @param isCellphoneUnlinked Whether a cellphone entry has been unlinked in
480 * @param isLandlineUnlinked Whether a land-line entry has been unlinked in
482 * @param isFaxUnlinked Whether a fax entry has been unlinked in contact
485 protected void setAllContactPhoneEntriesUpdated (final Contact contact, final boolean isCellphoneUnlinked, final boolean isLandlineUnlinked, final boolean isFaxUnlinked) {
487 this.getLoggerBeanLocal().logTrace(MessageFormat.format("setAllContactPhoneEntriesUpdated: contact={0},isCellphoneUnlinked={1},isLandlineUnlinked={2},isFaxUnlinked={3} - CALLED", contact, isCellphoneUnlinked, isLandlineUnlinked, isFaxUnlinked)); //NOI18N
489 // The contact instance must be valid
490 if (null == contact) {
492 throw new NullPointerException("contact is null"); //NOI18N
493 } else if (contact.getContactId() == null) {
495 throw new NullPointerException("contact.contactId is null"); //NOI18N //NOI18N
496 } else if (contact.getContactId() < 1) {
498 throw new IllegalStateException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
501 // Get all phone instances
502 DialableLandLineNumber landLineNumber = contact.getContactLandLineNumber();
503 DialableFaxNumber faxNumber = contact.getContactFaxNumber();
504 DialableCellphoneNumber cellphoneNumber = contact.getContactCellphoneNumber();
506 // Flags and instances must be constistent
507 if (isCellphoneUnlinked && cellphoneNumber instanceof DialableCellphoneNumber) {
509 throw new IllegalStateException("isCellPhoneUnlinked is TRUE, but cellphoneNumber is set."); //NOI18N
510 } else if (isLandlineUnlinked && landLineNumber instanceof DialableLandLineNumber) {
512 throw new IllegalStateException("isLandlineUnlinked is TRUE, but landLineNumber is set."); //NOI18N
513 } else if (isFaxUnlinked && faxNumber instanceof DialableFaxNumber) {
515 throw new IllegalStateException("isFaxUnlinked is TRUE, but faxNumber is set."); //NOI18N
518 // Is a phone number instance set?
519 if ((landLineNumber instanceof DialableLandLineNumber) && (landLineNumber.getPhoneId() instanceof Long) && (landLineNumber.getPhoneId() > 0)) {
521 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesUpdated: Setting updated timestamp for land-line number ..."); //NOI18N
523 // Set updated timestamp
524 landLineNumber.setPhoneEntryUpdated(new GregorianCalendar());
527 // Is a fax number instance set?
528 if ((faxNumber instanceof DialableFaxNumber) && (faxNumber.getPhoneId() instanceof Long) && (faxNumber.getPhoneId() > 0)) {
530 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesUpdated: Setting updated timestamp for fax number ..."); //NOI18N
532 // Set updated timestamp
533 faxNumber.setPhoneEntryUpdated(new GregorianCalendar());
536 // Is a mobile number instance set?
537 if ((cellphoneNumber instanceof DialableCellphoneNumber) && (cellphoneNumber.getPhoneId() instanceof Long) && (cellphoneNumber.getPhoneId() > 0)) {
539 this.getLoggerBeanLocal().logDebug("setAllContactPhoneEntriesUpdated: Setting updated timestamp for cellphone number ..."); //NOI18N
541 // Set updated timestamp
542 cellphoneNumber.setPhoneEntryUpdated(new GregorianCalendar());
546 this.getLoggerBeanLocal().logTrace("setAllContactPhoneEntriesUpdated: EXIT!"); //NOI18N