All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flexdock.util.Utilities Maven / Gradle / Ivy

The newest version!
/*
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.flexdock.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author Christopher Butler
 */
public class Utilities {

    /**
     * A constant representing the Java version. This constant is {@code true}
     * if the version is 1.4.
     */
    public static final boolean JAVA_1_4 = isJavaVersion("1.4");

    /**
     * A constant representing the Java version. This constant is {@code true}
     * if the version is 1.5.
     */
    public static final boolean JAVA_1_5 = isJavaVersion("1.5");

    /**
     * A String representing the flexdock version. This constant is a string.
     */
    public static final String VERSION = "1.2.4";

    private Utilities() {
        // does nothing
    }

    /**
     * Returns an {@code int} value for the specified {@code String}. This
     * method calls {@code Integer.parseInt(String s)} and returns the resulting
     * {@code int} value. If any {@code Exception} is thrown, this method
     * returns a value of {@code 0}.
     *
     * @param data
     *            a {@code String} containing the {@code int} representation to
     *            be parsed
     * @return the integer value represented by the argument in decimal
     * @see #getInt(String, int)
     * @see Integer#parseInt(java.lang.String)
     */
    public static int getInt(String data) {
        return getInt(data, 0);
    }

    /**
     * Returns an {@code int} value for the specified {@code String}. This
     * method calls {@code Integer.parseInt(String s)} and returns the resulting
     * {@code int} value. If any {@code Exception} is thrown, this method
     * returns the value supplied by the {@code defaultValue} parameter.
     *
     * @param data
     *            a {@code String} containing the {@code int} representation to
     *            be parsed
     * @param defaultValue
     *            the value to return if an {@code Exception} is encountered.
     * @return the integer value represented by the argument in decimal
     * @see Integer#parseInt(java.lang.String)
     */
    public static int getInt(String data, int defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        try {
            return Integer.parseInt(data);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * Returns a {@code float} value for the specified {@code String}. This
     * method calls {@code Float.parseFloat(String s)} and returns the resulting
     * {@code float} value. If any {@code Exception} is thrown by
     * {@code parseFloat}, this method returns the value supplied by the
     * {@code defaultValue} parameter.
     *
     * @param data
     *            a {@code String} containing the {@code float} representation
     *            to be parsed
     * @param defaultValue
     *            the value to return if an {@code Exception} is encountered on
     *            the underlying parse mechanism.
     * @return the floating-point value represented by the argument in decimal
     * @see Float#parseFloat(java.lang.String)
     */
    public static float getFloat(String data, float defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        try {
            return Float.parseFloat(data);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * Returns {@code true} if the specified {@code String} is {@code null} or
     * contains only whitespace. Otherwise, returns {@code false}. The
     * whitespace check is performed by calling {@code trim()} and checking to
     * see if the trimmed string {@code length()} is zero.
     *
     * @param data
     *            the {@code String} to check for non-whitespace content
     * @return {@code true} if the specified {@code String} is {@code null} or
     *         contains only whitespace, {@code false} otherwise.
     */
    public static boolean isEmpty(String data) {
        return data == null ? true : data.trim().length() == 0;
    }

    /**
     * Returns an instance of the specified class name. If {@code className} is
     * {@code null}, then this method returns a {@code null} reference.
     * 

* This method will try two different means of obtaining an instance of * {@code className}. First, it will attempt to resolve the {@code Class} * of {@code className} via {@code Class.forName(String className)}. It * will then use reflection to search for a method on the class named * {@code "getInstance()"}. If the method is found, then it is invoked and * the object instance is returned. *

* If there are any problems encountered while attempting to invoke * {@code getInstance()} on the specified class, the {@code Throwable} is * caught and this method dispatches to * {@code createInstance(String className, boolean failSilent)} with an * argument of {@code false} for {@code failSilent}. * {@code createInstance(String className, boolean failSilent)} will attempt * to invoke {@code newInstance()} on the {@code Class} for the specified * class name. If any {@code Throwable} is encountered during this process, * the value of {@code false} for {@code failSilent} will cause the stack * trace to be printed to the {@code System.err} and a {@code null} * reference will be returned. * * @param className * the fully qualified name of the desired class. * @return an instance of the specified class * @see #getInstance(String, boolean) * @see #createInstance(String, boolean) * @see Class#forName(java.lang.String) * @see Class#getMethod(java.lang.String, java.lang.Class[]) * @see Method#invoke(java.lang.Object, java.lang.Object[]) * @see Class#newInstance() */ public static Object getInstance(String className) { return getInstance(className, false); } /** * Returns an instance of the specified class name. If {@code className} is * {@code null}, then this method returns a {@code null} reference. *

* This method will try two different means of obtaining an instance of * {@code className}. First, it will attempt to resolve the {@code Class} * of {@code className} via {@code Class.forName(String className)}. It * will then use reflection to search for a method on the class named * {@code "getInstance()"}. If the method is found, then it is invoked and * the object instance is returned. *

* If there are any problems encountered while attempting to invoke * {@code getInstance()} on the specified class, the {@code Throwable} is * caught and this method dispatches to * {@code createInstance(String className, boolean failSilent)}, passing * the specified value for {@code failSilent}. * {@code createInstance(String className, boolean failSilent)} will attempt * to invoke {@code newInstance()} on the {@code Class} for the specified * class name. If any {@code Throwable} is encountered during this process, * the value of {@code failSilent} is checked to determine whether the stack * stack trace should be printed to the {@code System.err}. A {@code null} * reference will be returned if any problems are encountered. * * @param className * the fully qualified name of the desired class. * @param failSilent * {@code true} if the stack trace should not be printed * to the {@code System.err} when a {@code Throwable} is caught, * {@code false} otherwise. * @return an instance of the specified class * @see #createInstance(String, boolean) * @see Class#forName(java.lang.String) * @see Class#getMethod(java.lang.String, java.lang.Class[]) * @see Method#invoke(java.lang.Object, java.lang.Object[]) * @see Class#newInstance() */ public static Object getInstance(String className, boolean failSilent) { if (className == null) { return null; } try { Class c = Class.forName(className); Method m = c.getMethod("getInstance", new Class[0]); return m.invoke(null, new Object[0]); } catch (Throwable e) { return createInstance(className, failSilent); } } /** * Creates and returns an instance of the specified class name using * {@code Class.newInstance()}. If {@code className} is {@code null}, then * this method returns a {@code null} reference. This dispatches to * {@code createInstance(String className, Class superType, boolean failSilent)} * with an argument of {@code null} for {@code superType} and {@code false} * for {@code failSilent}. *

* This method will attempt to resolve the {@code Class} of * {@code className} via {@code Class.forName(String className)}. No class * assignability checkes are performed because this method uses a * {@code null} {@code superType}. *

* Once the desired class has been resolved, a new instance of it is created * and returned by invoking its {@code newInstance()} method. If there are * any problems encountered during this process, the value of {@code false} * for {@code failSilent} will ensure the stack stack trace is be printed to * the {@code System.err}. A {@code null} reference will be returned if any * problems are encountered. * * @param className * the fully qualified name of the desired class. * @return an instance of the specified class * @see #createInstance(String, Class, boolean) * @see Class#forName(java.lang.String) * @see Class#newInstance() */ public static Object createInstance(String className) { return createInstance(className, null); } /** * Creates and returns an instance of the specified class name using * {@code Class.newInstance()}. If {@code className} is {@code null}, then * this method returns a {@code null} reference. The {@code failSilent} * parameter will determine whether error stack traces should be reported to * the {@code System.err} before this method returns {@code null}. This * method dispatches to * {@code createInstance(String className, Class superType, boolean failSilent)} * with an argument of {@code null} for {@code superType}. *

* This method will attempt to resolve the {@code Class} of * {@code className} via {@code Class.forName(String className)}. No class * assignability checkes are performed because this method uses a * {@code null} {@code superType}. *

* Once the desired class has been resolved, a new instance of it is created * and returned by invoking its {@code newInstance()} method. If there are * any problems encountered during this process, the value of * {@code failSilent} is checked to determine whether the stack stack trace * should be printed to the {@code System.err}. A {@code null} reference * will be returned if any problems are encountered. * * @param className * the fully qualified name of the desired class. * @param failSilent * {@code true} if the stack trace should not be printed * to the {@code System.err} when a {@code Throwable} is caught, * {@code false} otherwise. * @return an instance of the specified class * @see #createInstance(String, Class, boolean) * @see Class#forName(java.lang.String) * @see Class#newInstance() */ public static Object createInstance(String className, boolean failSilent) { return createInstance(className, null, failSilent); } /** * Creates and returns an instance of the specified class name using * {@code Class.newInstance()}. If {@code className} is {@code null}, then * this method returns a {@code null} reference. If {@code superType} is * non-{@code null}, then this method will enforce polymorphic identity * via {@code Class.isAssignableFrom(Class cls)}. This method dispatches to * {@code createInstance(String className, Class superType, boolean failSilent)} * with an argument of {@code false} for {@code failSilent}. *

* This method will attempt to resolve the {@code Class} of * {@code className} via {@code Class.forName(String className)}. If * {@code superType} is non-{@code null}, then class identity is checked * by calling {@code superType.isAssignableFrom(c)} to ensure the resolved * class is an valid equivalent, descendent, or implementation of the * specified {@code className}. If this check fails, then a * {@code ClassCastException} is thrown and caught internally and this * method returns {@code null}. If {@code superType} is {@code null}, then * no assignability checks are performed on the resolved class. *

* Once the desired class has been resolved, a new instance of it is created * and returned by invoking its {@code newInstance()} method. If there are * any problems encountered during this process, the value of {@code false} * for {@code failSilent} will ensure the stack stack trace is be printed to * the {@code System.err}. A {@code null} reference will be returned if any * problems are encountered. * * @param className * the fully qualified name of the desired class. * @param superType * optional paramter used as a means of enforcing the inheritance * hierarchy * @return an instance of the specified class * @see #createInstance(String, Class, boolean) * @see Class#forName(java.lang.String) * @see Class#isAssignableFrom(java.lang.Class) * @see Class#newInstance() */ public static Object createInstance(String className, Class superType) { return createInstance(className, superType, false); } /** * Creates and returns an instance of the specified class name using * {@code Class.newInstance()}. If {@code className} is {@code null}, then * this method returns a {@code null} reference. If {@code superType} is * non-{@code null}, then this method will enforce polymorphic identity * via {@code Class.isAssignableFrom(Class cls)}. The {@code failSilent} * parameter will determine whether error stack traces should be reported to * the {@code System.err} before this method returns {@code null}. *

* This method will attempt to resolve the {@code Class} of * {@code className} via {@code Class.forName(String className)}. If * {@code superType} is non-{@code null}, then class identity is checked * by calling {@code superType.isAssignableFrom(c)} to ensure the resolved * class is an valid equivalent, descendent, or implementation of the * specified {@code className}. If this check fails, then a * {@code ClassCastException} is thrown and caught internally and this * method returns {@code null}. If {@code superType} is {@code null}, then * no assignability checks are performed on the resolved class. *

* Once the desired class has been resolved, a new instance of it is created * and returned by invoking its {@code newInstance()} method. If there are * any problems encountered during this process, the value of * {@code failSilent} is checked to determine whether the stack stack trace * should be printed to the {@code System.err}. A {@code null} reference * will be returned if any problems are encountered. * * @param className * the fully qualified name of the desired class. * @param superType * optional paramter used as a means of enforcing the inheritance * hierarchy * @param failSilent * {@code true} if the stack trace should not be printed * to the {@code System.err} when a {@code Throwable} is caught, * {@code false} otherwise. * @return an instance of the specified class * @see Class#forName(java.lang.String) * @see Class#isAssignableFrom(java.lang.Class) * @see Class#newInstance() */ public static Object createInstance(String className, Class superType, boolean failSilent) { if (className == null) { return null; } try { Class c = Class.forName(className); if (superType != null && !superType.isAssignableFrom(c)) { throw new ClassCastException("'" + c.getName() + "' is not a type of " + superType + "."); } return c.newInstance(); } catch (Throwable e) { if (!failSilent) { System.err.println("Exception: " +e.getMessage()); } return null; } } /** * Checks for equality between the two specified {@code Objects}. If both * arguments are the same {@code Object} reference using an {@code ==} * relationship, then this method returns {@code true}. Failing that check, * if either of the arguments is {@code null}, then the other must not be * and this method returns {@code false}. Finally, if both arguments are * non-{@code null} with different {@code Object} references, then this * method returns the value of {@code obj1.equals(obj2)}. *

* This method is the exact opposite of * {@code isChanged(Object oldObj, Object newObj)}. * * @param obj1 * the first {@code Object} to be checked for equality * @param obj2 * the second {@code Object} to be checked for equality * @return {@code true} if the {@code Objects} are equal, {@code false} * otherwise. * @see #isChanged(Object, Object) * @see Object#equals(java.lang.Object) */ public static boolean isEqual(Object obj1, Object obj2) { return !isChanged(obj1, obj2); } /** * Checks for inequality between the two specified {@code Objects}. If both * arguments are the same {@code Object} reference using an {@code ==} * relationship, then this method returns {@code false}. Failing that * check, if either of the arguments is {@code null}, then the other must * not be and this method returns {@code true}. Finally, if both arguments * are non-{@code null} with different {@code Object} references, then this * method returns the opposite value of {@code obj1.equals(obj2)}. *

* This method is the exact opposite of * {@code isEqual(Object obj1, Object obj2)}. * * @param oldObj * the first {@code Object} to be checked for inequality * @param newObj * the second {@code Object} to be checked for inequality * @return {@code false} if the {@code Objects} are equal, {@code true} * otherwise. * @see #isEqual(Object, Object) * @see Object#equals(java.lang.Object) */ public static boolean isChanged(Object oldObj, Object newObj) { if (oldObj == newObj) { return false; } if (oldObj == null || newObj == null) { return true; } return !oldObj.equals(newObj); } /** * Returns {@code true} if there is currently a {@code System} property with * the specified {@code key} whose value is "true". If the {@code System} * property does not exist, or the value is inequal to "true", this method * returns {@code false}. This method returns {@code false} if the * specified {@code key} parameter is {@code null}. * * @param key * the {@code System} property to test. * @return {@code true} if there is currently a {@code System} property with * the specified {@code key} whose value is "true". * @see System#getProperty(java.lang.String) * @see String#equals(java.lang.Object) * @deprecated Use {@link Boolean#getBoolean(String)}. */ public static boolean sysTrue(String key) { String value = key == null ? null : System.getProperty(key); return value == null ? false : "true".equals(value); } /** * Puts the supplied {@code value} into the specified {@code Map} using the * specified {@code key}. This is a convenience method to automate * null-checks. A {@code value} parameter of {@code null} is interpreted as * a removal from the specified {@code Map} rather than an {@code put} * operation. *

* If either {@code map} or {@code key} are {@code null} then this method * returns with no action taken. If {@code value} is {@code null}, * then this method calls {@code map.remove(key)}. Otherwise, this method * calls {@code map.put(key, value)}. * * @param map * the {@code Map} whose contents is to be modified * @param key * with which the specified value is to be associated. * @param value * value to be associated with the specified key. * @see Map#put(java.lang.Object, java.lang.Object) * @see Map#remove(java.lang.Object) */ public static void put(Map map, Object key, Object value) { if (map == null || key == null) { return; } if (value == null) { map.remove(key); } else { map.put(key, value); } } /** * Returns the value of the specified {@code fieldName} within the specified * {@code Object}. This is a convenience method for reflection hacks to * retrieve the value of protected, private, or package-private field * members while hiding the boilerplate reflection code within a single * utility method call. This method will return {@code true} if the * operation was successful and {@code false} if errors were encountered. *

* This method calls {@code obj.getClass()} to retrieve the {@code Class} of * the specified {@code Object}. It then retrieves the desired field by * calling the classes' {@code getDeclaredField(String name)} method, * passing the specified field name. If the field is deemed inaccessible via * it's {@code isAccessible()} method, then it is made accessible by calling * {@code setAccessible(true)}. The field value is set by invoking the * field's {@code set(Object obj, Object value)} method and passing the * original {@code Object} and {@code value} parameter as arguments. Before * returning, the field's accessibility is reset to its original state. *

* If either {@code obj} or {@code fieldName} are {@code null}, then this * method returns {@code false}. *

* It should be understood that this method will not function properly for * inaccessible fields in the presence of a {@code SecurityManager}. Nor * will it function properly for non-existent fields (if a field called * {@code fieldName} does not exist on the class). All {@code Throwable}s * encountered by this method will be caught and eaten and the method will * return {@code false}. This works under the assumption that the operation * might likely fail because the method itself is, in reality, a convenience * hack. Therefore, specifics of any generated errors on the call stack are * discarded and only the final outcome ({@code true}/{@code false}) of the * operation is deemed relevant. * * If call stack data is required within the application for any thrown * exceptions, then this method should not be used. * * @param obj * the object for which the represented field's value is to be * modified * @param fieldName * the name of the field to be set * @param value * the new value for the field of {@code obj} being modified * @return as described * @see Object#getClass() * @see Class#getDeclaredField(java.lang.String) * @see Field#isAccessible() * @see Field#setAccessible(boolean) * @see Field#set(Object, Object) */ public static boolean setValue(Object obj, String fieldName, Object value) { if (obj == null || fieldName == null) { return false; } try { Class c = obj.getClass(); Field field = c.getDeclaredField(fieldName); if (field.isAccessible()) { field.set(obj, value); return true; } field.setAccessible(true); field.set(obj, value); field.setAccessible(false); return true; } catch (Throwable t) { // don't report the error. the purpse of this method is to try to // access the field, but fail silently if we can't. return false; } } /** * Returns the value of the specified {@code fieldName} within the specified * {@code Object}. This is a convenience method for reflection hacks to * retrieve the value of protected, private, or package-private field * members while hiding the boilerplate reflection code within a single * utility method call. *

* This method calls {@code obj.getClass()} to retrieve the {@code Class} of * the specified {@code Object}. It then retrieves the desired field by * calling the classes' {@code getDeclaredField(String name)} method, * passing the specified field name. If the field is deemed inaccessible via * it's {@code isAccessible()} method, then it is made accessible by calling * {@code setAccessible(true)}. The return value is retrieved by invoking * the field's {@code get(Object obj)} method and passing the original * {@code Object} parameter as an argument. Before returning, the field's * accessibility is reset to its original state. *

* If either {@code obj} or {@code fieldName} are {@code null}, then this * method returns {@code null}. *

* It should be understood that this method will not function properly for * inaccessible fields in the presence of a {@code SecurityManager}. Nor * will it function properly for non-existent fields (if a field called * {@code fieldName} does not exist on the class). All {@code Throwables} * encountered by this method will be rethrown as * {@code IllegalAccessException}. For wrapped {@code Throwable}s, the * original cause can be accessed via {@code IllegalAccessException's} * {@code getCause()} method. * * @param obj * the object from which the represented field's value is to be * extracted * @param fieldName * the name of the field to be checked * @return the value of the represented field in object {@code obj}; * primitive values are wrapped in an appropriate object before * being returned * @throws IllegalAccessException all {@code Throwable}s as described * @see Object#getClass() * @see Class#getDeclaredField(java.lang.String) * @see Field#isAccessible() * @see Field#setAccessible(boolean) * @see Field#get(java.lang.Object) * @see IllegalAccessException#getCause() */ public static Object getValue(Object obj, String fieldName) throws IllegalAccessException { if (obj == null || fieldName == null) { return null; } try { Class c = obj.getClass(); Field field = c.getDeclaredField(fieldName); if (field.isAccessible()) { return field.get(obj); } field.setAccessible(true); Object ret = field.get(obj); field.setAccessible(false); return ret; } catch (Throwable t) { if (t instanceof IllegalAccessException) { throw (IllegalAccessException) t; } IllegalAccessException e = new IllegalAccessException(t .getMessage()); e.initCause(t); throw e; } } /** * Puts the current {@code Thread} to sleep for the specified timeout. This * method calls {@code Thread.sleep(long millis)}, catching any thrown * {@code InterruptedException} and printing a stack trace to the * {@code System.err}. * * @param millis * the length of time to sleep in milliseconds. * @see Thread#sleep(long) */ public static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { System.err.println("Exception: " +e.getMessage()); e.printStackTrace(); } } private static boolean isJavaVersion(String version) { if (version == null) { return false; } return System.getProperty("java.version").startsWith(version); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy