一、前言
关于hibernate(3.0.1)源码包中org.hibernate.exception.ExceptionUtils异常工具类,获取常规异常getCause、打印异常队列显示printRootCauseStackTrace等操作。
二、源码说明
1.ArrayHelper类
package org.hibernate.util;@b@@b@import java.lang.reflect.Array;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.Collection;@b@import java.util.Iterator;@b@import java.util.List;@b@import org.hibernate.LockMode;@b@import org.hibernate.type.Type;@b@@b@public final class ArrayHelper@b@{@b@ public static final String[] EMPTY_STRING_ARRAY = new String[0];@b@ public static final int[] EMPTY_INT_ARRAY = new int[0];@b@ public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];@b@ public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];@b@ public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];@b@ public static final Type[] EMPTY_TYPE_ARRAY = new Type[0];@b@ private static int SEED = 23;@b@ private static int PRIME_NUMER = 37;@b@@b@ public static int indexOf(Object[] array, Object object)@b@ {@b@ for (int i = 0; i < array.length; ++i)@b@ if (array[i].equals(object)) return i;@b@@b@ return -1;@b@ }@b@@b@ public static String[] toStringArray(Object[] objects)@b@ {@b@ int length = objects.length;@b@ String[] result = new String[length];@b@ for (int i = 0; i < length; ++i)@b@ result[i] = objects[i].toString();@b@@b@ return result;@b@ }@b@@b@ public static String[] fillArray(String value, int length) {@b@ String[] result = new String[length];@b@ Arrays.fill(result, value);@b@ return result;@b@ }@b@@b@ public static int[] fillArray(int value, int length) {@b@ int[] result = new int[length];@b@ Arrays.fill(result, value);@b@ return result;@b@ }@b@@b@ public static LockMode[] fillArray(LockMode lockMode, int length) {@b@ LockMode[] array = new LockMode[length];@b@ Arrays.fill(array, lockMode);@b@ return array;@b@ }@b@@b@ public static String[] toStringArray(Collection coll) {@b@ return ((String[])coll.toArray(EMPTY_STRING_ARRAY));@b@ }@b@@b@ public static String[][] to2DStringArray(Collection coll) {@b@ return ((String[][])coll.toArray(new String[coll.size()][]));@b@ }@b@@b@ public static int[][] to2DIntArray(Collection coll) {@b@ return ((int[][])coll.toArray(new int[coll.size()][]));@b@ }@b@@b@ public static Type[] toTypeArray(Collection coll) {@b@ return ((Type[])coll.toArray(EMPTY_TYPE_ARRAY));@b@ }@b@@b@ public static int[] toIntArray(Collection coll) {@b@ Iterator iter = coll.iterator();@b@ int[] arr = new int[coll.size()];@b@ int i = 0;@b@ while (iter.hasNext())@b@ arr[(i++)] = ((Integer)iter.next()).intValue();@b@@b@ return arr;@b@ }@b@@b@ public static boolean[] toBooleanArray(Collection coll) {@b@ Iterator iter = coll.iterator();@b@ boolean[] arr = new boolean[coll.size()];@b@ int i = 0;@b@ while (iter.hasNext())@b@ arr[(i++)] = ((Boolean)iter.next()).booleanValue();@b@@b@ return arr;@b@ }@b@@b@ public static Object[] typecast(Object[] array, Object[] to) {@b@ return Arrays.asList(array).toArray(to);@b@ }@b@@b@ public static List toList(Object array)@b@ {@b@ if (array instanceof Object[]) return Arrays.asList((Object[])array);@b@ int size = Array.getLength(array);@b@ ArrayList list = new ArrayList(size);@b@ for (int i = 0; i < size; ++i)@b@ list.add(Array.get(array, i));@b@@b@ return list;@b@ }@b@@b@ public static String[] slice(String[] strings, int begin, int length) {@b@ String[] result = new String[length];@b@ for (int i = 0; i < length; ++i)@b@ result[i] = strings[(begin + i)];@b@@b@ return result;@b@ }@b@@b@ public static Object[] slice(Object[] objects, int begin, int length) {@b@ Object[] result = new Object[length];@b@ for (int i = 0; i < length; ++i)@b@ result[i] = objects[(begin + i)];@b@@b@ return result;@b@ }@b@@b@ public static List toList(Iterator iter) {@b@ List list = new ArrayList();@b@ while (iter.hasNext())@b@ list.add(iter.next());@b@@b@ return list;@b@ }@b@@b@ public static String[] join(String[] x, String[] y) {@b@ String[] result = new String[x.length + y.length];@b@ for (int i = 0; i < x.length; ) { result[i] = x[i]; ++i; }@b@ for (i = 0; i < y.length; ) { result[(i + x.length)] = y[i]; ++i; }@b@ return result;@b@ }@b@@b@ public static int[] join(int[] x, int[] y) {@b@ int[] result = new int[x.length + y.length];@b@ for (int i = 0; i < x.length; ) { result[i] = x[i]; ++i; }@b@ for (i = 0; i < y.length; ) { result[(i + x.length)] = y[i]; ++i; }@b@ return result;@b@ }@b@@b@ public static String toString(Object[] array)@b@ {@b@ StringBuffer sb = new StringBuffer();@b@ sb.append("[");@b@ for (int i = 0; i < array.length; ++i) {@b@ sb.append(array[i]);@b@ if (i < array.length - 1) sb.append(",");@b@ }@b@ sb.append("]");@b@ return sb.toString();@b@ }@b@@b@ public static boolean isAllNegative(int[] array) {@b@ for (int i = 0; i < array.length; ++i)@b@ if (array[i] >= 0) return false;@b@@b@ return true;@b@ }@b@@b@ public static boolean isAllTrue(boolean[] array) {@b@ for (int i = 0; i < array.length; ++i)@b@ if (array[i] == 0) return false;@b@@b@ return true;@b@ }@b@@b@ public static int countTrue(boolean[] array) {@b@ int result = 0;@b@ for (int i = 0; i < array.length; ++i)@b@ if (array[i] != 0) ++result;@b@@b@ return result;@b@ }@b@@b@ public static boolean isAllFalse(boolean[] array) {@b@ for (int i = 0; i < array.length; ++i)@b@ if (array[i] != 0) return false;@b@@b@ return true;@b@ }@b@@b@ public static void addAll(Collection collection, Object[] array) {@b@ for (int i = 0; i < array.length; ++i)@b@ collection.add(array[i]);@b@ }@b@@b@ public static int[] getBatchSizes(int maxBatchSize)@b@ {@b@ int batchSize = maxBatchSize;@b@ int n = 1;@b@ while (batchSize > 1) {@b@ batchSize = getNextBatchSize(batchSize);@b@ ++n;@b@ }@b@ int[] result = new int[n];@b@ batchSize = maxBatchSize;@b@ for (int i = 0; i < n; ++i) {@b@ result[i] = batchSize;@b@ batchSize = getNextBatchSize(batchSize);@b@ }@b@ return result;@b@ }@b@@b@ private static int getNextBatchSize(int batchSize) {@b@ if (batchSize <= 10)@b@ return (batchSize - 1);@b@@b@ if (batchSize / 2 < 10) {@b@ return 10;@b@ }@b@@b@ return (batchSize / 2);@b@ }@b@@b@ public static int hash(Object[] array)@b@ {@b@ int length = array.length;@b@ int seed = SEED;@b@ for (int index = 0; index < length; ++index)@b@ seed = hash(seed, (array[index] == null) ? 0 : array[index].hashCode());@b@@b@ return seed;@b@ }@b@@b@ public static int hash(char[] array)@b@ {@b@ int length = array.length;@b@ int seed = SEED;@b@ for (int index = 0; index < length; ++index)@b@ seed = hash(seed, array[index]);@b@@b@ return seed;@b@ }@b@@b@ public static int hash(byte[] bytes)@b@ {@b@ int length = bytes.length;@b@ int seed = SEED;@b@ for (int index = 0; index < length; ++index)@b@ seed = hash(seed, bytes[index]);@b@@b@ return seed;@b@ }@b@@b@ private static int hash(int seed, int i) {@b@ return (PRIME_NUMER * seed + i);@b@ }@b@@b@ public static boolean isEquals(Object[] o1, Object[] o2)@b@ {@b@ if (o1 == o2) return true;@b@ if ((o1 == null) || (o2 == null)) return false;@b@ int length = o1.length;@b@ if (length != o2.length) return false;@b@ for (int index = 0; index < length; ++index)@b@ if (!(o1[index].equals(o2[index]))) return false;@b@@b@ return true;@b@ }@b@@b@ public static boolean isEquals(char[] o1, char[] o2)@b@ {@b@ if (o1 == o2) return true;@b@ if ((o1 == null) || (o2 == null)) return false;@b@ int length = o1.length;@b@ if (length != o2.length) return false;@b@ for (int index = 0; index < length; ++index)@b@ if (o1[index] != o2[index]) return false;@b@@b@ return true;@b@ }@b@@b@ public static boolean isEquals(byte[] b1, byte[] b2)@b@ {@b@ if (b1 == b2) return true;@b@ if ((b1 == null) || (b2 == null)) return false;@b@ int length = b1.length;@b@ if (length != b2.length) return false;@b@ for (int index = 0; index < length; ++index)@b@ if (b1[index] != b2[index]) return false;@b@@b@ return true;@b@ }@b@}
2.ExceptionUtils类
package org.hibernate.exception;@b@@b@import java.io.PrintStream;@b@import java.io.PrintWriter;@b@import java.io.StringWriter;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.sql.SQLException;@b@import java.util.ArrayList;@b@import java.util.LinkedList;@b@import java.util.List;@b@import java.util.StringTokenizer;@b@import org.hibernate.util.ArrayHelper;@b@@b@public final class ExceptionUtils@b@{@b@ private static final String LINE_SEPARATOR;@b@ static final String WRAPPED_MARKER = " [wrapped] ";@b@ private static final String[] CAUSE_METHOD_NAMES;@b@ private static final Method THROWABLE_CAUSE_METHOD;@b@@b@ public static Throwable getCause(Throwable throwable)@b@ {@b@ return getCause(throwable, CAUSE_METHOD_NAMES);@b@ }@b@@b@ public static Throwable getCause(Throwable throwable, String[] methodNames)@b@ {@b@ if (throwable == null)@b@ return null;@b@@b@ Throwable cause = getCauseUsingWellKnownTypes(throwable);@b@ if (cause == null) {@b@ if (methodNames == null)@b@ methodNames = CAUSE_METHOD_NAMES;@b@@b@ for (int i = 0; i < methodNames.length; ++i) {@b@ String methodName = methodNames[i];@b@ if (methodName != null) {@b@ cause = getCauseUsingMethodName(throwable, methodName);@b@ if (cause != null)@b@ break;@b@ }@b@@b@ }@b@@b@ if (cause == null)@b@ cause = getCauseUsingFieldName(throwable, "detail");@b@ }@b@@b@ return cause;@b@ }@b@@b@ public static Throwable getRootCause(Throwable throwable)@b@ {@b@ Throwable cause = getCause(throwable);@b@ if (cause != null) {@b@ throwable = cause;@b@ while ((throwable = getCause(throwable)) != null)@b@ cause = throwable;@b@ }@b@@b@ return cause;@b@ }@b@@b@ private static Throwable getCauseUsingWellKnownTypes(Throwable throwable)@b@ {@b@ if (throwable instanceof Nestable)@b@ return ((Nestable)throwable).getCause();@b@@b@ if (throwable instanceof SQLException)@b@ return ((SQLException)throwable).getNextException();@b@@b@ if (throwable instanceof InvocationTargetException) {@b@ return ((InvocationTargetException)throwable).getTargetException();@b@ }@b@@b@ return null;@b@ }@b@@b@ private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName)@b@ {@b@ Method method = null;@b@ try {@b@ method = throwable.getClass().getMethod(methodName, null);@b@ }@b@ catch (NoSuchMethodException ignored)@b@ {@b@ }@b@ catch (SecurityException ignored) {@b@ }@b@ if ((method != null) && (Throwable.class.isAssignableFrom(method.getReturnType())))@b@ try {@b@ return ((Throwable)method.invoke(throwable, ArrayHelper.EMPTY_OBJECT_ARRAY));@b@ }@b@ catch (IllegalAccessException ignored)@b@ {@b@ }@b@ catch (IllegalArgumentException ignored) {@b@ }@b@ catch (InvocationTargetException ignored) {@b@ }@b@ return null;@b@ }@b@@b@ private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName)@b@ {@b@ Field field = null;@b@ try {@b@ field = throwable.getClass().getField(fieldName);@b@ }@b@ catch (NoSuchFieldException ignored)@b@ {@b@ }@b@ catch (SecurityException ignored) {@b@ }@b@ if ((field != null) && (Throwable.class.isAssignableFrom(field.getType())))@b@ try {@b@ return ((Throwable)field.get(throwable));@b@ }@b@ catch (IllegalAccessException ignored)@b@ {@b@ }@b@ catch (IllegalArgumentException ignored) {@b@ }@b@ return null;@b@ }@b@@b@ public static boolean isThrowableNested()@b@ {@b@ return (THROWABLE_CAUSE_METHOD != null);@b@ }@b@@b@ public static boolean isNestedThrowable(Throwable throwable)@b@ {@b@ if (throwable == null) {@b@ return false;@b@ }@b@@b@ if (throwable instanceof Nestable)@b@ return true;@b@@b@ if (throwable instanceof SQLException)@b@ return true;@b@@b@ if (throwable instanceof InvocationTargetException)@b@ return true;@b@@b@ if (isThrowableNested()) {@b@ return true;@b@ }@b@@b@ Class cls = throwable.getClass();@b@ int i = 0; for (int isize = CAUSE_METHOD_NAMES.length; i < isize; ++i)@b@ try {@b@ Method method = cls.getMethod(CAUSE_METHOD_NAMES[i], null);@b@ if ((method != null) && (Throwable.class.isAssignableFrom(method.getReturnType())))@b@ return true;@b@ }@b@ catch (NoSuchMethodException ignored)@b@ {@b@ }@b@ catch (SecurityException ignored)@b@ {@b@ }@b@ try@b@ {@b@ Field field = cls.getField("detail");@b@ if (field != null)@b@ return true;@b@ }@b@ catch (NoSuchFieldException ignored)@b@ {@b@ }@b@ catch (SecurityException ignored)@b@ {@b@ }@b@ return false;@b@ }@b@@b@ public static int getThrowableCount(Throwable throwable)@b@ {@b@ int count = 0;@b@ while (throwable != null) {@b@ ++count;@b@ throwable = getCause(throwable);@b@ }@b@ return count;@b@ }@b@@b@ public static Throwable[] getThrowables(Throwable throwable)@b@ {@b@ List list = new ArrayList();@b@ while (throwable != null) {@b@ list.add(throwable);@b@ throwable = getCause(throwable);@b@ }@b@ return ((Throwable[])list.toArray(new Throwable[list.size()]));@b@ }@b@@b@ public static int indexOfThrowable(Throwable throwable, Class type)@b@ {@b@ return indexOfThrowable(throwable, type, 0);@b@ }@b@@b@ public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex)@b@ {@b@ if (throwable == null)@b@ return -1;@b@@b@ if (fromIndex < 0)@b@ fromIndex = 0;@b@@b@ Throwable[] throwables = getThrowables(throwable);@b@ if (fromIndex >= throwables.length)@b@ return -1;@b@@b@ for (int i = fromIndex; i < throwables.length; ++i)@b@ if (throwables[i].getClass().equals(type))@b@ return i;@b@@b@@b@ return -1;@b@ }@b@@b@ public static void printRootCauseStackTrace(Throwable throwable)@b@ {@b@ printRootCauseStackTrace(throwable, System.err);@b@ }@b@@b@ public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream)@b@ {@b@ if (throwable == null)@b@ return;@b@@b@ if (stream == null)@b@ throw new IllegalArgumentException("The PrintStream must not be null");@b@@b@ String[] trace = getRootCauseStackTrace(throwable);@b@ for (int i = 0; i < trace.length; ++i)@b@ stream.println(trace[i]);@b@@b@ stream.flush();@b@ }@b@@b@ public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer)@b@ {@b@ if (throwable == null)@b@ return;@b@@b@ if (writer == null)@b@ throw new IllegalArgumentException("The PrintWriter must not be null");@b@@b@ String[] trace = getRootCauseStackTrace(throwable);@b@ for (int i = 0; i < trace.length; ++i)@b@ writer.println(trace[i]);@b@@b@ writer.flush();@b@ }@b@@b@ public static String[] getRootCauseStackTrace(Throwable throwable)@b@ {@b@ List trace;@b@ int j;@b@ if (throwable == null)@b@ return ArrayHelper.EMPTY_STRING_ARRAY;@b@@b@ Throwable[] throwables = getThrowables(throwable);@b@ int count = throwables.length;@b@ ArrayList frames = new ArrayList();@b@ List nextTrace = getStackFrameList(throwables[(count - 1)]);@b@ for (int i = count; --i >= 0; ) {@b@ trace = nextTrace;@b@ if (i != 0) {@b@ nextTrace = getStackFrameList(throwables[(i - 1)]);@b@ removeCommonFrames(trace, nextTrace);@b@ }@b@ if (i == count - 1) {@b@ frames.add(throwables[i].toString());@b@ }@b@ else@b@ frames.add(" [wrapped] " + throwables[i].toString());@b@@b@ for (j = 0; j < trace.size(); ++j)@b@ frames.add(trace.get(j));@b@ }@b@@b@ return ((String[])frames.toArray(new String[0]));@b@ }@b@@b@ public static void removeCommonFrames(List causeFrames, List wrapperFrames)@b@ {@b@ if ((causeFrames == null) || (wrapperFrames == null))@b@ throw new IllegalArgumentException("The List must not be null");@b@@b@ int causeFrameIndex = causeFrames.size() - 1;@b@ int wrapperFrameIndex = wrapperFrames.size() - 1;@b@ while ((causeFrameIndex >= 0) && (wrapperFrameIndex >= 0))@b@ {@b@ String causeFrame = (String)causeFrames.get(causeFrameIndex);@b@ String wrapperFrame = (String)wrapperFrames.get(wrapperFrameIndex);@b@ if (causeFrame.equals(wrapperFrame))@b@ causeFrames.remove(causeFrameIndex);@b@@b@ --causeFrameIndex;@b@ --wrapperFrameIndex;@b@ }@b@ }@b@@b@ public static String getStackTrace(Throwable throwable)@b@ {@b@ StringWriter sw = new StringWriter();@b@ PrintWriter pw = new PrintWriter(sw, true);@b@ throwable.printStackTrace(pw);@b@ return sw.getBuffer().toString();@b@ }@b@@b@ public static String getFullStackTrace(Throwable throwable)@b@ {@b@ StringWriter sw = new StringWriter();@b@ PrintWriter pw = new PrintWriter(sw, true);@b@ Throwable[] ts = getThrowables(throwable);@b@ for (int i = 0; i < ts.length; ++i) {@b@ ts[i].printStackTrace(pw);@b@ if (isNestedThrowable(ts[i]))@b@ break;@b@ }@b@@b@ return sw.getBuffer().toString();@b@ }@b@@b@ public static String[] getStackFrames(Throwable throwable)@b@ {@b@ if (throwable == null)@b@ return ArrayHelper.EMPTY_STRING_ARRAY;@b@@b@ return getStackFrames(getStackTrace(throwable));@b@ }@b@@b@ static String[] getStackFrames(String stackTrace)@b@ {@b@ String linebreak = LINE_SEPARATOR;@b@ StringTokenizer frames = new StringTokenizer(stackTrace, linebreak);@b@ List list = new LinkedList();@b@ while (frames.hasMoreTokens())@b@ list.add(frames.nextToken());@b@@b@ return ((String[])list.toArray(new String[list.size()]));@b@ }@b@@b@ static List getStackFrameList(Throwable t)@b@ {@b@ String stackTrace = getStackTrace(t);@b@ String linebreak = LINE_SEPARATOR;@b@ StringTokenizer frames = new StringTokenizer(stackTrace, linebreak);@b@ List list = new LinkedList();@b@ boolean traceStarted = false;@b@ while (frames.hasMoreTokens()) {@b@ String token = frames.nextToken();@b@@b@ int at = token.indexOf("at");@b@ if ((at != -1) && (token.substring(0, at).trim().length() == 0)) {@b@ traceStarted = true;@b@ list.add(token);@b@ }@b@ else if (traceStarted) {@b@ break;@b@ }@b@ }@b@ return list;@b@ }@b@@b@ static@b@ {@b@ Method getCauseMethod;@b@ LINE_SEPARATOR = System.getProperty("line.separator");@b@@b@ CAUSE_METHOD_NAMES = new String[] { "getCause", "getNextException", "getTargetException", "getException", "getSourceException", "getRootCause", "getCausedByException", "getNested" };@b@ try@b@ {@b@ getCauseMethod = Throwable.class.getMethod("getCause", null);@b@ }@b@ catch (Exception e) {@b@ getCauseMethod = null;@b@ }@b@ THROWABLE_CAUSE_METHOD = getCauseMethod;@b@ }@b@}