Search in sources :

Example 1 with ErrorCode

use of org.rx.annotation.ErrorCode in project rxlib by RockyLOMO.

the class Reflects method changeType.

@SuppressWarnings(NON_RAW_TYPES)
@ErrorCode("enumError")
@ErrorCode(cause = NoSuchMethodException.class)
@ErrorCode(cause = ReflectiveOperationException.class)
public static <T> T changeType(Object value, @NonNull Class<T> toType) {
    if (value == null) {
        if (!toType.isPrimitive()) {
            if (List.class.equals(toType)) {
                return (T) Collections.emptyList();
            }
            if (Map.class.equals(toType)) {
                return (T) Collections.emptyMap();
            }
            return null;
        }
        if (boolean.class.equals(toType)) {
            return (T) Boolean.FALSE;
        } else {
            value = 0;
        }
    }
    Class<?> fromType = value.getClass();
    Object fValue = value;
    if (toType.equals(String.class)) {
        value = value.toString();
    } else if (toType.equals(UUID.class)) {
        value = UUID.fromString(value.toString());
    } else if (toType.equals(BigDecimal.class)) {
        value = new BigDecimal(value.toString());
    } else if (toType.isEnum()) {
        boolean failBack = true;
        if (NEnum.class.isAssignableFrom(toType)) {
            if (value instanceof String) {
                try {
                    value = Integer.valueOf((String) value);
                } catch (NumberFormatException e) {
                // ignore
                }
            }
            if (value instanceof Number) {
                int val = ((Number) value).intValue();
                value = NEnum.valueOf((Class) toType, val);
                failBack = false;
            }
        }
        if (failBack) {
            String val = value.toString();
            value = NQuery.of(toType.getEnumConstants()).singleOrDefault(p -> ((Enum) p).name().equals(val));
        }
        if (value == null) {
            throw new ApplicationException("enumError", values(fValue, toType.getSimpleName()));
        }
    } else if ((!toType.isPrimitive() && TypeUtils.isInstance(value, toType))) {
    // isInstance int to long/all to object ok, do nothing
    } else {
        try {
            toType = (Class) primitiveToWrapper(toType);
            if (toType.equals(Boolean.class) && isAssignable(fromType, Number.class)) {
                int val = ((Number) value).intValue();
                if (val == 0) {
                    value = Boolean.FALSE;
                } else if (val == 1) {
                    value = Boolean.TRUE;
                } else {
                    throw new InvalidException("Value should be 0 or 1");
                }
            } else {
                NQuery<Method> methods = getMethodMap(toType).get(CHANGE_TYPE_METHOD);
                if (methods == null || fromType.isEnum()) {
                    Class<T> fType = toType;
                    ConvertBean convertBean = NQuery.of(CONVERT_BEANS).firstOrDefault(p -> TypeUtils.isInstance(fValue, p.baseFromType) && p.toType.isAssignableFrom(fType));
                    if (convertBean != null) {
                        return (T) convertBean.converter.apply(value, convertBean.toType);
                    }
                    throw new NoSuchMethodException(CHANGE_TYPE_METHOD);
                }
                if (isAssignable(toType, Number.class) && primitiveToWrapper(fromType).equals(Boolean.class)) {
                    boolean val = (boolean) value;
                    if (!val) {
                        value = "0";
                    } else {
                        value = "1";
                    }
                }
                Method m = null;
                for (Method p : methods) {
                    if (!(p.getParameterCount() == 1 && p.getParameterTypes()[0].equals(String.class))) {
                        continue;
                    }
                    m = p;
                    break;
                }
                if (m == null) {
                    m = toType.getDeclaredMethod(CHANGE_TYPE_METHOD, String.class);
                }
                value = m.invoke(null, value.toString());
            }
        } catch (NoSuchMethodException e) {
            throw new ApplicationException(values(toType), e);
        } catch (ReflectiveOperationException e) {
            throw new ApplicationException(values(fromType, toType, value), e);
        }
    }
    return (T) value;
}
Also used : InvalidException(org.rx.exception.InvalidException) BigDecimal(java.math.BigDecimal) ApplicationException(org.rx.exception.ApplicationException) ErrorCode(org.rx.annotation.ErrorCode)

Example 2 with ErrorCode

use of org.rx.annotation.ErrorCode in project rxlib by RockyLOMO.

the class YamlCodeHandler method handle.

