]> git.mxchange.org Git - jaddressbook-lib.git/blob - Addressbook/src/org/mxchange/addressbook/client/console/ConsoleClient.java
Added show() method and in client a simple, textural display
[jaddressbook-lib.git] / Addressbook / src / org / mxchange / addressbook / client / console / ConsoleClient.java
1 /*\r
2  * Copyright (C) 2015 Roland Haeder\r
3  *\r
4  * This program is free software: you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation, either version 3 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License\r
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
16  */\r
17 package org.mxchange.addressbook.client.console;\r
18 \r
19 import java.util.Arrays;\r
20 import java.util.HashMap;\r
21 import java.util.Map;\r
22 import java.util.Scanner;\r
23 import org.mxchange.addressbook.application.AddressbookApplication;\r
24 import org.mxchange.addressbook.application.Application;\r
25 import org.mxchange.addressbook.client.BaseClient;\r
26 import org.mxchange.addressbook.client.Client;\r
27 import org.mxchange.addressbook.contact.Contact;\r
28 import org.mxchange.addressbook.menu.Menu;\r
29 import org.mxchange.addressbook.menu.MenuTools;\r
30 import org.mxchange.addressbook.menu.console.ConsoleMenu;\r
31 import org.mxchange.addressbook.menu.item.SelectableMenuItem;\r
32 import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem;\r
33 \r
34 /**\r
35  * A client for the console\r
36  *\r
37  * @author Roland Haeder\r
38  */\r
39 public class ConsoleClient extends BaseClient implements Client {\r
40     /**\r
41      * Menu system\r
42      */\r
43     private final Map<String, Menu> menus;\r
44 \r
45     /**\r
46      * Scanner instance for reading data from console input\r
47      */\r
48     private final Scanner scanner;\r
49 \r
50     /**\r
51      * Parameterless constructor\r
52      * @param application An instance of an Application class\r
53      */\r
54     public ConsoleClient (final Application application) {\r
55         super();\r
56 \r
57         // Set application instance\r
58         this.setApplication(application);\r
59 \r
60         // Init contact manager here\r
61         this.initContactManager(this);\r
62 \r
63         // Init scanner instance\r
64         this.scanner = new Scanner(System.in);\r
65 \r
66         // Init menu map\r
67         this.menus = new HashMap<>(10);\r
68 \r
69         // Fill menu map\r
70         this.fillConsoleMenuMap();\r
71     }\r
72 \r
73     /**\r
74      * Displays a textual address "box" of given contact\r
75      *\r
76      * @param contact Contact to show address for\r
77      * @todo Use mask\r
78      */\r
79     @Override\r
80     public void displayAddressBox (final Contact contact) {\r
81         // Simple display ...\r
82         // @todo Use mask\r
83         this.displayMessage("Strasse, PLZ Ort, Land: " + contact.getStreet() + "\n" + contact.getZipCode() + " " + contact.getCity() +  "\n" + contact.getCountryCode());\r
84     }\r
85 \r
86     /**\r
87      * Displays textural message to the user\r
88      * @param message \r
89      */\r
90     @Override\r
91     public void displayMessage (final String message) {\r
92         System.out.println(message);\r
93     }\r
94 \r
95     /**\r
96      * Displays a textual name "box" of given contact\r
97      *\r
98      * @param contact Contact to show name for\r
99      */\r
100     @Override\r
101     public void displayNameBox (final Contact contact) {\r
102         // Get translated gender as the user may want to see "Mr.", "Mrs."\r
103         String gender = contact.getTranslatedGender();\r
104 \r
105         // Get company name\r
106         String companyName = contact.getCompanyName();\r
107 \r
108         // If it is empty/null, then assume private contact\r
109         if ((companyName == null) || (companyName.isEmpty())) {\r
110             // Now put all together: gender, surname, family name\r
111             // @todo Use mask\r
112             this.displayMessage("Anrede, Vorname, Name: " + gender + " " + contact.getSurname() + " " + contact.getFamilyName());\r
113         } else {\r
114             // Company contact\r
115             this.displayMessage("Firma: " + companyName + "\nAnsprechpartner: " + gender + " " + contact.getSurname() + " " + contact.getFamilyName());\r
116         }\r
117     }\r
118 \r
119     /**\r
120      * Displays a textual other data "box" of given contact\r
121      *\r
122      * @param contact Contact to show other data for\r
123      */\r
124     @Override\r
125     public void displayOtherDataBox (final Contact contact) {\r
126         // Cellphone and such ...\r
127         this.displayMessage("Telefonnumer: " + contact.getPhoneNumber() + "\nFaxnummer: " + contact.getFaxNumber() + "\nHandy: " + contact.getCellphoneNumber() + "\nKommentar:\n" + contact.getComment());\r
128     }\r
129 \r
130     @Override\r
131     public void doUserChoice () throws Exception {\r
132         // Get all access keys from menu\r
133         char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.menus, this.getCurrentMenu());\r
134 \r
135         // Output textural message and ask for a char as input\r
136         char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Beenden/Zurück in's vorherhige Menü): ");\r
137 \r
138         // @TODO Rewrite this ugly switch() block\r
139         switch (choice) {\r
140             case '1': // Enter/add own data\r
141                 this.getContactManager().enterOwnData();\r
142                 break;\r
143         \r
144             case '2': // Change own data\r
145                 this.getContactManager().changeOwnData();\r
146                 break;\r
147         \r
148             case '3': // Add new addess\r
149                 this.getContactManager().addOtherAddress();\r
150                 break;\r
151         \r
152             case '4': // Change other addess\r
153                 this.getContactManager().changeOtherAddress();\r
154                 break;\r
155         \r
156             case '5': // Delete other address\r
157                 this.getContactManager().deleteOtherAddress();\r
158                 break;\r
159 \r
160             case '0': // Program exit\r
161                 this.disableIsRunning();\r
162                 break;\r
163         \r
164             default:\r
165                 // @TODO throw on exception\r
166                 throw new Exception("choice " + choice + " invalid");\r
167         }\r
168     }\r
169 \r
170     /**\r
171      * Asks the the user to enter a single character which must match validChars\r
172      * @param   validChars  Valid chars that are accepted\r
173      * @param   message     Message to user\r
174      * @return  Allowed character\r
175      */\r
176     @Override\r
177     public char enterChar (final char[] validChars, final String message) {\r
178         char input = 0;\r
179 \r
180         // Sort array, else binarySearch() won't work\r
181         Arrays.sort(validChars);\r
182 \r
183         // Keep asking until valid char has been entered\r
184         while (Arrays.binarySearch(validChars, input) < 0) {\r
185             // Output message\r
186             System.out.print(message);\r
187 \r
188             // Read char\r
189             input = this.readChar();\r
190         }\r
191 \r
192         // Return read char\r
193         return input;\r
194     }\r
195 \r
196     /**\r
197      * Reads a string of minimum and maximum length from the user\r
198      * @param minLength Minimum length of the string to read\r
199      * @param maxLength Maximum length of the string to read\r
200      * @param message   Message to user\r
201      * @return \r
202      */\r
203     @Override\r
204     public String enterString (final int minLength, final int maxLength, final String message) {\r
205         // Init input\r
206         String input = null;\r
207 \r
208         // Check if it is to short or to long\r
209         while ((input == null) || (input.length() < minLength) || (input.length() > maxLength)) {\r
210             // Output message\r
211             System.out.print(message);\r
212 \r
213             // Read line\r
214             input = this.readString();\r
215         }\r
216 \r
217         // Return it\r
218         return input;\r
219     }\r
220 \r
221     /**\r
222      * Returns a console menu item\r
223      * \r
224      * @param accessKey Key to access the menu\r
225      * @param text Text to show to user\r
226      * @return A SelectableMenuItem\r
227      * @todo Make sure the access key is unique\r
228      */\r
229     @Override\r
230     public SelectableMenuItem getMenuItem (final char accessKey, final String text) {\r
231         // Return a new console menu item\r
232         return new ConsoleMenuItem(accessKey,text);\r
233     }\r
234 \r
235     /**\r
236      * Shows textural menu on console\r
237      */\r
238     @Override\r
239     public void showCurrentMenu () {\r
240         this.showMenu(this.getCurrentMenu());\r
241     }\r
242 \r
243     @Override\r
244     public void showEntry (final SelectableMenuItem item) {\r
245         // Access key then text\r
246         this.displayMessage("[" + item.getAccessKey() + "] " + item.getText());\r
247     }\r
248 \r
249     /**\r
250      * Shows a textural message to the user\r
251      */\r
252     @Override\r
253     public void showWelcome () {\r
254          this.displayMessage("Welcome to " + AddressbookApplication.APP_TITLE + " v" + AddressbookApplication.APP_VERSION);\r
255          this.displayMessage("");\r
256          this.displayMessage("Copyright(c) 2015 by Roland Haeder, this is free software");\r
257          \r
258          // Debug message\r
259          this.getLogger().debug("Intro shown to user");\r
260      }\r
261 \r
262     /**\r
263      * Fills menu map with menu entries\r
264      */\r
265     private void fillConsoleMenuMap () {\r
266         // Initialize first (main) menu\r
267         Menu menu = new ConsoleMenu("main", this);\r
268 \r
269         // Add it\r
270         this.menus.put("main", menu);\r
271     }\r
272 \r
273     /**\r
274      * "Getter" for given menu type\r
275      * \r
276      * @param menuType Menu type instance to return\r
277      * @return Menu or null if not found\r
278      */\r
279     private Menu getMenu (final String menuType) {\r
280         // Default is not found\r
281         Menu menu = null;\r
282 \r
283         // Check array\r
284         if (this.menus.containsKey(menuType)) {\r
285             // Found!\r
286             menu = this.menus.get(menuType);\r
287         }\r
288         \r
289         // Return it\r
290         return menu;\r
291     }\r
292 \r
293     /**\r
294      * Reads one character\r
295      * @return \r
296      */\r
297     private char readChar () {\r
298         // Read line\r
299         String input = this.scanner.nextLine();\r
300 \r
301         // This must be only one character\r
302         if (input.length() != 1) {\r
303             // Return zero\r
304             return 0;\r
305         }\r
306 \r
307         // Get char from first (and only) position\r
308         return input.charAt(0);\r
309     }\r
310 \r
311     /**\r
312      * Reads a string from a scanner until RETURN is pressed\r
313      * \r
314      * @return Read string from scanner\r
315      */\r
316     private String readString () {\r
317         return this.scanner.nextLine();\r
318     }\r
319 \r
320     /**\r
321      * Shows given menu\r
322      *\r
323      * @param menuType Given menu to show\r
324      */\r
325     private void showMenu (final String menuType) {\r
326         Menu menu = this.getMenu(menuType);\r
327         \r
328         // Is the menu set?\r
329         if (!(menu instanceof Menu)) {\r
330             // Not found\r
331             // @todo Own exception?\r
332             throw new NullPointerException("Menu '" + menuType + "' not found.");\r
333         }\r
334         \r
335         // Show menu\r
336         menu.show(this);\r
337     }\r
338 }\r