/*
* 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.ExceptionType.*;
/**
* 断言工具,用来实现<a
* href="http://martinfowler.com/ieeeSoftware/failFast.pdf">Fail-Fast</a>。
* <p>
* <strong>注意事项:</strong>
* </p>
* <ul>
* <li>Assertion是用来明确设置程序中的条件和约定的,它是一种程序员之间交流的工具,而不是和最终用户交流的工具。</li>
* <li>一个经过完整单元测试的正确程序,不应该使任何一条assertion失败。</li>
* <li>应避免过于复杂的assertion条件,而占用过多的运行时间。除非Assertion失败。</li>
* <li>Assertion的出错信息不是给最终用户看的,因此没必要写得过于详细,更没必要考虑国际化的问题,以至于浪费CPU的时间。
* 例如下面的语句是要避免的:
* <p/>
* <pre>
* assertTrue(type instanceof MyType, "Unsupported type: " + type);
* </pre>
* <p/>
* 可以替换成:
* <p/>
* <pre>
* assertTrue(type instanceof MyType, "Unsupported type: %s", type);
* </pre>
* <p/>
* 这样,当assertion顺利通过时,不会占用CPU时间。</li>
* </ul>
* <p>
* 此外,部分方法具有返回值,以方便编程,例如:
* </p>
* <p/>
* <pre>
* void foo(String param) {
* bar(assertNotNull(param));
* }
*
* int bar(String param) {
* if (true) {
* ...
* }
*
* return unreachableCode();
* }
* </pre>
*
* @author Michael Zhou
*/
public final class Assert {
/** 确保对象不为空,否则抛出<code>IllegalArgumentException</code>。 */
public static <T> T assertNotNull(T object) {
return assertNotNull(object, null, null, (Object[]) null);
}
/** 确保对象不为空,否则抛出<code>IllegalArgumentException</code>。 */
public static <T> T assertNotNull(T object, String message, Object... args) {
return assertNotNull(object, null, message, args);
}
/** 确保对象不为空,否则抛出指定异常,默认为<code>IllegalArgumentException</code>。 */
public static <T> T assertNotNull(T object, ExceptionType exceptionType, String message, Object... args) {
if (object == null) {
if (exceptionType == null) {
exceptionType = ILLEGAL_ARGUMENT;
}
throw exceptionType.newInstance(getMessage(message, args,
"[Assertion failed] - the argument is required; it must not be null"));
}
return object;
}
/** 确保对象为空,否则抛出<code>IllegalArgumentException</code>。 */
public static <T> T assertNull(T object) {
return assertNull(object, null, null, (Object[]) null);
}
/** 确保对象为空,否则抛出<code>IllegalArgumentException</code>。 */
public static <T> T assertNull(T object, String message, Object... args) {
return assertNull(object, null, message, args);
}
/** 确保对象为空,否则抛出指定异常,默认为<code>IllegalArgumentException</code>。 */
public static <T> T assertNull(T object, ExceptionType exceptionType, String message, Object... args) {
if (object != null) {
if (exceptionType == null) {
exceptionType = ILLEGAL_ARGUMENT;
}
throw exceptionType.newInstance(getMessage(message, args,
"[Assertion failed] - the object argument must be null"));
}
return object;
}
/** 确保表达式为真,否则抛出<code>IllegalArgumentException</code>。 */
public static void assertTrue(boolean expression) {
assertTrue(expression, null, null, (Object[]) null);
}
/** 确保表达式为真,否则抛出<code>IllegalArgumentException</code>。 */
public static void assertTrue(boolean expression, String message, Object... args) {
assertTrue(expression, null, message, args);
}
/** 确保表达式为真,否则抛出指定异常,默认为<code>IllegalArgumentException</code>。 */
public static void assertTrue(boolean expression, ExceptionType exceptionType, String message, Object... args) {
if (!expression) {
if (exceptionType == null) {
exceptionType = ILLEGAL_ARGUMENT;
}
throw exceptionType.newInstance(getMessage(message, args,
"[Assertion failed] - the expression must be true"));
}
}
/** 不可能到达的代码。 */
public static <T> T unreachableCode() {
unreachableCode(null, (Object[]) null);
return null;
}
/** 不可能到达的代码。 */
public static <T> T unreachableCode(String message, Object... args) {
throw UNREACHABLE_CODE.newInstance(getMessage(message, args,
"[Assertion failed] - the code is expected as unreachable"));
}
/** 不可能发生的异常。 */
public static <T> T unexpectedException(Throwable e) {
unexpectedException(e, null, (Object[]) null);
return null;
}
/** 不可能发生的异常。 */
public static <T> T unexpectedException(Throwable e, String message, Object... args) {
RuntimeException exception = UNEXPECTED_FAILURE.newInstance(getMessage(message, args,
"[Assertion failed] - unexpected exception is thrown"));
exception.initCause(e);
throw exception;
}
/** 未预料的失败。 */
public static <T> T fail() {
fail(null, (Object[]) null);
return null;
}
/** 未预料的失败。 */
public static <T> T fail(String message, Object... args) {
throw UNEXPECTED_FAILURE.newInstance(getMessage(message, args, "[Assertion failed] - unexpected failure"));
}
/** 不支持的操作。 */
public static <T> T unsupportedOperation() {
unsupportedOperation(null, (Object[]) null);
return null;
}
/** 不支持的操作。 */
public static <T> T unsupportedOperation(String message, Object... args) {
throw UNSUPPORTED_OPERATION.newInstance(getMessage(message, args,
"[Assertion failed] - unsupported operation or unimplemented function"));
}
/** 取得带参数的消息。 */
private static String getMessage(String message, Object[] args, String defaultMessage) {
if (message == null) {
message = defaultMessage;
}
if (args == null || args.length == 0) {
return message;
}
return String.format(message, args);
}
/** Assertion错误类型。 */
public static enum ExceptionType {
ILLEGAL_ARGUMENT {
@Override
RuntimeException newInstance(String message) {
return new IllegalArgumentException(message);
}
},
ILLEGAL_STATE {
@Override
RuntimeException newInstance(String message) {
return new IllegalStateException(message);
}
},
NULL_POINT {
@Override
RuntimeException newInstance(String message) {
return new NullPointerException(message);
}
},
UNREACHABLE_CODE {
@Override
RuntimeException newInstance(String message) {
return new UnreachableCodeException(message);
}
},
UNEXPECTED_FAILURE {
@Override
RuntimeException newInstance(String message) {
return new UnexpectedFailureException(message);
}
},
UNSUPPORTED_OPERATION {
@Override
RuntimeException newInstance(String message) {
return new UnsupportedOperationException(message);
}
};
abstract RuntimeException newInstance(String message);
}
}