X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2Forg%2Fmxchange%2Fjcore%2FBaseFrameworkSystem.java;h=db3b9ed493a30a629f68c05dca4bc866ee672162;hb=b25962fcb9ada480dd8e8879b74410188604f47b;hp=d31239b48a9f25fc822a8f44c953327834af7ba8;hpb=6d337a85f1ce70856d438dae7379f5705a2ca020;p=jcore.git diff --git a/src/org/mxchange/jcore/BaseFrameworkSystem.java b/src/org/mxchange/jcore/BaseFrameworkSystem.java index d31239b..db3b9ed 100644 --- a/src/org/mxchange/jcore/BaseFrameworkSystem.java +++ b/src/org/mxchange/jcore/BaseFrameworkSystem.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Properties; import java.util.ResourceBundle; import java.util.StringTokenizer; +import java.util.logging.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.mxchange.jcore.application.Application; @@ -40,6 +41,7 @@ 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.Storeable; import org.mxchange.jcore.manager.Manageable; /** @@ -171,19 +173,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { return this.getBundle().getString(key); } - /** - * 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. - */ - @Override - public Object getValueFromColumn (final String columnName) throws IllegalArgumentException { - throw new UnsupportedOperationException(MessageFormat.format("Not implemented. columnName={0}", columnName)); //NOI18N - } - /** * Some "getter" for target class instance from given name. * @@ -191,26 +180,26 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @param targetClass Class name to look for * @return Class instance */ - @SuppressWarnings ("unchecked") + @SuppressWarnings("unchecked") private Class getClassFromTarget (final FrameworkInterface instance, final String targetClass) { // Trace message this.getLogger().debug(MessageFormat.format("instance={0},targetClass={1}", instance, targetClass)); //NOI18N - + // Instance reflaction of this class Class c = instance.getClass(); - + // Analyze class while (!targetClass.equals(c.getSimpleName())) { // Debug message this.getLogger().debug(MessageFormat.format("c={0}", c.getSimpleName())); //NOI18N - + // Get super class (causes unchecked warning) c = (Class) c.getSuperclass(); } // Trace message this.getLogger().trace(MessageFormat.format("c={0} - EXIT!", c)); //NOI18N - + // Return it return c; } @@ -223,30 +212,51 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @param methodName Method name * @return A Method instance */ - private Method getMethodFromName (final FrameworkInterface instance, final String targetClass, final String methodName) { + private Method getMethodFromName (final FrameworkInterface instance, final String targetClass, final String methodName) throws NoSuchMethodException { // Trace messahe this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N - + // Get target class instance Class c = this.getClassFromTarget(instance, targetClass); - + // Init field instance - Method method = null; - - // Use reflection to get all attributes - try { - method = c.getDeclaredMethod(methodName, new Class[0]); - } catch (final SecurityException | NoSuchMethodException ex) { - // Security problem - this.abortProgramWithException(ex); - } - + Method method = c.getDeclaredMethod(methodName, new Class[0]); + // Assert on field assert (method instanceof Method) : "method is not a Method instance"; //NOI18N - + // Trace message this.getLogger().trace(MessageFormat.format("method={0} - EXIT!", method)); //NOI18N - + + // Return it + return method; + } + + /** + * Some "getter" for a Method instance from given method name + * + * @param instance Actual instance to call + * @param targetClass Target class name + * @param methodName Method name + * @param type Type reflection to check type from + * @return A Method instance + */ + private Method getMethodFromName (final FrameworkInterface instance, final String targetClass, final String methodName, final Class type) throws NoSuchMethodException { + // Trace messahe + this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1},type={2}", targetClass, methodName, type)); //NOI18N + + // Get target class instance + Class c = this.getClassFromTarget(instance, targetClass); + + // Init field instance + Method method = c.getDeclaredMethod(methodName, type); + + // Assert on field + assert (method instanceof Method) : "method is not a Method instance"; //NOI18N + + // Trace message + this.getLogger().trace(MessageFormat.format("method={0} - EXIT!", method)); //NOI18N + // Return it return method; } @@ -262,15 +272,14 @@ public class BaseFrameworkSystem implements FrameworkInterface { /** * Aborts program with given exception * - * @param throwable Any type of Throwable + * @param throwable Any type of Throwable */ protected final void abortProgramWithException (final Throwable throwable) { // Log exception ... this.getLogger().catching(throwable); - + // .. and exit System.exit(1); - } /** @@ -325,9 +334,12 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @param columnName Column name to check * @param bool Boolean value * @return Whether all conditions are met + * @throws NoSuchMethodException May be thrown by some implementations + * @throws java.lang.IllegalAccessException If the method cannot be accessed + * @throws java.lang.reflect.InvocationTargetException Any other problems? */ @Override - public boolean isValueEqual (final String columnName, final boolean bool) { + public boolean isFieldValueEqual (final String columnName, final boolean bool) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { // Not implemented throw new UnsupportedOperationException(MessageFormat.format("Not implemented. columnName={0},bool={1}", columnName, bool)); //NOI18N } @@ -353,6 +365,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { // 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("database.backend.storagepath", "data/"); //NOI18N // For MySQL backend BaseFrameworkSystem.properties.put("org.mxchange.database.mysql.host", "localhost"); //NOI18N @@ -367,16 +380,12 @@ public class BaseFrameworkSystem implements FrameworkInterface { /** * Writes the properties file to disk */ - private void writePropertiesFile () { + private void writePropertiesFile () throws IOException { // Trace message this.getLogger().trace("CALLED!"); //NOI18N - try { - // Write it - BaseFrameworkSystem.properties.store(new PrintWriter(FrameworkInterface.PROPERTIES_CONFIG_FILE), "This file is automatically generated. You may wish to alter it."); //NOI18N - } catch (final IOException ex) { - this.abortProgramWithException(ex); - } + // 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 @@ -440,7 +449,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { */ protected String convertColumnNameToGetterMethod (final String columnName, boolean isBool) { // Trace message - this.getLogger().trace(MessageFormat.format("columnName={0} - CALLED!", columnName)); //NOI18N + this.getLogger().trace(MessageFormat.format("columnName={0},isBool={1} - CALLED!", columnName, isBool)); //NOI18N // Then split on "_" StringTokenizer tokenizer = new StringTokenizer(columnName, "_"); //NOI18N @@ -480,6 +489,49 @@ public class BaseFrameworkSystem implements FrameworkInterface { return builder.toString(); } + /** + * Converts a column name like "foo_bar" to a method name like "getFooBar" + * for non-booleans and to "isFooBar" for boolean fields. + * + * @param columnName Column name to convert + * @return Attribute name + */ + protected String convertColumnNameToSetterMethod (final String columnName) { + // Trace message + this.getLogger().trace(MessageFormat.format("columnName={0} - CALLED!", columnName)); //NOI18N + + // Then split on "_" + StringTokenizer tokenizer = new StringTokenizer(columnName, "_"); //NOI18N + + // Resulting string + StringBuilder builder = new StringBuilder(tokenizer.countTokens()); + + // Append "set" + builder.append("set"); //NOI18N + + // Walk through all + while (tokenizer.hasMoreTokens()) { + // Get token + String token = tokenizer.nextToken(); + + // Debug message + this.getLogger().debug(MessageFormat.format("token={0}", token)); //NOI18N + + // Make it upper-case + char c = token.charAt(0); + token = String.valueOf(c).toUpperCase() + token.substring(1); + + // Add token + builder.append(token); + } + + // Trace message + this.getLogger().trace(MessageFormat.format("builder={0} - EXIT!", builder)); //NOI18N + + // Return result + return builder.toString(); + } + /** * Some "getter" for an array from given string and tokenizer * @@ -526,8 +578,11 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @param targetClass Target class to look in * @param methodName Method name to look for * @return 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 boolean getBooleanField (final FrameworkInterface instance, final String targetClass, final String methodName) { + protected boolean getBooleanField (final FrameworkInterface instance, final String targetClass, final String methodName) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // Trace messahe this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N @@ -535,19 +590,44 @@ public class BaseFrameworkSystem implements FrameworkInterface { Method method = this.getMethodFromName(instance, targetClass, methodName); // Get value from field - Boolean value = false; + Boolean value = (Boolean) method.invoke(instance); - try { - value = (Boolean) method.invoke(instance); - } catch (final IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { - // Other problem - this.abortProgramWithException(ex); - } + // Trace message + this.getLogger().trace("value=" + value + " - EXIT!"); // Return value return value; } + /** + * 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!"); + } + /** * Manager instance * @@ -564,26 +644,91 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @param targetClass Target class to look in * @param methodName Method name to look for * @return 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 Object getField (final FrameworkInterface instance, final String targetClass, final String methodName) { + protected Object getField (final FrameworkInterface instance, final String targetClass, final String methodName) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // Trace messahe - this.getLogger().trace(MessageFormat.format("targetClass={0},methodName={1}", targetClass, methodName)); //NOI18N - + this.getLogger().trace(MessageFormat.format("instance={0},targetClass={1},methodName={2}", instance, targetClass, methodName)); //NOI18N + // Get method to call Method method = this.getMethodFromName(instance, targetClass, methodName); - + + // Debug message + this.getLogger().debug("method=" + method + ",instance=" + instance); + // Get value from field - Object object = null; - - try { - object = method.invoke(instance); - } catch (final IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) { - // Other problem - this.abortProgramWithException(ex); - } + Object value = method.invoke(instance); + + // Trace messahe + this.getLogger().trace("value=" + value + " - EXIT!"); // Return value - return object; + return value; + } + + /** + * 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("type=" + type); + + // Init object + Object object = value; + + // Hard-coded "cast" again ... :-( + // @TODO Can't we get rid of this??? + switch (type.getSimpleName()) { + case "Long": // Long object + object = Long.parseLong((String) value); + break; + + case "Float": // Float object + object = Float.parseFloat((String) value); + break; + + case "Boolean": // Boolean object + object = Boolean.parseBoolean((String) value); + break; + + case "String": // String object + break; + + default: // Unsupported type + throw new IllegalArgumentException("value " + value + " has unsupported type " + type.getSimpleName()); + } + + // Debug message + this.getLogger().debug("object[" + object.getClass().getSimpleName() + "]=" + object); + + // Get method to call + Method method = this.getMethodFromName(instance, targetClass, methodName, type); + + // Debug message + this.getLogger().debug("method=" + method + ",instance=" + instance + ",value[" + value.getClass().getSimpleName() + "]=" + value); + + // Get value from field + method.invoke(instance, object); + + // Trace messahe + this.getLogger().trace("EXIT!"); } /** @@ -614,7 +759,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { protected Object convertNullToEmpty (final Object str) { // Trace message this.getLogger().trace(MessageFormat.format("str={0}", str)); //NOI18N - + // Is it null? if (str == null) { // Return empty string @@ -623,7 +768,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Trace message this.getLogger().trace(MessageFormat.format("str={0} - EXIT!", str)); //NOI18N - + // Return it return str; } @@ -634,8 +779,11 @@ public class BaseFrameworkSystem implements FrameworkInterface { * @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> fieldIterator (final FrameworkInterface instance, final String className) { + protected Iterator> fieldIterator (final Storeable instance, final String className) throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { // Trace message this.getLogger().trace(MessageFormat.format("instance={0},className={1} - CALLED!", instance, className)); //NOI18N @@ -663,7 +811,7 @@ public class BaseFrameworkSystem implements FrameworkInterface { } // Debug message - this.getLogger().debug(MessageFormat.format("Calling getValueFromColumn({0}) on instance {1} ...", field.getName(), instance)); + 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()); @@ -740,6 +888,9 @@ public class BaseFrameworkSystem implements FrameworkInterface { * Initializes i18n bundles */ protected void initBundle () { + // Trace message + this.getLogger().trace("CALLED!"); + // Is the bundle set? if (bundle instanceof ResourceBundle) { // Is already set @@ -748,12 +899,17 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Set instance bundle = ResourceBundle.getBundle(FrameworkInterface.I18N_BUNDLE_FILE); // NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); } - + /** * Prepares all properties, the file is written if it is not found + * + * @throws java.io.IOException If any IO problem occurs */ - protected void initProperties () { + protected void initProperties () throws IOException { // Trace message this.getLogger().trace("CALLED!"); //NOI18N @@ -784,9 +940,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Write file this.writePropertiesFile(); - } catch (final IOException ex) { - // Something else didn't work - this.abortProgramWithException(ex); } // Trace message @@ -823,9 +976,6 @@ public class BaseFrameworkSystem implements FrameworkInterface { // Not found isBool = false; - } catch (final SecurityException ex) { - // Really bad? - this.abortProgramWithException(ex); } // Trace message @@ -835,4 +985,185 @@ public class BaseFrameworkSystem implements FrameworkInterface { return isBool; } + /** + * Sets value in properties instance. + * + * @param key Property key (part) to set + * @param value Property value to set + */ + protected void setProperty (final String key, final String value) { + // Trace message + this.getLogger().trace(MessageFormat.format("key={0},value={1} - CALLED!", key, value)); //NOI18N + + // Both should not be null + if (key == null) { + // key is null + throw new NullPointerException("key is null"); + } else if (value == null) { + // value is null + throw new NullPointerException("value is null"); + } + + // Set it + properties.setProperty(String.format("org.mxchange.%s", key), value); //NOI18N + + // Trace message + this.getLogger().trace("EXIT!"); //NOI18N + } + + /** + * 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 "setter" for a value in given Storeable instance and target class + * + * @param instance An instance of a Storeable 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 setValueInStoreableFromColumn (final Storeable instance, final String targetClass, final String columnName, final Object value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Trace message + this.getLogger().trace("instance=" + instance + ",targetClass=" + targetClass + ",columnName=" + columnName + ",value=" + value + " - CALLED!"); + + // A '$' means not our field + if (columnName.startsWith("$")) { + // Don't handle these + throw new IllegalArgumentException("columnsName contains $"); + } + + // Determine if the given column is boolean + if (this.isBooleanField(instance, targetClass, columnName)) { + // Debug message + this.getLogger().debug("Column " + columnName + " represents a boolean field."); + + // 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)); + + // Get field + this.setField(instance, targetClass, methodName, columnName, value); + + // Trace message + this.getLogger().trace("EXIT!"); + } + + /** + * Some "getter" for a value from given Storeable instance and target class + * + * @param instance An instance of a Storeable 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 getValueInStoreableFromColumn (final Storeable 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)); + + // A '$' means not our field + if (columnName.startsWith("$")) { + // Don't handle these + throw new IllegalArgumentException("columnsName contains $"); + } + + // Determine if the given column is boolean + if (this.isBooleanField(instance, targetClass, columnName)) { + // Debug message + this.getLogger().debug("Column " + columnName + " represents a boolean field."); + + // 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)); + + // Get field + Object value = this.getField(instance, targetClass, methodName); + + // Trace message + this.getLogger().trace("value=" + value + " - EXIT!"); + + // Return value + return value; + } + + /** + * 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("instance=" + instance + ",targetClass=" + targetClass + ",columnName=" + columnName + " - CALLED!"); + + // Init field tye + Class type = null; + + // Get all attributes from given instance + Field[] fields = this.getClassFromTarget(instance, targetClass).getDeclaredFields(); + + // Debug message + this.getLogger().debug("fields()=" + fields.length); + + // Search for proper field instance + for (final Field field : fields) { + // Debug message + this.getLogger().debug("field=" + field); + + // Does it match? + if (field.getName().equals(columnName)) { + // Found it + type = field.getType(); + break; + } + } + + // type should not be null + if (type == null) { + // No null allowed + throw new NullPointerException("type is null"); + } + + // Trace message + this.getLogger().debug("type=" + type + " - EXIT!"); + + // Return it + return type; + } }