@SuppressWarnings("unchecked") private <F, T> Castor<F, T> find(Mirror<F> from, Class<T> toType) { Mirror<T> to = Mirror.me(toType, extractor); Class<?>[] fets = from.extractTypes(); Class<?>[] tets = to.extractTypes(); for (Class<?> ft : fets) { for (Class<?> tt : tets) { if (map.containsKey(Castor.fetchHash(ft, tt))) { return (Castor<F, T>) map.get(Castor.fetchHash(ft, tt)); } } } return null; }
/** * 转换一个 POJO 从一个指定的类型到另外的类型 * * @param src 源对象 * @param fromType 源对象类型 * @param toType 目标类型 * @param args 转换时参数。有些 Castor 可能需要这个参数,比如 Array2Map * @return 目标对象 * @throws FailToCastObjectException 如果没有找到转换器,或者转换失败 */ @SuppressWarnings({"unchecked", "rawtypes"}) public <F, T> T cast(Object src, Class<F> fromType, Class<T> toType, String... args) throws FailToCastObjectException { if (null == src) { // 原生数据的默认值 if (toType.isPrimitive()) { if (toType == int.class) return (T) Integer.valueOf(0); else if (toType == long.class) return (T) Long.valueOf(0L); else if (toType == byte.class) return (T) Byte.valueOf((byte) 0); else if (toType == short.class) return (T) Short.valueOf((short) 0); else if (toType == float.class) return (T) Float.valueOf(.0f); else if (toType == double.class) return (T) Double.valueOf(.0); else if (toType == boolean.class) return (T) Boolean.FALSE; else if (toType == char.class) return (T) Character.valueOf(' '); throw Lang.impossible(); } // 是对象,直接返回 null return null; } if (fromType == toType || toType == null || fromType == null) return (T) src; if (fromType.getName().equals(toType.getName())) return (T) src; if (toType.isAssignableFrom(fromType)) return (T) src; Mirror<?> from = Mirror.me(fromType, extractor); if (from.canCastToDirectly(toType)) // Use language built-in cases return (T) src; Castor c = find(from, toType); if (null == c) throw new FailToCastObjectException( String.format( "Can not find castor for '%s'=>'%s' in (%d) because:\n%s", fromType.getName(), toType.getName(), map.size(), "Fail to find matched castor")); try { return (T) c.cast(src, toType, args); } catch (FailToCastObjectException e) { throw e; } catch (Exception e) { throw new FailToCastObjectException( String.format( "Fail to cast from <%s> to <%s> for {%s} because:\n%s:%s", fromType.getName(), toType.getName(), src, e.getClass().getSimpleName(), e.getMessage()), Lang.unwrapThrow(e)); } }
/** * 填充 map .<br> * 在map中使用hash值来做为key来进行存储 * * @param klass * @param settingMap * @throws InstantiationException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ private void fillMap(Class<?> klass, HashMap<Class<?>, Method> settingMap) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Castor<?, ?> castor = (Castor<?, ?>) klass.newInstance(); if (!map.containsKey(castor.hashCode())) { map.put(castor.hashCode(), castor); } Method m = settingMap.get(castor.getClass()); if (null == m) { for (Entry<Class<?>, Method> entry : settingMap.entrySet()) { Class<?> cc = entry.getKey(); if (cc.isAssignableFrom(klass)) { m = settingMap.get(cc); break; } } } if (null != m) m.invoke(setting, castor); }