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