]> git.mxchange.org Git - addressbook-swing.git/blob - Addressbook/src/org/mxchange/addressbook/BaseFrameworkSystem.java
f0fd4d4e3eed45ac6f1be3245fdbdb8153b19669
[addressbook-swing.git] / Addressbook / src / org / mxchange / addressbook / BaseFrameworkSystem.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;
18
19 import java.io.BufferedReader;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.PrintWriter;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.text.MessageFormat;
28 import java.util.Properties;
29 import java.util.ResourceBundle;
30 import java.util.StringTokenizer;
31 import org.apache.logging.log4j.LogManager;
32 import org.apache.logging.log4j.Logger;
33 import org.mxchange.addressbook.application.Application;
34 import org.mxchange.addressbook.client.Client;
35 import org.mxchange.addressbook.database.frontend.DatabaseWrapper;
36 import org.mxchange.addressbook.manager.contact.ManageableContact;
37
38 /**
39  * General class
40  *
41  * @author Roland Haeder
42  */
43 public class BaseFrameworkSystem implements FrameworkInterface {
44         /**
45          * Instance for own properties
46          */
47         private static final Properties properties = new Properties(System.getProperties());
48
49         /**
50          * Class' logger
51          */
52         private final Logger LOG;
53
54         /**
55          * Application instance
56          */
57         private Application application;
58
59         /**
60          * Bundle instance
61          */
62         private final ResourceBundle bundle;
63
64         /**
65          * Client instance
66          */
67         private Client client;
68
69         /**
70          * Contact manager instance
71          */
72         private ManageableContact contactManager;
73
74
75         /**
76          * Name of used database table, handled over to backend
77          */
78         private String tableName;
79
80         /**
81          * DatabaseWrapper instance
82          */
83         private DatabaseWrapper wrapper;
84
85         /**
86          * Initialize object
87          */
88         {
89                 LOG = LogManager.getLogger(this);
90                 bundle = ResourceBundle.getBundle("org/mxchange/addressbook/localization/bundle"); // NOI18N
91         }
92
93         /**
94          * No instances can be created of this class
95          */
96         protected BaseFrameworkSystem () {
97                 // Init properties file
98                 this.initProperties();
99         }
100
101         /**
102          * Application instance
103          *
104          * @return the application
105          */
106         @Override
107         public final Application getApplication () {
108                 return this.application;
109         }
110
111         /**
112          * Getter for human-readable string from given key
113          *
114          * @param key Key to return
115          * @return Human-readable message
116          */
117         @Override
118         public final String getMessageStringFromKey (final String key) {
119                 // Return message
120                 return this.getBundle().getString(key);
121         }
122
123         /**
124          * Some "getter for a value from given column name. This name will be
125          * translated into a method name and then this method is called.
126          *
127          * @param columnName Column name
128          * @return Value from field
129          */
130         @Override
131         public Object getValueFromColumn (final String columnName) {
132                 throw new UnsupportedOperationException(MessageFormat.format("Not implemented. columnName={0}", columnName));
133         }
134
135         /**
136          * Some "getter" for a Method instance from given method name
137          *
138          * @param instance Actual instance to call
139          * @param targetClass Target class name
140          * @param methodName Method name
141          * @return A Method instance
142          */
143         @SuppressWarnings ("unchecked")
144         private Method getMethodFromName (final FrameworkInterface instance, final String targetClass, final String methodName) {
145                 // Trace messahe
146                 this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName));
147
148                 // Instance reflaction of this class
149                 Class<? extends FrameworkInterface> c = instance.getClass();
150                 
151                 // Analyze class
152                 while (!targetClass.equals(c.getSimpleName())) {
153                         // Debug message
154                         this.getLogger().debug("c=" + c.getSimpleName());
155
156                         // Get super class (causes unchecked warning)
157                         c = (Class<? extends FrameworkInterface>) c.getSuperclass();
158                 }
159
160                 // Init field instance
161                 Method method = null;
162
163                 // Use reflection to get all attributes
164                 try {
165                         method = c.getDeclaredMethod(methodName, new Class<?>[0]);
166                 } catch (final SecurityException ex) {
167                         // Security problem
168                         this.abortProgramWithException(ex);
169                 } catch (final NoSuchMethodException ex) {
170                         // Method not found
171                         this.abortProgramWithException(ex);
172                 }
173
174                 // Assert on field
175                 assert(method instanceof Method) : "method is not a Method instance";
176
177                 // Trace message
178                 this.getLogger().trace(MessageFormat.format("method={0} - EXIT!", method));
179
180                 // Return it
181                 return method;
182         }
183
184         /**
185          * Aborts program with given exception
186          *
187          * @param       throwable Any type of Throwable
188          */
189         protected final void abortProgramWithException (final Throwable throwable) {
190                 // Log exception ...
191                 this.getLogger().catching(throwable);
192
193                 // .. and exit
194                 System.exit(1);
195                 
196         }
197
198         /**
199          * Application instance
200          *
201          * @param application the application to set
202          */
203         protected final void setApplication (final Application application) {
204                 this.application = application;
205         }
206
207         /**
208          * Client instance
209          *
210          * @return the client
211          */
212         @Override
213         public final Client getClient () {
214                 return this.client;
215         }
216
217         /**
218          * Getter for bundle instance
219          *
220          * @return Resource bundle
221          */
222         protected final ResourceBundle getBundle () {
223                 return this.bundle;
224         }
225
226         /**
227          * Client instance
228          *
229          * @param client the client to set
230          */
231         protected final void setClient (final Client client) {
232                 this.client = client;
233         }
234
235         /**
236          * Contact manager instance
237          *
238          * @return the contactManager
239          */
240         @Override
241         public final ManageableContact getContactManager () {
242                 return this.contactManager;
243         }
244
245         /**
246          * Contact manager instance
247          *
248          * @param contactManager the contactManager to set
249          */
250         protected final void setContactManager (final ManageableContact contactManager) {
251                 this.contactManager = contactManager;
252         }
253
254         /**
255          * Checks if given boolean field is available and set to same value
256          *
257          * @param columnName Column name to check
258          * @param bool Boolean value
259          * @return Whether all conditions are met
260          */
261         @Override
262         public boolean isValueEqual (final String columnName, final boolean bool) {
263                 // Not implemented
264                 throw new UnsupportedOperationException(MessageFormat.format("Not implemented. columnName={0},bool={1}", columnName, bool));
265         }
266
267         /**
268          * Log exception
269          *
270          * @param exception Exception to log
271          */
272         @Override
273         public final void logException (final Throwable exception) {
274                 // Log this exception
275                 this.getLogger().catching(exception);
276         }
277
278         /**
279          * Prepares all properties, the file is written if it is not found
280          */
281         private void initProperties () {
282                 // Trace message
283                 this.getLogger().trace("CALLED!"); //NOI18N
284
285                 // Debug message
286                 this.getLogger().debug(MessageFormat.format("{0} properties are loaded already.", BaseFrameworkSystem.properties.size())); //NOI18N
287
288                 // Are some properties loaded?
289                 if (!BaseFrameworkSystem.properties.isEmpty()) {
290                         // Some are already loaded, abort here
291                         return;
292                 }
293
294                 try {
295                         // Try to read it
296                         BaseFrameworkSystem.properties.load(new BufferedReader(new InputStreamReader(new FileInputStream(FrameworkInterface.PROPERTIES_CONFIG_FILE))));
297
298                         // Debug message
299                         this.getLogger().debug(MessageFormat.format("{0} properties has been loaded.", BaseFrameworkSystem.properties.size())); //NOI18N
300                 } catch (final FileNotFoundException ex) {
301                         // Debug message
302                         this.getLogger().debug(MessageFormat.format("Properties file {0} not found: {1}", FrameworkInterface.PROPERTIES_CONFIG_FILE, ex)); //NOI18N
303
304                         /*
305                          * The file is not found which is normal for first run, so
306                          * initialize default values.
307                          */
308                         this.initPropertiesWithDefault();
309
310                         // Write file
311                         this.writePropertiesFile();
312                 } catch (final IOException ex) {
313                         // Something else didn't work
314                         this.abortProgramWithException(ex);
315                 }
316
317                 // Trace message
318                 this.getLogger().trace("EXIT!"); //NOI18N
319         }
320
321         /**
322          * Initializes properties with default values
323          */
324         private void initPropertiesWithDefault () {
325                 // Trace message
326                 this.getLogger().trace("CALLED!"); //NOI18N
327
328                 // Init default values:
329                 // Default database backend
330                 BaseFrameworkSystem.properties.put("org.mxchange.addressbook.database.backendType", "base64csv"); //NOI18N
331
332                 // For MySQL backend
333                 BaseFrameworkSystem.properties.put("org.mxchange.addressbook.database.mysql.host", "localhost"); //NOI18N
334                 BaseFrameworkSystem.properties.put("org.mxchange.addressbook.database.mysql.dbname", "test"); //NOI18N
335                 BaseFrameworkSystem.properties.put("org.mxchange.addressbook.database.mysql.login", ""); //NOI18N
336                 BaseFrameworkSystem.properties.put("org.mxchange.addressbook.database.mysql.password", ""); //NOI18N
337
338                 // Trace message
339                 this.getLogger().trace("EXIT!"); //NOI18N
340         }
341
342         /**
343          * Writes the properties file to disk
344          */
345         private void writePropertiesFile () {
346                 // Trace message
347                 this.getLogger().trace("CALLED!"); //NOI18N
348
349                 try {
350                         // Write it
351                         BaseFrameworkSystem.properties.store(new PrintWriter(FrameworkInterface.PROPERTIES_CONFIG_FILE), "This file is automatically generated. You may wish to alter it."); //NOI18N
352                 } catch (final IOException ex) {
353                         this.abortProgramWithException(ex);
354                 }
355
356                 // Trace message
357                 this.getLogger().trace("EXIT!"); //NOI18N
358         }
359
360         /**
361          * Converts a column name like "foo_bar" to an attribute name like "fooBar"
362          *
363          * @param columnName Column name to convert
364          * @return Attribute name
365          */
366         protected String convertColumnNameToAttribute (final String columnName) {
367                 // Trace message
368                 this.getLogger().trace(MessageFormat.format("columnName={0} - CALLED!", columnName));
369
370                 // First all lower case
371                 String lower = columnName.toLowerCase();
372
373                 // Then split on "_"
374                 StringTokenizer tokenizer = new StringTokenizer(lower, "_");
375
376                 // Resulting string
377                 StringBuilder builder = new StringBuilder(tokenizer.countTokens());
378
379                 // Init counter
380                 int count = 0;
381
382                 // Walk through all
383                 while (tokenizer.hasMoreTokens()) {
384                         // Get token
385                         String token = tokenizer.nextToken();
386
387                         // Is later than first element?
388                         if (count > 0) {
389                                 // Make first character upper-case
390                                 char c = token.charAt(0);
391                                 token = String.valueOf(c).toUpperCase() + token.substring(1);
392                         }
393
394                         // Add token
395                         builder.append(token);
396
397                         // Increment counter
398                         count++;
399                 }
400         
401                 // Trace message
402                 this.getLogger().trace(MessageFormat.format("builder={0} - EXIT!", builder));
403
404                 // Return result
405                 return builder.toString();
406         }
407
408         /**
409          * Converts a column name like "foo_bar" to a method name like "getFooBar"
410          * for non-booleans and to "isFooBar" for boolean fields.
411          *
412          * @param columnName Column name to convert
413          * @param isBool Whether the parameter is boolean
414          * @return Attribute name
415          */
416         protected String convertColumnNameToGetterMethod (final String columnName, boolean isBool) {
417                 // Trace message
418                 this.getLogger().trace(MessageFormat.format("columnName={0} - CALLED!", columnName));
419
420                 // First all lower case
421                 String lower = columnName.toLowerCase();
422
423                 // Then split on "_"
424                 StringTokenizer tokenizer = new StringTokenizer(lower, "_");
425
426                 // Resulting string
427                 StringBuilder builder = new StringBuilder(tokenizer.countTokens());
428
429                 // Is it boolean?
430                 if (isBool) {
431                         // Append "is"
432                         builder.append("is");
433                 } else {
434                         // Append "get"
435                         builder.append("get");
436                 }
437
438                 // Walk through all
439                 while (tokenizer.hasMoreTokens()) {
440                         // Get token
441                         String token = tokenizer.nextToken();
442
443                         // Debug message
444                         this.getLogger().debug(MessageFormat.format("token={0}", token));
445
446                         // Make it upper-case
447                         char c = token.charAt(0);
448                         token = String.valueOf(c).toUpperCase() + token.substring(1);
449
450                         // Add token
451                         builder.append(token);
452                 }
453         
454                 // Trace message
455                 this.getLogger().trace(MessageFormat.format("builder={0} - EXIT!", builder));
456
457                 // Return result
458                 return builder.toString();
459         }
460
461         /**
462          * Returns boolean field value from given method call
463          *
464          * @param instance The instance to call
465          * @param targetClass Target class to look in
466          * @param methodName Method name to look for
467          * @return Boolean value from field
468          */
469         protected boolean getBooleanField (final FrameworkInterface instance, final String targetClass, final String methodName) {
470                 // Trace messahe
471                 this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName));
472
473                 // Get method instance
474                 Method method = this.getMethodFromName(instance, targetClass, methodName);
475
476                 // Get value from field
477                 Boolean value = false;
478
479                 try {
480                         value = (Boolean) method.invoke(instance);
481                 } catch (final IllegalArgumentException ex) {
482                         // Other problem
483                         this.abortProgramWithException(ex);
484                 } catch (final IllegalAccessException ex) {
485                         // Other problem
486                         this.abortProgramWithException(ex);
487                 } catch (final InvocationTargetException ex) {
488                         // Other problem
489                         this.abortProgramWithException(ex);
490                 }
491
492                 // Return value
493                 return value;
494         }
495
496         /**
497          * Returns any field value from given method call
498          *
499          * @param instance The instance to call
500          * @param targetClass Target class to look in
501          * @param methodName Method name to look for
502          * @return Any value from field
503          */
504         protected Object getField (final FrameworkInterface instance, final String targetClass, final String methodName) {
505                 // Trace messahe
506                 this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName));
507
508                 // Get method to call
509                 Method method = this.getMethodFromName(instance, targetClass, methodName);
510
511                 // Get value from field
512                 Object object = null;
513
514                 try {
515                         object = method.invoke(instance);
516                 } catch (final IllegalArgumentException ex) {
517                         // Other problem
518                         this.abortProgramWithException(ex);
519                 } catch (final IllegalAccessException ex) {
520                         // Other problem
521                         this.abortProgramWithException(ex);
522                 } catch (final InvocationTargetException ex) {
523                         // Other problem
524                         this.abortProgramWithException(ex);
525                 }
526
527                 // Return value
528                 return object;
529         }
530         
531         /**
532          * Getter for logger
533          *
534          * @return Logger
535          */
536         protected final Logger getLogger () {
537                 return this.LOG;
538         }
539
540         /**
541          * Getter for property which must exist
542          *
543          * @param key Key to get
544          * @return Propety value
545          */
546         protected final String getProperty (final String key) {
547                 return BaseFrameworkSystem.properties.getProperty(String.format("org.mxchange.addressbook.%s", key)); //NOI18N
548         }
549
550         /**
551          * Name of used database table, handled over to backend
552          *
553          * @return the tableName
554          */
555         protected final String getTableName () {
556                 return this.tableName;
557         }
558
559         /**
560          * Name of used database table, handled over to backend
561          *
562          * @param tableName the tableName to set
563          */
564         protected final void setTableName (final String tableName) {
565                 this.tableName = tableName;
566         }
567
568         /**
569          * Getter for DatabaseWrapper instance
570          *
571          * @return DatabaseWrapper instance
572          */
573         protected DatabaseWrapper getWrapper () {
574                 return this.wrapper;
575         }
576
577         /**
578          * Setter for wrapper instance
579          *
580          * @param wrapper A DatabaseWrapper instance
581          */
582         protected void setWrapper (final DatabaseWrapper wrapper) {
583                 this.wrapper = wrapper;
584         }
585 }