]> git.mxchange.org Git - addressbook-lib.git/blob - Addressbook/src/org/mxchange/addressbook/manager/contact/ContactManager.java
Implemented getColumnName() + added it to ContactManager as this class holds the...
[addressbook-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.client.Client;
25 import org.mxchange.addressbook.contact.Contact;
26 import org.mxchange.addressbook.database.frontend.contact.ContactDatabaseFrontend;
27 import org.mxchange.addressbook.database.frontend.contact.ContactWrapper;
28 import org.mxchange.addressbook.exceptions.UnhandledUserChoiceException;
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 address data
105      * 
106      * @param contact Instance to change data
107      * @param client Client instance to call back
108      */
109     @Override
110     public void doChangeAddressData (final Contact contact, final Client client) {
111         // First display it again
112         client.displayAddressBox(contact);
113
114         // Is it own data?
115         if (contact.isOwnContact()) {
116             // Deligate to client
117             this.getClient().doChangeOwnAddressData(contact);
118         } else {
119             // Other contact's address data to change
120             throw new UnsupportedOperationException("Changing contact entries not finished.");
121         }
122
123         // Flush whole list
124         this.flush();
125     }
126
127     /**
128      * Let the user change "name data"
129      * 
130      * @param contact Instance to change data
131      * @param client Client instance to call back
132      */
133     @Override
134     public void doChangeNameData (final Contact contact, final Client client) {
135         // First display them again
136         client.displayNameBox(contact);
137
138         // Is this own data?
139         if (contact.isOwnContact()) {
140             // Re-ask own data
141             this.getClient().doChangeOwnNameData(contact);
142         } else {
143             // Then re-ask them ...
144             throw new UnsupportedOperationException("Changing contact entries not finished.");
145         }
146
147         // Flush whole list
148         this.flush();
149     }
150
151     /**
152      * Let the user change other address
153      */
154     @Override
155     public void doChangeOtherAddress () {
156         throw new UnsupportedOperationException("Not supported yet.");
157     }
158
159     /**
160      * Let the user change other data
161      *
162      * @param contact Instance to change data
163      * @param client Client instance to call back
164      * @todo Didn't handle birthday
165      */
166     @Override
167     public void doChangeOtherData (final Contact contact, final Client client) {
168         // First display them again
169         this.getClient().displayOtherDataBox(contact);
170
171         // Is this own data?
172         if (contact.isOwnContact()) {
173             // Re-ask own data
174             this.getClient().doChangeOwnOtherData(contact);
175         } else {
176             // Then re-ask them ...
177             throw new UnsupportedOperationException("Changing contact entries not finished.");
178         }
179
180         // Flush whole list
181         this.flush();
182     }
183
184     /**
185      * Allows the user to change his/her own data
186      */
187     @Override
188     public void doChangeOwnData () {
189         /*
190          * First check if the user has registered own contact, before that
191          * nothing can be changed.
192          */
193         if (!this.isOwnContactAdded()) {
194             // Not added
195             this.getClient().outputMessage("Sie haben noch nicht Ihre Daten eingegeben.");
196             
197             // Skip any below code
198             return;
199         }
200         
201         // Instance
202         Contact contact = this.getOwnContact();
203         
204         // It must be found
205         assert(contact instanceof Contact);
206         
207         // Display contact
208         contact.show(this.getClient());
209         
210         try {
211             // Ask user what to change
212             this.getClient().userChooseChangeContactData(contact);
213         } catch (final UnhandledUserChoiceException ex) {
214             this.getLogger().catching(ex);
215         }
216     }
217
218     /**
219      * Let the user delete other address
220      */
221     @Override
222     public void doDeleteOtherAddress () {
223         throw new UnsupportedOperationException("Not supported yet.");
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     @Override
239     public void doListContacts () {
240         throw new UnsupportedOperationException("Not supported yet.");
241     }
242
243     @Override
244     public void doSearchContacts () {
245         throw new UnsupportedOperationException("Not supported yet.");
246     }
247
248     /**
249      * Shuts down this contact manager
250      */
251     @Override
252     public void doShutdown () {
253         // Shut down the database layer
254         this.getContactDatabase().doShutdown();
255     }
256
257     /**
258      * Asks the user for his/her cellphone number
259      * 
260      * @return User's cellphone number
261      */
262     @Override
263     public String enterOwnCellNumber () {
264         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Handynummer an: ", true);
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 enterOwnCity () {
274         return this.getClient().enterString(3, 50, "Bitte geben Sie Ihre Wohnort ein: ", false);
275     }
276
277     /**
278      * Asks the user for his/her city's name
279      *
280      * @return City's name of the user
281      */
282     @Override
283     public String enterOwnComment () {
284         return this.getClient().enterString(0, 100, "Kommentar zu Ihrem Eintrag: ", true);
285     }
286
287     /**
288      * Asks the user for his/her company name
289      * 
290      * @return User's company name
291      */
292     @Override
293     public String enterOwnCompanyName () {
294         return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Firmenbezeichnung ein: ", true);
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 enterOwnCountryCode () {
304         return this.getClient().enterString(2, 2, "Bitte geben Sie den zweistelligen Ländercode von Ihrem Land ein: ", false).toUpperCase();
305     }
306
307     /**
308      * Asks user for his/her own country code
309      * 
310      * @return User's own country code
311      */
312     @Override
313     public String enterOwnEmailAddress () {
314         return this.getClient().enterString(10, 50, "Bitte geben Sie Ihre Email-Adresse ein: ", true);
315     }
316
317     /**
318      * Asks the user for family name
319      * 
320      * @return Family name of the user
321      */
322     @Override
323     public String enterOwnFamilyName () {
324         return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Nachnamen ein: ", false);
325     }
326
327     /**
328      * Asks the user for family name
329      * 
330      * @return Family name of the user
331      */
332     @Override
333     public String enterOwnFaxNumber () {
334         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Faxnummer an: ", true);
335     }
336
337     /**
338      * Asks the user for gender, until a valid has been entered
339      * 
340      * @return Gender of the user
341      */
342     @Override
343     public char enterOwnGender () {
344         return this.getClient().enterChar(new char[] {'M', 'F', 'C'}, "Bitte geben Sie die Anrede ein: (M=Herr, F=Frau, C=Firma): ");
345     }
346
347     /**
348      * Asks the user for phone number
349      * 
350      * @return Phone number of the user
351      */
352     @Override
353     public String enterOwnPhoneNumber () {
354         return this.getClient().enterString(5, 30, "Bitte geben Sie Ihre Telefonnummer an: ", true);
355     }
356
357     /**
358      * Asks the user for own street (including number)
359      * @return Own street an number
360      */
361     @Override
362     public String enterOwnStreet () {
363         return this.getClient().enterString(5, 50, "Bitte geben Sie Ihre Strasse und Hausnummer ein: ", false);
364     }
365
366     /**
367      * Asks the user for surname
368      * @return Surname of the user
369      */
370     @Override
371     public String enterOwnSurname () {
372         return this.getClient().enterString(2, 50, "Bitte geben Sie Ihren Vornamen ein: ", false);
373     }
374
375     /**
376      * Asks the user for own ZIP code
377      * 
378      * @return ZIP code
379      */
380     @Override
381     public int enterOwnZipCode () {
382         return this.getClient().enterInt(0, 99_999, "Bitte geben Sie Ihre Postleitzahl ein: ");
383     }
384
385     @Override
386     public final int getColumnCount () {
387         return this.columnNames.size();
388     }
389
390     /**
391      * Getter for whole contact list
392      *
393      * @return List of all contacts
394      */
395     @Override
396     public List<Contact> getList () {
397         return Collections.unmodifiableList(this.contacts);
398     }
399
400     /**
401      * Checks whether own contact is already added by checking all entries for
402      * isOwnContact flag
403      *
404      * @return Whether own contact is already added
405      */
406     @Override
407     public boolean isOwnContactAdded () {
408         // Default is not added
409         boolean isAdded = false;
410         
411         // Now get it back from address book, first get an iterator
412         Iterator<Contact> iterator = this.contacts.iterator();
413         
414         // Check entries
415         while (iterator.hasNext()) {
416             // Get next entry
417             Contact contact = iterator.next();
418             
419             // Is it valid?
420             if (contact instanceof Contact) {
421                 // Get flag
422                 isAdded = contact.isOwnContact();
423                 
424                 // Is this own contact?
425                 if (isAdded) {
426                     // Then abort loop
427                     break;
428                 }
429             }
430         }
431         // Return result
432         return isAdded;
433     }
434
435     /**
436      * Adds given contact to address book and flushes all entries to database
437      *
438      * @param contact Contact being added
439      * @todo Add check for book size
440      */
441     @Override
442     public void registerContact (final Contact contact) {
443         // Check if contact is found
444         if (this.isContactAlreadyAdded(contact)) {
445             // Contact already added
446             // @todo Do something here
447         } else if ((contact.isOwnContact()) && (this.isOwnContactAdded())) {
448             // Own contact already added
449             // @todo Do something
450         }
451         
452         // Debug message
453         /* NOISY-DEBUG: */ this.getLogger().debug(MessageFormat.format("Adding '{0}' '{1}' at pos '{2}' ...", contact.getSurname(), contact.getFamilyName(), this.size()));
454         
455         // Add contact to internal list
456         this.addContact(contact);
457         
458         // Flush whole list
459         this.flush();
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("ContactManager.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      * Getter for column name at given index.
503      * 
504      * @param columnIndex Column index
505      * @return Human-readable column name
506      */
507     @Override
508     public String getColumnName (final int columnIndex) {
509         // Get column name at index
510         return this.columnNames.get(columnIndex);
511     }
512
513     /**
514      * Flushes all entries by calling database backend
515      */
516     private void flush () {
517         // Flusgh all
518         this.getContactDatabase().flushAllContacts();
519     }
520
521     /**
522      * A ContactWrapper instance
523      *
524      * @return the database
525      */
526     private ContactWrapper getContactDatabase () {
527         return this.contactDatabase;
528     }
529
530     /**
531      * "Getter" for own contact instance or null if not found
532      *
533      * @return Contact instance or null
534      */
535     private Contact getOwnContact () {
536         // Now get it back from address book, first get an iterator
537         Iterator<Contact> iterator = this.contacts.iterator();
538
539         // Init instance
540         Contact contact = null;
541
542         // Search all contact
543         while (iterator.hasNext()) {
544             // Get next instance
545             Contact next = iterator.next();
546
547             // Is this own contact?
548             if (next.isOwnContact()) {
549                 // Found it
550                 contact = next;
551                 break;
552                 
553             }
554         }
555
556         // Return instance or null
557         return contact;
558     }
559
560     /**
561      * Checks whether given contact was found in "address book"
562      *
563      * @param checkContact Contact to be checked
564      * @return TRUE if found, FALSE if not found
565      */
566     private boolean isContactAlreadyAdded (final Contact checkContact) throws NullPointerException {
567         // Default is not found
568         boolean isFound = false;
569
570         // Debug message
571         //* NOISY-DEBUG: */ this.getLogger().debug("Checking '" +  this.contacts.length + "' entries...");
572
573         // Now get it back from address book, first get an iterator
574         Iterator<Contact> iterator = this.contacts.iterator();
575
576         // Check entries
577         while (iterator.hasNext()) {
578             // Get next entry
579             Contact contact = iterator.next();
580
581             // Debug message
582             //* NOISY-DEBUG: */ this.getLogger().debug("contact=" + contact + ",checkContent=" + checkContact);
583
584             // Is it valid?
585             if ((contact instanceof Contact) && ((contact.equals(checkContact)))) {
586                 // Found matching entry
587                 isFound = true;
588                 break;
589             }
590         }
591
592         // Return result
593         return isFound;
594     }
595 }