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.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.BadTokenException;
30 import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
31 import org.mxchange.addressbook.exceptions.UnhandledUserChoiceException;
32 import org.mxchange.addressbook.manager.BaseManager;
35 * A manager for contacts, please note that this implementation loads the whole
38 * @author Roland Haeder
41 public class ContactManager extends BaseManager implements ManageableContact {
46 private final List<String> columnNames;
49 * A ContactWrapper instance
51 private final ContactWrapper contactDatabase;
54 * Constructor which accepts maxContacts for maximum (initial) contacts and
57 * @param client Client instance to use
59 public ContactManager (final Client client) {
61 this.getLogger().trace(MessageFormat.format("client={1} - CALLED!", client)); //NOI18N
63 // Make sure all parameters are set correctly
66 throw new NullPointerException("client is null"); //NOI18N
69 // Set client instance
70 this.setClient(client);
72 // Init database connection
73 this.contactDatabase = new ContactDatabaseFrontend(this);
76 this.columnNames = new ArrayList<>(15);
79 this.fillColumnNamesFromBundle();
82 //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
86 * Adds given Contact instance to list
88 * @param contact Contact instance to add
91 public void addContact (final Contact contact) throws ContactAlreadyAddedException {
93 this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
95 // Contact instance must not be null
96 if (contact == null) {
98 throw new NullPointerException("contact is null"); //NOI18N
102 this.getContactDatabase().addContact(contact);
105 this.getLogger().trace("EXIT!"); //NOI18N
109 * Let the user add a new other address
112 public void doAddOtherAddress () {
113 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
117 * Let the user change address data
119 * @param contact Instance to change data
122 public void doChangeAddressData (final Contact contact) {
124 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
126 // Contact must not be null
127 if (contact == null) {
129 throw new NullPointerException("contact is null"); //NOI18N
132 // First display it again
133 this.getClient().displayAddressBox(contact);
136 if (contact.isOwnContact()) {
137 // Deligate to client
138 this.getClient().doChangeOwnAddressData(contact);
140 // Other contact's address data to change
141 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
145 this.getLogger().trace("EXIT!"); //NOI18N
149 * Let the user change "name data"
151 * @param contact Instance to change data
154 public void doChangeNameData (final Contact contact) {
156 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
158 // Contact must not be null
159 if (contact == null) {
161 throw new NullPointerException("contact is null"); //NOI18N
164 // First display them again
165 this.getClient().displayNameBox(contact);
168 if (contact.isOwnContact()) {
170 this.getClient().doChangeOwnNameData(contact);
172 // Then re-ask them ...
173 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
177 this.getLogger().trace("EXIT!"); //NOI18N
181 * Let the user change other address
184 public void doChangeOtherAddress () {
185 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
189 * Let the user change other data
191 * @param contact Instance to change data
192 * @todo Didn't handle birthday
195 public void doChangeOtherData (final Contact contact) {
197 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
199 // Contact must not be null
200 if (contact == null) {
202 throw new NullPointerException("contact is null"); //NOI18N
205 // First display them again
206 this.getClient().displayOtherDataBox(contact);
209 if (contact.isOwnContact()) {
211 this.getClient().doChangeOwnOtherData(contact);
213 // Then re-ask them ...
214 throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
218 this.getLogger().trace("EXIT!"); //NOI18N
222 * Allows the user to change his/her own data
225 public void doChangeOwnData () {
227 this.getLogger().trace("CALLED!"); //NOI18N
230 * First check if the user has registered own contact, before that
231 * nothing can be changed.
233 if (!this.isOwnContactAdded()) {
235 this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
237 // Skip any below code
242 Contact contact = this.getOwnContact();
245 assert (contact instanceof Contact);
248 contact.show(this.getClient());
251 // Ask user what to change
252 this.getClient().userChooseChangeContactData(contact);
253 } catch (final UnhandledUserChoiceException ex) {
254 this.getLogger().catching(ex);
258 this.getLogger().trace("EXIT!"); //NOI18N
262 * Let the user delete other address
265 public void doDeleteOtherAddress () {
266 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
270 * Asks user for own data
273 public void doEnterOwnData () throws ContactAlreadyAddedException {
275 this.getLogger().trace("CALLED!"); //NOI18N
277 // Is own contact already added?
278 if (this.isOwnContactAdded()) {
279 // Don't continue here
280 throw new ContactAlreadyAddedException();
283 // Deligate this call to the client
284 Contact contact = this.getClient().doEnterOwnData();
287 if (contact instanceof Contact) {
288 // Add it to contact "book"
289 this.registerContact(contact);
293 this.getLogger().trace("EXIT!"); //NOI18N
297 public void doListContacts () {
298 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
302 public void doSearchContacts () {
303 throw new UnsupportedOperationException("Not supported yet."); //NOI18N
307 * Shuts down this contact manager
310 public void doShutdown () {
312 this.getLogger().trace("CALLED!"); //NOI18N
314 // Shut down the database layer
315 this.getContactDatabase().doShutdown();
318 this.getLogger().trace("EXIT!"); //NOI18N
322 * Asks the user for his/her cellphone number
324 * @return User's cellphone number
327 public String enterOwnCellNumber () {
329 this.getLogger().trace("CALLED!"); //NOI18N
331 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
335 * Asks the user for his/her city's name
337 * @return City's name of the user
340 public String enterOwnCity () {
342 this.getLogger().trace("CALLED!"); //NOI18N
344 return this.getClient().enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
348 * Asks the user for his/her city's name
350 * @return City's name of the user
353 public String enterOwnComment () {
355 this.getLogger().trace("CALLED!"); //NOI18N
357 return this.getClient().enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
361 * Asks the user for his/her company name
363 * @return User's company name
366 public String enterOwnCompanyName () {
368 this.getLogger().trace("CALLED!"); //NOI18N
370 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
374 * Asks user for his/her own country code
376 * @return User's own country code
379 public String enterOwnCountryCode () {
381 this.getLogger().trace("CALLED!"); //NOI18N
383 return this.getClient().enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
387 * Asks user for his/her own country code
389 * @return User's own country code
392 public String enterOwnEmailAddress () {
394 this.getLogger().trace("CALLED!"); //NOI18N
396 return this.getClient().enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
400 * Asks the user for family name
402 * @return Family name of the user
405 public String enterOwnFamilyName () {
407 this.getLogger().trace("CALLED!"); //NOI18N
409 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
413 * Asks the user for family name
415 * @return Family name of the user
418 public String enterOwnFaxNumber () {
420 this.getLogger().trace("CALLED!"); //NOI18N
422 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
426 * Asks the user for gender, until a valid has been entered
428 * @return Gender of the user
431 public Gender enterOwnGender () {
433 this.getLogger().trace("CALLED!"); //NOI18N
435 return this.getClient().enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
439 * Asks the user for phone number
441 * @return Phone number of the user
444 public String enterOwnPhoneNumber () {
446 this.getLogger().trace("CALLED!"); //NOI18N
448 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
452 * Asks the user for own street (including number)
454 * @return Own street an number
457 public String enterOwnStreet () {
459 this.getLogger().trace("CALLED!"); //NOI18N
461 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
465 * Asks the user for surname
467 * @return Surname of the user
470 public String enterOwnSurname () {
472 this.getLogger().trace("CALLED!"); //NOI18N
474 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
478 * Asks the user for own ZIP code
483 public int enterOwnZipCode () {
485 this.getLogger().trace("CALLED!"); //NOI18N
487 return this.getClient().enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
491 public final int getColumnCount () {
492 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
494 return this.columnNames.size();
498 * Getter for column name at given index.
500 * @param columnIndex Column index
501 * @return Human-readable column name
504 public String getColumnName (final int columnIndex) {
505 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
507 // Get column name at index
508 return this.columnNames.get(columnIndex);
512 * Somewhat "getter" for value from given row and column index
514 * @param rowIndex Row index
515 * @param columnIndex Column index
516 * @return Value from given row/column
519 public Object getValueFromRowColumn (final int rowIndex, final int columnIndex) {
521 this.getLogger().trace(MessageFormat.format("rowIndex={0},columnIndex={1} CALLED!", rowIndex, columnIndex));
523 // Then get specific row from database which is a Contact instance
524 Contact contact = this.getContactDatabase().readSingleContact(rowIndex);
527 this.getLogger().debug(MessageFormat.format("contact={0}", contact));
529 // It may return null
530 if (contact == null) {
532 this.getLogger().warn("contact is null - returning null ...");
536 // Convert column index -> name
537 String columnName = this.getColumnName(columnIndex);
540 this.getLogger().debug(MessageFormat.format("columnName={0}", columnName));
542 // Now get that column
543 Object value = contact.getValueFromColumn(columnName);
546 this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value));
553 * Checks whether own contact is already added by checking all entries for
556 * @return Whether own contact is already added
559 public boolean isOwnContactAdded () {
561 this.getLogger().trace("CALLED!"); //NOI18N
564 boolean isAdded = false;
567 // Deligate this call to frontend
568 isAdded = this.getContactDatabase().isOwnContactFound();
569 } catch (final SQLException ex) {
570 // Something bad happened
571 this.abortProgramWithException(ex);
575 this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
582 * Adds given contact to address book and flushes all entries to database
584 * @param contact Contact being added
585 * @todo Add check for book size
588 public void registerContact (final Contact contact) {
590 this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
593 if (contact == null) {
595 throw new NullPointerException("contact is null"); //NOI18N
599 /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
601 // Check if contact is found
602 if (this.getContactDatabase().isContactFound(contact)) {
603 // Contact already added
604 // @todo Do something here
605 } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
606 // Own contact already added
607 // @todo Do something
610 // Add contact to internal list
611 this.addContact(contact);
612 } catch (final ContactAlreadyAddedException ex) {
614 this.abortProgramWithException(ex);
615 } catch (final BadTokenException ex) {
617 this.abortProgramWithException(ex);
621 this.getLogger().trace("EXIT!"); //NOI18N
627 * @return size of contact "book"
630 public final int size () {
635 size = this.getContactDatabase().getContactsCount();
636 } catch (final SQLException ex) {
637 // Something happened
638 this.abortProgramWithException(ex);
646 * Fills the column names array with strings from bundle
648 private void fillColumnNamesFromBundle () {
649 assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
652 this.getLogger().trace("CALLED!"); //NOI18N
654 // First get an iterator from key set to iterate over
655 Iterator<String> iterator = this.getBundle().keySet().iterator();
657 // Then iterate over all
658 while (iterator.hasNext()) {
660 String key = iterator.next();
662 // Does the key start with ContactManager.columnName ?
663 if (key.startsWith("ContactManager.columnName")) { //NOI18N
664 // This is the wanted entry.
665 this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
668 this.columnNames.add(this.getBundle().getString(key));
673 this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
677 * A ContactWrapper instance
679 * @return the database
681 private ContactWrapper getContactDatabase () {
682 return this.contactDatabase;
686 * "Getter" for own contact instance or null if not found
688 * @return Contact instance or null
690 private Contact getOwnContact () {
692 this.getLogger().trace("CALLED!"); //NOI18N
694 // Deligate this call to database frontend
695 Contact contact = this.getContactDatabase().getOwnContact();
698 this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
700 // Return instance or null