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.sql.SQLException;
20 import java.text.MessageFormat;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Iterator;
24 import java.util.List;
25 import org.mxchange.addressbook.client.AddressbookClient;
26 import org.mxchange.addressbook.database.frontend.contact.AddressbookContactDatabaseFrontend;
27 import org.mxchange.addressbook.database.frontend.contact.AddressbookContactFrontend;
28 import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
29 import org.mxchange.jcore.client.Client;
30 import org.mxchange.jcore.contact.Contact;
31 import org.mxchange.jcore.contact.Gender;
32 import org.mxchange.jcore.exceptions.BadTokenException;
33 import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
34 import org.mxchange.jcore.manager.BaseManager;
37 * A manager for contacts.
39 * @author Roland Haeder
42 public class AddressbookContactManager extends BaseManager implements ManageableAddressbookContact {
47 private final List<String> columnNames;
50 * A AddressbookContactFrontend instance
52 private final AddressbookContactFrontend contactDatabase;
55 * Translated column name list
57 private final List<String> translatedColumnNames;
60 * Constructor which accepts maxContacts for maximum (initial) contacts and
63 * @param client Client instance to use
65 public AddressbookContactManager (final Client client) {
67 this.getLogger().trace(MessageFormat.format("client={1} - CALLED!", client)); //NOI18N
69 // Make sure all parameters are set correctly
72 throw new NullPointerException("client is null"); //NOI18N
75 // Set client instance
76 this.setClient(client);
78 // Init database connection
79 this.contactDatabase = new AddressbookContactDatabaseFrontend(this);
82 this.columnNames = new ArrayList<>(15);
83 this.translatedColumnNames = new ArrayList<>(15);
86 this.fillColumnNamesFromBundle();
89 //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
93 * Adds given Contact instance to list
95 * @param contact Contact instance to add
98 public void addContact (final Contact contact) throws ContactAlreadyAddedException {
100 this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
102 // Contact instance must not be null
103 if (contact == null) {
105 throw new NullPointerException("contact is null"); //NOI18N
109 this.getContactDatabase().addContact(contact);
112 this.getLogger().trace("EXIT!"); //NOI18N
116 * Let the user add a new other address
119 public void doAddOtherAddress () {
120 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
124 * Let the user change address data
126 * @param contact Instance to change data
129 public void doChangeAddressData (final Contact contact) {
131 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
133 // Contact must not be null
134 if (contact == null) {
136 throw new NullPointerException("contact is null"); //NOI18N
139 // Get and cast client instance
140 AddressbookClient client = (AddressbookClient) this.getClient();
142 // First display it again
143 client.displayAddressBox(contact);
146 if (contact.isOwnContact()) {
147 // Deligate to client
148 client.doChangeOwnAddressData(contact);
150 // Other contact's address data to change
151 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
155 this.getLogger().trace("EXIT!"); //NOI18N
159 * Let the user change "name data"
161 * @param contact Instance to change data
164 public void doChangeNameData (final Contact contact) {
166 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
168 // Contact must not be null
169 if (contact == null) {
171 throw new NullPointerException("contact is null"); //NOI18N
174 // Get and cast client instance
175 AddressbookClient client = (AddressbookClient) this.getClient();
177 // First display them again
178 client.displayNameBox(contact);
181 if (contact.isOwnContact()) {
183 client.doChangeOwnNameData(contact);
185 // Then re-ask them ...
186 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
190 this.getLogger().trace("EXIT!"); //NOI18N
194 * Let the user change other address
197 public void doChangeOtherAddress () {
198 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
202 * Let the user change other data
204 * @param contact Instance to change data
205 * @todo Didn't handle birthday
208 public void doChangeOtherData (final Contact contact) {
210 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
212 // Contact must not be null
213 if (contact == null) {
215 throw new NullPointerException("contact is null"); //NOI18N
218 // Get and cast client instance
219 AddressbookClient client = (AddressbookClient) this.getClient();
221 // First display them again
222 client.displayOtherDataBox(contact);
225 if (contact.isOwnContact()) {
227 client.doChangeOwnOtherData(contact);
229 // Then re-ask them ...
230 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
234 this.getLogger().trace("EXIT!"); //NOI18N
238 * Allows the user to change his/her own data
241 public void doChangeOwnData () {
243 this.getLogger().trace("CALLED!"); //NOI18N
246 * First check if the user has registered own contact, before that
247 * nothing can be changed.
249 if (!this.isOwnContactAdded()) {
251 this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
253 // Skip any below code
258 Contact contact = this.getOwnContact();
261 assert (contact instanceof Contact);
264 contact.show(this.getClient());
266 // Get and cast client instance
267 AddressbookClient client = (AddressbookClient) this.getClient();
270 // Ask user what to change
271 client.userChooseChangeContactData(contact);
272 } catch (final UnhandledUserChoiceException ex) {
273 this.getLogger().catching(ex);
277 this.getLogger().trace("EXIT!"); //NOI18N
281 * Let the user delete other address
284 public void doDeleteOtherAddress () {
285 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
289 * Asks user for own data
292 public void doEnterOwnData () throws ContactAlreadyAddedException {
294 this.getLogger().trace("CALLED!"); //NOI18N
296 // Is own contact already added?
297 if (this.isOwnContactAdded()) {
298 // Don't continue here
299 throw new ContactAlreadyAddedException();
302 // Get and cast client instance
303 AddressbookClient client = (AddressbookClient) this.getClient();
305 // Deligate this call to the client
306 Contact contact = client.doEnterOwnData();
309 if (contact instanceof Contact) {
310 // Add it to contact "book"
311 this.registerContact(contact);
315 this.getLogger().trace("EXIT!"); //NOI18N
319 public void doListContacts () {
320 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
324 public void doSearchContacts () {
325 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
329 * Shuts down this contact manager
332 public void doShutdown () {
334 this.getLogger().trace("CALLED!"); //NOI18N
336 // Shut down the database layer
337 this.getContactDatabase().doShutdown();
340 this.getLogger().trace("EXIT!"); //NOI18N
344 * Asks the user for his/her cellphone number
346 * @return User's cellphone number
349 public String enterOwnCellNumber () {
351 this.getLogger().trace("CALLED!"); //NOI18N
353 // Get and cast client instance
354 AddressbookClient client = (AddressbookClient) this.getClient();
356 return client.enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
360 * Asks the user for his/her city's name
362 * @return City's name of the user
365 public String enterOwnCity () {
367 this.getLogger().trace("CALLED!"); //NOI18N
369 // Get and cast client instance
370 AddressbookClient client = (AddressbookClient) this.getClient();
372 return client.enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
376 * Asks the user for his/her city's name
378 * @return City's name of the user
381 public String enterOwnComment () {
383 this.getLogger().trace("CALLED!"); //NOI18N
385 // Get and cast client instance
386 AddressbookClient client = (AddressbookClient) this.getClient();
388 return client.enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
392 * Asks the user for his/her company name
394 * @return User's company name
397 public String enterOwnCompanyName () {
399 this.getLogger().trace("CALLED!"); //NOI18N
401 // Get and cast client instance
402 AddressbookClient client = (AddressbookClient) this.getClient();
404 return client.enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
408 * Asks user for his/her own country code
410 * @return User's own country code
413 public String enterOwnCountryCode () {
415 this.getLogger().trace("CALLED!"); //NOI18N
417 // Get and cast client instance
418 AddressbookClient client = (AddressbookClient) this.getClient();
420 return client.enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
424 * Asks user for his/her own country code
426 * @return User's own country code
429 public String enterOwnEmailAddress () {
431 this.getLogger().trace("CALLED!"); //NOI18N
433 // Get and cast client instance
434 AddressbookClient client = (AddressbookClient) this.getClient();
436 return client.enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
440 * Asks the user for family name
442 * @return Family name of the user
445 public String enterOwnFamilyName () {
447 this.getLogger().trace("CALLED!"); //NOI18N
449 // Get and cast client instance
450 AddressbookClient client = (AddressbookClient) this.getClient();
452 return client.enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
456 * Asks the user for family name
458 * @return Family name of the user
461 public String enterOwnFaxNumber () {
463 this.getLogger().trace("CALLED!"); //NOI18N
465 // Get and cast client instance
466 AddressbookClient client = (AddressbookClient) this.getClient();
468 return client.enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
472 * Asks the user for gender, until a valid has been entered
474 * @return Gender of the user
477 public Gender enterOwnGender () {
479 this.getLogger().trace("CALLED!"); //NOI18N
481 // Get and cast client instance
482 AddressbookClient client = (AddressbookClient) this.getClient();
484 return client.enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
488 * Asks the user for phone number
490 * @return Phone number of the user
493 public String enterOwnPhoneNumber () {
495 this.getLogger().trace("CALLED!"); //NOI18N
497 // Get and cast client instance
498 AddressbookClient client = (AddressbookClient) this.getClient();
500 return client.enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
504 * Asks the user for own street (including number)
506 * @return Own street an number
509 public String enterOwnStreet () {
511 this.getLogger().trace("CALLED!"); //NOI18N
513 // Get and cast client instance
514 AddressbookClient client = (AddressbookClient) this.getClient();
516 return client.enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
520 * Asks the user for surname
522 * @return Surname of the user
525 public String enterOwnSurname () {
527 this.getLogger().trace("CALLED!"); //NOI18N
529 // Get and cast client instance
530 AddressbookClient client = (AddressbookClient) this.getClient();
532 return client.enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
536 * Asks the user for own ZIP code
541 public int enterOwnZipCode () {
543 this.getLogger().trace("CALLED!"); //NOI18N
545 // Get and cast client instance
546 AddressbookClient client = (AddressbookClient) this.getClient();
548 return client.enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
552 public final int getColumnCount () {
553 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
555 return this.columnNames.size();
559 * Getter for column name at given index.
561 * @param columnIndex Column index
562 * @return Database column name
565 public String getColumnName (final int columnIndex) {
566 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
568 // Get column name at index
569 return this.columnNames.get(columnIndex);
573 * Getter for translated column name at given index.
575 * @param columnIndex Column index
576 * @return Human-readable column name
579 public String getTranslatedColumnName (final int columnIndex) {
580 assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
582 // Get column name at index
583 return this.translatedColumnNames.get(columnIndex);
587 * Somewhat "getter" for value from given row and column index
589 * @param rowIndex Row index
590 * @param columnIndex Column index
591 * @return Value from given row/column
594 public Object getValueFromRowColumn (final int rowIndex, final int columnIndex) {
596 this.getLogger().trace(MessageFormat.format("rowIndex={0},columnIndex={1} CALLED!", rowIndex, columnIndex));
598 // Then get specific row from database which is a Contact instance
599 Contact contact = this.getContactDatabase().readSingleContact(rowIndex);
602 this.getLogger().debug(MessageFormat.format("contact={0}", contact));
604 // It may return null
605 if (contact == null) {
607 this.getLogger().warn("contact is null - returning null ...");
611 // Convert column index -> name
612 String columnName = this.getColumnName(columnIndex);
615 this.getLogger().debug(MessageFormat.format("columnName={0}", columnName));
617 // Now get that column
618 Object value = contact.getValueFromColumn(columnName);
621 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value));
628 * Checks whether own contact is already added by checking all entries for
631 * @return Whether own contact is already added
634 public boolean isOwnContactAdded () {
636 this.getLogger().trace("CALLED!"); //NOI18N
639 boolean isAdded = false;
642 // Deligate this call to frontend
643 isAdded = this.getContactDatabase().isOwnContactFound();
644 } catch (final SQLException ex) {
645 // Something bad happened
646 this.abortProgramWithException(ex);
650 this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
657 * Adds given contact to address book and flushes all entries to database
659 * @param contact Contact being added
660 * @todo Add check for book size
663 public void registerContact (final Contact contact) {
665 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
668 if (contact == null) {
670 throw new NullPointerException("contact is null"); //NOI18N
674 /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
676 // Check if contact is found
677 if (this.getContactDatabase().isContactFound(contact)) {
678 // Contact already added
679 // @todo Do something here
680 } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
681 // Own contact already added
682 // @todo Do something
685 // Add contact to internal list
686 this.addContact(contact);
687 } catch (final ContactAlreadyAddedException ex) {
689 this.abortProgramWithException(ex);
690 } catch (final BadTokenException ex) {
692 this.abortProgramWithException(ex);
696 this.getLogger().trace("EXIT!"); //NOI18N
702 * @return size of contact "book"
705 public final int size () {
710 size = this.getContactDatabase().getContactsCount();
711 } catch (final SQLException ex) {
712 // Something happened
713 this.abortProgramWithException(ex);
721 * Fills the column names array with strings from bundle
723 private void fillColumnNamesFromBundle () {
724 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
725 assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
728 this.getLogger().trace("CALLED!"); //NOI18N
730 // First get an iterator from key set to iterate over
731 Iterator<String> iterator = this.getBundle().keySet().iterator();
733 // Then iterate over all
734 while (iterator.hasNext()) {
736 String key = iterator.next();
738 // Does the key start with AddressbookContactManager.columnName ?
739 if (key.startsWith("ContactManager.columnName")) { //NOI18N
740 // This is the wanted entry.
741 this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
743 // Convert string to array based on delimiter '.'
744 String[] tokens = this.getArrayFromString(key, ".", 4);
746 // Token array must contain 4 elements (AddressbookContactManager.columnName.foo.text)
747 assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens));
749 // Get pre-last element
750 String columnName = tokens[tokens.length - 2];
753 this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName));
756 this.columnNames.add(columnName);
757 this.translatedColumnNames.add(this.getBundle().getString(key));
762 this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
766 * A AddressbookContactFrontend instance
768 * @return the database
770 private AddressbookContactFrontend getContactDatabase () {
771 return this.contactDatabase;
775 * "Getter" for own contact instance or null if not found
777 * @return Contact instance or null
779 private Contact getOwnContact () {
781 this.getLogger().trace("CALLED!"); //NOI18N
783 // Deligate this call to database frontend
784 Contact contact = this.getContactDatabase().getOwnContact();
787 this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
789 // Return instance or null