You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
5.4 KiB
Java
167 lines
5.4 KiB
Java
package cokr.xit.foundation;
|
|
|
|
import java.lang.reflect.Array;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.function.Supplier;
|
|
|
|
/**Assertion 유틸리티
|
|
* */
|
|
public class Assert {
|
|
private Assert() {}
|
|
|
|
/**lv와 rv가 같은지 반환한다.
|
|
* @param lv 좌측항의 값
|
|
* @param rv 우측항의 값
|
|
* @return
|
|
* <ul><li>lv와 rv가 같으면 true</li>
|
|
* <li>그렇지 않으면 false</li>
|
|
* </ul>
|
|
*/
|
|
public static final boolean equals(Object lv, Object rv) {
|
|
return lv == rv || lv != null && lv.equals(rv);
|
|
}
|
|
|
|
/**obj가 null인지, 공백문자인지, 빈 collection인지, 빈 배열인지 반환한다.
|
|
* @param obj 오브젝트
|
|
* @return
|
|
* <ul><li>obj가 null인지, 공백문자인지, 빈 collection인지, 빈 배열이면 true</li>
|
|
* <li>그렇지 않으면 false</li>
|
|
* </ul>
|
|
*/
|
|
public static final boolean isEmpty(Object obj) {
|
|
if (obj == null) return true;
|
|
if (obj instanceof String str) {
|
|
return str.isEmpty() || str.isBlank();
|
|
}
|
|
if (obj instanceof Iterable<?> objs) {
|
|
return !objs.iterator().hasNext();
|
|
}
|
|
if (obj.getClass().isArray()) {
|
|
return Array.getLength(obj) < 1;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**t가 {@link #isEmpty(Object) 공백이면} nt가 반환하는 값을, 그렇지 않으면 t를 반환한다.
|
|
* @param <T> 타입
|
|
* @param t 오브젝트
|
|
* @param nt 공백일 경우 nt를 반환할 Supplier
|
|
* @return
|
|
* <ul><li>t가 공백이 아니면 t</li>
|
|
* <li>t가 공백이면 Supplier가 반환하는 값</li>
|
|
* </ul>
|
|
*/
|
|
public static final <T> T ifEmpty(T t, Supplier<T> nt) {
|
|
return !isEmpty(t) ? t : nt != null ? nt.get() : t;
|
|
}
|
|
|
|
/**t가 {@link #isEmpty(Object) 공백이면} nt를, 그렇지 않으면 t를 반환한다.
|
|
* @param <T> 타입
|
|
* @param t 오브젝트
|
|
* @param nt 공백일 경우 반환할 값
|
|
* @return
|
|
* <ul><li>t가 공백이 아니면 t</li>
|
|
* <li>t가 공백이면 nt</li>
|
|
* </ul>
|
|
*/
|
|
public static final <T> T ifEmpty(T t, T nt) {
|
|
return ifEmpty(t, () -> nt);
|
|
}
|
|
|
|
/**t가 공백이 아닌지 확인하고 t를 반환한다.<br />
|
|
* 올바로 동작하려면 JVM을 시작할 때 <code>-enableassertion:cokr.xit.Assert</code>나 <code>-ea:cokr.xit.Assert</code> 옵션을 지정해야 한다.<br />
|
|
* t가 {@link #isEmpty(Object) 공백이면}, NullPointerException을 발생시킨다.
|
|
* @param t 오브젝트
|
|
* @param name assertion 실패 시 오류 메시지에 사용할 이름
|
|
* @param <T> 객체 타입
|
|
* @return t
|
|
*/
|
|
public static final <T> T assertNotEmpty(T t, String name) {
|
|
try {
|
|
assert !isEmpty(t);
|
|
return t;
|
|
} catch (AssertionError e) {
|
|
throw new NullPointerException(name + " 값이 없습니다.");
|
|
}
|
|
}
|
|
|
|
/**t가 공백이 아닌지 확인하고 t를 반환한다.<br />
|
|
* t가 {@link #isEmpty(Object) 공백이면}, NullPointerException을 발생시킨다.
|
|
* @param t 오브젝트
|
|
* @param name assertion 실패 시 오류 메시지에 사용할 이름
|
|
* @param <T> 객체 타입
|
|
* @return t
|
|
*/
|
|
public static final <T> T notEmpty(T t, String name) {
|
|
if (!isEmpty(t)) return t;
|
|
throw new NullPointerException(name + " 값이 없습니다.");
|
|
}
|
|
|
|
/**t의 최초원인이 되는 Throwable을 반환한다.
|
|
* @param t Throwable
|
|
* @return t의 최초원인이 되는 Throwable
|
|
*/
|
|
public static final Throwable rootCause(Throwable t) {
|
|
Throwable cause = t != null ? t.getCause() : null;
|
|
if (cause == null
|
|
&& t instanceof InvocationTargetException e)
|
|
cause = e.getTargetException();
|
|
return cause == null || cause == t ? t : rootCause(cause);
|
|
}
|
|
|
|
/**t의 최초 원인이 된 예외를 RuntimeException에 담아 반환한다.
|
|
* @param t 예외
|
|
* @return RuntimeException
|
|
*/
|
|
public static final RuntimeException runtimeException(Throwable t) {
|
|
t = rootCause(t);
|
|
return t instanceof RuntimeException re ? re : new RuntimeException(t);
|
|
}
|
|
|
|
/**{@link Assert}에 대한 인터페이스.
|
|
* <p>이 인터페이스의 모든 메소드는 디폴트로 Assert 클래스의 메소드를 호출하도록 구현돼 있다.<br />
|
|
* Assert를 상속받지 않는 클래스에서 쉽게 Assert의 메소드를 사용하도록 하기 위한 것이다.
|
|
* </p>
|
|
*/
|
|
public static interface Support {
|
|
/** {@link Assert#equals(Object, Object)} 참고 */
|
|
default boolean equals(Object lv, Object rv) {
|
|
return Assert.equals(lv, rv);
|
|
}
|
|
|
|
/** {@link Assert#isEmpty(Object)} 참고 */
|
|
default boolean isEmpty(Object obj) {
|
|
return Assert.isEmpty(obj);
|
|
}
|
|
|
|
/** {@link Assert#ifEmpty(Object, Supplier)} 참고 */
|
|
default <T> T ifEmpty(T t, Supplier<T> nt) {
|
|
return Assert.ifEmpty(t, nt);
|
|
}
|
|
|
|
/** {@link Assert#ifEmpty(Object, Object)} 참고 */
|
|
default <T> T ifEmpty(T t, T nt) {
|
|
return Assert.ifEmpty(t, nt);
|
|
}
|
|
|
|
/** {@link Assert#assertNotEmpty(Object, String)} 참고 */
|
|
default <T> T assertNotEmpty(T t, String name) {
|
|
return Assert.assertNotEmpty(t, name);
|
|
}
|
|
|
|
/** {@link Assert#notEmpty(Object, String)} 참고 */
|
|
default <T> T notEmpty(T t, String name) {
|
|
return Assert.notEmpty(t, name);
|
|
}
|
|
|
|
/** {@link Assert#rootCause(Throwable)} 참고 */
|
|
default Throwable rootCause(Throwable t) {
|
|
return Assert.rootCause(t);
|
|
}
|
|
|
|
/** {@link Assert#runtimeException(Throwable)} 참고 */
|
|
default RuntimeException runtimeException(Throwable t) {
|
|
return runtimeException(t);
|
|
}
|
|
}
|
|
} |