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
67 // Set client instance
68 this.setClient(client);
71 this.contacts = new ArrayList<>(maxContacts);
73 // Init database connection
74 this.contactDatabase = new ContactDatabaseFrontend(this);
77 this.columnNames = new ArrayList<>(15);
80 this.fillColumnNamesFromBundle();
83 this.contactDatabase.readAllContacts();
86 //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
90 * Adds given Contact instance to list
92 * @param contact Contact instance to add
95 public void addContact (final Contact contact) {
96 assert (this.contacts instanceof List) : "this.contacts is not initialized";
98 this.contacts.add(contact);
102 * Let the user add a new other address
105 public void doAddOtherAddress () {
106 throw new UnsupportedOperationException("Not supported yet.");
110 * Let the user change address data
112 * @param contact Instance to change data
113 * @param client Client instance to call back
116 public void doChangeAddressData (final Contact contact, final Client client) {
117 // First display it again
118 client.displayAddressBox(contact);
121 if (contact.isOwnContact()) {
122 // Deligate to client
123 this.getClient().doChangeOwnAddressData(contact);
125 // Other contact's address data to change
126 throw new UnsupportedOperationException("Changing contact entries not finished.");
134 * Let the user change "name data"
136 * @param contact Instance to change data
137 * @param client Client instance to call back
140 public void doChangeNameData (final Contact contact, final Client client) {
141 // First display them again
142 client.displayNameBox(contact);
145 if (contact.isOwnContact()) {
147 this.getClient().doChangeOwnNameData(contact);
149 // Then re-ask them ...
150 throw new UnsupportedOperationException("Changing contact entries not finished.");
158 * Let the user change other address
161 public void doChangeOtherAddress () {
162 throw new UnsupportedOperationException("Not supported yet.");
166 * Let the user change other data
168 * @param contact Instance to change data
169 * @param client Client instance to call back
170 * @todo Didn't handle birthday
173 public void doChangeOtherData (final Contact contact, final Client client) {
174 // First display them again
175 this.getClient().displayOtherDataBox(contact);
178 if (contact.isOwnContact()) {
180 this.getClient().doChangeOwnOtherData(contact);
182 // Then re-ask them ...
183 throw new UnsupportedOperationException("Changing contact entries not finished.");
191 * Allows the user to change his/her own data
194 public void doChangeOwnData () {
196 * First check if the user has registered own contact, before that
197 * nothing can be changed.
199 if (!this.isOwnContactAdded()) {
201 this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben.");
203 // Skip any below code
208 Contact contact = this.getOwnContact();
211 assert (contact instanceof Contact);
214 contact.show(this.getClient());
217 // Ask user what to change
218 this.getClient().userChooseChangeContactData(contact);
219 } catch (final UnhandledUserChoiceException ex) {
220 this.getLogger().catching(ex);
225 * Let the user delete other address
228 public void doDeleteOtherAddress () {
229 throw new UnsupportedOperationException("Not supported yet.");
233 * Asks user for own data
236 public void doEnterOwnData () {
237 // Deligate this call to the client
238 Contact contact = this.getClient().doEnterOwnData();
241 if (contact instanceof Contact) {
242 // Add it to contact "book"
243 this.registerContact(contact);
248 public void doListContacts () {
249 throw new UnsupportedOperationException("Not supported yet.");
253 public void doSearchContacts () {
254 throw new UnsupportedOperationException("Not supported yet.");
258 * Shuts down this contact manager
261 public void doShutdown () {
262 // Shut down the database layer
263 this.getContactDatabase().doShutdown();
267 * Asks the user for his/her cellphone number
269 * @return User's cellphone number
272 public String enterOwnCellNumber () {
273 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
277 * Asks the user for his/her city's name
279 * @return City's name of the user
282 public String enterOwnCity () {
283 return this.getClient().enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
287 * Asks the user for his/her city's name
289 * @return City's name of the user
292 public String enterOwnComment () {
293 return this.getClient().enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
297 * Asks the user for his/her company name
299 * @return User's company name
302 public String enterOwnCompanyName () {
303 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
307 * Asks user for his/her own country code
309 * @return User's own country code
312 public String enterOwnCountryCode () {
313 return this.getClient().enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
317 * Asks user for his/her own country code
319 * @return User's own country code
322 public String enterOwnEmailAddress () {
323 return this.getClient().enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
327 * Asks the user for family name
329 * @return Family name of the user
332 public String enterOwnFamilyName () {
333 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
337 * Asks the user for family name
339 * @return Family name of the user
342 public String enterOwnFaxNumber () {
343 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
347 * Asks the user for gender, until a valid has been entered
349 * @return Gender of the user
352 public Gender enterOwnGender () {
353 return this.getClient().enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
357 * Asks the user for phone number
359 * @return Phone number of the user
362 public String enterOwnPhoneNumber () {
363 return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
367 * Asks the user for own street (including number)
369 * @return Own street an number
372 public String enterOwnStreet () {
373 return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
377 * Asks the user for surname
379 * @return Surname of the user
382 public String enterOwnSurname () {
383 return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
387 * Asks the user for own ZIP code
392 public int enterOwnZipCode () {
393 return this.getClient().enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
397 public final int getColumnCount () {
398 assert (this.columnNames instanceof List) : "this.columnNames is not initialized";
400 return this.columnNames.size();
404 * Getter for column name at given index.
406 * @param columnIndex Column index
407 * @return Human-readable column name
410 public String getColumnName (final int columnIndex) {
411 assert (this.columnNames instanceof List) : "this.columnNames is not initialized";
413 // Get column name at index
414 return this.columnNames.get(columnIndex);
418 * Getter for whole contact list
420 * @return List of all contacts
423 public List<Contact> getList () {
424 assert (this.contacts instanceof List) : "this.contacts is not initialized";
425 return Collections.unmodifiableList(this.contacts);
429 * Checks whether own contact is already added by checking all entries for
432 * @return Whether own contact is already added
435 public boolean isOwnContactAdded () {
437 this.getLogger().trace("CALLED!");
439 assert (this.contacts instanceof List) : "this.contacts is not initialized";
441 // Default is not added
442 boolean isAdded = false;
444 // Now get it back from address book, first get an iterator
445 Iterator<Contact> iterator = this.contacts.iterator();
448 while (iterator.hasNext()) {
450 Contact contact = iterator.next();
453 if (contact instanceof Contact) {
455 isAdded = contact.isOwnContact();
457 // Is this own contact?
466 this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded));
473 * Adds given contact to address book and flushes all entries to database
475 * @param contact Contact being added
476 * @todo Add check for book size
479 public void registerContact (final Contact contact) {
481 if (contact == null) {
483 throw new NullPointerException("contact is null");
486 // Check if contact is found
487 if (this.isContactAlreadyAdded(contact)) {
488 // Contact already added
489 // @todo Do something here
490 } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
491 // Own contact already added
492 // @todo Do something
496 /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size()));
498 // Add contact to internal list
499 this.addContact(contact);
508 * @return size of contact "book"
511 public final int size () {
512 assert (this.contacts instanceof List) : "this.contacts is not initialized";
513 return this.contacts.size();
517 * Fills the column names array with strings from bundle
519 private void fillColumnNamesFromBundle () {
520 assert (this.columnNames instanceof List) : "this.columnNames is not initialized";
523 this.getLogger().trace("CALLED!");
525 // First get an iterator from key set to iterate over
526 Iterator<String> iterator = this.getBundle().keySet().iterator();
528 // Then iterate over all
529 while (iterator.hasNext()) {
531 String key = iterator.next();
533 // Does the key start with ContactManager.columnName ?
534 if (key.startsWith("ContactManager.columnName")) {
535 // This is the wanted entry.
536 this.getLogger().debug(MessageFormat.format("key={0}", key));
539 this.columnNames.add(this.getBundle().getString(key));
544 this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount()));
548 * Flushes all entries by calling database backend
550 private void flush () {
552 this.getContactDatabase().flushAllContacts();
556 * A ContactWrapper instance
558 * @return the database
560 private ContactWrapper getContactDatabase () {
561 return this.contactDatabase;
565 * "Getter" for own contact instance or null if not found
567 * @return Contact instance or null
569 private Contact getOwnContact () {
570 assert (this.contacts instanceof List) : "this.contacts is not initialized";
572 // Now get it back from address book, first get an iterator
573 Iterator<Contact> iterator = this.contacts.iterator();
576 Contact contact = null;
578 // Search all contact
579 while (iterator.hasNext()) {
581 Contact next = iterator.next();
583 // Is this own contact?
584 if (next.isOwnContact()) {
592 // Return instance or null
597 * Checks whether given contact was found in "address book"
599 * @param checkContact Contact to be checked
600 * @return TRUE if found, FALSE if not found
602 private boolean isContactAlreadyAdded (final Contact checkContact) throws NullPointerException {
603 assert (this.contacts instanceof List) : "this.contacts is not initialized";
605 // Default is not found
606 boolean isFound = false;
609 //* NOISY-DEBUG: */ this.getLogger().debug("Checking '" + this.contacts.length + "' entries...");
610 // Now get it back from address book, first get an iterator
611 Iterator<Contact> iterator = this.contacts.iterator();
614 while (iterator.hasNext()) {
616 Contact contact = iterator.next();
619 //* NOISY-DEBUG: */ this.getLogger().debug("contact=" + contact + ",checkContent=" + checkContact);
621 if ((contact instanceof Contact) && ((contact.equals(checkContact)))) {
622 // Found matching entry