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