2 * Copyright (C) 2015 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.manager.contact;
19 import java.text.MessageFormat;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import org.mxchange.addressbook.client.Client;
25 import org.mxchange.addressbook.contact.Contact;
26 import org.mxchange.addressbook.contact.Gender;
27 import org.mxchange.addressbook.database.frontend.contact.ContactDatabaseFrontend;
28 import org.mxchange.addressbook.database.frontend.contact.ContactWrapper;
29 import org.mxchange.addressbook.exceptions.UnhandledUserChoiceException;
30 import org.mxchange.addressbook.manager.BaseManager;
33 * A manager for contacts, please note that this implementation loads the whole
36 * @author Roland Haeder
39 public class ContactManager extends BaseManager implements ManageableContact {
44 private final List<String> columnNames;
47 * A ContactWrapper instance
49 private final ContactWrapper contactDatabase;
52 * A list of all contacts
54 private final List<Contact> contacts;
57 * Constructor which accepts maxContacts for maximum (initial) contacts and
60 * @param maxContacts Maximum allowed contacts
61 * @param client Client instance to use
63 public ContactManager (final int maxContacts, final Client client) {
64 // Always call super constructor first
68 this.getLogger().trace(MessageFormat.format("maxContacts={0},client={1} - CALLED!", maxContacts, client)); //NOI18N
70 // Make sure all parameters are set correctly
71 if (maxContacts <= 0) {
72 // Must not be zero or smaller
73 throw new IllegalArgumentException(MessageFormat.format("maxContacts is below or zero: {0}", maxContacts)); //NOI18N
74 } else if (client == null) {
76 throw new NullPointerException("client is null"); //NOI18N
79 // Set client instance
80 this.setClient(client);
83 this.contacts = new ArrayList<>(maxContacts);
85 // Init database connection
86 this.contactDatabase = new ContactDatabaseFrontend(this);
89 this.columnNames = new ArrayList<>(15);
92 this.fillColumnNamesFromBundle();
95 this.contactDatabase.readAllContacts();
98 //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
102 * Adds given Contact instance to list
104 * @param contact Contact instance to add
107 public void addContact (final Contact contact) {
108 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
111 this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
113 // Contact instance must not be null
114 if (contact == null) {
116 throw new NullPointerException("contact is null"); //NOI18N
120 this.contacts.add(contact);
123 this.getLogger().trace("EXIT!"); //NOI18N
127 * Let the user add a new other address
130 public void doAddOtherAddress () {
131 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
135 * Let the user change address data
137 * @param contact Instance to change data
140 public void doChangeAddressData (final Contact contact) {
142 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
144 // Contact must not be null
145 if (contact == null) {
147 throw new NullPointerException("contact is null"); //NOI18N
150 // First display it again
151 this.getClient().displayAddressBox(contact);
154 if (contact.isOwnContact()) {
155 // Deligate to client
156 this.getClient().doChangeOwnAddressData(contact);
158 // Other contact's address data to change
159 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
166 this.getLogger().trace("EXIT!"); //NOI18N
170 * Let the user change "name data"
172 * @param contact Instance to change data
175 public void doChangeNameData (final Contact contact) {
177 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
179 // Contact must not be null
180 if (contact == null) {
182 throw new NullPointerException("contact is null"); //NOI18N
185 // First display them again
186 this.getClient().displayNameBox(contact);
189 if (contact.isOwnContact()) {
191 this.getClient().doChangeOwnNameData(contact);
193 // Then re-ask them ...
194 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
200 this.getLogger().trace("EXIT!"); //NOI18N
204 * Let the user change other address
207 public void doChangeOtherAddress () {
208 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
212 * Let the user change other data
214 * @param contact Instance to change data
215 * @todo Didn't handle birthday
218 public void doChangeOtherData (final Contact contact) {
220 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
222 // Contact must not be null
223 if (contact == null) {
225 throw new NullPointerException("contact is null"); //NOI18N
228 // First display them again
229 this.getClient().displayOtherDataBox(contact);
232 if (contact.isOwnContact()) {
234 this.getClient().doChangeOwnOtherData(contact);
236 // Then re-ask them ...
237 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
244 this.getLogger().trace("EXIT!"); //NOI18N
248 * Allows the user to change his/her own data
251 public void doChangeOwnData () {
253 this.getLogger().trace("CALLED!"); //NOI18N
256 * First check if the user has registered own contact, before that
257 * nothing can be changed.
259 if (!this.isOwnContactAdded()) {
261 this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
263 // Skip any below code
268 Contact contact = this.getOwnContact();
271 assert (contact instanceof Contact);
274 contact.show(this.getClient());
277 // Ask user what to change
278 this.getClient().userChooseChangeContactData(contact);
279 } catch (final UnhandledUserChoiceException ex) {
280 this.getLogger().catching(ex);
284 this.getLogger().trace("EXIT!"); //NOI18N
288 * Let the user delete other address
291 public void doDeleteOtherAddress () {
292 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
296 * Asks user for own data
299 public void doEnterOwnData () {
301 this.getLogger().trace("CALLED!"); //NOI18N
303 // Deligate this call to the client
304 Contact contact = this.getClient().doEnterOwnData();
307 if (contact instanceof Contact) {
308 // Add it to contact "book"
309 this.registerContact(contact);
313 this.getLogger().trace("EXIT!"); //NOI18N
317 public void doListContacts () {
318 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
322 public void doSearchContacts () {
323 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
327 * Shuts down this contact manager
330 public void doShutdown () {
332 this.getLogger().trace("CALLED!"); //NOI18N
334 // Shut down the database layer
335 this.getContactDatabase().doShutdown();
338 this.getLogger().trace("EXIT!"); //NOI18N
342 * Asks the user for his/her cellphone number
344 * @return User's cellphone number
347 public String enterOwnCellNumber () {
349 this.getLogger().trace("CALLED!"); //NOI18N
351 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
355 * Asks the user for his/her city's name
357 * @return City's name of the user
360 public String enterOwnCity () {
362 this.getLogger().trace("CALLED!"); //NOI18N
364 return this.getClient().enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
368 * Asks the user for his/her city's name
370 * @return City's name of the user
373 public String enterOwnComment () {
375 this.getLogger().trace("CALLED!"); //NOI18N
377 return this.getClient().enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
381 * Asks the user for his/her company name
383 * @return User's company name
386 public String enterOwnCompanyName () {
388 this.getLogger().trace("CALLED!"); //NOI18N
390 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
394 * Asks user for his/her own country code
396 * @return User's own country code
399 public String enterOwnCountryCode () {
401 this.getLogger().trace("CALLED!"); //NOI18N
403 return this.getClient().enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
407 * Asks user for his/her own country code
409 * @return User's own country code
412 public String enterOwnEmailAddress () {
414 this.getLogger().trace("CALLED!"); //NOI18N
416 return this.getClient().enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
420 * Asks the user for family name
422 * @return Family name of the user
425 public String enterOwnFamilyName () {
427 this.getLogger().trace("CALLED!"); //NOI18N
429 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
433 * Asks the user for family name
435 * @return Family name of the user
438 public String enterOwnFaxNumber () {
440 this.getLogger().trace("CALLED!"); //NOI18N
442 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
446 * Asks the user for gender, until a valid has been entered
448 * @return Gender of the user
451 public Gender enterOwnGender () {
453 this.getLogger().trace("CALLED!"); //NOI18N
455 return this.getClient().enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
459 * Asks the user for phone number
461 * @return Phone number of the user
464 public String enterOwnPhoneNumber () {
466 this.getLogger().trace("CALLED!"); //NOI18N
468 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
472 * Asks the user for own street (including number)
474 * @return Own street an number
477 public String enterOwnStreet () {
479 this.getLogger().trace("CALLED!"); //NOI18N
481 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
485 * Asks the user for surname
487 * @return Surname of the user
490 public String enterOwnSurname () {
492 this.getLogger().trace("CALLED!"); //NOI18N
494 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
498 * Asks the user for own ZIP code
503 public int enterOwnZipCode () {
505 this.getLogger().trace("CALLED!"); //NOI18N
507 return this.getClient().enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
511 public final int getColumnCount () {
512 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
514 return this.columnNames.size();
518 * Getter for column name at given index.
520 * @param columnIndex Column index
521 * @return Human-readable column name
524 public String getColumnName (final int columnIndex) {
525 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
527 // Get column name at index
528 return this.columnNames.get(columnIndex);
532 * Getter for whole contact list
534 * @return List of all contacts
537 public List<Contact> getList () {
538 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
539 return Collections.unmodifiableList(this.contacts);
543 * Checks whether own contact is already added by checking all entries for
546 * @return Whether own contact is already added
549 public boolean isOwnContactAdded () {
551 this.getLogger().trace("CALLED!"); //NOI18N
553 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
555 // Default is not added
556 boolean isAdded = false;
558 // Now get it back from address book, first get an iterator
559 Iterator<Contact> iterator = this.contacts.iterator();
562 while (iterator.hasNext()) {
564 Contact contact = iterator.next();
567 if (contact instanceof Contact) {
569 isAdded = contact.isOwnContact();
571 // Is this own contact?
580 this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
587 * Adds given contact to address book and flushes all entries to database
589 * @param contact Contact being added
590 * @todo Add check for book size
593 public void registerContact (final Contact contact) {
595 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
597 // Contact must not be null
598 if (contact == null) {
600 throw new NullPointerException("contact is null"); //NOI18N
604 if (contact == null) {
606 throw new NullPointerException("contact is null"); //NOI18N
609 // Check if contact is found
610 if (this.isContactAlreadyAdded(contact)) {
611 // Contact already added
612 // @todo Do something here
613 } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
614 // Own contact already added
615 // @todo Do something
619 /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
621 // Add contact to internal list
622 this.addContact(contact);
631 * @return size of contact "book"
634 public final int size () {
635 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
636 return this.contacts.size();
640 * Fills the column names array with strings from bundle
642 private void fillColumnNamesFromBundle () {
643 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
646 this.getLogger().trace("CALLED!"); //NOI18N
648 // First get an iterator from key set to iterate over
649 Iterator<String> iterator = this.getBundle().keySet().iterator();
651 // Then iterate over all
652 while (iterator.hasNext()) {
654 String key = iterator.next();
656 // Does the key start with ContactManager.columnName ?
657 if (key.startsWith("ContactManager.columnName")) { //NOI18N
658 // This is the wanted entry.
659 this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
662 this.columnNames.add(this.getBundle().getString(key));
667 this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
671 * Flushes all entries by calling database backend
673 private void flush () {
675 this.getLogger().trace("CALLED!"); //NOI18N
678 this.getContactDatabase().flushAllContacts();
681 this.getLogger().trace("EXIT!"); //NOI18N
685 * A ContactWrapper instance
687 * @return the database
689 private ContactWrapper getContactDatabase () {
690 return this.contactDatabase;
694 * "Getter" for own contact instance or null if not found
696 * @return Contact instance or null
698 private Contact getOwnContact () {
699 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
702 this.getLogger().trace("CALLED!"); //NOI18N
704 // Now get it back from address book, first get an iterator
705 Iterator<Contact> iterator = this.contacts.iterator();
708 Contact contact = null;
710 // Search all contact
711 while (iterator.hasNext()) {
713 Contact next = iterator.next();
715 // Is this own contact?
716 if (next.isOwnContact()) {
725 this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
727 // Return instance or null
732 * Checks whether given contact was found in "address book"
734 * @param checkContact Contact to be checked
735 * @return TRUE if found, FALSE if not found
737 private boolean isContactAlreadyAdded (final Contact checkContact) throws NullPointerException {
738 assert (this.contacts instanceof List) : "this.contacts is not initialized"; //NOI18N
741 this.getLogger().trace(MessageFormat.format("checkContact={0} - CALLED!", checkContact)); //NOI18N
743 // Contact instance must not be null
744 if (checkContact == null) {
746 throw new NullPointerException("checkContact is null");
749 // Default is not found
750 boolean isFound = false;
753 //* NOISY-DEBUG: */ this.getLogger().debug("Checking '" + this.contacts.length + "' entries...");
754 // Now get it back from address book, first get an iterator
755 Iterator<Contact> iterator = this.contacts.iterator();
758 while (iterator.hasNext()) {
760 Contact contact = iterator.next();
763 //* NOISY-DEBUG: */ this.getLogger().debug("contact=" + contact + ",checkContent=" + checkContact);
765 if ((contact instanceof Contact) && ((contact.equals(checkContact)))) {
766 // Found matching entry
773 this.getLogger().trace(MessageFormat.format("isFound={0} - EXIT!", isFound)); //NOI18N