*/
package org.mxchange.jcore;
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.logging.log4j.LogManager;
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.database.storage.Storable;
import org.mxchange.jcore.manager.Manageable;
/**
*/
private static ResourceBundle bundle;
- /**
- * Instance for own properties
- */
- private static final Properties properties = new Properties(System.getProperties());
-
/**
* Self instance
*/
*/
private Application application;
- /**
- * Instance for database backend
- */
- private DatabaseBackend backend;
-
/**
* Client instance
*/
*/
private Contact contact;
- /**
- * DatabaseFrontend instance
- */
- private DatabaseFrontend frontend;
-
/**
* Manager instance
*/
this.getLogger().catching(exception);
}
- /**
- * Initializes properties with default values
- */
- private void initPropertiesWithDefault () {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Init default values:
- // Default database backend
- BaseFrameworkSystem.properties.put("org.mxchange.database.backend.class", "org.mxchange.jcore.database.backend.base64.Base64CsvDatabaseBackend"); //NOI18N
- BaseFrameworkSystem.properties.put("org.mxchange.database.backend.storagepath", "data/"); //NOI18N
- BaseFrameworkSystem.properties.put("org.mxchange.database.datasource.name", ""); //NOI18N
-
- // For MySQL backend
- BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.host", "localhost"); //NOI18N
- BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.dbname", "test"); //NOI18N
- BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.login", ""); //NOI18N
- BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.password", ""); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Writes the properties file to disk
- */
- private void writePropertiesFile () throws IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Write it
- BaseFrameworkSystem.properties.store(new PrintWriter(FrameworkInterface.PROPERTIES_CONFIG_FILE), "This file is automatically generated. You may wish to alter it."); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
/**
* Converts a column name like "foo_bar" to an attribute name like "fooBar"
*
return value;
}
- /**
- * Getter for property which must exist
- *
- * @param key Key to get
- * @return Propety value
- */
- protected final String getProperty (final String key) {
- return BaseFrameworkSystem.properties.getProperty(String.format("org.mxchange.%s", key)); //NOI18N
- }
-
/**
* Name of used database table, handled over to backend
*
this.tableName = tableName;
}
- /**
- * Some getter for type reflection of given column name
- *
- * @param instance The instance to check
- * @param targetClass Target class to check
- * @param columnName Column name
- * @return Type reflection of value
- */
- private Class<?> getType (final FrameworkInterface instance, final String targetClass, final String columnName) {
- // Trace message
- this.getLogger().trace(MessageFormat.format("instance={0},targetClass={1},columnName={2} - CALLED!", instance, targetClass, columnName)); //NOI18N
-
- // Init field tye
- Class<?> type = null;
-
- // Get super class fields
- Field[] superFields = this.getClassFromTarget(instance, "BaseFrameworkSystem").getDeclaredFields(); //NOI18N
-
- // Get all attributes from given instance
- Field[] fields = ArrayUtils.addAll(superFields, this.getClassFromTarget(instance, targetClass).getDeclaredFields());
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("fields()={0}", fields.length)); //NOI18N
-
- // Convert column_name to fieldName ;-)
- String fieldName = this.convertColumnNameToFieldName(columnName);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("fieldName={0}", fieldName)); //NOI18N
-
- // Search for proper field instance
- for (final Field field : fields) {
- // Is a dollar character there?
- if (field.getName().startsWith("$")) { //NOI18N
- // Debug message
- this.getLogger().debug(MessageFormat.format("Field name {0} starts with a dollar, skipped.", field.getName())); //NOI18N
- // Skip this
- continue;
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("field.getName()={0},fieldName={1}", field.getName(), fieldName)); //NOI18N
-
- // Does it match?
- if (field.getName().equals(fieldName)) {
- // Found it
- type = field.getType();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Found fieldName={0}: setting type={1}", fieldName, type.getSimpleName())); //NOI18N
-
- // Don't continue with searching
- break;
- }
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("type={0}", type)); //NOI18N
-
- // type should not be null
- if (null == type) {
- // No null allowed
- throw new NullPointerException("type is null"); //NOI18N
- }
-
- // Trace message
- this.getLogger().debug(MessageFormat.format("type={0} - EXIT!", type)); //NOI18N
-
- // Return it
- return type;
- }
-
/**
* Converts null to empty string or leaves original string.
*
return str;
}
- /**
- * 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
- * @throws java.lang.NoSuchMethodException If the called method does not
- * exist
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- protected Iterator<Map.Entry<Field, Object>> fieldIterator (final Storable instance, final String className) throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("instance={0},className={1} - CALLED!", instance, className)); //NOI18N
-
- // 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)); //NOI18N
-
- // A simple map with K=fieldName and V=Value is fine
- Map<Field, Object> map = new HashMap<>(fields.length);
-
- // Walk through all
- for (final Field field : fields) {
- // Debug log
- this.getLogger().debug(MessageFormat.format("field={0}", field.getName())); //NOI18N
-
- // Does the field start with "$"?
- if (field.getName().startsWith("$")) { //NOI18N
- // Debug message
- this.getLogger().debug(MessageFormat.format("Skipping field={0} as it starts with a dollar character.", field.getName())); //NOI18N
-
- // Skip it silently
- continue;
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Calling getValueFromColumn({0}) on instance {1} ...", field.getName(), instance)); //NOI18N
-
- // Get value from it
- Object value = instance.getValueFromColumn(field.getName());
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Adding field={0},value={1}", field.getName(), value)); //NOI18N
-
- // Add it to list
- map.put(field, value);
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Returning iterator for {0} entries ...", map.size())); //NOI18N
-
- // Return list iterator
- return map.entrySet().iterator();
- }
-
- /**
- * 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;
- }
-
/**
* Getter for Contact instance
*
this.contact = contact;
}
- /**
- * Getter for DatabaseFrontend instance
- *
- * @return DatabaseFrontend instance
- */
- protected final DatabaseFrontend getFrontend () {
- return this.frontend;
- }
-
- /**
- * Setter for wrapper instance
- *
- * @param frontend A DatabaseFrontend instance
- */
- protected final void setFrontend (final DatabaseFrontend frontend) {
- this.frontend = frontend;
- }
-
- /**
- * Some getter for properties names (without org.mxchange)
- *
- * @return An array with property names
- */
- protected String[] getPropertyNames () {
- // Init array
- String[] names = {
- "database.backend.class", //NOI18N
- "database.backend.storagepath", //NOI18N
- "database.mysql.login", //NOI18N
- "database.mysql.host", //NOI18N
- "database.mysql.password", //NOI18N
- "database.mysql.dbname", //NOI18N
- };
-
- // Return it
- return names;
- }
-
- /**
- * Some "getter" for a value from given Storable instance and target class
- *
- * @param instance An instance of a Storable class
- * @param targetClass The target class (where the field resides)
- * @param columnName Column name (= field name)
- * @return value Value to get
- * @throws java.lang.NoSuchMethodException If the getter was not found
- * @throws java.lang.IllegalAccessException If the getter cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Some other problems?
- */
- protected Object getValueInStorableFromColumn (final Storable instance, final String targetClass, final String columnName) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("instance={0},targetClass={1},columnName={2} - CALLED!", instance, targetClass, columnName)); //NOI18N
-
- // A '$' means not our field
- if (columnName.startsWith("$")) { //NOI18N
- // Don't handle these
- throw new IllegalArgumentException("columnsName contains $"); //NOI18N
- }
-
- // Determine if the given column is boolean
- if (this.isBooleanField(instance, targetClass, columnName)) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Column {0} represents a boolean field.", columnName)); //NOI18N
-
- // Yes, then call other method
- return this.getBooleanField(instance, targetClass, this.convertColumnNameToGetterMethod(columnName, true));
- }
-
- // Convert column name to field name
- String methodName = this.convertColumnNameToGetterMethod(columnName, false);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("methodName={0}", methodName)); //NOI18N
-
- // Get field
- Object value = this.getField(instance, targetClass, methodName);
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
-
- // Return value
- return value;
- }
-
/**
* Initializes i18n bundles
*/
this.getLogger().trace("EXIT!"); //NOI18N
}
- /**
- * Prepares all properties, the file is written if it is not found
- *
- * @throws java.io.IOException If any IO problem occurs
- */
- protected void initProperties () throws IOException {
- // 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();
- }
-
- // 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
- * @return Whether the given column name represents a boolean field
- */
- protected boolean isBooleanField (final FrameworkInterface instance, final String targetClass, final String columnName) {
- // Trace message
- this.getLogger().trace(MessageFormat.format("instance={0},targetCLass={1},columnName={2} - CALLED!", instance, targetClass, columnName)); //NOI18N
-
- // Convert column name to getter name (boolean)
- String methodName = this.convertColumnNameToGetterMethod(columnName, true);
-
- // Get class instance
- Class<? extends FrameworkInterface> c = this.getClassFromTarget(instance, targetClass);
-
- // Defauzlt is boolean
- boolean isBool = true;
-
- try {
- // Now try to instance the method
- Method method = c.getDeclaredMethod(methodName, new Class<?>[0]);
- } catch (final NoSuchMethodException ex) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Method {0} does not exist, field {1} cannot be boolean: {2}", methodName, columnName, ex)); //NOI18N
-
- // Not found
- isBool = false;
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("isBool={0} - EXIT!", isBool)); //NOI18N
-
- // Return result
- return isBool;
- }
-
/**
* Checks if the bundle is initialized
*
// Check it
return (bundle instanceof ResourceBundle);
}
-
- /**
- * Sets boolean field value with given method name by invoking it
- *
- * @param instance The instance to call
- * @param targetClass Target class to look in
- * @param methodName Method name to look for
- * @param columnName Column name
- * @param value Boolean value from field
- * @throws java.lang.NoSuchMethodException If the method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Some other problems?
- */
- protected void setBooleanField (final FrameworkInterface instance, final String targetClass, final String methodName, final String columnName, final Boolean value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace messahe
- this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N
-
- // Get field type
- Class<?> type = this.getType(instance, targetClass, columnName);
-
- // Get method instance
- Method method = this.getMethodFromName(instance, targetClass, methodName, type);
-
- // Try to get the value by invoking the method
- method.invoke(instance, value);
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Sets any field value with given method name by invoking it
- *
- * @param instance The instance to call
- * @param targetClass Target class to look in
- * @param methodName Method name to look for
- * @param columnName Column name
- * @param value Any value from field
- * @throws java.lang.NoSuchMethodException If the method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Some other problems?
- */
- protected void setField (final FrameworkInterface instance, final String targetClass, final String methodName, final String columnName, final Object value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace messahe
- this.getLogger().trace(MessageFormat.format("instance={0},targetClass={1},methodName={2},value={3}", instance, targetClass, methodName, value)); //NOI18N
-
- // Get field type
- Class<?> type = this.getType(instance, targetClass, columnName);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("type={0}", type)); //NOI18N
-
- // Init object
- Object object = value;
-
- // Is the value null?
- if ("null".equals(value)) { //NOI18N
- // Warning message
- this.getLogger().warn(MessageFormat.format("columnName={0} has null value.", columnName)); //NOI18N
-
- // Set null
- object = null;
- } else {
- // Hard-coded "cast" again ... :-(
- // TODO Can't we get rid of this???
- switch (type.getSimpleName()) {
- case "Long": // Long object //NOI18N
- object = Long.parseLong((String) value);
- break;
-
- case "Float": // Float object //NOI18N
- object = Float.parseFloat((String) value);
- break;
-
- case "Boolean": // Boolean object //NOI18N
- object = Boolean.parseBoolean((String) value);
- break;
-
- case "String": // String object //NOI18N
- break;
-
- default: // Unsupported type
- throw new IllegalArgumentException(MessageFormat.format("value {0} has unsupported type {1}", value, type.getSimpleName())); //NOI18N
- }
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("object={0}", object)); //NOI18N
-
- // Get method to call
- Method method = this.getMethodFromName(instance, targetClass, methodName, type);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("method={0},instance={1},value[{2}]={3}", method, instance, value.getClass().getSimpleName(), value)); //NOI18N
-
- // Get value from field
- method.invoke(instance, object);
-
- // Trace messahe
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * 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)); //NOI18N
-
- // Both should not be null
- if (null == key) {
- // key is null
- throw new NullPointerException("key is null"); //NOI18N
- } else if (null == value) {
- // value is null
- throw new NullPointerException("value is null"); //NOI18N
- }
-
- // Set it
- properties.setProperty(String.format("org.mxchange.%s", key), value); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Some "setter" for a value in given Storable instance and target class
- *
- * @param instance An instance of a Storable class
- * @param targetClass The target class (where the field resides)
- * @param columnName Column name (= field name)
- * @param value Value to set
- * @throws java.lang.NoSuchMethodException If the setter is not found
- * @throws java.lang.IllegalAccessException If the setter cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problem?
- */
- protected void setValueInStorableFromColumn (final Storable instance, final String targetClass, final String columnName, final Object value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("instance={0},targetClass={1},columnName={2},value={3} - CALLED!", instance, targetClass, columnName, value)); //NOI18N
-
- // A '$' means not our field
- if (columnName.startsWith("$")) { //NOI18N
- // Don't handle these
- throw new IllegalArgumentException("columnsName contains $"); //NOI18N
- }
-
- // Determine if the given column is boolean
- if (this.isBooleanField(instance, targetClass, columnName)) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Column {0} represents a boolean field.", columnName)); //NOI18N
-
- // Yes, then call other method
- this.setBooleanField(instance, targetClass, this.convertColumnNameToSetterMethod(columnName), columnName, (Boolean) value);
- }
-
- // Convert column name to field name
- String methodName = this.convertColumnNameToSetterMethod(columnName);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("methodName={0}", methodName)); //NOI18N
-
- // Get field
- this.setField(instance, targetClass, methodName, columnName, value);
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
}
*/
public static final String I18N_BUNDLE_FILE = "org/mxchange/localization/bundle";
- /*
- * Properties file name
- */
- public static final String PROPERTIES_CONFIG_FILE = "config.properties";
-
/**
* Getter for manager
*
*/
package org.mxchange.jcore.contact;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
-import java.util.Iterator;
-import java.util.Map;
import java.util.Objects;
import org.mxchange.jcore.BaseFrameworkSystem;
import org.mxchange.jcore.client.Client;
return translated;
}
- /**
- * Some "getter for a value from given column name. This name will be
- * translated into a method name and then this method is called.
- *
- * @param columnName Column name
- * @return Value from field
- */
- @Override
- public Object getValueFromColumn (final String columnName) throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("columnName={0} - CALLED!", columnName)); //NOI18N
-
- // A '$' means not our field
- if (columnName.startsWith("$")) { //NOI18N
- // Don't handle these
- throw new IllegalArgumentException("columnsName contains $"); //NOI18N
- }
-
- // Determine if the given column is boolean
- if (this.isBooleanField(this, "BaseContact", columnName)) { //NOI18N
- // Debug message
- this.getLogger().debug(MessageFormat.format("Column {0} represents a boolean field.", columnName)); //NOI18N
-
- // Yes, then call other method
- return this.getBooleanField(this, "BaseContact", this.convertColumnNameToGetterMethod(columnName, true)); //NOI18N
- }
-
- // Convert column name to field name
- String methodName = this.convertColumnNameToGetterMethod(columnName, false);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("field={0}", methodName)); //NOI18N
-
- // Get field
- Object value = this.getField(this, "BaseContact", methodName); //NOI18N
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("value={0} - EXIT!", value)); //NOI18N
-
- // Return it
- return value;
- }
-
/**
* ZIP code
*
return hash;
}
- /**
- * Checks if given boolean field is available and set to same value
- *
- * @param columnName Column name to check
- * @param bool Boolean value
- * @return Whether all conditions are met
- */
- @Override
- public boolean isFieldValueEqual (final String columnName, final boolean bool) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("columnName={0},bool={1} - CALLED!", columnName, bool)); //NOI18N
-
- // Convert column name to field name
- String methodName = this.convertColumnNameToGetterMethod(columnName, true);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("field={0}", methodName)); //NOI18N
-
- // Init class instance
- boolean value = this.getBooleanField(this, "BaseContact", methodName); //NOI18N
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N
-
- // Compare it
- boolean isFound = (bool == value);
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("isFound={0} - EXIT!", isFound)); //NOI18N
-
- // Return result
- return isFound;
- }
-
/**
* Checks whether the contact is user's own data
*
return this.ownContact;
}
- /**
- * Returns an iterator of all values from this object
- * @return An iterator
- */
- @Override
- public Iterator<Map.Entry<Field, Object>> iterator () throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- return this.fieldIterator(this, "BaseContact"); //NOI18N
- }
-
- @Override
- public void setValueFromColumn (final String columnName, final Object value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("columnName={0},value={1} - CALLED!", columnName, value)); //NOI18N
-
- // Call super method
- this.setValueInStorableFromColumn(this, "BaseContact", columnName, value); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
/**
* Shows this contact to the user
*
*/
package org.mxchange.jcore.contact;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Iterator;
-import java.util.Map;
+import org.mxchange.jcore.FrameworkInterface;
import org.mxchange.jcore.client.Client;
import org.mxchange.jcore.contact.gender.Gender;
-import org.mxchange.jcore.database.storage.Storable;
/**
* A general contact interface
*
* @author Roland Haeder
*/
-public interface Contact extends Storable, Comparable<Contact> {
- /**
- * Returns an iterator of all values from this object
- *
- * @return An iterator
- * @throws java.lang.NoSuchMethodException If the invoked method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public Iterator<Map.Entry<Field, Object>> iterator ()throws NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
+public interface Contact extends FrameworkInterface, Comparable<Contact> {
/**
* Some "getter" for translated gender of the contact
*
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.criteria.logical.Logical;
-
-/**
- * A general criteria class
- *
- * @author Roland Haeder
- */
-public class BaseCriteria extends BaseFrameworkSystem implements Criteria {
- /**
- * Criteria map
- */
- private final Map<String, Object> criteria;
-
- /**
- * Logical matcher instance
- */
- private Logical logcial;
-
- /**
- * 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);
- }
-
- @Override
- public void addCriteria (final String key, final String value) {
- // Add to map
- this.criteria.put(key, value);
- }
-
- @Override
- public void addCriteria (final String key, final Number value) {
- this.criteria.put(key, value);
- }
-
- @Override
- public Set<Map.Entry<String, Object>> entrySet () {
- return this.criteria.entrySet();
- }
-
- /**
- * Setter for Logical instance
- *
- * @param logcial the Logical instance to set
- */
- public final void setLogical (final Logical logcial) {
- this.logcial = logcial;
- }
-
- @Override
- public Iterable<Object> values () {
- // Call map's method
- return this.criteria.values();
-
- }
-
- /**
- * Getter for Logical matcher instance
- *
- * @return Logical matcher instance
- */
- protected final Logical getLogical () {
- return this.logcial;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria;
-
-import java.util.Map;
-import java.util.Set;
-import org.mxchange.jcore.FrameworkInterface;
-import org.mxchange.jcore.criteria.logical.Logical;
-
-/**
- * A general interface for criteria
- *
- * @author Roland Haeder
- */
-public interface Criteria extends FrameworkInterface {
- /**
- * Adds a boolean criteria
- *
- * @param key Key of criteria
- * @param value Value of criteria
- */
- public void addCriteria (final String key, final Boolean value);
-
- /**
- * Adds a string criteria
- *
- * @param key Key of criteria
- * @param value Value of criteria
- */
- public void addCriteria (final String key, final String value);
-
- /**
- * Adds a number criteria
- *
- * @param key Key of criteria
- * @param value Value of criteria
- */
- public void addCriteria (final String key, final Number value);
-
- /**
- * Gets all values from underlaying map in an iterator.
- *
- * @return Values iteratable
- */
- public Iterable<Object> values ();
-
- /**
- * Gets all entries as a key-value pair
- *
- * @return Key-value paira of all entries
- */
- public Set<Map.Entry<String, Object>> entrySet ();
-
- /**
- * Setter for logical matcher instance
- *
- * @param logical Logical matcher instance
- */
- public void setLogical (final Logical logical);
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria.logical;
-
-import java.util.Map;
-import java.util.Set;
-import org.mxchange.jcore.FrameworkInterface;
-
-/**
- * An interface for logical tests
- *
- * @author Roland Haeder
- */
-public interface Logical extends FrameworkInterface {
-
- /**
- * Checks logical match condition
- *
- * @param entrySet Entry set where the values are
- * @param criteriaMatches Criteria matches
- * @return Whether it matches
- */
- public boolean matches (final Set<Map.Entry<String, Object>> entrySet, final Map<String, Boolean> criteriaMatches);
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria.logical.and;
-
-import java.text.MessageFormat;
-import java.util.Map;
-import java.util.Set;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.criteria.logical.Logical;
-
-/**
- * A boolean AND "logical matcher" class
- *
- * @author Roland Haeder
- */
-public class AndLogicalMatcher extends BaseFrameworkSystem implements Logical {
- /**
- * Default constructor
- */
- public AndLogicalMatcher () {
- }
-
- @Override
- public boolean matches (final Set<Map.Entry<String, Object>> entrySet, final Map<String, Boolean> criteriaMatches) {
- // Trace message
- this.getLogger().trace(MessageFormat.format("entrySet={0},criteriaMatches={1} - CALLED!", entrySet, criteriaMatches)); //NOI18N
-
- // Default is matching, then check if something is not matching and set result to false
- boolean matches = true;
-
- // Walk through set
- for (Map.Entry<String, Object> entry : entrySet) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("entry.key={0},entry.value={1}", entry.getKey(), entry.getValue())); //NOI18N
-
- // Check all matches
- for (Map.Entry<String, Boolean> criteriaMatch : criteriaMatches.entrySet()) {
- // Get key and value
- String criteriaKey = criteriaMatch.getKey();
- Boolean criteriaMatching = criteriaMatch.getValue();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("criteriaKey={0},criteriaMatching={1}", criteriaKey, criteriaMatching)); //NOI18N
-
- // Is both the same and false?
- if ((entry.getKey().equals(criteriaKey)) && (!criteriaMatching)) {
- // Debug message
- this.getLogger().debug("Not matching, aborting search."); //NOI18N
-
- // Doesn't match
- matches = false;
- break;
- }
- }
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("matches={0} - EXIT!", matches)); //NOI18N
-
- // Return it
- return matches;
- }
-
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria.searchable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import org.mxchange.jcore.criteria.BaseCriteria;
-import org.mxchange.jcore.database.storage.Storable;
-
-/**
- * A search criteria class
- *
- * @author Roland Haeder
- */
-public class SearchCriteria extends BaseCriteria implements SearchableCriteria {
- /**
- * Limit of matches
- */
- private int limit;
-
- /**
- * Skipping of matches
- */
- private int skip;
-
- /**
- * Default constructor
- */
- public SearchCriteria () {
- }
-
- @Override
- public int getLimit () {
- return this.limit;
- }
-
- @Override
- public final void setLimit (final int limit) {
- this.limit = limit;
- }
-
- @Override
- public int getSkip () {
- return this.skip;
- }
-
- @Override
- public final void setSkip (final int skip) {
- this.skip = skip;
- }
-
- @Override
- public boolean matches (final Storable storable) throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("storable={0} - CALLED!", storable)); //NOI18N
-
- // Must not be null
- if (null == storable) {
- // Abort here
- throw new NullPointerException("storable is null"); //NOI18N
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("this.entrySet().size()={0}", this.entrySet().size())); //NOI18N //NOI18N
-
- // No matches found?
- if (this.entrySet().isEmpty()) {
- // Debug message
- this.getLogger().debug("No criteria set, returning true ..."); //NOI18N
-
- // Then there is nothing to match!
- return true;
- }
-
- // Init matches array
- Map<String, Boolean> criteriaMatches = new HashMap<>(this.entrySet().size());
-
- // Check all conditions
- for (final Map.Entry<String, Object> criteria : this.entrySet()) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("criteria: key={0},value[{1}]={2}", criteria.getKey(), criteria.getValue().getClass().getSimpleName(), criteria.getValue())); //NOI18N
-
- // Get value from column name
- Object value = storable.getValueFromColumn(criteria.getKey());
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0},getValue()={1}", value, criteria.getValue())); //NOI18N
-
- // Is both same?
- if (((null == value) && ("null".equals(criteria.getValue()))) || ((value != null) && (value.equals(criteria.getValue())))) { //NOI18N
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0} - MATCHES!", value)); //NOI18N
-
- // Matching criteria found
- criteriaMatches.put(criteria.getKey(), true);
- }
- }
-
- // Init matches
- boolean matches = false;
-
- // Is only one entry given?
- if (this.entrySet().size() == 1) {
- // Okay, one criteria only, no need for a "complex" logical match check
- matches = (criteriaMatches.size() == 1);
- } else if (this.getLogical() == null) {
- // Logical instance is null
- throw new NullPointerException(MessageFormat.format("logical is not set, but more than one column ({0}/{1}) shall be matched.", this.entrySet().size(), criteriaMatches.size())); //NOI18N
- } else if (this.entrySet().size() == criteriaMatches.size()) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("entrySet.size()={0},criteriaMatches.size()={1} - Calling matches() on {2} ...", this.entrySet().size(), criteriaMatches.size(), this.getLogical())); //NOI18N
-
- // Now for the final test
- matches = this.getLogical().matches(this.entrySet(), criteriaMatches);
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("matches={0} - EXIT!", matches)); //NOI18N
-
- // Return result
- return matches;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.criteria.searchable;
-
-import java.lang.reflect.InvocationTargetException;
-import org.mxchange.jcore.criteria.Criteria;
-import org.mxchange.jcore.database.storage.Storable;
-
-/**
- * A searchable criteria
- *
- * @author Roland Haeder
- */
-public interface SearchableCriteria extends Criteria {
- /**
- * Checks if the given instance of a Storable class matches
- *
- * @param storable A Storable instance to check
- * @return Whether the Storable instance matches
- * @throws IllegalArgumentException Some implementations may throw this
- * @throws java.lang.NoSuchMethodException If the invoked method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public boolean matches (final Storable storable) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
-
- /**
- * Setter for limit of possible matches
- *
- * @param limit Limit of matches
- */
- public void setLimit (final int limit);
-
- /**
- * Getter for limit of possible matches
- *
- * @return Limit of matches
- */
- public int getLimit ();
-
- /**
- * Setter for skipping of possible matches
- *
- * @param skip Skipping of matches
- */
- public void setSkip (final int skip);
-
- /**
- * Getter for skipping of possible matches
- *
- * @return Skipping of matches
- */
- public int getSkip ();
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.backend;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.Enumeration;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException;
-
-/**
- * Generall database backend
- *
- * @author Roland Haeder
- */
-public abstract class BaseDatabaseBackend extends BaseFrameworkSystem {
-
- /**
- * No instances from this class
- */
- protected BaseDatabaseBackend () {
- }
-
- /**
- * Validates driver name and throws an exception if the driver is not valid
- *
- * @param driverName Driver name (e.g. "mysql")
- * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException If the given driver name cannot be solved into a driver instance
- */
- protected void validateDriver (final String driverName) throws UnsupportedDatabaseDriverException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("driverName={0} - CALLED!", driverName)); //NOI18N
-
- // driverName shall not be null
- if (null == driverName) {
- // Is null
- throw new NullPointerException("driverName is null");
- }
-
- // Get all registered/installed drivers
- Enumeration<Driver> drivers = DriverManager.getDrivers();
-
- // Default is not found
- boolean isFound = false;
-
- // Search for it
- while (drivers.hasMoreElements()) {
- // Get element
- Driver driver = drivers.nextElement();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Driver {0} is installed.", driver)); //NOI18N
-
- // Get class name
- String className = driver.getClass().getName();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("className={0}", className));
-
- // Is this wanted?
- if (className.contains(driverName)) {
- // Debug message
- this.getLogger().debug("Found driver!"); //NOI18N
-
- // Found it
- isFound = true;
- break;
- }
- }
-
- // Debug message
- this.getLogger().debug("isFound=" + isFound);
-
- // Is it found?
- if (!isFound) {
- // Throw exception
- throw new UnsupportedDatabaseDriverException(driverName);
- }
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- public int numRows (final SearchableCriteria criteria) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- // Trace message
- this.getLogger().trace("criteria=" + criteria + " - CALLED!");
-
- // Criteria should not be null
- if (null == criteria) {
- // Abort here
- throw new NullPointerException("criteria is null");
- }
-
- // Run "SELECT"
- Result<? extends Storable> result = this.doSelectByCriteria(criteria);
-
- // Get size
- int numRows = result.size();
-
- // Trace message
- this.getLogger().trace("numRows=" + numRows + " - EXIT!");
-
- // Return it
- return numRows;
- }
-
- /**
- * Runs a SELECT "query" on database backend
- *
- * @param criteria Criteria instance
- * @return Result instance
- * @throws java.io.IOException If any IO error occurs
- * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
- * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the file is badly damaged
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.lang.NoSuchMethodException If a method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public abstract Result<? extends Storable> doSelectByCriteria (SearchableCriteria criteria) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.backend;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.SQLException;
-import java.util.Map;
-import javax.naming.NamingException;
-import org.mxchange.jcore.FrameworkInterface;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-
-/**
- * A generic interface for database frontends
- *
- * @author Roland Haeder
- */
-public interface DatabaseBackend extends FrameworkInterface {
-
- /**
- * Tries a connection to the database
- *
- * @throws java.sql.SQLException If the connection attempt fails
- * @throws javax.naming.NamingException May be thrown by a backend implementation
- */
- public void connectToDatabase () throws SQLException, NamingException;
-
- /**
- * Inserts given dataset instance and returns a Result instance on success.
- * The callee should not modify any content of the dataset instance.
- *
- * @param dataset A dataset instance
- * @return An instance of Result
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.io.IOException If an IO error occurs
- */
- public Result<? extends Storable> doInsertDataSet (final Map<String, Object> dataset) throws SQLException, IOException;
-
- /**
- * 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.
- *
- * The callee should not modify any content of the criteria instance.
- *
- * @param criteria Search criteria
- * @return A result instance
- * @throws java.io.IOException If any IO error occurs
- * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
- * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the file is badly damaged
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.lang.NoSuchMethodException If a method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public Result<? extends Storable> doSelectByCriteria (final SearchableCriteria criteria) throws IOException, BadTokenException, CorruptedDatabaseFileException, SQLException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
-
- /**
- * Shuts down this backend
- *
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.io.IOException If any IO error occurs
- */
- public void doShutdown () throws SQLException, IOException;
-
- /**
- * Some getter for total rows
- *
- * @return Total rows
- * @throws java.io.IOException If an IO error occurs
- * @throws java.sql.SQLException If any SQL error occurs
- */
- public int getTotalRows () throws IOException, SQLException;
-
- /**
- * Number of total found rows.
- *
- * @param criteria Search criteria instance
- * @return Number of found rows
- * @throws java.io.IOException If any IO error occurs
- * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token was found
- * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If the file is badly damaged
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.lang.NoSuchMethodException If a method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public int numRows (final SearchableCriteria criteria) throws IOException, SQLException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.backend.base64;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.apache.commons.codec.binary.Base64;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-import org.mxchange.jcore.database.backend.BaseDatabaseBackend;
-import org.mxchange.jcore.database.backend.DatabaseBackend;
-import org.mxchange.jcore.database.file.DatabaseFile;
-import org.mxchange.jcore.database.file.SynchronizeableFile;
-import org.mxchange.jcore.database.frontend.DatabaseFrontend;
-import org.mxchange.jcore.database.result.DatabaseResult;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-
-/**
- * A database backend with CSV file as storage implementation
- *
- * @author Roland Haeder
- */
-public class Base64CsvDatabaseBackend extends BaseDatabaseBackend implements DatabaseBackend {
- /**
- * File name to access
- */
- private final String fileName;
-
- /**
- * Output stream for this storage engine
- */
- private final SynchronizeableFile storageFile;
-
- /**
- * Constructor with table name
- *
- * @param frontend Wrapper instance to call back
- * @throws java.io.FileNotFoundException If the file was not found
- */
- public Base64CsvDatabaseBackend (final DatabaseFrontend frontend) throws FileNotFoundException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("frontend={0} - CALLED!", frontend)); //NOI18N
-
- // Get table name
- String tableName = frontend.getTableName();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Trying to initialize table {0} ...", tableName)); //NOI18N
-
- // Set table name here, too
- this.setTableName(tableName);
-
- // Set frontend here
- this.setFrontend(frontend);
-
- // Construct file name
- this.fileName = String.format("%s/table_%s.b64", this.getProperty("database.backend.storagepath"), tableName); //NOI18N
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Trying to open file {0} ...", this.fileName)); //NOI18N
-
- try {
- // Try to initialize the storage (file instance)
- this.storageFile = new DatabaseFile(this.fileName); //NOI18N
- } catch (final FileNotFoundException ex) {
- // Did not work
- this.getLogger().error(MessageFormat.format("File {0} cannot be opened: {1}", this.fileName, ex.toString())); //NOI18N
- throw ex;
- }
-
- // Output message
- this.getLogger().debug(MessageFormat.format("Database for {0} has been initialized.", tableName)); //NOI18N
- }
-
- /**
- * This database backend does not need to connect
- */
- @Override
- public void connectToDatabase () {
- // Empty body
- }
-
- @Override
- public Result<? extends Storable> doInsertDataSet (final Map<String, Object> dataset) throws IOException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("dataset={0} - CALLED!", dataset)); //NOI18N
-
- // dataset should not be null and not empty
- if (null == dataset) {
- // It is null, so abort here
- throw new NullPointerException("dataset is null"); //NOI18N
- } else if (dataset.isEmpty()) {
- // It is empty, also abort here
- throw new IllegalArgumentException("dataset is empty"); //NOI18N
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Need to parse {0} values ...", dataset.size())); //NOI18N
-
- // Get iterator from it
- Iterator<Map.Entry<String, Object>> iterator = dataset.entrySet().iterator();
-
- // Full output string
- StringBuilder output = new StringBuilder(dataset.size() * 20);
-
- // Add index column
- output.append(String.format("key=%s,value=\"%s\";", this.getFrontend().getIdName(), this.getTotalRows() + 1)); //NOI18N
-
- // "Walk" over all entries
- while (iterator.hasNext()) {
- // Get next entry
- Map.Entry<String, Object> entry = iterator.next();
-
- // Get value
- Object value = entry.getValue();
-
- // Validate value, should not contain "
- if (value instanceof String) {
- // Is String so cast ist
- String str = (String) value;
-
- // Does it contain a " ?
- if (str.contains("\"")) { //NOI18N
- // Don't accept here
- throw new IllegalArgumentException(MessageFormat.format("value {0} with double-quote not supported yet.", value)); //NOI18N
- }
- }
-
- // Generate key=value pair
- String pair = String.format("key=%s,value=\"%s\";", entry.getKey(), String.valueOf(value)); //NOI18N
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("pair={0}", pair)); //NOI18N
-
- // Append to output
- output.append(pair);
- }
-
- // Then write it to file
- this.writeData(output);
-
- // The result set needs to be transformed into Result, so initialize a result instance here
- Result<? extends Storable> result = new DatabaseResult();
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("result={0} - EXIT!", result)); //NOI18N
-
- // Return it
- return result;
- }
-
- @Override
- public Result<? extends Storable> doSelectByCriteria (final SearchableCriteria criteria) throws IOException, BadTokenException, CorruptedDatabaseFileException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("criteria={0} - CALLED!", criteria)); //NOI18N
-
- // Init result instance
- Result<? extends Storable> result = new DatabaseResult();
-
- // First rewind this backend
- this.rewind();
-
- // Then loop over all rows until the end has reached
- while (!this.isEndOfFile()) {
- // Read line
- String line = this.readLine();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N
-
- // Parse it to a Map<String, Object>
- Map<String, String> map = this.getMapFromLine(line);
-
- // Convert it to a Storable instance
- Storable storable = this.getFrontend().toStorable(map);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("storable={0}", storable)); //NOI18N
-
- // Now matches the found instance
- if (criteria.matches(storable)) {
- // Then add it to result
- result.add(storable);
- }
- }
-
- // Return the result
- return result;
- }
-
- /**
- * Shuts down this backend
- */
- @Override
- public void doShutdown () throws IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Close file
- this.getStorageFile().close();
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- @Override
- public final int getTotalRows () throws IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Init count
- int count = 0;
-
- // First rewind
- this.rewind();
-
- // Walk through all rows
- while (!this.isEndOfFile()) {
- // Get next line
- String line = this.readLine();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("line={0}", line)); //NOI18N
-
- // Count one up
- count++;
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("count={0} - EXIT!", count)); //NOI18N
-
- // Return it
- return count;
- }
-
- /**
- * Tries to interpret the given decoded line and puts its key/value pairs
- * into a map.
- *
- * @param line Decoded line from database file
- * @return A Map with keys and values from line
- * @throws org.mxchange.jcore.exceptions.CorruptedDatabaseFileException If
- * the file is believed damaged
- * @throws org.mxchange.jcore.exceptions.BadTokenException If a bad token
- * was found
- */
- private Map<String, String> getMapFromLine (final String line) throws CorruptedDatabaseFileException, BadTokenException {
- // Trace message
- this.getLogger().debug(MessageFormat.format("line={0} - CALLED!", line)); //NOI18N
-
- // "line" must not be null or empty
- if (null == line) {
- // Is null
- throw new NullPointerException("line is null"); //NOI18N
- } else if (line.isEmpty()) {
- // Is empty
- throw new IllegalArgumentException("line is empty, maybe isEndOfFile() was not called?"); //NOI18N
- } else if (!line.endsWith(";")) { //NOI18N
- // Bad line found
- throw new CorruptedDatabaseFileException(this.fileName, "No semicolon at end of line"); //NOI18N
- } else if (!line.contains("key=")) { //NOI18N
- // Bad line found
- throw new CorruptedDatabaseFileException(this.fileName, "No \"key=bla\" found."); //NOI18N
- } else if (!line.contains("value=")) { //NOI18N
- // Bad line found
- throw new CorruptedDatabaseFileException(this.fileName, "No \"value=bla\" found."); //NOI18N
- }
-
- Pattern pattern = Pattern.compile("(key=([a-zA-Z0-9_]{1,}),value=\"([^\"]*)\";){1,}"); //NOI18N
- Matcher matcher = pattern.matcher(line);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("matches={0}", matcher.matches())); //NOI18N
-
- // Matches?
- if (!matcher.matches()) {
- // Corrupted file found
- throw new CorruptedDatabaseFileException(this.fileName, MessageFormat.format("line {0} does not match regular expression.", line)); //NOI18N
- }
-
- // Instance map
- Map<String, String> map = new HashMap<>(line.length() / 40);
-
- pattern = Pattern.compile("(key=([a-zA-Z0-9_]{1,}),value=\"([^\"]*)\";)"); //NOI18N
- matcher = pattern.matcher(line);
-
- // Init group count
- int init = 0;
-
- // Then get all
- while (matcher.find(init)) {
- // Get group match
- String match = matcher.group(1);
- String key = matcher.group(2);
- String value = matcher.group(3);
-
- // Debug log
- this.getLogger().debug(MessageFormat.format("match={0},key={1},value={2}", match, key, value));
-
- // key must noch be empty
- assert ((key != null) && (!key.isEmpty())) : MessageFormat.format("key={0} is not valid", key); //NOI18N
-
- // Get start and end
- int start = matcher.start();
- int end = matcher.end();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("init={0},start={1},end={2},match={3},key={4},value={5}", init, start, end, match, key, value)); //NOI18N
-
- // Add key/value to map
- map.put(key, value);
-
- // Hop to next match
- init = end;
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("map()={0} - EXIT!", map.size())); //NOI18N
-
- // Return finished map
- return map;
- }
-
- /**
- * Returns storage file
- *
- * @return Storage file instance
- */
- private SynchronizeableFile getStorageFile () {
- return this.storageFile;
- }
-
- /**
- * Checks whether end of file has been reached
- *
- * @return Whether lines are left to read
- */
- private boolean isEndOfFile () {
- // Default is EOF
- boolean isEof = true;
-
- try {
- isEof = (this.getStorageFile().getFilePointer() >= this.length());
- } catch (final IOException ex) {
- // Length cannot be determined
- this.logException(ex);
- }
-
- // Return status
- this.getLogger().trace(MessageFormat.format("isEof={0} : EXIT!", isEof)); //NOI18N
- return isEof;
- }
-
- /**
- * Get length of underlaying file
- *
- * @return Length of underlaying file
- */
- private long length () throws IOException {
- // Trace message
- this.getLogger().trace("CALLED!");
-
- // Try to get length from file
- long length = this.getStorageFile().length();
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("length={0} : EXIT!", length)); //NOI18N
-
- // Return it
- return length;
- }
-
- /**
- * Reads a line from file base
- *
- * @return Read line from file
- */
- private String readLine () {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Init input
- String input = null;
-
- try {
- // Read single line
- String base64 = this.getStorageFile().readLine();
-
- // Is the line null?
- if (null == base64) {
- // Then throw NPE here
- throw new NullPointerException("base64 is null, maybe missed to call isEndOfFile() ?"); //NOI18N
- }
-
- // Decode BASE-64
- byte[] decoded = Base64.decodeBase64(base64);
-
- // Convert to string
- input = new String(decoded).trim();
- } catch (final IOException ex) {
- this.logException(ex);
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("input={0} - EXIT!", input)); //NOI18N
-
- // Return read string or null
- return input;
- }
-
- /**
- * Rewinds backend
- */
- private void rewind () throws IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Rewind underlaying database file
- this.getStorageFile().seek(0);
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Writes a line with BASE64 encoding to database file
- *
- * @param output Output string to write
- */
- private void writeData (final StringBuilder output) throws IOException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("output={0} - CALLED!", output)); //NOI18N
-
- // No null or empty strings
- if (null == output) {
- // Is null
- throw new NullPointerException("output is null"); //NOI18N
- } else if (output.length() == 0) {
- // Is empty
- throw new IllegalArgumentException("output is empty"); //NOI18N
- }
-
- // Encode it to BASE64
- String rawOutput = Base64.encodeBase64String(output.toString().getBytes());
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("rawOutput={0}", rawOutput)); //NOI18N
-
- // Write each line separately
- this.getStorageFile().writeBytes(String.format("%s\n", rawOutput)); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.backend.datasource;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.Map;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-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.Storable;
-import org.mxchange.jcore.exceptions.BadTokenException;
-import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException;
-
-/**
- * A backend class for MySQL connections
- *
- * @author Roland Haeder
- */
-public class DataSourceDatabaseBackend extends BaseDatabaseBackend implements DatabaseBackend {
- /**
- * Connection instance
- */
- private static Connection connection;
-
- /**
- * Prepared statement for total row count
- */
- private PreparedStatement totalRows;
-
- /**
- * Constructor with table name
- *
- * @param frontend An instance of the frontend
- * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException
- * If the requested driver is not supported
- */
- public DataSourceDatabaseBackend (final DatabaseFrontend frontend) throws UnsupportedDatabaseDriverException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("frontend={0} - CALLED!", frontend)); //NOI18N
-
- // Get table name
- String tableName = frontend.getTableName();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("tableName={0}", tableName)); //NOI18N
-
- // Now that the driver is there, set the table name
- this.setTableName(tableName);
-
- // Set frontend
- this.setFrontend(frontend);
- }
-
- @Override
- public void connectToDatabase () throws SQLException, NamingException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Is the connection given?
- if (null == connection) {
- // Initial context
- Context context = new InitialContext();
-
- // Get data source instance
- DataSource source = (DataSource) context.lookup("jdbc/pizza-service"); //NOI18N
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("source={0}", source)); //NOI18N
-
- // Now as all access data is stored in data source, get a connection from it
- connection = source.getConnection();
-
- // Debug log
- this.getLogger().debug(MessageFormat.format("connection={0}", connection)); //NOI18N
- }
-
- // Debug message
- this.getLogger().debug("Connection is up, preparing some statements ..."); //NOI18N
-
- // Set prepared statement
- this.totalRows = connection.prepareStatement(String.format("SELECT COUNT(`%s`) AS `cnt` FROM `%s` LIMIT 1", this.getFrontend().getIdName(), this.getTableName())); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- @Override
- public Result<? extends Storable> doInsertDataSet (final Map<String, Object> dataset) throws SQLException, IOException {
- throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: dataset={0}", dataset));
- }
-
- @Override
- public Result<? extends Storable> doSelectByCriteria (final SearchableCriteria criteria) throws IOException, BadTokenException, CorruptedDatabaseFileException, SQLException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- throw new UnsupportedOperationException(MessageFormat.format("Not supported yet: criteria={0}", criteria));
- }
-
- @Override
- public void doShutdown () throws SQLException, IOException {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public int getTotalRows () throws IOException, SQLException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Get long
- int count = 0;
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("count={0} - EXIT!", count)); //NOI18N
-
- // Return it
- return count;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-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 java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import org.mxchange.jcore.criteria.searchable.SearchableCriteria;
-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.DatabaseResult;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException;
-
-/**
- * A backend class for MySQL connections
- *
- * @author Roland Haeder
- */
-public class MySqlDatabaseBackend extends BaseDatabaseBackend implements DatabaseBackend {
- /**
- * An instance of a datbase connection
- */
- private static Connection connection;
-
- /**
- * Prepared statement for total row count
- */
- private PreparedStatement totalRows;
-
- /**
- * Constructor with table name
- *
- * @param frontend An instance of the frontend
- * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseDriverException
- * If the requested driver is not supported
- */
- public MySqlDatabaseBackend (final DatabaseFrontend frontend) throws UnsupportedDatabaseDriverException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("frontend={0} - CALLED!", frontend)); //NOI18N
-
- // Validate driver
- this.validateDriver("mysql"); //NOI18N
-
- // Get table name
- String tableName = frontend.getTableName();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("tableName={0}", tableName)); //NOI18N
-
- // Now that the driver is there, set the table name
- this.setTableName(tableName);
-
- // Set frontend
- this.setFrontend(frontend);
- }
-
- @Override
- public void connectToDatabase () throws SQLException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Is the connection already there?
- if (connection instanceof Connection) {
- // Is the connection really up?
- if (connection.isClosed()) {
- // Connection is closed again
- throw new SQLException("Connection is closed."); //NOI18N
- }
-
- // Already connected
- this.getLogger().debug("Connection is already established."); //NOI18N
-
- // No need to connect
- return;
- }
-
- // Generate connection string
- String connect = String.format("jdbc:mysql://%s/%s", //NOI18N
- this.getProperty("database.mysql.host"), //NOI18N
- this.getProperty("database.mysql.dbname") //NOI18N
- );
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Attempting to connect to {0} ...", connect)); //NOI18N
-
- // Now get a connection instance back
- connection = DriverManager.getConnection(
- connect,
- this.getProperty("database.mysql.login"), //NOI18N
- this.getProperty("database.mysql.password") //NOI18N
- );
-
- // Debug message
- this.getLogger().debug("Connection is up, preparing some statements ..."); //NOI18N
-
- // Set prepared statement
- this.totalRows = connection.prepareStatement(String.format("SELECT COUNT(`%s`) AS `cnt` FROM `%s` LIMIT 1", this.getFrontend().getIdName(), this.getTableName())); //NOI18N
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Inserts given dataset instance and returns a Result instance on success.
- * Please note that this method can insert only a single record into
- * database. Multiple inserts are not yet supported.
- *
- * @param dataset A dataset instance
- * @return An instance of Result
- * TODO Support more than one record being inserted in a separate method
- */
- @Override
- public Result<? extends Storable> doInsertDataSet (final Map<String, Object> dataset) throws SQLException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("dataset={0} - CALLED!", dataset)); //NOI18N
-
- // dataset should not be null and not empty
- if (null == dataset) {
- // It is null, so abort here
- throw new NullPointerException("dataset is null"); //NOI18N
- } else if (dataset.isEmpty()) {
- // It is empty, also abort here
- throw new IllegalArgumentException("dataset is empty"); //NOI18N
- }
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("Need to parse {0} values ...", dataset.size())); //NOI18N
-
- // Init values
- Set<Object> values = new LinkedHashSet<>(dataset.size());
-
- // Start with INSERT INTO
- StringBuilder query = new StringBuilder(String.format("INSERT INTO `%s` (", this.getTableName())); //NOI18N
- StringBuilder valueQuery = new StringBuilder("("); //NOI18N
-
- // Get iterator from it
- Iterator<Map.Entry<String, Object>> iterator = dataset.entrySet().iterator();
-
- // "Walk" over all entries
- while (iterator.hasNext()) {
- // Get next entry
- Map.Entry<String, Object> entry = iterator.next();
-
- // Add key as database column to query
- query.append(String.format("`%s`,", entry.getKey())); //NOI18N
-
- // Get value
- Object value = entry.getValue();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0} - BEFORE!", value)); //NOI18N
-
- // Handle possible empty->null convertion
- value = this.getFrontend().emptyStringToNull(entry.getKey(), value);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0} - AFTER!", value)); //NOI18N
-
- // Is the value null?
- if (null == value) {
- // Add null
- valueQuery.append("NULL,"); //NOI18N
- } else {
- // Add value
- valueQuery.append("?,"); //NOI18N
- values.add(value);
- }
- }
-
- // Now put all together
- query.replace(query.length() - 1, query.length(), ") VALUES "); //NOI18N
- query.append(valueQuery.substring(0, valueQuery.length() - 1));
- query.append(")"); //NOI18N
-
- // Full statement is complete here, better log it
- this.getLogger().debug(MessageFormat.format("query={0} is complete.", query)); //NOI18N
-
- // Prepare statement instance
- PreparedStatement statement = this.getPreparedStatement(query, values);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("statement={0}", statement));
-
- // Run it
- int status = statement.executeUpdate();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("status={0}", status)); //NOI18N
-
- // The result set needs to be transformed into Result, so initialize a result instance here
- Result<? extends Storable> result = new DatabaseResult(status, statement);
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("result={0} - EXIT!", result)); //NOI18N
-
- // Return it
- return result;
- }
-
- @Override
- public Result<? extends Storable> doSelectByCriteria (final SearchableCriteria criteria) throws SQLException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("criteria={0} - CALLED!", criteria)); //NOI18N
-
- // criteria must not be null
- if (null == criteria) {
- // Abort here
- throw new NullPointerException("criteria is null"); //NOI18N
- }
-
- // Start SELECT query
- StringBuilder query = new StringBuilder(String.format("SELECT * FROM `%s`", this.getTableName())); //NOI18N
-
- // Get entry set
- Set<Map.Entry<String, Object>> set = criteria.entrySet();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("set.isEmpty()={0}", set.isEmpty())); //NOI18N
-
- // Init values
- Set<Object> values = new LinkedHashSet<>(set.size());
-
- // Are there conditions?
- if (!set.isEmpty()) {
- // Continue with WHERE
- query.append(" WHERE "); //NOI18N
-
- // No more than 1 value currently
- if (set.size() > 1) {
- // Not supported yet
- throw new IllegalArgumentException("More than one criteria is not supported yet."); //NOI18N
- }
-
- // Get iterator
- Iterator<Map.Entry<String, Object>> iterator = set.iterator();
-
- // "Walk through all
- while (iterator.hasNext()) {
- // Get element
- Map.Entry<String, Object> entry = iterator.next();
-
- // Add key as column name
- query.append(String.format("`%s`", entry.getKey())); //NOI18N
-
- // Get value
- Object value = entry.getValue();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("value={0}", value)); //NOI18N
-
- // Add value
- query.append("=?"); //NOI18N
- values.add(value);
- }
- }
-
- // Is limit set?
- if (criteria.getLimit() > 0) {
- // Is skip set?
- if (criteria.getSkip() > 0) {
- // Limit with skip
- query.append(String.format(" LIMIT %d,%d", criteria.getSkip(), criteria.getLimit())); //NOI18N
- } else {
- // Only limit
- query.append(String.format(" LIMIT %d", criteria.getLimit())); //NOI18N
- }
- }
-
- // Full statement is complete here, better log it
- this.getLogger().debug(MessageFormat.format("query={0} is complete.", query)); //NOI18N
-
- // Get a prepared instance
- PreparedStatement statement = this.getPreparedStatement(query, values);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("statement={0}", statement));
-
- // Run it
- ResultSet resultSet = statement.executeQuery();
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("resultSet={0}", resultSet));
-
- // The result set needs to be transformed into Result, so initialize a result instance here
- Result<? extends Storable> result = this.getFrontend().getResultFromSet(resultSet);
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("result={0} - EXIT!", result)); //NOI18N
-
- // Return it
- return result;
- }
-
- @Override
- public void doShutdown () throws SQLException, IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Is the connection still there?
- if (!connection.isClosed()) {
- // Close down database connection
- connection.close();
- }
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- @Override
- public int getTotalRows () throws IOException, SQLException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Execute query
- ResultSet set = this.totalRows.executeQuery();
-
- // Rewind to beginning
- set.beforeFirst();
-
- // Get long
- int count = set.getInt("cnt"); //NOI18N
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("count={0} - EXIT!", count)); //NOI18N
-
- // Return it
- return count;
- }
-
- /**
- * Some "getter" for a prepared statement with inserted values
- *
- * @param query SQL query string
- * @param values Values set
- * @return A fully prepared statement
- */
- private PreparedStatement getPreparedStatement (final StringBuilder query, final Set<Object> values) throws SQLException {
- // Trace message
- this.getLogger().trace(MessageFormat.format("query={0},values={1} - CALLED!", query, values)); //NOI18N
-
- // Init prepared statement
- PreparedStatement statement = connection.prepareStatement(query.toString());
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("statement={0}", statement)); //NOI18N
-
- // Get iterator on values
- Iterator<Object> valueIterator = values.iterator();
-
- // Init index with 1
- int index = 1;
-
- // Set all values
- while (valueIterator.hasNext()) {
- // Get next value
- Object value = valueIterator.next();
-
- //Debug message
- this.getLogger().debug(MessageFormat.format("index={1} has value={0}", value, index)); //NOI18N
-
- // Detect type again
- if (value instanceof Boolean) {
- // Debug log
- this.getLogger().debug(MessageFormat.format("Setting boolean value={0} for index={1}", value, index)); //NOI18N
-
- // Found boolean
- statement.setBoolean(index, (boolean) value);
- } else if (value instanceof String) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Setting string value={0} for index={1}", value, index)); //NOI18N
-
- // Found string
- statement.setString(index, (String) value);
- } else if (value instanceof Integer) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Setting integer value={0} for index={1}", value, index)); //NOI18N
-
- // Found ineteger
- statement.setInt(index, (int) value);
- } else if (value instanceof Long) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Setting long value={0} for index={1}", value, index)); //NOI18N
-
- // Found ineteger
- statement.setLong(index, (long) value);
- } else if (value instanceof Float) {
- // Debug message
- this.getLogger().debug(MessageFormat.format("Setting float value={0} for index={1}", value, index)); //NOI18N
-
- // Found ineteger
- statement.setFloat(index, (float) value);
- } else if (null == value) {
- // Debug message
- this.getLogger().warn(MessageFormat.format("Null value in index={0} is not supported (yet)", index)); //NOI18N
- } else {
- // Not parseable type
- throw new SQLException(MessageFormat.format("Cannot handle value({0})={1} for index={2} in table {3}", value.getClass().getSimpleName(), value, index, this.getTableName())); //NOI18N
- }
-
- // Increment index
- index++;
- }
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("statement={0} - EXIT!", statement)); //NOI18N
-
- // Return it
- return statement;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.file;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import org.mxchange.jcore.BaseFrameworkSystem;
-
-/**
- * This implementation of SynchronizeableFile provides synchronized access on the RandomAccessFile
- instance. This implementation is thread-safe, therefor.
- *
- * @author Roland Haeder
- */
-public class DatabaseFile extends BaseFrameworkSystem implements SynchronizeableFile {
- /**
- * The actual file instance
- */
- private final RandomAccessFile file;
-
- /**
- * A constructor accepting a full-qualified file name (FQFN).
- * @param fqfn Full-qualified file name
- * @throws FileNotFoundException
- */
- public DatabaseFile (final String fqfn) throws FileNotFoundException {
- // Init it here
- this.file = new RandomAccessFile(fqfn, "rw"); //NOI18N
- }
-
- @Override
- public void close () throws IOException{
- synchronized (this.file) {
- this.file.close();
- }
- }
-
- @Override
- public long getFilePointer () throws IOException {
- synchronized (this.file) {
- return this.file.getFilePointer();
- }
- }
-
- @Override
- public long length () throws IOException {
- synchronized (this.file) {
- return this.file.length();
- }
- }
-
- @Override
- public String readLine () throws IOException {
- synchronized (this.file) {
- return this.file.readLine();
- }
- }
-
- @Override
- public void seek (final long i) throws IOException {
- synchronized (this.file) {
- this.file.seek(i);
- }
- }
-
- @Override
- public void writeBytes (final String string) throws IOException {
- synchronized (this.file) {
- this.file.writeBytes(string);
- }
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.file;
-
-import java.io.IOException;
-import org.mxchange.jcore.FrameworkInterface;
-
-/**
- * An interface for sy nchronized access on files, with auto-close support.
- *
- * @author Roland Haeder
- */
-public interface SynchronizeableFile extends FrameworkInterface, AutoCloseable{
-
- public void close () throws IOException;
-
- public long getFilePointer () throws IOException;
-
- public long length () throws IOException;
-
- public String readLine () throws IOException;
-
- public void seek (final long i) throws IOException;
-
- public void writeBytes (final String string) throws IOException;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.frontend;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import javax.naming.NamingException;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.database.backend.DatabaseBackend;
-import org.mxchange.jcore.database.result.DatabaseResult;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-import org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException;
-import org.mxchange.jcore.factory.database.backend.BackendFactory;
-
-/**
- * General database frontend class
- *
- * @author Roland Haeder
- */
-public abstract class BaseDatabaseFrontend extends BaseFrameworkSystem implements DatabaseFrontend {
- /**
- * A map instance for data sets being inserted
- */
- private final Map<String, Object> dataset;
-
- /**
- * Last num rows
- */
- private int lastNumRows = 0;
-
- /**
- * No instances from this class
- */
- protected BaseDatabaseFrontend () {
- // Init dataset instance
- this.dataset = new HashMap<>();
- }
-
- /**
- * Gets a Result back from given ResultSet instance. You may wish to
- * overwrite this method and call this with
- * super.getResultFromSet(resultSet) as this method doesn't do anything but
- * copy the SQLWarning instance to the Result instance.
- *
- * @param resultSet ResultSet instance from SQL driver
- * @return A typorized Result instance
- * @throws java.sql.SQLException If an SQL error occurs
- */
- @Override
- public Result<? extends Storable> getResultFromSet (final ResultSet resultSet) throws SQLException {
- // Init result instance
- Result<? extends Storable> result = new DatabaseResult();
-
- // Attach all possible warnings
- result.setWarnings(resultSet.getWarnings());
-
- // And return it
- return result;
- }
-
- /**
- * Adds given key-value pair to dataset instance. The key must not be null,
- * but value can be null.
- *
- * @param key Key to set
- * @param value Value to set or null
- */
- protected void addToDataSet (final String key, final Object value) {
- // Trace message
- this.getLogger().trace(MessageFormat.format("key={0},value={1} - CALLED!", key, value)); //NOI18N
-
- // Is key null?
- if (null == key) {
- // Key is null
- throw new NullPointerException("key is null"); //NOI18N
- } else if (null == value) {
- // Issue warning about null reference
- this.getLogger().warn(MessageFormat.format("value for key={0} is null, this may cause problems.", key));
- }
-
- // Add it to map
- this.dataset.put(key, value);
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Clears dataset instance. You should call this before you use it for
- * inserting data into your database.
- */
- protected void clearDataSet () {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Clear dataset
- this.dataset.clear();
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Inserts currently filled dataset and returns the result of the operation.
- * This may return no rows, but the affectedRows field may have been
- * updated.
- *
- * @return An instance of Result
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.io.IOException If an IO error occurs
- */
- protected Result<? extends Storable> doInsertDataSet () throws SQLException, IOException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Is the dataset instance empty?
- if (this.dataset.isEmpty()) {
- // Cannot insert an empty dataset
- throw new IllegalStateException("The dataset instance is empty."); //NOI18N
- }
-
- // Call backend method
- Result<? extends Storable> result = this.getBackend().doInsertDataSet(this.dataset);
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("result={0} - EXIT!", result)); //NOI18N
-
- // Return it
- return result;
- }
-
- /**
- * Initialize backend
- *
- * @throws org.mxchange.jcore.exceptions.UnsupportedDatabaseBackendException If the backend is not supported
- * @throws java.sql.SQLException If a SQL database backend fails to connect
- */
- protected void initBackend () throws UnsupportedDatabaseBackendException, SQLException {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Try it
- try {
- // Try to get get instance from factory
- DatabaseBackend backend = BackendFactory.createInstance(this);
-
- // Debug message
- this.getLogger().debug(MessageFormat.format("backend={0}", backend));
-
- // Try to run a connect on it
- backend.connectToDatabase();
-
- // All fine so far, then set it here
- this.setBackend(backend);
- } catch (final ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NamingException ex) {
- // Continue to throw
- throw new UnsupportedDatabaseBackendException(ex);
- }
-
- // Trace message
- this.getLogger().trace("EXIT!"); //NOI18N
- }
-
- /**
- * Setter for last num rows
- *
- * @param lastNumRows
- */
- protected final void setLastNumRows (final int lastNumRows) {
- // Set it here
- this.lastNumRows = lastNumRows;
- }
-
- /**
- * Getter for last num rows
- *
- * @return Last num rows
- */
- @Override
- public final int getLastNumRows () {
- return this.lastNumRows;
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.frontend;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-import org.mxchange.jcore.FrameworkInterface;
-import org.mxchange.jcore.database.result.Result;
-import org.mxchange.jcore.database.storage.Storable;
-
-/**
- * A generic interface for database frontends
- *
- * @author Roland Haeder
- */
-public interface DatabaseFrontend extends FrameworkInterface {
- /**
- * Depending on column, an empty value may be converted to null
- *
- * @param key Key to check
- * @param value Value to check
- * @return Possible previous value or null
- */
- public Object emptyStringToNull (final String key, final Object value);
-
- /**
- * Gets a Result back from given ResultSet instance
- *
- * @param resultSet ResultSet instance from SQL driver
- * @return A typorized Result instance
- * @throws java.sql.SQLException If an SQL error occurs
- */
- public Result<? extends Storable> getResultFromSet (final ResultSet resultSet) throws SQLException;
-
- /**
- * Returns a Storable instance from given row index. Value 0 means first
- * row and so on. Row index below zero results in an exception.
- *
- * @param rowIndex Row index too look for
- * @return A Storable instance
- */
- public Storable getStorableAtRow (final int rowIndex);
-
- /**
- * Name of used database table, handled over to backend
- *
- * @return the tableName
- */
- public String getTableName ();
-
- /**
- * Shuts down the database layer
- * @throws java.sql.SQLException If any SQL error occurs
- * @throws java.io.IOException If any IO error occurs
- */
- public void doShutdown () throws SQLException, IOException;
-
- /**
- * Converts the given map into a Storable instance, depending on which class implements it. All
- * keys are being interpreted as class fields/attributes and their respective setters are being searched for. As
- * this method may fail to find one or access it, this method throws some exception.
- *
- * @param map Map instance to convert to Storable
- * @return An instance of a Storable implementation
- * @throws IllegalArgumentException Some implementations may throw this
- * @throws java.lang.NoSuchMethodException If the invoked method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public Storable toStorable (final Map<String, String> map) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
-
- /**
- * Some getter for name of id column
- *
- * @return Name of id column
- */
- public String getIdName ();
-
- /**
- * Getter for last num rows
- *
- * @return Last num rows
- */
- public int getLastNumRows ();
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.result;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import org.mxchange.jcore.BaseFrameworkSystem;
-import org.mxchange.jcore.database.storage.Storable;
-
-/**
- * A database result
- * @author Roland Haeder
- */
-public class DatabaseResult extends BaseFrameworkSystem implements Result<Storable> {
- /**
- * Set of all found Storable instances
- */
- private final SortedSet<Storable> result;
-
- /**
- * Status value from previous executeUpdate() call
- */
- private int status;
-
- /**
- * SQLWarning instance
- */
- private SQLWarning warnings;
-
- /**
- * Default constructor
- */
- public DatabaseResult () {
- // Trace message
- this.getLogger().trace("CALLED!"); //NOI18N
-
- // Init set here
- this.result = new TreeSet<>();
- }
-
- /**
- * A constructor that accepts a status integer from previous executeUpdate()
- * call and a the prepared statement instance.
- *
- * @param status Status code
- * @param statement A PreparedStatement instance
- * @throws java.sql.SQLException If any SQL error occurs
- */
- public DatabaseResult (final int status, final PreparedStatement statement) throws SQLException {
- // Call parent constructor
- this();
-
- // Trace message
- this.getLogger().trace(MessageFormat.format("status={0},statement={1} - CALLED!", status, statement)); //NOI18N
-
- // Set warnings
- this.setWarnings(statement.getWarnings());
-
- // Set status
- this.status = status;
- }
-
- /**
- * Given Storable instance as a query result.
- *
- * @param storable An instance of a Storable class
- */
- @Override
- public final void add (final Storable storable) {
- // Add to result
- this.result.add(storable);
- }
-
- /**
- * Getter for warnings
- *
- * @return SQLQarning from ResultSet instance
- */
- @Override
- public final SQLWarning getWarnings () {
- return this.warnings;
- }
-
- /**
- * Setter for warnings
- *
- * @param warnings SQLQarning from ResultSet instance
- */
- @Override
- public final void setWarnings (final SQLWarning warnings) {
- this.warnings = warnings;
- }
-
- @Override
- public final boolean hasNext () {
- // Call iterator's method
- return this.iterator().hasNext();
- }
-
- @Override
- public final Iterator<Storable> iterator () {
- // Return iterator from result set
- return this.result.iterator();
- }
-
- @Override
- public final Storable next () {
- // Call iterator's method
- return this.iterator().next();
- }
-
- @Override
- public final void remove () {
- // Call iterator's method
- this.iterator().remove();
- }
-
- @Override
- public final int size () {
- return this.result.size();
- }
-
- @Override
- public SortedSet<? extends Storable> resultSet () {
- // Return it unmodifiable
- return Collections.unmodifiableSortedSet(this.result);
- }
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.result;
-
-import java.sql.SQLWarning;
-import java.util.Iterator;
-import java.util.SortedSet;
-import org.mxchange.jcore.FrameworkInterface;
-import org.mxchange.jcore.database.storage.Storable;
-
-/**
- * An interface for database results
- *
- * @author Roland Haeder
- * @param <T> Anything that is storable
- */
-public interface Result<T extends Storable> extends FrameworkInterface, Iterator<T>, Iterable<T> {
-
- /**
- * Given Storable instance as a query result.
- *
- * @param storable An instance of a Storable class
- */
- public void add (final Storable storable);
-
- /**
- * Setter for warnings
- *
- * @param warnings SQLQarning from ResultSet instance
- */
- public void setWarnings (final SQLWarning warnings);
-
- /**
- * Getter for warnings
- *
- * @return SQLQarning from ResultSet instance
- */
- public SQLWarning getWarnings ();
-
- /**
- * Returns size of result
- *
- * @return Size of result
- */
- public int size ();
-
- /**
- * Getter for a whole unmodifiable result set from this result. The id number is used as key
- *
- * @return A map from this result
- */
- public SortedSet<? extends Storable> resultSet ();
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.database.storage;
-
-import java.lang.reflect.InvocationTargetException;
-import org.mxchange.jcore.FrameworkInterface;
-
-/**
- * An interface for objects being stored in databases
- *
- * @author Roland Haeder
- */
-public interface Storable extends FrameworkInterface {
- /**
- * Some "getter for a value from given column name. This name will be
- * translated into a method name and then this method is called.
- *
- * @param columnName Column name
- * @return Value from field
- * @throws IllegalArgumentException Some implementations may throw this
- * @throws java.lang.NoSuchMethodException If the invoked method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public Object getValueFromColumn (final String columnName) throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
- /**
- * Some "setter" for a value from given column name. You may wish to overwrite this method in your
- * own class.
- *
- * @param columnName Column name
- * @param value Value to set in object's field
- * @throws IllegalArgumentException Some implementations may throw this
- * @throws java.lang.NoSuchMethodException If the invoked method was not found
- * @throws java.lang.IllegalAccessException If the method cannot be accessed
- * @throws java.lang.reflect.InvocationTargetException Any other problems?
- */
- public void setValueFromColumn (final String columnName, final Object value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.exceptions;
-
-import java.text.MessageFormat;
-
-/**
- * This exception is thrown when a token has been badly formated. This may
- * happen when a CSV file is broken.
- *
- * @author Roland Haeder
- */
-public class BadTokenException extends Exception {
-
- /**
- * Constructor with token and count
- * @param token Token that is not valid
- * @param count Count
- */
- public BadTokenException (final String token, final int count) {
- super(MessageFormat.format("Token {0} at position {1} has not double-quotes on both ends.", token, count));
- }
-
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.exceptions;
-
-/**
- * An exception thrown when the file is corrupted (damaged)
- *
- * @author Roland Haeder
- */
-public class CorruptedDatabaseFileException extends Exception {
-
- /**
- * Constructor with file name
- *
- * @param fileName File name
- * @param message Debug message
- */
- public CorruptedDatabaseFileException (final String fileName, final String message) {
- super("Database file \"" + fileName + "\" is corrupted: " + message);
- }
-
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.exceptions;
-
-import java.text.MessageFormat;
-
-/**
- * An exception thrown when the given backend type is not valid
- *
- * @author Roland Haeder
- */
-public class UnsupportedDatabaseBackendException extends Exception {
-
- /**
- * Constructor with only cause
- *
- * @param cause
- */
- public UnsupportedDatabaseBackendException (final Throwable cause) {
- // Call super constructor
- super(MessageFormat.format("Backend is not supported: {0}", cause), cause); //NOI18N
- }
-
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jcore.exceptions;
-
-import java.text.MessageFormat;
-
-/**
- * Thrown when the given driver is not found
- *
- * @author Roland Haeder
- */
-public class UnsupportedDatabaseDriverException extends Exception {
-
- /**
- * Default constructor with driver name
- * @param driverName
- */
- public UnsupportedDatabaseDriverException (final String driverName) {
- // Call super method
- super(MessageFormat.format("Database driver {0} is not found.", driverName)); //NOI18N
- }
-
-}
+++ /dev/null
-/*
- * 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 <http://www.gnu.org/licenses/>.
- */
-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
-
- // frontend must be set
- if (null == frontend) {
- // Is null
- throw new NullPointerException("frontend is null");
- }
-
- // Get property
- String className = factory.getProperty("database.backend.class"); //NOI18N
-
- // Debug message
- factory.getLogger().debug(MessageFormat.format("className={0}", className)); //NOI18N
-
- // Is it null?
- if (null == className) {
- // Not valid
- throw new NullPointerException("className is null"); //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(DatabaseFrontend.class);
-
- // 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;
- }
-
-}