/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.
*/
package com.alibaba.citrus.util;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringEscapeUtil.*;
import static com.alibaba.citrus.util.internal.Entities.*;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.alibaba.citrus.util.internal.Entities;
/**
* 处理异常的工具类。
*
* @author Michael Zhou
*/
public class ExceptionUtil {
/** 检查异常是否由指定类型的异常引起。 */
public static boolean causedBy(Throwable t, Class<? extends Throwable> causeType) {
assertNotNull(causeType, "causeType");
Set<Throwable> causes = createHashSet();
for (; t != null && !causeType.isInstance(t) && !causes.contains(t); t = t.getCause()) {
causes.add(t);
}
return t != null && causeType.isInstance(t);
}
/** 取得最根本的异常。 */
public static Throwable getRootCause(Throwable t) {
List<Throwable> causes = getCauses(t, true);
if (causes.isEmpty()) {
return null;
} else {
return causes.get(0);
}
}
/** 取得包括当前异常在内的所有的causes异常,按出现的顺序排列。 */
public static List<Throwable> getCauses(Throwable t) {
return getCauses(t, false);
}
/** 取得包括当前异常在内的所有的causes异常,按出现的顺序排列。 */
public static List<Throwable> getCauses(Throwable t, boolean reversed) {
LinkedList<Throwable> causes = createLinkedList();
for (; t != null && !causes.contains(t); t = t.getCause()) {
if (reversed) {
causes.addFirst(t);
} else {
causes.addLast(t);
}
}
return causes;
}
/** 将异常转换成<code>RuntimeException</code>。 */
public static RuntimeException toRuntimeException(Exception e) {
return toRuntimeException(e, null);
}
/** 将异常转换成<code>RuntimeException</code>。 */
public static RuntimeException toRuntimeException(Exception e,
Class<? extends RuntimeException> runtimeExceptionClass) {
if (e == null) {
return null;
} else if (e instanceof RuntimeException) {
return (RuntimeException) e;
} else {
if (runtimeExceptionClass == null) {
return new RuntimeException(e);
} else {
RuntimeException runtimeException;
try {
runtimeException = runtimeExceptionClass.newInstance();
} catch (Exception ee) {
return new RuntimeException(e);
}
runtimeException.initCause(e);
return runtimeException;
}
}
}
/** 抛出Throwable,但不需要声明<code>throws Throwable</code>。 */
public static void throwExceptionOrError(Throwable t) throws Exception {
if (t instanceof Exception) {
throw (Exception) t;
} else if (t instanceof Error) {
throw (Error) t;
} else {
throw new RuntimeException(t); // unreachable code
}
}
/** 抛出Throwable,但不需要声明<code>throws Throwable</code>。 */
public static void throwRuntimeExceptionOrError(Throwable t) {
if (t instanceof Error) {
throw (Error) t;
} else if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new RuntimeException(t);
}
}
/**
* 取得异常的stacktrace字符串。
*
* @param throwable 异常
* @return stacktrace字符串
*/
public static String getStackTrace(Throwable throwable) {
StringWriter buffer = new StringWriter();
PrintWriter out = new PrintWriter(buffer);
throwable.printStackTrace(out);
out.flush();
return buffer.toString();
}
public static final Entities HTML40_COMMENT;
static {
HTML40_COMMENT = new Entities(HTML40_MODIFIED);
HTML40_COMMENT.addEntity("#45", 45);
}
/**
* 取得异常的stacktrace字符串,可用于填写在HTML comment中。
* <ul>
* <li>先对stacktrace进行HTML escape。</li>
* <li>然后除去double dash(--)。</li>
* </ul>
*
* @param throwable 异常
* @return stacktrace字符串
*/
public static String getStackTraceForHtmlComment(Throwable throwable) {
return escapeEntities(HTML40_COMMENT, getStackTrace(throwable));
}
}