From: Roland Haeder Date: Wed, 12 Aug 2015 09:36:37 +0000 (+0200) Subject: Added criteria stuff for data-gateway patterm + a lot refacturings X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=088aad46fdd7c0c7f3e52107c1d5b5bd1c76c95d;p=jcore.git Added criteria stuff for data-gateway patterm + a lot refacturings Signed-off-by:Roland Häder --- diff --git a/src/org/mxchange/jcore/BaseFrameworkSystem.java b/src/org/mxchange/jcore/BaseFrameworkSystem.java index d31239b..68e74ab 100644 --- a/src/org/mxchange/jcore/BaseFrameworkSystem.java +++ b/src/org/mxchange/jcore/BaseFrameworkSystem.java @@ -262,15 +262,14 @@ public class BaseFrameworkSystem implements FrameworkInterface { /** * Aborts program with given exception * - * @param throwable Any type of Throwable + * @param throwable Any type of Throwable */ - protected final void abortProgramWithException (final Throwable throwable) { + protected void abortProgramWithException (final Throwable throwable) { // Log exception ... this.getLogger().catching(throwable); // .. and exit System.exit(1); - } /** @@ -749,7 +748,7 @@ 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 */ @@ -835,4 +834,39 @@ public class BaseFrameworkSystem implements FrameworkInterface { return isBool; } + /** + * Sets value in properties instance. + * + * @param key Property key (part) to set + * @param value Property value to set + */ + protected void setProperty (final String key, final String value) { + // Trace message + this.getLogger().trace(MessageFormat.format("key={0},value={1} - CALLED!", key, value)); + + // Set it + properties.setProperty(String.format("org.mxchange.%s", key), value); + + // Trace message + this.getLogger().trace("EXIT!"); + } + + /** + * Some getter for properties names (without org.mxchange) + * + * @return An array with property names + */ + protected String[] getPropertyNames () { + // Init array + String[] names = { + "database.backend.class", + "database.mysql.login", + "database.mysql.host", + "database.mysql.password", + "database.mysql.dbname", + }; + + // Return it + return names; + } } diff --git a/src/org/mxchange/jcore/criteria/BaseCriteria.java b/src/org/mxchange/jcore/criteria/BaseCriteria.java new file mode 100644 index 0000000..36028fc --- /dev/null +++ b/src/org/mxchange/jcore/criteria/BaseCriteria.java @@ -0,0 +1,47 @@ +/* + * 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.criteria; + +import java.util.HashMap; +import java.util.Map; +import org.mxchange.jcore.BaseFrameworkSystem; + +/** + * A general criteria class + * + * @author Roland Haeder + */ +public class BaseCriteria extends BaseFrameworkSystem implements Criteria { + /** + * Criteria map + */ + private final Map criteria; + + /** + * Protected default construtctor + */ + protected BaseCriteria () { + // Init criteria instance + this.criteria = new HashMap<>(); + } + + @Override + public void addCriteria (final String key, final boolean value) { + // Add to map + this.criteria.put(key, value); + } +} diff --git a/src/org/mxchange/jcore/criteria/Criteria.java b/src/org/mxchange/jcore/criteria/Criteria.java new file mode 100644 index 0000000..a2003ec --- /dev/null +++ b/src/org/mxchange/jcore/criteria/Criteria.java @@ -0,0 +1,36 @@ +package org.mxchange.jcore.criteria; + +/* + * 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 . + */ + + +import org.mxchange.jcore.FrameworkInterface; + +/** + * A general interface for criteria + * + * @author Roland Haeder + */ +public interface Criteria extends FrameworkInterface { + /** + * Adds a binary criteria + * + * @param key Key of criteria + * @param value Value of criteria + */ + public void addCriteria (final String key, final boolean value); +} diff --git a/src/org/mxchange/jcore/criteria/searchable/SearchCriteria.java b/src/org/mxchange/jcore/criteria/searchable/SearchCriteria.java new file mode 100644 index 0000000..6f85f44 --- /dev/null +++ b/src/org/mxchange/jcore/criteria/searchable/SearchCriteria.java @@ -0,0 +1,32 @@ +/* + * 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.criteria.searchable; + +import org.mxchange.jcore.criteria.BaseCriteria; + +/** + * A search criteria class + * + * @author Roland Haeder + */ +public class SearchCriteria extends BaseCriteria implements SearchableCritera { + /** + * Default constructor + */ + public SearchCriteria () { + } +} diff --git a/src/org/mxchange/jcore/criteria/searchable/SearchableCritera.java b/src/org/mxchange/jcore/criteria/searchable/SearchableCritera.java new file mode 100644 index 0000000..5f85a36 --- /dev/null +++ b/src/org/mxchange/jcore/criteria/searchable/SearchableCritera.java @@ -0,0 +1,29 @@ +package org.mxchange.jcore.criteria.searchable; + +import org.mxchange.jcore.criteria.Criteria; + +/* + * 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 . + */ + + +/** + * A searchable criteria + * + * @author Roland Haeder + */ +public interface SearchableCritera extends Criteria { +} diff --git a/src/org/mxchange/jcore/database/backend/DatabaseBackend.java b/src/org/mxchange/jcore/database/backend/DatabaseBackend.java index 3a81542..26a6c4c 100644 --- a/src/org/mxchange/jcore/database/backend/DatabaseBackend.java +++ b/src/org/mxchange/jcore/database/backend/DatabaseBackend.java @@ -16,12 +16,11 @@ */ package org.mxchange.jcore.database.backend; -import java.io.IOException; import java.sql.SQLException; -import java.util.Iterator; import org.mxchange.jcore.FrameworkInterface; +import org.mxchange.jcore.criteria.searchable.SearchableCritera; +import org.mxchange.jcore.database.result.Result; import org.mxchange.jcore.database.storage.Storeable; -import org.mxchange.jcore.exceptions.BadTokenException; /** * A generic interface for database frontends @@ -38,71 +37,17 @@ public interface DatabaseBackend extends FrameworkInterface { public void connectToDatabase () throws SQLException; /** - * Shuts down this backend - */ - public void doShutdown (); - - /** - * Some "getter" for row index from given boolean row value - * - * @param columnName Name of column - * @param bool Boolean value to look for - * @return Row index - */ - public int getRowIndexFromColumn (final String columnName, final boolean bool); - - /** - * Some "getter" for total table row count - * - * @return Total row count - * @throws java.sql.SQLException If an SQL error occurs - */ - public int getTotalCount () throws SQLException; - - /** - * Checks whether at least one row is found with given boolean value. + * Run a "SELECT" statement with given criteria and always return a Result + * instance. The result instance then provides methods to iterate over all + * found entries. * - * @param columnName Column to check for boolean value - * @param bool Boolean value to check - * @return Whether boolean value is found and returns at least one row - * @throws java.sql.SQLException If an SQL error occurs - */ - public boolean isRowFound (final String columnName, final boolean bool) throws SQLException; - - /** - * Rewinds backend + * @param critera Search critera + * @return A result instance */ - public void rewind (); + public Result doSelectByCriteria (final SearchableCritera critera); /** - * Get length of underlaying file - * - * @return Length of underlaying file - */ - public long length (); - - /** - * Stores an object in the database. - * - * @param object Object to store in database - * @throws java.io.IOException From inner class - */ - public void store (final Storeable object) throws IOException; - - /** - * Gets an iterator for contacts - * - * @return Iterator for contacts - * @throws org.mxchange.jcore.exceptions.BadTokenException If the CSV token is badly formulated - */ - public Iterator iterator () throws BadTokenException; - - /** - * Reads a single row from database. - * - * @param rowIndex Row index (or how much to skip) - * @return A Storeable instance - * @throws org.mxchange.jcore.exceptions.BadTokenException If a token was badly formatted + * Shuts down this backend */ - public Storeable readRow (final int rowIndex) throws BadTokenException; + public void doShutdown (); } diff --git a/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java b/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java index da18a25..c8a54cb 100644 --- a/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java +++ b/src/org/mxchange/jcore/database/backend/base64/Base64CsvDatabaseBackend.java @@ -16,22 +16,21 @@ */ package org.mxchange.jcore.database.backend.base64; -import java.io.DataOutput; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.sql.SQLException; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import javax.xml.bind.DatatypeConverter; import org.mxchange.jcore.FrameworkInterface; +import org.mxchange.jcore.criteria.searchable.SearchableCritera; 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.result.Result; import org.mxchange.jcore.database.storage.Storeable; -import org.mxchange.jcore.database.storage.csv.StoreableCsv; import org.mxchange.jcore.exceptions.BadTokenException; /** @@ -94,6 +93,11 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat // Empty body } + @Override + public Result doSelectByCriteria (final SearchableCritera critera) { + throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: criteria={0}", critera)); + } + /** * Shuts down this backend */ @@ -114,182 +118,12 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat this.getLogger().trace("EXIT!"); //NOI18N } - /** - * Some "getter" for row index from given boolean row value - * - * @param columnName Name of column - * @param bool Boolean value to look for - * @return Row index - */ - @Override - public int getRowIndexFromColumn (final String columnName, final boolean bool) { - // Trace message - this.getLogger().trace(MessageFormat.format("columnName={0},bool={1} - CALLED!", columnName, bool)); //NOI18N - - // Row indexes start with zero - int rowIndex = 0; - - // First rewind - this.rewind(); - - // Try to find the proper row - while (!this.isEndOfFile()) { - // Read line - String line = this.readLine(); - - // Debug message - this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N - - // Callback the frontend to handle parsing - try { - Storeable storeable = this.getFrontend().parseLineToStoreable(line); - - // Debug message - this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N - - // Is the value qual - if (storeable.isValueEqual(columnName, bool)) { - // Debug message - this.getLogger().debug(MessageFormat.format("Found storeable={0} for columnName={1} and bool={2}", storeable, columnName, bool)); //NOI18N - - // Found it - break; - } - } catch (final BadTokenException ex) { - // Bad token found - this.abortProgramWithException(ex); - } - - // Count up - rowIndex++; - } - - // Return it - return rowIndex; - } - - /** - * Some "getter" for total row count - * - * @return Total row count - */ - @Override - public int getTotalCount () { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - try { - // Do a deprecated call - // @todo this needs rewrite! - return this.readList().size(); - } catch (final BadTokenException ex) { - this.abortProgramWithException(ex); - } - - // Invalid return - this.getLogger().trace("Returning -1 ... : EXIT!"); //NOI18N - return -1; - } - - /** - * Checks whether at least one row is found with given boolean value. - * - * @param columnName Column to check for boolean value - * @param bool Boolean value to check - * @return Whether boolean value is found and returns at least one row - */ - @Override - public boolean isRowFound (final String columnName, final boolean bool) { - // Trace message - this.getLogger().trace(MessageFormat.format("columnName={0},bool={1} - CALLED!", columnName, bool)); //NOI18N - - // Is at least one entry found? - if (this.getTotalCount() == 0) { - // No entry found at all - return false; - } - - // Default is not found - boolean isFound = false; - - // Firsr rewind - this.rewind(); - - // Then loop through all lines - while (!this.isEndOfFile()) { - // Read line - String line = this.readLine(); - - // Debug message - this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N - - try { - // And parse it to a Contact instance - Storeable storeable = this.getFrontend().parseLineToStoreable(line); - - // Debug message - this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N - - // This should not be null - if (storeable == null) { - // Throw exception - throw new NullPointerException("storeable is null"); //NOI18N - } - - // Now let the contact object check if it has such attribute - if (storeable.isValueEqual(columnName, bool)) { - // Yes, it is set - isFound = true; - break; - } - } catch (final BadTokenException ex) { - // Don't continue with bad data - this.abortProgramWithException(ex); - } - } - - // Trace message - this.getLogger().trace(MessageFormat.format("isFound={0} - EXIT!", isFound)); //NOI18N - - // Return result - return isFound; - } - - /** - * Gets an iterator for contacts - * - * @return Iterator for contacts - * @throws org.mxchange.jcore.exceptions.BadTokenException If the - * underlaying method has found an invalid token - */ - @Override - public Iterator iterator () throws BadTokenException { - // Trace message - this.getLogger().trace("CALLED!"); //NOI18N - - /* - * Then read the file into RAM (yes, not perfect for >1000 entries ...) - * and get a List back. - */ - List list = this.readList(); - - // List must be set - assert (list instanceof List) : "list has not been set."; //NOI18N - - // Trace message - this.getLogger().trace(MessageFormat.format("list.iterator()={0} - EXIT!", list.iterator())); //NOI18N - - // Get iterator from list and return it - return list.iterator(); - } - /** * Get length of underlaying file * * @return Length of underlaying file */ - @Override - public long length () { + private long length () { long length = 0; try { @@ -306,52 +140,10 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat return length; } - /** - * Reads a single row from database. - * - * @param rowIndex Row index (or how much to skip) - * @return A Storeable instance - * @throws org.mxchange.jcore.exceptions.BadTokenException If a token - * was badly formatted - */ - @Override - public Storeable readRow (final int rowIndex) throws BadTokenException { - // First rewind - this.rewind(); - - // Intialize variables - int count = -1; - Storeable storeable = null; - - // Read all rows - while (!this.isEndOfFile() || (count < rowIndex)) { - // Read row - String line = this.readLine(); - - // Debug message - this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N - - // Callback the frontend to handle parsing - storeable = this.getFrontend().parseLineToStoreable(line); - - // Debug message - this.getLogger().debug(MessageFormat.format("storeable={0}", storeable)); //NOI18N - - // Increment counter - count++; - } - - // Trace message - this.getLogger().trace(MessageFormat.format("storeable={0} - EXIT!", storeable)); //NOI18N - // Return found element - return storeable; - } - /** * Rewinds backend */ - @Override - public void rewind () { + private void rewind () { // Trace message this.getLogger().trace("CALLED!"); //NOI18N @@ -367,45 +159,6 @@ public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements Dat this.getLogger().trace("EXIT!"); //NOI18N } - /** - * Stores given object by "visiting" it - * - * @param object An object implementing Storeable - * @throws java.io.IOException From "inner" class - */ - @Override - public void store (final Storeable object) throws IOException { - // Trace message - this.getLogger().trace(MessageFormat.format("object={0} - CALLED!", object)); //NOI18N - - // Object must not be null - if (object == null) { - // Abort here - throw new NullPointerException("object is null"); //NOI18N - } - - // Make sure the instance is there (DataOutput flawor) - assert (this.storageFile instanceof DataOutput); - - // Try to cast it, this will fail if the interface is not implemented - StoreableCsv csv = (StoreableCsv) object; - - // Now get a string from the object that needs to be stored - String str = csv.getCsvStringFromStoreableObject(); - - // Debug message - this.getLogger().debug(MessageFormat.format("str({0})={1}", str.length(), str)); //NOI18N - - // Encode line in BASE-64 - String encoded = DatatypeConverter.printBase64Binary(str.getBytes()); - - // The string is now a valid CSV string - this.getStorageFile().write(encoded.getBytes()); - - // Trace message - this.getLogger().trace("EXIT!"); //NOI18N - } - /** * Adds given contact to list * diff --git a/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java b/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java index 1924861..cf77ec6 100644 --- a/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java +++ b/src/org/mxchange/jcore/database/backend/mysql/MySqlDatabaseBackend.java @@ -16,19 +16,17 @@ */ package org.mxchange.jcore.database.backend.mysql; -import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.text.MessageFormat; -import java.util.Iterator; +import org.mxchange.jcore.criteria.searchable.SearchableCritera; 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.result.Result; import org.mxchange.jcore.database.storage.Storeable; -import org.mxchange.jcore.exceptions.BadTokenException; import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException; /** @@ -116,6 +114,11 @@ public class MySqlDatabaseBackend extends BaseDatabaseBackend implements Databas this.getLogger().trace("EXIT!"); //NOI18N } + @Override + public Result doSelectByCriteria (final SearchableCritera critera) { + throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: criteria={0}", critera)); + } + @Override public void doShutdown () { // This should not happen: @@ -129,94 +132,4 @@ public class MySqlDatabaseBackend extends BaseDatabaseBackend implements Databas this.abortProgramWithException(ex); } } - - /** - * Some "getter" for row index from given boolean row value - * - * @param columnName Name of column - * @param bool Boolean value to look for - * @return Row index - */ - @Override - public int getRowIndexFromColumn (final String columnName, final boolean bool) { - throw new UnsupportedOperationException(MessageFormat.format("columnName={0},bool={1}", columnName, bool)); - } - - @Override - public int getTotalCount () throws SQLException { - // Trace message - this.getLogger().trace(MessageFormat.format("tableName={0} - CALLED!", this.getTableName())); //NOI18N - - // Nothing counted by default - int count = 0; - - // Prepared statements are cool ... - if (this.totalRowCount.execute()) { - // Did fully work, so get result set - ResultSet set = this.totalRowCount.getResultSet(); - - // First rewind it - assert(set.last()) : ": last() failed"; //NOI18N - - // Get integer from 'cnt' alias (see statement) - count = set.getInt("cnt"); //NOI18N - - // Debug message - this.getLogger().debug(MessageFormat.format("count={0}", count)); //NOI18N - - // Go back to beginning - set.beforeFirst(); - } else { - // Empty result - this.getLogger().warn(MessageFormat.format("COUNT() query didn't return any result on table {0}.", this.getTableName())); //NOI18N - } - - // Trace message - this.getLogger().trace(MessageFormat.format("count={0} - EXIT!", count)); //NOI18N - - // Return result - return count; - } - - /** - * Checks whether at least one row is found with given boolean value. - * - * @param columnName Column to check for boolean value - * @param bool Boolean value to check - * @return Whether boolean value is found and returns at least one row - */ - @Override - public boolean isRowFound (final String columnName, final boolean bool) throws SQLException { - // Is at least one entry found? - if (this.getTotalCount() == 0) { - // No entry found at all - return false; - } - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Iterator iterator () throws BadTokenException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public long length () { - throw new UnsupportedOperationException("Not implemented for this backend."); //NOI18N - } - - @Override - public Storeable readRow (final int rowIndex) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void rewind () { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void store (final Storeable object) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } } diff --git a/src/org/mxchange/jcore/database/result/Result.java b/src/org/mxchange/jcore/database/result/Result.java new file mode 100644 index 0000000..32b00dd --- /dev/null +++ b/src/org/mxchange/jcore/database/result/Result.java @@ -0,0 +1,30 @@ +/* + * 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.database.result; + +import java.util.Iterator; +import org.mxchange.jcore.FrameworkInterface; +import org.mxchange.jcore.database.storage.Storeable; + +/** + * An interface for database results + * + * @author Roland Haeder + * @param Anything that is storeable + */ +public interface Result extends FrameworkInterface, Iterator, Iterable { +} diff --git a/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java b/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java index d86cfb5..821779b 100644 --- a/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java +++ b/src/org/mxchange/jcore/factory/database/backend/BackendFactory.java @@ -54,6 +54,12 @@ public class BackendFactory extends BaseFrameworkSystem { // Debug message factory.getLogger().debug(MessageFormat.format("className={0}", className)); //NOI18N + // Is it null? + if (className == null) { + // Not valid + throw new NullPointerException("className is null"); //NOI18N + } + // Try to get the instance Class reflection = Class.forName(className);