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