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