]> git.mxchange.org Git - jaddressbook-share-lib.git/blob - Addressbook/src/org/mxchange/addressbook/manager/contact/ContactManager.java
Added 'final' keyword to getters/setters as it makes no sense overwriting them.
[jaddressbook-share-lib.git] / Addressbook / src / org / mxchange / addressbook / manager / contact / ContactManager.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.manager.contact;\r
18 \r
19 import java.text.MessageFormat;\r
20 import java.util.ArrayList;\r
21 import java.util.Collections;\r
22 import java.util.Iterator;\r
23 import java.util.List;\r
24 import org.mxchange.addressbook.UnhandledUserChoiceException;\r
25 import org.mxchange.addressbook.client.Client;\r
26 import org.mxchange.addressbook.contact.Contact;\r
27 import org.mxchange.addressbook.database.frontend.contact.ContactDatabaseFrontend;\r
28 import org.mxchange.addressbook.database.frontend.contact.ContactWrapper;\r
29 import org.mxchange.addressbook.manager.BaseManager;\r
30 \r
31 /**\r
32  * A manager for contacts, please note that this implementation loads the whole\r
33  * list into RAM.\r
34  *\r
35  * @author Roland Haeder\r
36  * @version 0.0\r
37  */\r
38 public class ContactManager extends BaseManager implements ManageableContact {\r
39     /**\r
40      * Column name list\r
41      */\r
42     private final List<String> columnNames;\r
43 \r
44     /**\r
45      * A ContactWrapper instance\r
46      */\r
47     private final ContactWrapper contactDatabase;\r
48 \r
49     /**\r
50      * A list of all contacts\r
51      */\r
52     private final List<Contact> contacts;\r
53 \r
54 \r
55     /**\r
56      * @param maxContacts Maximum allowed contacts\r
57      * @param client Client instance to use\r
58      */\r
59     public ContactManager (final int maxContacts, final Client client) {\r
60         // Always call super constructor first\r
61         super();\r
62 \r
63         // Set client instance\r
64         this.setClient(client);\r
65 \r
66         // Init contacts\r
67         this.contacts = new ArrayList<>(maxContacts);\r
68 \r
69         // Init database connection\r
70         this.contactDatabase = new ContactDatabaseFrontend(this);\r
71 \r
72         // Initialize list\r
73         this.columnNames = new ArrayList<>(15);\r
74 \r
75         // And fill it\r
76         this.fillColumnNamesFromBundle();\r
77 \r
78         // Read all entries\r
79         this.contactDatabase.readAllContacts();\r
80 \r
81         // Debug message\r
82         //* NOISY-DEBUG: */ this.getLogger().debug("client=" + client);\r
83     }\r
84 \r
85     /**\r
86      * Adds given Contact instance to list\r
87      *\r
88      * @param contact Contact instance to add\r
89      */\r
90     @Override\r
91     public void addContact (final Contact contact) {\r
92         this.contacts.add(contact);\r
93     }\r
94 \r
95     /**\r
96      * Let the user add a new other address\r
97      */\r
98     @Override\r
99     public void addOtherAddress () {\r
100         throw new UnsupportedOperationException("Not supported yet.");\r
101     }\r
102 \r
103     /**\r
104      * Let the user change other address\r
105      */\r
106     @Override\r
107     public void changeOtherAddress () {\r
108         throw new UnsupportedOperationException("Not supported yet.");\r
109     }\r
110 \r
111     /**\r
112      * Allows the user to change his/her own data\r
113      */\r
114     @Override\r
115     public void changeOwnData () {\r
116         /*\r
117          * First check if the user has registered own contact, before that\r
118          * nothing can be changed.\r
119          */\r
120         if (!this.isOwnContactAdded()) {\r
121             // Not added\r
122             this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben.");\r
123             \r
124             // Skip any below code\r
125             return;\r
126         }\r
127         \r
128         // Instance\r
129         Contact contact = this.getOwnContact();\r
130         \r
131         // It must be found\r
132         assert(contact instanceof Contact);\r
133         \r
134         // Display contact\r
135         contact.show(this.getClient());\r
136         \r
137         try {\r
138             // Ask user what to change\r
139             this.getClient().userChooseChangeContactData(contact);\r
140         } catch (final UnhandledUserChoiceException ex) {\r
141             this.getLogger().catching(ex);\r
142         }\r
143     }\r
144 \r
145     /**\r
146      * Let the user delete other address\r
147      */\r
148     @Override\r
149     public void deleteOtherAddress () {\r
150         throw new UnsupportedOperationException("Not supported yet.");\r
151     }\r
152 \r
153     /**\r
154      * Let the user change address data\r
155      * \r
156      * @param contact Instance to change data\r
157      * @param client Client instance to call back\r
158      */\r
159     @Override\r
160     public void doChangeAddressData (final Contact contact, final Client client) {\r
161         // First display it again\r
162         client.displayAddressBox(contact);\r
163 \r
164         // Is it own data?\r
165         if (contact.isOwnContact()) {\r
166             // Deligate to client\r
167             this.getClient().doChangeOwnAddressData(contact);\r
168         } else {\r
169             // Other contact's address data to change\r
170             throw new UnsupportedOperationException("Changing contact entries not finished.");\r
171         }\r
172 \r
173         // Flush whole list\r
174         this.flush();\r
175     }\r
176 \r
177     /**\r
178      * Let the user change "name data"\r
179      * \r
180      * @param contact Instance to change data\r
181      * @param client Client instance to call back\r
182      */\r
183     @Override\r
184     public void doChangeNameData (final Contact contact, final Client client) {\r
185         // First display them again\r
186         client.displayNameBox(contact);\r
187 \r
188         // Is this own data?\r
189         if (contact.isOwnContact()) {\r
190             // Re-ask own data\r
191             this.getClient().doChangeOwnNameData(contact);\r
192         } else {\r
193             // Then re-ask them ...\r
194             throw new UnsupportedOperationException("Changing contact entries not finished.");\r
195         }\r
196 \r
197         // Flush whole list\r
198         this.flush();\r
199     }\r
200 \r
201     /**\r
202      * Let the user change other data\r
203      *\r
204      * @param contact Instance to change data\r
205      * @param client Client instance to call back\r
206      * @todo Didn't handle birthday\r
207      */\r
208     @Override\r
209     public void doChangeOtherData (final Contact contact, final Client client) {\r
210         // First display them again\r
211         this.getClient().displayOtherDataBox(contact);\r
212 \r
213         // Is this own data?\r
214         if (contact.isOwnContact()) {\r
215             // Re-ask own data\r
216             this.getClient().doChangeOwnOtherData(contact);\r
217         } else {\r
218             // Then re-ask them ...\r
219             throw new UnsupportedOperationException("Changing contact entries not finished.");\r
220         }\r
221 \r
222         // Flush whole list\r
223         this.flush();\r
224     }\r
225 \r
226     /**\r
227      * Asks user for own data\r
228      */\r
229     @Override\r
230     public void doEnterOwnData () {\r
231         // Deligate this call to the client\r
232         Contact contact = this.getClient().doEnterOwnData();\r
233 \r
234         // Add it to contact "book"\r
235         this.registerContact(contact);\r
236     }\r
237 \r
238     /**\r
239      * Shuts down this contact manager\r
240      */\r
241     @Override\r
242     public void doShutdown () {\r
243         // Shut down the database layer\r
244         this.getContactDatabase().doShutdown();\r
245     }\r
246 \r
247     /**\r
248      * Asks the user for his/her cellphone number\r
249      * \r
250      * @return User's cellphone number\r
251      */\r
252     @Override\r
253     public String enterOwnCellNumber () {\r
254         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);\r
255     }\r
256 \r
257     /**\r
258      * Asks the user for his/her city's name\r
259      *\r
260      * @return City's name of the user\r
261      */\r
262     @Override\r
263     public String enterOwnCity () {\r
264         return this.getClient().enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);\r
265     }\r
266 \r
267     /**\r
268      * Asks the user for his/her city's name\r
269      *\r
270      * @return City's name of the user\r
271      */\r
272     @Override\r
273     public String enterOwnComment () {\r
274         return this.getClient().enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);\r
275     }\r
276 \r
277     /**\r
278      * Asks the user for his/her company name\r
279      * \r
280      * @return User's company name\r
281      */\r
282     @Override\r
283     public String enterOwnCompanyName () {\r
284         return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);\r
285     }\r
286 \r
287     /**\r
288      * Asks user for his/her own country code\r
289      * \r
290      * @return User's own country code\r
291      */\r
292     @Override\r
293     public String enterOwnCountryCode () {\r
294         return this.getClient().enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();\r
295     }\r
296 \r
297     /**\r
298      * Asks user for his/her own country code\r
299      * \r
300      * @return User's own country code\r
301      */\r
302     @Override\r
303     public String enterOwnEmailAddress () {\r
304         return this.getClient().enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);\r
305     }\r
306 \r
307     /**\r
308      * Asks the user for family name\r
309      * \r
310      * @return Family name of the user\r
311      */\r
312     @Override\r
313     public String enterOwnFamilyName () {\r
314         return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);\r
315     }\r
316 \r
317     /**\r
318      * Asks the user for family name\r
319      * \r
320      * @return Family name of the user\r
321      */\r
322     @Override\r
323     public String enterOwnFaxNumber () {\r
324         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);\r
325     }\r
326 \r
327     /**\r
328      * Asks the user for gender, until a valid has been entered\r
329      * \r
330      * @return Gender of the user\r
331      */\r
332     @Override\r
333     public char enterOwnGender () {\r
334         return this.getClient().enterChar(new char[] {'M', 'F', 'C'}, "Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");\r
335     }\r
336 \r
337     /**\r
338      * Asks the user for phone number\r
339      * \r
340      * @return Phone number of the user\r
341      */\r
342     @Override\r
343     public String enterOwnPhoneNumber () {\r
344         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);\r
345     }\r
346 \r
347     /**\r
348      * Asks the user for own street (including number)\r
349      * @return Own street an number\r
350      */\r
351     @Override\r
352     public String enterOwnStreet () {\r
353         return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);\r
354     }\r
355 \r
356     /**\r
357      * Asks the user for surname\r
358      * @return Surname of the user\r
359      */\r
360     @Override\r
361     public String enterOwnSurname () {\r
362         return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);\r
363     }\r
364 \r
365     /**\r
366      * Asks the user for own ZIP code\r
367      * \r
368      * @return ZIP code\r
369      */\r
370     @Override\r
371     public int enterOwnZipCode () {\r
372         return this.getClient().enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");\r
373     }\r
374 \r
375     @Override\r
376     public final int getColumnCount () {\r
377         return this.columnNames.size();\r
378     }\r
379 \r
380     /**\r
381      * Getter for whole contact list\r
382      *\r
383      * @return List of all contacts\r
384      */\r
385     @Override\r
386     public List<Contact> getList () {\r
387         return Collections.unmodifiableList(this.contacts);\r
388     }\r
389 \r
390     /**\r
391      * Checks whether own contact is already added by checking all entries for\r
392      * isOwnContact flag\r
393      *\r
394      * @return Whether own contact is already added\r
395      */\r
396     @Override\r
397     public boolean isOwnContactAdded () {\r
398         // Default is not added\r
399         boolean isAdded = false;\r
400         \r
401         // Now get it back from address book, first get an iterator\r
402         Iterator<Contact> iterator = this.contacts.iterator();\r
403         \r
404         // Check entries\r
405         while (iterator.hasNext()) {\r
406             // Get next entry\r
407             Contact contact = iterator.next();\r
408             \r
409             // Is it valid?\r
410             if (contact instanceof Contact) {\r
411                 // Get flag\r
412                 isAdded = contact.isOwnContact();\r
413                 \r
414                 // Is this own contact?\r
415                 if (isAdded) {\r
416                     // Then abort loop\r
417                     break;\r
418                 }\r
419             }\r
420         }\r
421         // Return result\r
422         return isAdded;\r
423     }\r
424 \r
425     @Override\r
426     public void listContacts () {\r
427         throw new UnsupportedOperationException("Not supported yet.");\r
428     }\r
429 \r
430     /**\r
431      * Adds given contact to address book and flushes all entries to database\r
432      *\r
433      * @param contact Contact being added\r
434      * @todo Add check for book size\r
435      */\r
436     @Override\r
437     public void registerContact (final Contact contact) {\r
438         // Check if contact is found\r
439         if (this.isContactAlreadyAdded(contact)) {\r
440             // Contact already added\r
441             // @todo Do something here\r
442         } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {\r
443             // Own contact already added\r
444             // @todo Do something\r
445         }\r
446         \r
447         // Debug message\r
448         /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size()));\r
449         \r
450         // Add contact to internal list\r
451         this.addContact(contact);\r
452         \r
453         // Flush whole list\r
454         this.flush();\r
455     }\r
456 \r
457     @Override\r
458     public void searchContacts () {\r
459         throw new UnsupportedOperationException("Not supported yet.");\r
460     }\r
461 \r
462     /**\r
463      * Getter for size\r
464      *\r
465      * @return size of contact "book"\r
466      */\r
467     @Override\r
468     public final int size () {\r
469         return this.contacts.size();\r
470     }\r
471 \r
472     /**\r
473      * Fills the column names array with strings from bundle\r
474      */\r
475     private void fillColumnNamesFromBundle () {\r
476         // Debug message\r
477         this.getLogger().trace("CALLED!");\r
478 \r
479         // First get an iterator from key set to iterate over\r
480         Iterator<String> iterator = this.getBundle().keySet().iterator();\r
481 \r
482         // Then iterate over all\r
483         while (iterator.hasNext()) {\r
484             // Get next element\r
485             String key = iterator.next();\r
486 \r
487             // Does the key start with ContactManager.columnName ?\r
488             if (key.startsWith("ContactManager.columnName")) {\r
489                 // This is the wanted entry.\r
490                 this.getLogger().debug(MessageFormat.format("key={0}", key));\r
491 \r
492                 // So add it\r
493                 this.columnNames.add(this.getBundle().getString(key));\r
494             }\r
495         }\r
496 \r
497         // Debug message\r
498         this.getLogger().trace(MessageFormat.format("getColumnCount()={0}: EXIT!", this.getColumnCount()));\r
499     }\r
500 \r
501     /**\r
502      * Flushes all entries by calling database backend\r
503      */\r
504     private void flush () {\r
505         // Flusgh all\r
506         this.getContactDatabase().flushAllContacts();\r
507     }\r
508 \r
509     /**\r
510      * A ContactWrapper instance\r
511      *\r
512      * @return the database\r
513      */\r
514     private ContactWrapper getContactDatabase () {\r
515         return this.contactDatabase;\r
516     }\r
517 \r
518     /**\r
519      * "Getter" for own contact instance or null if not found\r
520      *\r
521      * @return Contact instance or null\r
522      */\r
523     private Contact getOwnContact () {\r
524         // Now get it back from address book, first get an iterator\r
525         Iterator<Contact> iterator = this.contacts.iterator();\r
526 \r
527         // Init instance\r
528         Contact contact = null;\r
529 \r
530         // Search all contact\r
531         while (iterator.hasNext()) {\r
532             // Get next instance\r
533             Contact next = iterator.next();\r
534 \r
535             // Is this own contact?\r
536             if (next.isOwnContact()) {\r
537                 // Found it\r
538                 contact = next;\r
539                 break;\r
540                 \r
541             }\r
542         }\r
543 \r
544         // Return instance or null\r
545         return contact;\r
546     }\r
547 \r
548     /**\r
549      * Checks whether given contact was found in "address book"\r
550      *\r
551      * @param checkContact Contact to be checked\r
552      * @return TRUE if found, FALSE if not found\r
553      */\r
554     private boolean isContactAlreadyAdded (final Contact checkContact) throws NullPointerException {\r
555         // Default is not found\r
556         boolean isFound = false;\r
557 \r
558         // Debug message\r
559         //* NOISY-DEBUG: */ this.getLogger().debug("Checking '" +  this.contacts.length + "' entries...");\r
560 \r
561         // Now get it back from address book, first get an iterator\r
562         Iterator<Contact> iterator = this.contacts.iterator();\r
563 \r
564         // Check entries\r
565         while (iterator.hasNext()) {\r
566             // Get next entry\r
567             Contact contact = iterator.next();\r
568 \r
569             // Debug message\r
570             //* NOISY-DEBUG: */ this.getLogger().debug("contact=" + contact + ",checkContent=" + checkContact);\r
571 \r
572             // Is it valid?\r
573             if ((contact instanceof Contact) && ((contact.equals(checkContact)))) {\r
574                 // Found matching entry\r
575                 isFound = true;\r
576                 break;\r
577             }\r
578         }\r
579 \r
580         // Return result\r
581         return isFound;\r
582     }\r
583 }\r