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