blob: 80380baec1cde049e534ec91fa9bda2ded6a211e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.tools.utility;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* {@link Object} utility methods.
* <p>
* There are a number of convenience reflection methods.
* These methods provide shortcuts for manipulating objects via
* reflection; particularly when dealing with fields and/or methods that
* are not publicly accessible or are inherited.
* <p>
* In most cases, all exceptions are handled and wrapped in
* {@link java.lang.RuntimeException}s; so these methods should
* be used when there should be no problems using reflection (i.e.
* the referenced members are presumably present etc.).
* <p>
* There are also a number of methods whose names
* end with an underscore. These methods declare the expected checked
* exceptions (e.g. {@link NoSuchMethodException}, {@link NoSuchFieldException}).
* These methods can be used to probe
* for methods, fields, etc. that should be present but might not be.
*/
public final class ObjectTools {
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
// ********** object comparison **********
/**
* Return whether the specified objects are equal, with the appropriate
* <code>null</code> checks.
* @see Object#equals(Object)
*/
public static boolean equals(Object object1, Object object2) {
return (object1 == null) ?
(object2 == null) :
((object2 != null) && object1.equals(object2));
}
/**
* Return whether the specified objects are not equal, with the appropriate
* <code>null</code> checks.
* @see Object#equals(Object)
*/
public static boolean notEquals(Object object1, Object object2) {
return ! equals(object1, object2);
}
// ********** hash code **********
/**
* Return the hash code of the specified object, with the appropriate
* <code>null</code> check (i.e. return <code>0</code> if the specified
* object is <code>null</code>).
* @see Object#hashCode()
*/
public static int hashCode(Object object) {
return hashCode(object, 0);
}
/**
* Return the hash code of the specified object, with the appropriate
* <code>null</code> check (i.e. return the specified <code>null</code>
* hash code if the specified object is <code>null</code>).
* @see Object#hashCode()
*/
public static int hashCode(Object object, int nullHashCode) {
return (object == null) ? nullHashCode : object.hashCode();
}
// ********** string representation **********
/**
* Build a "Dali standard" {@link Object#toString() toString()} result for
* the specified object and additional information:<pre>
* ClassName[00-F3-EE-42](add'l info)
* </pre>
* @see Object#toString()
*/
public static String toString(Object object, Object additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, boolean additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, char additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, char[] additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, CharSequence additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, double additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, float additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, int additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, long additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, String additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* @see #toString(Object, Object)
*/
public static String toString(Object object, StringBuffer additionalInfo) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
sb.append('(');
sb.append(additionalInfo);
sb.append(')');
return sb.toString();
}
/**
* Build a "Dali standard" {@link Object#toString() toString()} result for
* the specified object:<pre>
* ClassName[00-F3-EE-42]
* </pre>
* @see Object#toString()
*/
public static String toString(Object object) {
StringBuilder sb = new StringBuilder();
StringBuilderTools.appendHashCodeToString(sb, object);
return sb.toString();
}
/**
* Return a string suitable for a <em>singleton</em>; which is the simple
* name of the object's class, since there should only be one.
*
* @see ClassTools#toStringName(Class)
* @see Object#toString()
*/
public static String singletonToString(Object object) {
return ClassTools.toStringName(object.getClass());
}
// ********** fields **********
/**
* Return the value of the specified object's field with the specified
* name.
* Useful for accessing private, package, or protected fields.
* @see Field#get(Object)
*/
public static Object get(Object object, String fieldName) {
try {
return get_(object, fieldName);
} catch (NoSuchFieldException ex) {
throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
}
}
/**
* @see #get(Object, String)
*/
public static Object get_(Object object, String fieldName)
throws NoSuchFieldException, IllegalAccessException
{
return field_(object, fieldName).get(object);
}
/**
* Set the value of the specified object's field with the specified
* name to the specified value.
* Useful for accessing private, package, or protected fields.
* @see Field#set(Object, Object)
*/
public static void set(Object object, String fieldName, Object value) {
try {
set_(object, fieldName, value);
} catch (NoSuchFieldException ex) {
throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
}
}
/**
* @see #set(Object, String, Object)
*/
public static void set_(Object object, String fieldName, Object value)
throws NoSuchFieldException, IllegalAccessException
{
field_(object, fieldName).set(object, value);
}
/**
* @see ClassTools#field(Class, String)
*/
public static Field field(Object object, String fieldName) {
try {
return field_(object, fieldName);
} catch (NoSuchFieldException ex) {
throw new RuntimeException(ex + StringTools.CR + buildFullyQualifiedFieldName(object, fieldName), ex);
}
}
/**
* @see ClassTools#field_(Class, String)
*/
public static Field field_(Object object, String fieldName)
throws NoSuchFieldException
{
return ClassTools.field_(object.getClass(), fieldName);
}
/**
* Return a string representation of the specified field.
*/
private static String buildFullyQualifiedFieldName(Object object, String fieldName) {
return ClassTools.buildFullyQualifiedFieldName(object.getClass(), fieldName);
}
// ********** methods **********
/**
* Execute the specified zero-argument method.
* Return its result.
* Useful for invoking private, package, or protected methods.
*/
public static Object execute(Object object, String methodName) {
return execute(object, methodName, ClassTools.EMPTY_ARRAY, EMPTY_OBJECT_ARRAY);
}
/**
* @see #execute(Object, String)
*/
public static Object execute_(Object object, String methodName)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
return execute_(object, methodName, ClassTools.EMPTY_ARRAY, EMPTY_OBJECT_ARRAY);
}
/**
* Execute the specified one-argument method.
* Return its result.
* Useful for invoking private, package, or protected methods.
*/
public static Object execute(Object object, String methodName, Class<?> parameterType, Object argument) {
return execute(object, methodName, new Class[] {parameterType}, new Object[] {argument});
}
/**
* @see #execute(Object, String, Class, Object)
*/
public static Object execute_(Object object, String methodName, Class<?> parameterType, Object argument)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
return execute_(object, methodName, new Class[] {parameterType}, new Object[] {argument});
}
/**
* Execute the specified method.
* Return its result.
* Useful for invoking private, package, or protected methods.
*/
public static Object execute(Object object, String methodName, Class<?>[] parameterTypes, Object[] arguments) {
return execute(object, method(object, methodName, parameterTypes), arguments);
}
/**
* Execute the specified method, given the receiver and arguments.
* Return its result.
* Useful for invoking cached methods.
*/
public static Object execute(Object receiver, Method method, Object[] arguments) {
try {
return method.invoke(receiver, arguments);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex + StringTools.CR + method, ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(method + StringTools.CR + ex.getTargetException(), ex);
}
}
/**
* @see #execute(Object, String, Class[], Object[])
*/
public static Object execute_(Object object, String methodName, Class<?>[] parameterTypes, Object[] arguments)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
return method_(object, methodName, parameterTypes).invoke(object, arguments);
}
/**
* Return the zero-argument method for the specified object
* and method name. If the object's class does not directly
* implement the method, look for it in the class's superclasses.
* Make any private/package/protected method accessible.
*/
public static Method method(Object object, String methodName) {
return ClassTools.method(object.getClass(), methodName);
}
/**
* @see #method(Object, String)
*/
public static Method method_(Object object, String methodName)
throws NoSuchMethodException
{
return ClassTools.method_(object.getClass(), methodName);
}
/**
* Return the one-argument method for the specified object, method name,
* and formal parameter type. If the object's class does not directly
* implement the method, look for it in the class's superclasses.
* Make any private/package/protected method accessible.
*/
public static Method method(Object object, String methodName, Class<?> parameterType) {
return ClassTools.method(object.getClass(), methodName, parameterType);
}
/**
* @see #method(Object, String, Class)
*/
public static Method method_(Object object, String methodName, Class<?> parameterType)
throws NoSuchMethodException
{
return ClassTools.method_(object.getClass(), methodName, parameterType);
}
/**
* Return the method for the specified object, method name,
* and formal parameter types. If the object's class does not directly
* implement the method, look for it in the class's superclasses.
* Make any private/package/protected method accessible.
*/
public static Method method(Object object, String methodName, Class<?>[] parameterTypes) {
return ClassTools.method(object.getClass(), methodName, parameterTypes);
}
/**
* @see #method(Object, String, Class[])
*/
public static Method method_(Object object, String methodName, Class<?>[] parameterTypes)
throws NoSuchMethodException
{
return ClassTools.method_(object.getClass(), methodName, parameterTypes);
}
// ********** suppressed constructor **********
/**
* Suppress default constructor, ensuring non-instantiability.
*/
private ObjectTools() {
super();
throw new UnsupportedOperationException();
}
}