@SneakyThrows
public void handle(ApplicationException e) {
    Class<?> codeType = e.getErrorCode().getClass();
    if (codeType.isEnum()) {
        Map<String, Object> messageSource = getMessageSource().readAs(codeType.getName(), Map.class);
        if (messageSource == null) {
            return;
        }
        Enum<?> anEnum = (Enum<?>) e.getErrorCode();
        Field field = codeType.getDeclaredField(anEnum.name());
        ErrorCode errorCode;
        if ((errorCode = findCode(field, null, null)) == null) {
            errorCode = new ErrorCode() {

                @Override
                public Class<? extends Annotation> annotationType() {
                    return ErrorCode.class;
                }

                @Override
                public String value() {
                    return null;
                }

                @Override
                public Class<? extends Throwable> cause() {
                    return Exception.class;
                }

                @Override
                public MessageFormatter messageFormatter() {
                    return MessageFormatter.MessageFormat;
                }
            };
        }
        e.setFriendlyMessage(friendlyMessage(errorCode, messageSource, anEnum.name(), e.getCodeValues()));
        return;
    }
    for (StackTraceElement stack : e.getStacks()) {
        Map<String, Object> messageSource = getMessageSource().readAs(stack.getClassName(), Map.class);
        if (messageSource == null) {
            continue;
        }
        Tuple<Class<?>, Method[]> caller = as(Cache.getOrSet(stack.getClassName(), p -> {
            Class<?> type = Reflects.loadClass(p, false);
            return Tuple.of(type, type.getDeclaredMethods());
        }, Cache.MEMORY_CACHE), Tuple.class);
        if (caller == null) {
            continue;
        }
        Method targetSite = null;
        ErrorCode errorCode = null;
        for (Method method : caller.right) {
            if (!method.getName().equals(stack.getMethodName())) {
                continue;
            }
            if ((errorCode = findCode(method, e.getErrorCode().toString(), e.getCause())) == null) {
                continue;
            }
            log.debug("SystemException: Found @ErrorCode at {}", method);
            targetSite = method;
            break;
        }
        if (errorCode == null) {
            continue;
        }
        e.setFriendlyMessage(friendlyMessage(errorCode, messageSource, targetSite.getName(), e.getCodeValues()));
        break;
    }
    if (e.getFriendlyMessage() == null) {
        log.debug("SystemException: Not found @ErrorCode");
    }
}
Also used : org.rx.core(org.rx.core) AccessibleObject(java.lang.reflect.AccessibleObject) SneakyThrows(lombok.SneakyThrows) YamlConfiguration(org.rx.core.YamlConfiguration) Field(java.lang.reflect.Field) Extends.as(org.rx.core.Extends.as) Tuple(org.rx.bean.Tuple) MessageFormat(java.text.MessageFormat) Slf4j(lombok.extern.slf4j.Slf4j) AccessLevel(lombok.AccessLevel) Map(java.util.Map) Annotation(java.lang.annotation.Annotation) ErrorCode(org.rx.annotation.ErrorCode) Method(java.lang.reflect.Method) NoArgsConstructor(lombok.NoArgsConstructor) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) Field(java.lang.reflect.Field) AccessibleObject(java.lang.reflect.AccessibleObject) ErrorCode(org.rx.annotation.ErrorCode) SneakyThrows(lombok.SneakyThrows)

Example 3 with ErrorCode

use of org.rx.annotation.ErrorCode in project rxlib by RockyLOMO.

the class CoreTester method exceptionHandle.

@ErrorCode
@ErrorCode(cause = IllegalArgumentException.class)
@Test
public void exceptionHandle() {
    ExceptionHandler handler = ExceptionHandler.INSTANCE;
    handler.log(new InvalidException("test error"));
    System.out.println(handler.queryTraces(null, null, null));
    String err = "ERR";
    ApplicationException ex = new ApplicationException(values(err));
    assert eq(ex.getFriendlyMessage(), "Test error code, value=" + err);
    ex = new ApplicationException(values(err), new IllegalArgumentException());
    assert eq(ex.getFriendlyMessage(), "Test IAException, value=" + err);
    $<IllegalArgumentException> out = $();
    assert ex.tryGet(out, IllegalArgumentException.class);
    String errCode = "ERR_CODE";
    ex = new ApplicationException(UserManager.BizCode.USER_NOT_FOUND, values(errCode));
    assert eq(ex.getFriendlyMessage(), "User " + errCode + " not found");
    ex = new ApplicationException(UserManager.BizCode.COMPUTE_FAIL, values(errCode));
    assert eq(ex.getFriendlyMessage(), "Compute user level error " + errCode);
    try {
        Reflects.changeType("x", Date.class);
    } catch (InvalidException e) {
        e.printStackTrace();
    }
}
Also used : ExceptionHandler(org.rx.exception.ExceptionHandler) ApplicationException(org.rx.exception.ApplicationException) InvalidException(org.rx.exception.InvalidException) Test(org.junit.jupiter.api.Test) ErrorCode(org.rx.annotation.ErrorCode)

