/*
* Created on Nov 23, 2005
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* Copyright @2005 the original author or authors.
*/
package org.springmodules.util;
import java.util.HashSet;
import java.util.Set;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* <p>
* Miscellaneous object utility methods.
* </p>
*
* @author Alex Ruiz
*/
public abstract class Objects {
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
private static final String ARRAY_END = "}";
private static final String ARRAY_START = "{";
private static final String EMPTY_ARRAY = "{}";
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
private static final String NULL_ARRAY = "null";
private static final Set primitivesAndWrappers;
static {
primitivesAndWrappers = new HashSet();
primitivesAndWrappers.add(boolean.class);
primitivesAndWrappers.add(Boolean.class);
primitivesAndWrappers.add(byte.class);
primitivesAndWrappers.add(Byte.class);
primitivesAndWrappers.add(char.class);
primitivesAndWrappers.add(Character.class);
primitivesAndWrappers.add(double.class);
primitivesAndWrappers.add(Double.class);
primitivesAndWrappers.add(float.class);
primitivesAndWrappers.add(Float.class);
primitivesAndWrappers.add(int.class);
primitivesAndWrappers.add(Integer.class);
primitivesAndWrappers.add(long.class);
primitivesAndWrappers.add(Long.class);
primitivesAndWrappers.add(short.class);
primitivesAndWrappers.add(Short.class);
}
/**
* Returns the same value as <code>{@link Boolean#hashCode()}</code>.
*
* @param bool
* the given <code>boolean</code>.
* @return the hash code for the given <code>boolean</code>.
* @see Boolean#hashCode()
*/
public static int hashCode(boolean bool) {
return bool ? 1231 : 1237;
}
/**
* Returns the same value as <code>{@link Double#hashCode()}</code>.
*
* @param dbl
* the given <code>double</code>.
* @return the hash code for the given <code>double</code>.
* @see Double#hashCode()
*/
public static int hashCode(double dbl) {
long bits = Double.doubleToLongBits(dbl);
return hashCode(bits);
}
/**
* Returns the same value as <code>{@link Float#hashCode()}</code>.
*
* @param flt
* the given <code>float</code>.
* @return the hash code for the given <code>float</code>.
* @see Float#hashCode()
*/
public static int hashCode(float flt) {
return Float.floatToIntBits(flt);
}
/**
* Returns the same value as <code>{@link Long#hashCode()}</code>.
*
* @param lng
* the given <code>long</code>.
* @return the hash code for the given <code>long</code>.
* @see Long#hashCode()
*/
public static int hashCode(long lng) {
return (int) (lng ^ (lng >>> 32));
}
/**
* <p>
* Returns a <code>StringBuffer</code> containing:
* <ol>
* <li>the class name of the given object</li>
* <li>the character '@'</li>
* <li>the hex string for the object's identity hash code</li>
* </ol>
* </p>
* <p>
* This method will return an empty <code>StringBuffer</code> if the given
* object is <code>null</code>.
* </p>
*
* @param obj
* the given object.
* @return a <code>StringBuffer</code> containing identity information of
* the given object.
*/
public static StringBuffer identityToString(Object obj) {
StringBuffer buffer = new StringBuffer();
if (obj != null) {
buffer.append(obj.getClass().getName());
buffer.append("@");
buffer.append(ObjectUtils.getIdentityHexString(obj));
}
return buffer;
}
/**
* Returns <code>true</code> if the given object is an array of primitives.
*
* @param array
* the given object to check.
* @return <code>true</code> if the given object is an array of primitives.
*/
public static boolean isArrayOfPrimitives(Object array) {
boolean primitiveArray = false;
if (array != null) {
Class clazz = array.getClass();
primitiveArray = clazz.isArray()
&& clazz.getComponentType().isPrimitive();
}
return primitiveArray;
}
/**
* Returns <code>true</code> if the given class is any of the following:
* <ul>
* <li><code>boolean</code></li>
* <li>Boolean</li>
* <li><code>byte</code></li>
* <li>Byte</li>
* <li><code>char</code></li>
* <li>Character</li>
* <li><code>double</code></li>
* <li>Double</li>
* <li><code>float</code></li>
* <li>Float</li>
* <li><code>int</code></li>
* <li>Integer</li>
* <li><code>long</code></li>
* <li>Long</li>
* <li><code>short</code></li>
* <li>Short</li>
* </ul>
*
* @param clazz
* the given class.
* @return <code>true</code> if the given class represents a primitive or a
* wrapper, <code>false</code> otherwise.
*/
public static boolean isPrimitiveOrWrapper(Class clazz) {
return primitivesAndWrappers.contains(clazz);
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>boolean</code> arrays <code>a</code> and <code>b</code>
* such that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
* @see #hashCode(boolean)
*/
public static int nullSafeHashCode(boolean[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + hashCode(array[i]);
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>byte</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
*/
public static int nullSafeHashCode(byte[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>char</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
*/
public static int nullSafeHashCode(char[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>double</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
* @see #hashCode(double)
*/
public static int nullSafeHashCode(double[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + hashCode(array[i]);
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>float</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
* @see #hashCode(float)
*/
public static int nullSafeHashCode(float[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + hashCode(array[i]);
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>int</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
*/
public static int nullSafeHashCode(int[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>long</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
* </p>
*
* @param array
* the array whose hash value to compute.
* @return a content-based hash code for <code>array</code>.
* @see #hashCode(long)
*/
public static int nullSafeHashCode(long[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + hashCode(array[i]);
}
return hash;
}
/**
* <p>
* Returns the value of <code>{@link Object#hashCode()}</code>. If the
* object is an array, this method will delegate to any of the
* <code>nullSafeHashCode</code> methods for arrays in this class.
* </p>
*
* <p>
* If the object is <code>null</code>, this method returns 0.
* </p>
*
* @param obj
* the object whose hash value to compute.
* @return the hash code of the given object.
* @see #nullSafeHashCode(boolean[])
* @see #nullSafeHashCode(byte[])
* @see #nullSafeHashCode(char[])
* @see #nullSafeHashCode(double[])
* @see #nullSafeHashCode(float[])
* @see #nullSafeHashCode(int[])
* @see #nullSafeHashCode(long[])
* @see #nullSafeHashCode(Object[])
* @see #nullSafeHashCode(short[])
*/
public static int nullSafeHashCode(Object obj) {
if (obj == null)
return 0;
if (obj instanceof boolean[]) {
return nullSafeHashCode((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeHashCode((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeHashCode((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeHashCode((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeHashCode((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeHashCode((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeHashCode((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeHashCode((short[]) obj);
}
if (obj instanceof Object[]) {
return nullSafeHashCode((Object[]) obj);
}
return obj.hashCode();
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two arrays <code>a</code> and <code>b</code> such that
* <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
* <p>
* The value returned by this method is equal to the value that would be
* returned by <code>Arrays.asList(a).hashCode()</code>, unless
* <code>array</code> is <code>null</code>, in which case <code>0</code>
* is returned.
* </p>
*
* @param array
* the array whose content-based hash code to compute.
* @return a content-based hash code for <code>array</code>.
*/
public static int nullSafeHashCode(Object[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + nullSafeHashCode(array[i]);
}
return hash;
}
/**
* <p>
* Returns a hash code based on the contents of the specified array. For any
* two <code>short</code> arrays <code>a</code> and <code>b</code> such
* that <code>Arrays.equals(a, b)</code>, it is also the case that
* <code>Arrays.hashCode(a) == Arrays.hashCode(b)</code>.
* </p>
*
* <p>
* If <code>array</code> is <code>null</code>, this method returns 0.
*
* @param array
* the array whose hash value to compute
* @return a content-based hash code for <code>array</code>
*/
public static int nullSafeHashCode(short[] array) {
if (array == null)
return 0;
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(boolean[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(byte[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(char[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append("'" + array[i] + "'");
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(double[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(float[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(int[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(long[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(Object[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(StringUtils.quoteIfString(array[i]));
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(short[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(array[i]);
}
buffer.append(ARRAY_END);
return buffer.toString();
}
/**
* Returns a string representation of the contents of the specified array. The
* string representation consists of a list of the array's elements, enclosed
* in curly braces (<code>"{}"</code>). Adjacent elements are separated by
* the characters <code>", "</code> (a comma followed by a space). Returns
* <code>"null"</code> if <code>array</code> is <code>null</code>.
*
* @param array
* the array whose string representation to return.
* @return a string representation of <code>array</code>.
*/
public static String nullSafeToString(String[] array) {
if (array == null)
return NULL_ARRAY;
int length = array.length;
if (length == 0)
return EMPTY_ARRAY;
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
if (i == 0)
buffer.append(ARRAY_START);
else
buffer.append(ARRAY_ELEMENT_SEPARATOR);
buffer.append(StringUtils.quote(array[i]));
}
buffer.append(ARRAY_END);
return buffer.toString();
}
}