From befbf4e89fa45152ee03d3da2ba68b3beb098b18 Mon Sep 17 00:00:00 2001 From: Roland Haeder Date: Mon, 10 Aug 2015 11:22:19 +0200 Subject: [PATCH] =?utf8?q?Introduced=20BackendFactory=20which=20does=20now?= =?utf8?q?=20instance=20the=20database=20backend=20class.=20You=20only=20n?= =?utf8?q?eed=20to=20implement=20DatabaseBackend=20and=20have=20the=20clas?= =?utf8?q?s'=20name=20set=20in=20property=20org.mxchange.jcore.database.ba?= =?utf8?q?ckend.class=20Signed-off-by:Roland=20H=C3=A4der=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../mxchange/jcore/BaseFrameworkSystem.java | 370 +++++++++--------- .../base64/Base64CsvDatabaseBackend.java | 26 +- .../backend/mysql/MySqlDatabaseBackend.java | 14 +- .../frontend/BaseDatabaseFrontend.java | 56 +-- .../database/frontend/DatabaseFrontend.java | 7 + .../UnsupportedDatabaseBackendException.java | 18 +- .../database/backend/BackendFactory.java | 79 ++++ 7 files changed, 313 insertions(+), 257 deletions(-) create mode 100644 src/org/mxchange/jcore/factory/database/backend/BackendFactory.java diff --git a/src/org/mxchange/jcore/BaseFrameworkSystem.java b/src/org/mxchange/jcore/BaseFrameworkSystem.java index a9192d4..efee713 100644 --- a/src/org/mxchange/jcore/BaseFrameworkSystem.java +++ b/src/org/mxchange/jcore/BaseFrameworkSystem.java @@ -38,6 +38,7 @@ import org.apache.logging.log4j.Logger; import org.mxchange.jcore.application.Application; import org.mxchange.jcore.client.Client; import org.mxchange.jcore.contact.Contact; +import org.mxchange.jcore.database.backend.DatabaseBackend; import org.mxchange.jcore.database.frontend.DatabaseFrontend; import org.mxchange.jcore.manager.Manageable; @@ -47,6 +48,7 @@ import org.mxchange.jcore.manager.Manageable; * @author Roland Haeder */ public class BaseFrameworkSystem implements FrameworkInterface { + /** * Bundle instance */ @@ -72,6 +74,10 @@ public class BaseFrameworkSystem implements FrameworkInterface { */ private Application application; + /** + * Instance for database backend + */ + private DatabaseBackend backend; /** * Client instance @@ -98,7 +104,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { */ private DatabaseFrontend wrapper; - /** * Initialize object */ @@ -106,6 +111,14 @@ public class BaseFrameworkSystem implements FrameworkInterface { LOG = LogManager.getLogger(this); } + /** + * No instances can be created of this class + */ + protected BaseFrameworkSystem () { + // Set own instance + this.setSelfInstance(); + } + /** * Getter for this application * @@ -116,17 +129,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { return selfInstance; } - /** - * No instances can be created of this class - */ - protected BaseFrameworkSystem () { - // Init properties file - this.initProperties(); - - // Set own instance - this.setSelfInstance(); - } - /** * Application instance * @@ -175,7 +177,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { * * @param columnName Column name * @return Value from field - * @throws IllegalArgumentException Some implementations may throw this. + * @throws IllegalArgumentException Some implementations may throw this. */ @Override public Object getValueFromColumn (final String columnName) throws IllegalArgumentException { @@ -193,22 +195,22 @@ public class BaseFrameworkSystem implements FrameworkInterface { private Class getClassFromTarget (final FrameworkInterface instance, final String targetClass) { // Trace message this.getLogger().debug(MessageFormat.format("instance={0},targetClass={1}", instance, targetClass)); //NOI18N - + // Instance reflaction of this class Class c = instance.getClass(); - + // Analyze class while (!targetClass.equals(c.getSimpleName())) { // Debug message this.getLogger().debug(MessageFormat.format("c={0}", c.getSimpleName())); //NOI18N - + // Get super class (causes unchecked warning) c = (Class) c.getSuperclass(); } // Trace message this.getLogger().trace(MessageFormat.format("c={0} - EXIT!", c)); //NOI18N - + // Return it return c; } @@ -224,30 +226,27 @@ public class BaseFrameworkSystem implements FrameworkInterface { private Method getMethodFromName (final FrameworkInterface instance, final String targetClass, final String methodName) { // Trace messahe this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N - + // Get target class instance Class c = this.getClassFromTarget(instance, targetClass); - + // Init field instance Method method = null; - + // Use reflection to get all attributes try { method = c.getDeclaredMethod(methodName, new Class[0]); - } catch (final SecurityException ex) { + } catch (final SecurityException | NoSuchMethodException ex) { // Security problem this.abortProgramWithException(ex); - } catch (final NoSuchMethodException ex) { - // Method not found - this.abortProgramWithException(ex); } - + // Assert on field assert (method instanceof Method) : "method is not a Method instance"; //NOI18N - + // Trace message this.getLogger().trace(MessageFormat.format("method={0} - EXIT!", method)); //NOI18N - + // Return it return method; } @@ -268,10 +267,10 @@ public class BaseFrameworkSystem implements FrameworkInterface { protected final void abortProgramWithException (final Throwable throwable) { // Log exception ... this.getLogger().catching(throwable); - + // .. and exit System.exit(1); - + } /** @@ -311,6 +310,15 @@ public class BaseFrameworkSystem implements FrameworkInterface { this.client = client; } + /** + * Name of used database table, handled over to backend + * + * @return the tableName + */ + public final String getTableName () { + return this.tableName; + } + /** * Checks if given boolean field is available and set to same value * @@ -335,49 +343,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { this.getLogger().catching(exception); } - /** - * Prepares all properties, the file is written if it is not found - */ - private void initProperties () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - // Debug message - this.getLogger().debug(MessageFormat.format("{0} properties are loaded already.", BaseFrameworkSystem.properties.size())); //NOI18N - - // Are some properties loaded? - if (!BaseFrameworkSystem.properties.isEmpty()) { - // Some are already loaded, abort here - return; - } - - try { - // Try to read it - BaseFrameworkSystem.properties.load(new BufferedReader(new InputStreamReader(new FileInputStream(FrameworkInterface.PROPERTIES_CONFIG_FILE)))); - - // Debug message - this.getLogger().debug(MessageFormat.format("{0} properties has been loaded.", BaseFrameworkSystem.properties.size())); //NOI18N - } catch (final FileNotFoundException ex) { - // Debug message - this.getLogger().debug(MessageFormat.format("Properties file {0} not found: {1}", FrameworkInterface.PROPERTIES_CONFIG_FILE, ex)); //NOI18N - - /* - * The file is not found which is normal for first run, so - * initialize default values. - */ - this.initPropertiesWithDefault(); - - // Write file - this.writePropertiesFile(); - } catch (final IOException ex) { - // Something else didn't work - this.abortProgramWithException(ex); - } - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - /** * Initializes properties with default values */ @@ -387,7 +352,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Init default values: // Default database backend - BaseFrameworkSystem.properties.put("org.mxchange.database.backendType", "base64csv"); //NOI18N + BaseFrameworkSystem.properties.put("org.mxchange.database.backend.class", "org.mxchange.jcore.database.backend.base64.Base64CsvDatabaseBackend"); //NOI18N // For MySQL backend BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.host", "localhost"); //NOI18N @@ -527,26 +492,26 @@ public class BaseFrameworkSystem implements FrameworkInterface { protected String[] getArrayFromString (final String str, final String delimiter, final int size) { // Trace message this.getLogger().trace(MessageFormat.format("str={0},delimiter={1},size={2} - CALLED!", str, delimiter, size)); //NOI18N - + // Get tokenizer StringTokenizer tokenizer = new StringTokenizer(str, delimiter); - + // Init array and index String[] tokens = new String[size]; int index = 0; - + // Run through all tokens while (tokenizer.hasMoreTokens()) { // Get current token and add it tokens[index] = tokenizer.nextToken(); - + // Debug message this.getLogger().debug(MessageFormat.format("Token at index{0}: {1}", index, tokens[1])); //NOI18N - + // Increment index index++; } - + // Trace message this.getLogger().trace(MessageFormat.format("tokens({0})={1} - EXIT!", tokens.length, Arrays.toString(tokens))); //NOI18N @@ -574,13 +539,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { try { value = (Boolean) method.invoke(instance); - } catch (final IllegalArgumentException ex) { - // Other problem - this.abortProgramWithException(ex); - } catch (final IllegalAccessException ex) { - // Other problem - this.abortProgramWithException(ex); - } catch (final InvocationTargetException ex) { + } catch (final IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { // Other problem this.abortProgramWithException(ex); } @@ -609,22 +568,16 @@ public class BaseFrameworkSystem implements FrameworkInterface { protected Object getField (final FrameworkInterface instance, final String targetClass, final String methodName) { // Trace messahe this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N - + // Get method to call Method method = this.getMethodFromName(instance, targetClass, methodName); - + // Get value from field Object object = null; - + try { object = method.invoke(instance); - } catch (final IllegalArgumentException ex) { - // Other problem - this.abortProgramWithException(ex); - } catch (final IllegalAccessException ex) { - // Other problem - this.abortProgramWithException(ex); - } catch (final InvocationTargetException ex) { + } catch (final IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { // Other problem this.abortProgramWithException(ex); } @@ -646,37 +599,99 @@ public class BaseFrameworkSystem implements FrameworkInterface { /** * Name of used database table, handled over to backend * - * @return the tableName + * @param tableName the tableName to set */ - protected final String getTableName () { - return this.tableName; + protected final void setTableName (final String tableName) { + this.tableName = tableName; } /** - * Name of used database table, handled over to backend + * Converts null to empty string or leaves original string. * - * @param tableName the tableName to set + * @param str Any string + * @return Empty string if null or original string */ - protected final void setTableName (final String tableName) { - this.tableName = tableName; + protected Object convertNullToEmpty (final Object str) { + // Trace message + this.getLogger().trace(MessageFormat.format("str={0}", str)); + + // Is it null? + if (str == null) { + // Return empty string + return ""; + } + + // Trace message + this.getLogger().trace(MessageFormat.format("str={0} - EXIT!", str)); + + // Return it + return str; } /** - * Getter for DatabaseFrontend instance + * Creates an iterator from given instance and class name. * - * @return DatabaseFrontend instance + * @param instance Instance to run getter calls on + * @param className Class name to iterate over + * @return An iterator over all object's fields */ - protected final DatabaseFrontend getWrapper () { - return this.wrapper; + protected Iterator> fieldIterator (final FrameworkInterface instance, final String className) { + // Trace message + this.getLogger().trace(MessageFormat.format("instance={0},className={1} - CALLED!", instance, className)); + + // Get all attributes from given instance + Field[] fields = this.getClassFromTarget(instance, className).getDeclaredFields(); + + // Debug message + this.getLogger().debug(MessageFormat.format("Found {0} fields.", fields.length)); + + // A simple map with K=fieldName and V=Value is fine + Map map = new HashMap<>(fields.length); + + // Walk through all + for (final Field field : fields) { + // Debug log + this.getLogger().debug(MessageFormat.format("field={0}", field.getName())); + + // Does the field start with "$"? + if (field.getName().startsWith("$")) { + // Skip it silently + continue; + } + + // Get value from it + Object value = this.getValueFromColumn(field.getName()); + + // Debug message + this.getLogger().debug(MessageFormat.format("value={0}", value)); + + // Add it to list + map.put(field, value); + } + + // Debug message + this.getLogger().debug(MessageFormat.format("Returning iterator for {0} entries ...", map.size())); + + // Return list iterator + return map.entrySet().iterator(); } /** - * Setter for wrapper instance + * Instance for database backend * - * @param wrapper A DatabaseFrontend instance + * @return the backend */ - protected final void setWrapper (final DatabaseFrontend wrapper) { - this.wrapper = wrapper; + protected final DatabaseBackend getBackend () { + return this.backend; + } + + /** + * Instance for database backend + * + * @param backend the backend to set + */ + protected final void setBackend (final DatabaseBackend backend) { + this.backend = backend; } /** @@ -697,6 +712,24 @@ public class BaseFrameworkSystem implements FrameworkInterface { this.contact = contact; } + /** + * Getter for DatabaseFrontend instance + * + * @return DatabaseFrontend instance + */ + protected final DatabaseFrontend getFrontend () { + return this.wrapper; + } + + /** + * Setter for wrapper instance + * + * @param wrapper A DatabaseFrontend instance + */ + protected final void setFrontend (final DatabaseFrontend wrapper) { + this.wrapper = wrapper; + } + /** * Initializes i18n bundles */ @@ -710,10 +743,53 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Set instance bundle = ResourceBundle.getBundle(FrameworkInterface.I18N_BUNDLE_FILE); // NOI18N } + + /** + * Prepares all properties, the file is written if it is not found + */ + protected void initProperties () { + // Trace message + this.getLogger().trace("CALLED!"); //NOI18N + + // Debug message + this.getLogger().debug(MessageFormat.format("{0} properties are loaded already.", BaseFrameworkSystem.properties.size())); //NOI18N + + // Are some properties loaded? + if (!BaseFrameworkSystem.properties.isEmpty()) { + // Some are already loaded, abort here + return; + } + + try { + // Try to read it + BaseFrameworkSystem.properties.load(new BufferedReader(new InputStreamReader(new FileInputStream(FrameworkInterface.PROPERTIES_CONFIG_FILE)))); + + // Debug message + this.getLogger().debug(MessageFormat.format("{0} properties has been loaded.", BaseFrameworkSystem.properties.size())); //NOI18N + } catch (final FileNotFoundException ex) { + // Debug message + this.getLogger().debug(MessageFormat.format("Properties file {0} not found: {1}", FrameworkInterface.PROPERTIES_CONFIG_FILE, ex)); //NOI18N + + /* + * The file is not found which is normal for first run, so + * initialize default values. + */ + this.initPropertiesWithDefault(); + + // Write file + this.writePropertiesFile(); + } catch (final IOException ex) { + // Something else didn't work + this.abortProgramWithException(ex); + } + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } /** * Checks whether the given field is a boolean field by probing it. - * + * * @param instance Instance to call * @param targetClass Target class * @param columnName Column name to check @@ -753,74 +829,4 @@ public class BaseFrameworkSystem implements FrameworkInterface { return isBool; } - /** - * Creates an iterator from given instance and class name. - * - * @param instance Instance to run getter calls on - * @param className Class name to iterate over - * @return An iterator over all object's fields - */ - protected Iterator> fieldIterator (final FrameworkInterface instance, final String className) { - // Trace message - this.getLogger().trace(MessageFormat.format("instance={0},className={1} - CALLED!", instance, className)); - - // Get all attributes from given instance - Field[] fields = this.getClassFromTarget(instance, className).getDeclaredFields(); - - // Debug message - this.getLogger().debug(MessageFormat.format("Found {0} fields.", fields.length)); - - // A simple map with K=fieldName and V=Value is fine - Map map = new HashMap<>(fields.length); - - // Walk through all - for (final Field field : fields) { - // Debug log - this.getLogger().debug(MessageFormat.format("field={0}", field.getName())); - - // Does the field start with "$"? - if (field.getName().startsWith("$")) { - // Skip it silently - continue; - } - - // Get value from it - Object value = this.getValueFromColumn(field.getName()); - - // Debug message - this.getLogger().debug(MessageFormat.format("value={0}", value)); - - // Add it to list - map.put(field, value); - } - - // Debug message - this.getLogger().debug(MessageFormat.format("Returning iterator for {0} entries ...", map.size())); - - // Return list iterator - return map.entrySet().iterator(); - } - - /** - * Converts null to empty string or leaves original string. - * - * @param str Any string - * @return Empty string if null or original string - */ - protected Object convertNullToEmpty (final Object str) { - // Trace message - this.getLogger().trace(MessageFormat.format("str={0}", str)); - - // Is it null? - if (str == null) { - // Return empty string - return ""; - } - - // Trace message - this.getLogger().trace(MessageFormat.format("str={0} - EXIT!", str)); - - // Return it - return str; - } } diff --git a/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java b/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java index aba21ce..2a3e87b 100644 --- a/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java +++ b/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java @@ -49,12 +49,14 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat /** * Constructor with table name * - * @param tableName Name of "table" - * @param wrapper Wrapper instance to call back + * @param frontend Wrapper instance to call back */ - public Base64CsvDatabaseBackend (final String tableName, final DatabaseFrontend wrapper) { + public Base64CsvDatabaseBackend (final DatabaseFrontend frontend) { // Trace message - this.getLogger().trace(MessageFormat.format("tableName={0},wrapper={1}", tableName, wrapper)); //NOI18N + this.getLogger().trace(MessageFormat.format("frontend={1} - CALLED!", frontend)); //NOI18N + + // Get table name + String tableName = frontend.getTableName(); // Debug message this.getLogger().debug(MessageFormat.format("Trying to initialize table {0} ...", tableName)); //NOI18N @@ -62,8 +64,8 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat // Set table name here, too this.setTableName(tableName); - // Set wrapper here - this.setWrapper(wrapper); + // Set frontend here + this.setFrontend(frontend); // Construct file name String fileName = String.format("data/table_%s.b64", tableName); //NOI18N @@ -138,9 +140,9 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat // Debug message this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N - // Callback the wrapper to handle parsing + // Callback the frontend to handle parsing try { - Storeable storeable = this.getWrapper().parseLineToStoreable(line); + Storeable storeable = this.getFrontend().parseLineToStoreable(line); // Debug message this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N @@ -223,7 +225,7 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat try { // And parse it to a Contact instance - Storeable storeable = this.getWrapper().parseLineToStoreable(line); + Storeable storeable = this.getFrontend().parseLineToStoreable(line); // Debug message this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N @@ -329,8 +331,8 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat // Debug message this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N - // Callback the wrapper to handle parsing - storeable = this.getWrapper().parseLineToStoreable(line); + // Callback the frontend to handle parsing + storeable = this.getFrontend().parseLineToStoreable(line); // Debug message this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N @@ -545,7 +547,7 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat line = this.readLine(); // Parse line - instance = this.getWrapper().parseLineToStoreable(line); + instance = this.getFrontend().parseLineToStoreable(line); // The contact instance should be there now assert (instance instanceof FrameworkInterface) : MessageFormat.format("instance is not set: {0}", instance); //NOI18N diff --git a/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java b/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java index 054edf1..1924861 100644 --- a/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java +++ b/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java @@ -26,6 +26,7 @@ import java.text.MessageFormat; import java.util.Iterator; import org.mxchange.jcore.database.backend.BaseDatabaseBackend; import org.mxchange.jcore.database.backend.DatabaseBackend; +import org.mxchange.jcore.database.frontend.DatabaseFrontend; import org.mxchange.jcore.database.storage.Storeable; import org.mxchange.jcore.exceptions.BadTokenException; import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException; @@ -49,13 +50,22 @@ public class MySqlDatabaseBackend extends BaseDatabaseBackend implements Databas /** * Constructor with table name * - * @param tableName Table to access + * @param frontend An instance of the frontend * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException If the requested driver is not supported */ - public MySqlDatabaseBackend (final String tableName) throws UnsupportedDatabaseDriverException { + public MySqlDatabaseBackend (final DatabaseFrontend frontend) throws UnsupportedDatabaseDriverException { + // Trace message + this.getLogger().trace(MessageFormat.format("frontend={0} - CALLED!", frontend)); + // Validate driver this.validateDriver("mysql"); //NOI18N + // Get table name + String tableName = frontend.getTableName(); + + // Debug message + this.getLogger().debug(MessageFormat.format("tableName={0}", tableName)); + // Now that the driver is there, set the table name this.setTableName(tableName); } diff --git a/src/org/mxchange/jcore/database/frontend/BaseDatabaseFrontend.java b/src/org/mxchange/jcore/database/frontend/BaseDatabaseFrontend.java index 3ac5257..7e7a6a3 100644 --- a/src/org/mxchange/jcore/database/frontend/BaseDatabaseFrontend.java +++ b/src/org/mxchange/jcore/database/frontend/BaseDatabaseFrontend.java @@ -16,13 +16,12 @@ */ package org.mxchange.jcore.database.frontend; +import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import org.mxchange.jcore.BaseFrameworkSystem; import org.mxchange.jcore.database.backend.DatabaseBackend; -import org.mxchange.jcore.database.backend.base64.Base64CsvDatabaseBackend; -import org.mxchange.jcore.database.backend.mysql.MySqlDatabaseBackend; import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException; -import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException; +import org.mxchange.jcore.factory.database.backend.BackendFactory; /** * General database frontend class @@ -31,35 +30,12 @@ import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException; */ public abstract class BaseDatabaseFrontend extends BaseFrameworkSystem implements DatabaseFrontend { - /** - * Instance for database backend - */ - private DatabaseBackend backend; - /** * No instances from this class */ protected BaseDatabaseFrontend () { } - /** - * Instance for database backend - * - * @return the backend - */ - protected final DatabaseBackend getBackend () { - return this.backend; - } - - /** - * Instance for database backend - * - * @param backend the backend to set - */ - protected final void setBackend (final DatabaseBackend backend) { - this.backend = backend; - } - /** * Initialize backend * @@ -70,31 +46,19 @@ public abstract class BaseDatabaseFrontend extends BaseFrameworkSystem implement // Trace message this.getLogger().trace("CALLED!"); //NOI18N - // Read property - // @TODO rewrite this to own properties file - String backendType = this.getProperty("database.backendType"); //NOI18N - // Try it try { - // Switch on backend type - switch (backendType) { - case "mysql": // MySQL backend, this requires more information //NOI18N - this.backend = new MySqlDatabaseBackend(this.getTableName()); - break; - - case "base64csv": // BASE64-encoded CSV rows //NOI18N - this.backend = new Base64CsvDatabaseBackend(this.getTableName(), this); - break; - - default: // Unsupported - throw new UnsupportedDatabaseBackendException(backendType); - } + // Try to get get instance from factory + DatabaseBackend backend = BackendFactory.createInstance(this); // Try to run a connect on it - this.backend.connectToDatabase(); - } catch (final UnsupportedDatabaseDriverException ex) { + backend.connectToDatabase(); + + // All fine so far, then set it here + this.setBackend(backend); + } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { // Continue to throw - throw new UnsupportedDatabaseBackendException(backendType, ex); + throw new UnsupportedDatabaseBackendException(ex); } // Trace message diff --git a/src/org/mxchange/jcore/database/frontend/DatabaseFrontend.java b/src/org/mxchange/jcore/database/frontend/DatabaseFrontend.java index fa779e5..fd8dbd3 100644 --- a/src/org/mxchange/jcore/database/frontend/DatabaseFrontend.java +++ b/src/org/mxchange/jcore/database/frontend/DatabaseFrontend.java @@ -35,4 +35,11 @@ public interface DatabaseFrontend extends FrameworkInterface { * @throws org.mxchange.jcore.exceptions.BadTokenException If a token was badly formatted */ public Storeable parseLineToStoreable (final String line) throws BadTokenException; + + /** + * Name of used database table, handled over to backend + * + * @return the tableName + */ + public String getTableName (); } diff --git a/src/org/mxchange/jcore/exceptions/UnsupportedDatabaseBackendException.java b/src/org/mxchange/jcore/exceptions/UnsupportedDatabaseBackendException.java index daceeb4..395a5f6 100644 --- a/src/org/mxchange/jcore/exceptions/UnsupportedDatabaseBackendException.java +++ b/src/org/mxchange/jcore/exceptions/UnsupportedDatabaseBackendException.java @@ -16,8 +16,6 @@ */ package org.mxchange.jcore.exceptions; -import java.text.MessageFormat; - /** * An exception thrown when the given backend type is not valid * @@ -26,23 +24,13 @@ import java.text.MessageFormat; public class UnsupportedDatabaseBackendException extends Exception { /** + * Constructor with only cause * - * @param backendType - */ - public UnsupportedDatabaseBackendException (final String backendType) { - // Call super constructor - super(MessageFormat.format("Backend {0} is not supported.", backendType)); //NOI18N - } - - /** - * Constructor with backend type and cause - * - * @param backendType Backend type * @param cause */ - public UnsupportedDatabaseBackendException (final String backendType, final Throwable cause) { + public UnsupportedDatabaseBackendException (final Throwable cause) { // Call super constructor - super(MessageFormat.format("Backend {0} is not supported.", backendType), cause); //NOI18N + super("Backend is not supported.", cause); //NOI18N } } diff --git a/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java b/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java new file mode 100644 index 0000000..59f949f --- /dev/null +++ b/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 Roland Haeder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.mxchange.jcore.factory.database.backend; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import org.mxchange.jcore.BaseFrameworkSystem; +import org.mxchange.jcore.database.backend.DatabaseBackend; +import org.mxchange.jcore.database.frontend.DatabaseFrontend; + +/** + * A factory class for database backends + * + * @author Roland Haeder + */ +public class BackendFactory extends BaseFrameworkSystem { + + /** + * Creates instance of a database backend as configured in properties file + * + * @param frontend Frontend instance + * @return An instance of a DatabaseBackend class + * @throws java.lang.ClassNotFoundException If the configured class was not found + * @throws java.lang.NoSuchMethodException If the constructor with a frontend instance is not found + * @throws java.lang.InstantiationException + * @throws java.lang.IllegalAccessException + * @throws java.lang.reflect.InvocationTargetException + */ + public static final DatabaseBackend createInstance (final DatabaseFrontend frontend) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Get factory instance + BackendFactory factory = new BackendFactory(); + + // Trace message + factory.getLogger().trace(MessageFormat.format("frontend={0} - CALLED!", frontend)); //NOI18N + + // Get property + String className = factory.getProperty("database.backend.class"); //NOI18N + + // Debug message + factory.getLogger().debug(MessageFormat.format("className={0}", className)); //NOI18N + + // Try to get the instance + Class reflection = Class.forName(className); + + // Debug message + factory.getLogger().debug(MessageFormat.format("reflection={0}", reflection)); //NOI18N + + // Get constructor + Constructor constructor = reflection.getConstructor(frontend.getClass()); + + // Debug message + factory.getLogger().debug(MessageFormat.format("constructor={0}", constructor)); //NOI18N + + // Now invoke it + DatabaseBackend backend = (DatabaseBackend) constructor.newInstance(frontend); + + // Trace message + factory.getLogger().trace(MessageFormat.format("backend={0} - EXIT!", backend)); //NOI18N + + // Return it + return backend; + } + +} -- 2.39.5