]> git.mxchange.org Git - jaddressbook-lib.git/blobdiff - Addressbook/src/org/mxchange/addressbook/manager/contact/ContactManager.java
Moved a lot classes and interfaces (generalized) to new jcore project + added a few...
[jaddressbook-lib.git] / Addressbook / src / org / mxchange / addressbook / manager / contact / ContactManager.java
index 80cffd3ce5eab8f2d54ea5d854fe29fb8907fc6b..4191f0c6d0b39d328cb93726d28d902252bbb8d2 100644 (file)
-/*\r
- * Copyright (C) 2015 Roland Haeder\r
- *\r
- * This program is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- */\r
-package org.mxchange.addressbook.manager.contact;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import org.mxchange.addressbook.client.Client;\r
-import org.mxchange.addressbook.contact.Contact;\r
-import org.mxchange.addressbook.contact.user.UserContact;\r
-import org.mxchange.addressbook.manager.BaseManager;\r
-\r
-/**\r
- * A manager for contacts\r
- *\r
- * @author Roland Haeder\r
- * @version 0.0\r
- * @since 0.0\r
- */\r
-public class ContactManager extends BaseManager implements ManageableContact {\r
-\r
-    /**\r
-     * All contacts\r
-     */\r
-    private final List<Contact> contacts;\r
-\r
-    /**\r
-     * @param maxContacts Maximum allowed contacts\r
-     * @param client Client instance to use\r
-     */\r
-    public ContactManager (final int maxContacts, final Client client) {\r
-       // Always call super constructor first\r
-       super();\r
-\r
-       // Init contacts\r
-       this.contacts = new ArrayList<>(maxContacts);\r
-\r
-       // Debug message\r
-       //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);\r
-\r
-       // Init client\r
-       this.setClient(client);\r
-    }\r
-\r
-    /**\r
-     * Adds given contact to address book\r
-     *\r
-     * @param contact Contact being added\r
-     * @todo Add check for book size\r
-     */\r
-    @Override\r
-    public void addContact (final Contact contact) {\r
-       // Check if contact is found\r
-       if (this.isContactAlreadyAdded(contact)) {\r
-           // Contact already added\r
-           // @todo Do something here\r
-       } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {\r
-           // Own contact already added\r
-           // @todo Do something\r
-       }\r
-\r
-       // Debug message\r
-       /* NOISY-DEBUG: */ this.getLogger().debug("Adding '" + contact.getSurname() + "' '" + contact.getFamilyName() + "' at pos '" + this.size () + "' ...");\r
-\r
-       // Add contact\r
-       this.contacts.add(contact);\r
-    }\r
-\r
-    /**\r
-     * Let the user add a new other address\r
-     */\r
-    @Override\r
-    public void addOtherAddress () {\r
-       throw new UnsupportedOperationException("Not supported yet.");\r
-    }\r
-\r
-    /**\r
-     * Let the user change other address\r
-     */\r
-    @Override\r
-    public void changeOtherAddress () {\r
-       throw new UnsupportedOperationException("Not supported yet.");\r
-    }\r
-\r
-    /**\r
-     * Allows the user to change his/her own data\r
-     */\r
-    @Override\r
-    public void changeOwnData () {\r
-       /*\r
-        * First check if the user has registered own contact, before that \r
-        * nothing can be changed.\r
-        */\r
-       if (!this.isOwnContactAdded()) {\r
-           // Not added\r
-           this.getClient().displayMessage("Sie haben noch nicht Ihre Daten eingegeben.");\r
-\r
-           // Skip any below code\r
-           return;\r
-       }\r
-\r
-       // Instance\r
-       Contact contact = this.getOwnContact();\r
-\r
-       // It must be found\r
-       assert(contact instanceof Contact);\r
-\r
-       // Display contact\r
-       contact.show(this.getClient());\r
-\r
-       // @TODO Unfinished\r
-       throw new UnsupportedOperationException("Method is not finished.");\r
-    }\r
-\r
-    /**\r
-     * Let the user delete other address\r
-     */\r
-    @Override\r
-    public void deleteOtherAddress () {\r
-       throw new UnsupportedOperationException("Not supported yet.");\r
-    }\r
-\r
-    /**\r
-     * Asks user for own data\r
-     */\r
-    @Override\r
-    public void enterOwnData () {\r
-       // First ask for gender\r
-       char gender = this.enterOwnGender();\r
-\r
-       // 2nd for surname\r
-       String surname = this.enterOwnSurname();\r
-       \r
-       // And 3rd for family name\r
-       String familyName = this.enterOwnFamilyName();\r
-\r
-       // Construct UserContact instance\r
-       Contact contact = new UserContact(gender, surname, familyName);\r
-\r
-       // Mark contact as own\r
-       contact.enableFlagOwnContact();\r
-\r
-       // Add it to contact "book"\r
-       this.addContact(contact);\r
-    }\r
-\r
-    /**\r
-     * Getter for size\r
-     *\r
-     * @return size of contact "book"\r
-     */\r
-    @Override\r
-    public int size () {\r
-       return this.contacts.size();\r
-    }\r
-\r
-    /**\r
-     * Asks the user for family name\r
-     * @return Family name of the user\r
-     */\r
-    private String enterOwnFamilyName () {\r
-       return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ");\r
-    }\r
-\r
-    /**\r
-     * Asks the user for gender, until a valid has been entered\r
-     * @return Gender of the user\r
-     */\r
-    private char enterOwnGender () {\r
-       return this.getClient().enterChar(new char[] {'M', 'F', 'C'}, "Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");\r
-    }\r
-\r
-    /**\r
-     * Asks the user for surname\r
-     * @return Surname of the user\r
-     */\r
-    private String enterOwnSurname () {\r
-       return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ");\r
-    }\r
-\r
-    /**\r
-     * "Getter" for own contact instance or null if not found\r
-     *\r
-     * @return Contact instance or null\r
-     */\r
-    private Contact getOwnContact () {\r
-       // Now get it back from address book, first get an iterator\r
-       Iterator<Contact> iterator = this.contacts.iterator();\r
-\r
-       // Init instance\r
-       Contact contact = null;\r
-\r
-       // Search all contact\r
-       while (iterator.hasNext()) {\r
-           // Get next instance\r
-           Contact next = iterator.next();\r
-\r
-           // Is this own contact?\r
-           if (next.isOwnContact()) {\r
-               // Found it\r
-               contact = next;\r
-               break;\r
-               \r
-           }\r
-       }\r
-\r
-       // Return instance or null\r
-       return contact;\r
-    }\r
-\r
-    /**\r
-     * Checks whether given contact was found in "address book"\r
-     *\r
-     * @param checkContact Contact to be checked\r
-     * @return TRUE if found, FALSE if not found\r
-     */\r
-    private boolean isContactAlreadyAdded (final Contact checkContact) throws NullPointerException {\r
-       // Default is not found\r
-       boolean isFound = false;\r
-\r
-       // Debug message\r
-       //* NOISY-DEBUG: */ this.getLogger().debug("Checking '" +  this.contacts.length + "' entries...");\r
-\r
-       // Now get it back from address book, first get an iterator\r
-       Iterator<Contact> iterator = this.contacts.iterator();\r
-\r
-       // Check entries\r
-       while (iterator.hasNext()) {\r
-           // Get next entry\r
-           Contact contact = iterator.next();\r
-\r
-           // Debug message\r
-           //* NOISY-DEBUG: */ this.getLogger().debug("contact=" + contact + ",checkContent=" + checkContact);\r
-\r
-           // Is it valid?\r
-           if ((contact instanceof Contact) && ((contact.equals(checkContact)))) {\r
-               // Found matching entry\r
-               isFound = true;\r
-               break;\r
-           }\r
-       }\r
-\r
-       // Return result\r
-       return isFound;\r
-    }\r
-\r
-    /**\r
-     * Checks whether own contact is already added by checking all entries for isOwnContact flag\r
-     * @return Whether own contact is already added\r
-     */\r
-    private boolean isOwnContactAdded () {\r
-       // Default is not added\r
-       boolean isAdded = false;\r
-\r
-       // Now get it back from address book, first get an iterator\r
-       Iterator<Contact> iterator = this.contacts.iterator();\r
-\r
-       // Check entries\r
-       while (iterator.hasNext()) {\r
-           // Get next entry\r
-           Contact contact = iterator.next();\r
-\r
-           // Is it valid?\r
-           if (contact instanceof Contact) {\r
-               // Get flag\r
-               isAdded = contact.isOwnContact();\r
-\r
-               // Is this own contact?\r
-               if (isAdded) {\r
-                   // Then abort loop\r
-                   break;\r
-               }\r
-           }\r
-       }\r
-       // Return result\r
-       return isAdded;\r
-    }\r
-}\r
+/*
+ * Copyright (C) 2015 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.addressbook.manager.contact;
+
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import org.mxchange.addressbook.client.AddressbookClient;
+import org.mxchange.addressbook.contact.Contact;
+import org.mxchange.addressbook.contact.Gender;
+import org.mxchange.addressbook.database.frontend.contact.ContactDatabaseFrontend;
+import org.mxchange.addressbook.database.frontend.contact.ContactFrontend;
+import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
+import org.mxchange.jcore.client.Client;
+import org.mxchange.jcore.exceptions.BadTokenException;
+import org.mxchange.jcore.exceptions.UnhandledUserChoiceException;
+import org.mxchange.jcore.manager.BaseManager;
+
+/**
+ * A manager for contacts, please note that this implementation loads the whole
+ * list into RAM.
+ *
+ * @author Roland Haeder
+ * @version 0.0
+ */
+public class ContactManager extends BaseManager implements ManageableContact {
+
+       /**
+        * Column name list
+        */
+       private final List<String> columnNames;
+
+       /**
+        * Translated column name list
+        */
+       private final List<String> translatedColumnNames;
+
+       /**
+        * A ContactFrontend instance
+        */
+       private final ContactFrontend contactDatabase;
+
+       /**
+        * Constructor which accepts maxContacts for maximum (initial) contacts and
+        * a client instance.
+        *
+        * @param client Client instance to use
+        */
+       public ContactManager (final Client client) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("client={1} - CALLED!", client)); //NOI18N
+
+               // Make sure all parameters are set correctly
+               if (client == null) {
+                       // Abort here
+                       throw new NullPointerException("client is null"); //NOI18N
+               }
+
+               // Set client instance
+               this.setClient(client);
+
+               // Init database connection
+               this.contactDatabase = new ContactDatabaseFrontend(this);
+
+               // Initialize list
+               this.columnNames = new ArrayList<>(15);
+               this.translatedColumnNames = new ArrayList<>(15);
+
+               // And fill it
+               this.fillColumnNamesFromBundle();
+
+               // Debug message
+               //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);
+       }
+
+       /**
+        * Adds given Contact instance to list
+        *
+        * @param contact Contact instance to add
+        */
+       @Override
+       public void addContact (final Contact contact)  throws ContactAlreadyAddedException {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N
+
+               // Contact instance must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Add it
+               this.getContactDatabase().addContact(contact);
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user add a new other address
+        */
+       @Override
+       public void doAddOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Let the user change address data
+        *
+        * @param contact Instance to change data
+        */
+       @Override
+       public void doChangeAddressData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display it again
+               client.displayAddressBox(contact);
+
+               // Is it own data?
+               if (contact.isOwnContact()) {
+                       // Deligate to client
+                       client.doChangeOwnAddressData(contact);
+               } else {
+                       // Other contact's address data to change
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user change "name data"
+        *
+        * @param contact Instance to change data
+        */
+       @Override
+       public void doChangeNameData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display them again
+               client.displayNameBox(contact);
+
+               // Is this own data?
+               if (contact.isOwnContact()) {
+                       // Re-ask own data
+                       client.doChangeOwnNameData(contact);
+               } else {
+                       // Then re-ask them ...
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user change other address
+        */
+       @Override
+       public void doChangeOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Let the user change other data
+        *
+        * @param contact Instance to change data
+        * @todo Didn't handle birthday
+        */
+       @Override
+       public void doChangeOtherData (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Contact must not be null
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // First display them again
+               client.displayOtherDataBox(contact);
+
+               // Is this own data?
+               if (contact.isOwnContact()) {
+                       // Re-ask own data
+                       client.doChangeOwnOtherData(contact);
+               } else {
+                       // Then re-ask them ...
+                       throw new UnsupportedOperationException("Changing contact entries not finished."); //NOI18N
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Allows the user to change his/her own data
+        */
+       @Override
+       public void doChangeOwnData () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               /*
+                * First check if the user has registered own contact, before that
+                * nothing can be changed.
+                */
+               if (!this.isOwnContactAdded()) {
+                       // Not added
+                       this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben."); //NOI18N
+
+                       // Skip any below code
+                       return;
+               }
+
+               // Instance
+               Contact contact = this.getOwnContact();
+
+               // It must be found
+               assert (contact instanceof Contact);
+
+               // Display contact
+               contact.show(this.getClient());
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               try {
+                       // Ask user what to change
+                       client.userChooseChangeContactData(contact);
+               } catch (final UnhandledUserChoiceException ex) {
+                       this.getLogger().catching(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Let the user delete other address
+        */
+       @Override
+       public void doDeleteOtherAddress () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Asks user for own data
+        */
+       @Override
+       public void doEnterOwnData () throws ContactAlreadyAddedException {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Is own contact already added?
+               if (this.isOwnContactAdded()) {
+                       // Don't continue here
+                       throw new ContactAlreadyAddedException();
+               }
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               // Deligate this call to the client
+               Contact contact = client.doEnterOwnData();
+
+               // Is it set?
+               if (contact instanceof Contact) {
+                       // Add it to contact "book"
+                       this.registerContact(contact);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       @Override
+       public void doListContacts () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       @Override
+       public void doSearchContacts () {
+               throw new UnsupportedOperationException("Not supported yet."); //NOI18N
+       }
+
+       /**
+        * Shuts down this contact manager
+        */
+       @Override
+       public void doShutdown () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Shut down the database layer
+               this.getContactDatabase().doShutdown();
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Asks the user for his/her cellphone number
+        *
+        * @return User's cellphone number
+        */
+       @Override
+       public String enterOwnCellNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
+       }
+
+       /**
+        * Asks the user for his/her city's name
+        *
+        * @return City's name of the user
+        */
+       @Override
+       public String enterOwnCity () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
+       }
+
+       /**
+        * Asks the user for his/her city's name
+        *
+        * @return City's name of the user
+        */
+       @Override
+       public String enterOwnComment () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
+       }
+
+       /**
+        * Asks the user for his/her company name
+        *
+        * @return User's company name
+        */
+       @Override
+       public String enterOwnCompanyName () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
+       }
+
+       /**
+        * Asks user for his/her own country code
+        *
+        * @return User's own country code
+        */
+       @Override
+       public String enterOwnCountryCode () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
+       }
+
+       /**
+        * Asks user for his/her own country code
+        *
+        * @return User's own country code
+        */
+       @Override
+       public String enterOwnEmailAddress () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
+       }
+
+       /**
+        * Asks the user for family name
+        *
+        * @return Family name of the user
+        */
+       @Override
+       public String enterOwnFamilyName () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
+       }
+
+       /**
+        * Asks the user for family name
+        *
+        * @return Family name of the user
+        */
+       @Override
+       public String enterOwnFaxNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
+       }
+
+       /**
+        * Asks the user for gender, until a valid has been entered
+        *
+        * @return Gender of the user
+        */
+       @Override
+       public Gender enterOwnGender () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterGender("Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
+       }
+
+       /**
+        * Asks the user for phone number
+        *
+        * @return Phone number of the user
+        */
+       @Override
+       public String enterOwnPhoneNumber () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
+       }
+
+       /**
+        * Asks the user for own street (including number)
+        *
+        * @return Own street an number
+        */
+       @Override
+       public String enterOwnStreet () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
+       }
+
+       /**
+        * Asks the user for surname
+        *
+        * @return Surname of the user
+        */
+       @Override
+       public String enterOwnSurname () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
+       }
+
+       /**
+        * Asks the user for own ZIP code
+        *
+        * @return ZIP code
+        */
+       @Override
+       public int enterOwnZipCode () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Get and cast client instance
+               AddressbookClient client = (AddressbookClient) this.getClient();
+
+               return client.enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
+       }
+
+       @Override
+       public final int getColumnCount () {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+
+               return this.columnNames.size();
+       }
+
+       /**
+        * Getter for column name at given index.
+        *
+        * @param columnIndex Column index
+        * @return Database column name
+        */
+       @Override
+       public String getColumnName (final int columnIndex) {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+
+               // Get column name at index
+               return this.columnNames.get(columnIndex);
+       }
+
+       /**
+        * Getter for translated column name at given index.
+        *
+        * @param columnIndex Column index
+        * @return Human-readable column name
+        */
+       @Override
+       public String getTranslatedColumnName (final int columnIndex) {
+               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
+
+               // Get column name at index
+               return this.translatedColumnNames.get(columnIndex);
+       }
+
+       /**
+        * Somewhat "getter" for value from given row and column index
+        *
+        * @param rowIndex Row index
+        * @param columnIndex Column index
+        * @return Value from given row/column
+        */
+       @Override
+       public Object getValueFromRowColumn (final int rowIndex, final int columnIndex) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("rowIndex={0},columnIndex={1} CALLED!", rowIndex, columnIndex));
+
+               // Then get specific row from database which is a Contact instance
+               Contact contact = this.getContactDatabase().readSingleContact(rowIndex);
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("contact={0}", contact));
+
+               // It may return null
+               if (contact == null) {
+                       // Nothing found
+                       this.getLogger().warn("contact is null - returning null ...");
+                       return null;
+               }
+
+               // Convert column index -> name
+               String columnName = this.getColumnName(columnIndex);
+
+               // Debug message
+               this.getLogger().debug(MessageFormat.format("columnName={0}", columnName));
+
+               // Now get that column
+               Object value = contact.getValueFromColumn(columnName);
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value));
+
+               // Return it
+               return value;
+       }
+
+       /**
+        * Checks whether own contact is already added by checking all entries for
+        * isOwnContact flag
+        *
+        * @return Whether own contact is already added
+        */
+       @Override
+       public boolean isOwnContactAdded () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Init variable
+               boolean isAdded = false;
+
+               try {
+                       // Deligate this call to frontend
+                       isAdded = this.getContactDatabase().isOwnContactFound();
+               } catch (final SQLException ex) {
+                       // Something bad happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("isAdded={0} : EXIT!", isAdded)); //NOI18N
+
+               // Return result
+               return isAdded;
+       }
+
+       /**
+        * Adds given contact to address book and flushes all entries to database
+        *
+        * @param contact Contact being added
+        * @todo Add check for book size
+        */
+       @Override
+       public void registerContact (final Contact contact) {
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N
+
+               // Sanity check
+               if (contact == null) {
+                       // Abort here
+                       throw new NullPointerException("contact is null"); //NOI18N
+               }
+
+               // Debug message
+               /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size())); //NOI18N
+               try {
+                       // Check if contact is found
+                       if (this.getContactDatabase().isContactFound(contact)) {
+                               // Contact already added
+                               // @todo Do something here
+                       } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
+                               // Own contact already added
+                               // @todo Do something
+                       }
+
+                       // Add contact to internal list
+                       this.addContact(contact);
+               } catch (final ContactAlreadyAddedException ex) {
+                       // Abort here
+                       this.abortProgramWithException(ex);
+               } catch (final BadTokenException ex) {
+                       // Abort here
+                       this.abortProgramWithException(ex);
+               }
+
+               // Trace message
+               this.getLogger().trace("EXIT!"); //NOI18N
+       }
+
+       /**
+        * Getter for size
+        *
+        * @return size of contact "book"
+        */
+       @Override
+       public final int size () {
+               // Init size
+               int size = -1;
+
+               try {
+                       size = this.getContactDatabase().getContactsCount();
+               } catch (final SQLException ex) {
+                       // Something happened
+                       this.abortProgramWithException(ex);
+               }
+
+               // Return amount
+               return size;
+       }
+
+       /**
+        * Fills the column names array with strings from bundle
+        */
+       private void fillColumnNamesFromBundle () {
+               assert (this.columnNames instanceof List) : "this.columnNames is not initialized"; //NOI18N
+               assert (this.translatedColumnNames instanceof List) : "this.translatedColumnNames is not initialized"; //NOI18N
+
+               // Debug message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // First get an iterator from key set to iterate over
+               Iterator<String> iterator = this.getBundle().keySet().iterator();
+
+               // Then iterate over all
+               while (iterator.hasNext()) {
+                       // Get next element
+                       String key = iterator.next();
+
+                       // Does the key start with ContactManager.columnName ?
+                       if (key.startsWith("ContactManager.columnName")) { //NOI18N
+                               // This is the wanted entry.
+                               this.getLogger().debug(MessageFormat.format("key={0}", key)); //NOI18N
+
+                               // Convert string to array based on delimiter '.'
+                               String[] tokens = this.getArrayFromString(key, ".", 4);
+
+                               // Token array must contain 4 elements (ContactManager.columnName.foo.text)
+                               assert(tokens.length == 4) : MessageFormat.format("Array tokens contains not 4 elements: {0}", Arrays.toString(tokens));
+
+                               // Get pre-last element
+                               String columnName = tokens[tokens.length - 2];
+
+                               // Debug message
+                               this.getLogger().debug(MessageFormat.format("columnName={0} - adding ...", columnName));
+
+                               // So add it
+                               this.columnNames.add(columnName);
+                               this.translatedColumnNames.add(this.getBundle().getString(key));
+                       }
+               }
+
+               // Debug message
+               this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount())); //NOI18N
+       }
+
+       /**
+        * A ContactFrontend instance
+        *
+        * @return the database
+        */
+       private ContactFrontend getContactDatabase () {
+               return this.contactDatabase;
+       }
+
+       /**
+        * "Getter" for own contact instance or null if not found
+        *
+        * @return Contact instance or null
+        */
+       private Contact getOwnContact () {
+               // Trace message
+               this.getLogger().trace("CALLED!"); //NOI18N
+
+               // Deligate this call to database frontend
+               Contact contact = this.getContactDatabase().getOwnContact();
+
+               // Trace message
+               this.getLogger().trace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N
+
+               // Return instance or null
+               return contact;
+       }
+}