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