X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2Forg%2Fmxchange%2Faddressbook%2Fclient%2Fconsole%2FConsoleClient.java;h=5deface1b526c4c01d336563c8f9adfc89f16f01;hb=16624bae7209070f842d14159924d85a320c362d;hp=b97600e42d1643e88202ac0868b2f37454524a39;hpb=31fce847a127086ff40fa9b4edde6137a8ef7e3f;p=jfinancials-swing.git
diff --git a/src/org/mxchange/addressbook/client/console/ConsoleClient.java b/src/org/mxchange/addressbook/client/console/ConsoleClient.java
index b97600e..5deface 100644
--- a/src/org/mxchange/addressbook/client/console/ConsoleClient.java
+++ b/src/org/mxchange/addressbook/client/console/ConsoleClient.java
@@ -1,505 +1,673 @@
-/*
- * 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
+ * @author Roland Haeder + */ +public class ConsoleClient extends BaseAddressbookClient implements AddressbookClient { + + /** + * Scanner instance for reading data from console input + */ + private final Scanner scanner; + + /** + * Parameterless constructor + *
+ * @param application An instance of an Application class + */ + public ConsoleClient (final Application application) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("application={0} - CALLED!", application)); //NOI18N + + // Set application instance + this.setApplication(application); + + // Init scanner instance + this.scanner = new Scanner(System.in, "UTF-8"); //NOI18N + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void displayAddressBox (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Simple display ... + this.outputMessage(MessageFormat.format("Strasse, PLZ Ort, Land: {0}\n{1} {2}\n{3}", contact.getStreet(), contact.getZipCode(), contact.getCity(), contact.getCountryCode())); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void displayNameBox (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Get translated gender as the user may want to see "Mr.", "Mrs." + String gender = GenderUtils.getTranslatedGender(contact); + + // Get company name + String companyName = contact.getCompanyName(); + + // If it is empty/null, then assume private contact + if ((null == companyName) || (companyName.isEmpty())) { + // Now put all together: gender, surname, family name + // TODO Use mask + this.outputMessage(MessageFormat.format("Anrede, Vorname, Name: {0} {1} {2}", gender, contact.getFirstName(), contact.getFamilyName())); + } else { + // Company contact + this.outputMessage(MessageFormat.format("Firma: {0}\nAnsprechpartner: {1} {2} {3}", companyName, gender, contact.getFirstName(), contact.getFamilyName())); + } + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void displayOtherDataBox (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Cellphone and such ... + this.outputMessage(MessageFormat.format("Telefonnumer: {0}\nFaxnummer: {1}\nHandy: {2}\nKommentar:\n{3}", contact.getPhoneNumber(), contact.getFaxNumber(), contact.getCellphoneNumber(), contact.getComment())); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnAddressData (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // Own street and number + String streetNumber = manager.enterOwnStreet(); + + // Get zip code + Long zipCode = (long) manager.enterOwnZipCode(); + + // Get city name + String city = manager.enterOwnCity(); + + // Get country code + String countryCode = manager.enterOwnCountryCode(); + + // Update address data + contact.setStreet(streetNumber); + contact.setZipCode(zipCode); + contact.setCity(city); + contact.setCountryCode(countryCode); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnNameData (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // Gender: + Gender gender = manager.enterOwnGender(); + + // Surname + String firstName = manager.enterOwnFirstName(); + + // Family name + String familyName = manager.enterOwnFamilyName(); + + // And company + String companyName = manager.enterOwnCompanyName(); + + // Update contact instance + contact.setGender(gender); + contact.setFirstName(firstName); + contact.setFamilyName(familyName); + contact.setCompanyName(companyName); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void doChangeOwnOtherData (final Contact contact) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - CALLED!", contact)); //NOI18N + + // Is it null? + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Make sure it is own contact + if (!contact.isOwnContact()) { + // Not own contact + throw new IllegalArgumentException("Contact is not own data."); //NOI18N + } + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // Phone number + String phoneNumber = manager.enterOwnPhoneNumber(); + + // Phone number + String cellphonePhoneNumber = manager.enterOwnCellNumber(); + + // Fax number + String faxNumber = manager.enterOwnFaxNumber(); + + // Email address + String email = manager.enterOwnEmailAddress(); + + // Comment + String comment = manager.enterOwnComment(); + + // Update contact instance + contact.setPhoneNumber(phoneNumber); + contact.setCellphoneNumber(cellphonePhoneNumber); + contact.setFaxNumber(faxNumber); + contact.setEmailAddress(email); + contact.setComment(comment); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public Contact doEnterOwnData () { + // Trace message + this.getLogger().logTrace("CALLED!"); //NOI18N + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // First ask for gender + Gender gender = manager.enterOwnGender(); + + // 2nd for first name + String firstName = manager.enterOwnFirstName(); + + // And 3rd for family name + String familyName = manager.enterOwnFamilyName(); + + // Company name ... + String companyName = manager.enterOwnCompanyName(); + + // Construct UserContact instance + Contact contact = new UserContact(gender, firstName, familyName, companyName); + + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} - EXIT!", contact)); //NOI18N + + // And return object + return contact; + } + + @Override + public void doShutdown () throws SQLException, IOException { + // Trace message + this.getLogger().logTrace("CALLED!"); //NOI18N + + // Parent call + super.doShutdown(); + + // TODO Add other shutdown stuff + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void doUserMenuChoice () throws UnhandledUserChoiceException { + // Trace message + this.getLogger().logTrace("CALLED!"); //NOI18N + + // Get all access keys from menu + char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.getMenus(), this.getCurrentMenu()); + + // Output textural message and ask for a char as input + char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Programm beenden): "); + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // Try it! + try { + // TODO Rewrite this ugly switch() block + switch (choice) { + case '1': + try { + // Enter/add own data + manager.doEnterOwnData(); + } catch (final ContactAlreadyAddedException ex) { + // Already added + this.outputMessage("Sie haben bereits Ihre eigenen Daten eingegeben."); + } + break; + + case '2': // Change own data + manager.doChangeOwnData(); + break; + + case '3': // Add new addess + manager.doAddOtherAddress(); + break; + + case '4': // List contacts + manager.doListContacts(); + break; + + case '5': // Search addresses + manager.doSearchContacts(); + break; + + case '6': // Change other addess + manager.doChangeOtherAddress(); + break; + + case '7': // Delete other address + manager.doDeleteOtherAddress(); + break; + + case '0': + try { + // Program exit + this.getApplication().doShutdown(); + } catch (final SQLException | IOException ex) { + this.abortProgramWithException(ex); + } + break; + + default: + // TODO throw own exception + throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N + } + } catch (final IOException | SQLException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + // Something bad happened + this.abortProgramWithException(ex); + } + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public char enterChar (final char[] validChars, final String message) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("validChars={0},message={1} - CALLED!", Arrays.toString(validChars), message)); //NOI18N + + // The validChars must not null be null and filled with at least one char + if (null == validChars) { + // Is null + throw new NullPointerException("validChars is null"); //NOI18N + } else if (validChars.length == 0) { + // Is not filled + throw new IllegalArgumentException("validChars is not filled."); //NOI18N + } + + char input = 0; + + // Sort array, else binarySearch() won't work + Arrays.sort(validChars); + + // Keep asking until valid char has been entered + while (Arrays.binarySearch(validChars, input) < 0) { + // Output message + System.out.print(message); + + // Read char + input = this.readChar(); + } + + // Trace message + this.getLogger().logTrace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return read char + return input; + } + + @Override + public Gender enterGender (final String message) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("message={0} - CALLED!", message)); //NOI18N + + // Get valid chars + char[] validChars = Gender.validChars(); + + // Debug message + //* NOISY-DEBUG: */ System.out.println(validChars); + // Call inner method + char gender = this.enterChar(validChars, message); + + // Now get a Gender instance back + Gender g = Gender.fromChar(gender); + + // g must not be null + assert (g instanceof Gender) : "g is not set."; //NOI18N + + // Trace message + this.getLogger().logTrace(MessageFormat.format("g={0} - EXIT!", g)); //NOI18N + + // Return it + return g; + } + + @Override + public int enterInt (final int minimum, final int maximum, final String message) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("minimum={0},maximum={1},message={2} - CALLED!", minimum, maximum, message)); //NOI18N + + // Minimum should not be below zero + assert (minimum >= 0) : MessageFormat.format("minimum={0} is below zero", minimum); //NOI18N + assert (maximum > minimum) : MessageFormat.format("maximum {0} is smaller than minimum {1}", maximum, minimum); //NOI18N + + // Init input + int input = -1; + + while ((input < minimum) || (input > maximum)) { + // Output message + System.out.print(message); + + // Read integer from user + input = this.readInt(); + } + + // Trace message + this.getLogger().logTrace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return it + return input; + } + + @Override + public String enterString (final int minLength, final int maxLength, final String message, final boolean allowEmpty) { + // Trace message + this.getLogger().logTrace(MessageFormat.format("minLength={0},maxLength={1},message={2}allowEmpty={3} - CALLED!", minLength, maxLength, message, allowEmpty)); //NOI18N + + // Check on length, e.g. country codes are excactly 2 chars long + assert (maxLength >= minLength); + + // Init input + String input = null; + + // Check if it is to short or to long + while (((null == input) || ((input.length() < minLength) && (!allowEmpty))) || ((input.length() > 0) && (input.length() < minLength) && (allowEmpty)) || ((input instanceof String) && (input.length() > maxLength))) { + // Output message + System.out.print(message); + + // Read line + input = this.readString(); + } + + // Trace message + this.getLogger().logTrace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N + + // Return it + return input; + } + + @Override + public SelectableMenuItem getMenuItem (final char accessKey, final String text) { + // Return a new console menu item + return new ConsoleMenuItem(accessKey, text); + } + + @Override + public void init () { + // Trace message + this.getLogger().logTrace("CALLED!"); //NOI18N + + // Init contact manager here + try { + this.initContactManager(); + } catch (final SQLException ex) { + // End here + this.abortProgramWithException(ex); + } + + // Fill menu map + this.fillMenuMap(); + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + @Override + public void outputMessage (final String message) { + System.out.println(message); + } + + @Override + public void showCurrentMenu () { + this.showMenu(this.getCurrentMenu()); + } + + @Override + public void showEntry (final SelectableMenuItem item) { + // Access key then text + this.outputMessage(MessageFormat.format("[{0}] {1}", item.getAccessKey(), item.getText())); //NOI18N + } + + @Override + public void showWelcome () { + this.outputMessage(MessageFormat.format("Welcome to {0}", AddressbookApplication.printableTitle())); //NOI18N + this.outputMessage(""); //NOI18N + this.outputMessage("Copyright(c) 2015 by Roland Haeder, this is free software"); //NOI18N + + // Debug message + this.getLogger().logDebug("Intro shown to user"); //NOI18N + } + + @Override + public void userChooseChangeContactData (final Contact contact) throws UnhandledUserChoiceException { + // Trace message + this.getLogger().logTrace(MessageFormat.format("contact={0} CALLED!", contact)); //NOI18N + + // Contact must not be null + if (null == contact) { + // Abort here + throw new NullPointerException("contact is null"); //NOI18N + } + + // Ask the user for editing [name], [a]ddress or [other] data + char choice = this.enterChar(new char[] {'n', 'a', 'o', 'x'}, "Welchen Daten möchten Sie ändern? (n=Namensdaten, a=Anschriftsdaten, o=Andere, x=Zurück zur Hauptauswahl) "); + + // Get manager and cast it + ManageableContactAddressbook manager = (ManageableContactAddressbook) this.getManager(); + + // TODO Get rid of this ugly switch block, too + switch (choice) { + case 'n': // Name data + manager.doChangeNameData(contact); + break; + + case 'a': // Address data + manager.doChangeAddressData(contact); + break; + + case 'o': // Other data + manager.doChangeOtherData(contact); + break; + + case 'x': // Exit this menu + // Ignored as it should go back + break; + + default: + // TODO throw own exception + throw new UnhandledUserChoiceException(MessageFormat.format("Choice '{0}' not handled yet.", choice)); //NOI18N + } + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } + + /** + * Reads one character + *
+ * @return A single character + */ + private char readChar () { + // Read line + String input = this.readString(); + + // Debug message + this.getLogger().logDebug(MessageFormat.format("input={0}", input)); //NOI18N + + // This must be only one character + if (input.length() != 1) { + // Return zero + return 0; + } + + // Get char from first (and only) position + return input.charAt(0); + } + + /** + * Reads an integer (int) from user + *
+ * @return An integer number + */ + private int readInt () { + // First read a string + String input = this.readString(); + + // Debug message + this.getLogger().logDebug(MessageFormat.format("input={0}", input)); //NOI18N + + // Init number with invalid value + int num = -1; + + // Parse number, this can be risky + try { + num = Integer.parseInt(input); + } catch (final NumberFormatException e) { + this.outputMessage("Bitte geben Sie nur Zahlen ein!"); + this.getLogger().logWarning(MessageFormat.format("No numbers-only entered. input={0},message={1}", input, e.getMessage())); //NOI18N + } + + // Trace message + this.getLogger().logTrace(MessageFormat.format("num={0} - EXIT!", num)); //NOI18N + + // Return read number + return num; + } + + /** + * Reads a string from a scanner until RETURN is pressed + *
+ * @return Read string from scanner + */ + private String readString () { + return this.scanner.nextLine(); + } + + @Override + protected final void fillMenuMap () { + // Trace message + this.getLogger().logTrace("CALLED!"); //NOI18N + + // Initialize first (main) menu + Menu menu = new ConsoleMenu("main", this); //NOI18N + + // Add it + this.getMenus().put("main", menu); //NOI18N + + // Trace message + this.getLogger().logTrace("EXIT!"); //NOI18N + } +}