Example 4 with ErrorCode

use of org.rx.annotation.ErrorCode in project rxlib by RockyLOMO.

the class Reflects method invokeMethod.

@SneakyThrows
@ErrorCode
public static <T, TT> T invokeMethod(Class<? extends TT> type, TT instance, String name, Object... args) {
    boolean isStatic = type != null;
    Class<?> searchType = isStatic ? type : instance.getClass();
    Method method = null;
    NQuery<Method> methods = getMethodMap(searchType).get(name);
    if (methods != null) {
        for (Method p : methods) {
            if (p.getParameterCount() != args.length) {
                continue;
            }
            boolean find = true;
            Class<?>[] parameterTypes = p.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                Class<?> parameterType = parameterTypes[i];
                Object arg = args[i];
                if (arg == null) {
                    if (parameterType.isPrimitive()) {
                        find = false;
                        break;
                    }
                    continue;
                }
                if (!primitiveToWrapper(parameterType).isInstance(arg)) {
                    find = false;
                    break;
                }
            }
            if (find) {
                method = p;
                break;
            }
        }
    }
    if (method != null) {
        return (T) method.invoke(instance, args);
    }
    try {
        if (isStatic) {
            // null 不准
            Class<?>[] parameterTypes = toClass(args);
            method = MethodUtils.getMatchingMethod(searchType, name, parameterTypes);
            return invokeMethod(method, args);
        } else {
            return (T) MethodUtils.invokeMethod(instance, true, name, args);
        }
    } catch (Exception e) {
        throw new ApplicationException(values(searchType.getName(), name), e);
    }
}
Also used : ApplicationException(org.rx.exception.ApplicationException) ApplicationException(org.rx.exception.ApplicationException) InvalidException(org.rx.exception.InvalidException) ErrorCode(org.rx.annotation.ErrorCode)

Example 5 with ErrorCode

use of org.rx.annotation.ErrorCode in project rxlib by RockyLOMO.

the class YamlConfiguration method readAs.

@ErrorCode("keyError")
@ErrorCode("partialKeyError")
public synchronized <T> T readAs(String key, Class<T> type, boolean throwOnEmpty) {
    Map<String, Object> tmp = yaml;
    if (key == null) {
        return convert(tmp, type);
    }
    Object val;
    if ((val = tmp.get(key)) != null) {
        return convert(val, type);
    }
    StringBuilder buf = new StringBuilder();
    String[] splits = Strings.split(key, Constants.CONFIG_KEY_SPLITS);
    int c = splits.length - 1;
    for (int i = 0; i <= c; i++) {
        if (buf.length() > 0) {
            buf.append(Constants.CONFIG_KEY_SPLITS);
        }
        String k = buf.append(splits[i]).toString();
        if ((val = tmp.get(k)) == null) {
            continue;
        }
        if (i == c) {
            return convert(val, type);
        }
        if ((tmp = as(val, Map.class)) == null) {
            throw new ApplicationException("partialKeyError", values(k, type));
        }
        buf.setLength(0);
    }
    if (throwOnEmpty) {
        throw new ApplicationException("keyError", values(key, type));
    }
    return null;
}
Also used : ApplicationException(org.rx.exception.ApplicationException) JSONObject(com.alibaba.fastjson.JSONObject) ErrorCode(org.rx.annotation.ErrorCode)

Aggregations

ErrorCode (org.rx.annotation.ErrorCode)6 ApplicationException (org.rx.exception.ApplicationException)5 InvalidException (org.rx.exception.InvalidException)3 JSONObject (com.alibaba.fastjson.JSONObject)1 Annotation (java.lang.annotation.Annotation)1 AccessibleObject (java.lang.reflect.AccessibleObject)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 BigDecimal (java.math.BigDecimal)1 MessageFormat (java.text.MessageFormat)1 ParseException (java.text.ParseException)1 Map (java.util.Map)1 AccessLevel (lombok.AccessLevel)1 NoArgsConstructor (lombok.NoArgsConstructor)1 SneakyThrows (lombok.SneakyThrows)1 Slf4j (lombok.extern.slf4j.Slf4j)1 Test (org.junit.jupiter.api.Test)1 Tuple (org.rx.bean.Tuple)1 org.rx.core (org.rx.core)1 Extends.as (org.rx.core.Extends.as)1