/** * 根据一个对象的字段 生成一个 Chain 对象 * * <p>这个对象可以是一个 POJO 或者是一个 Map。 * * <p>支持 FieldMatcher,即你可以通过 FieldMatcher 来指定你需要哪些字段加入 Chain * * @param obj 对象,可以是一个 POJO 或者是一个 Map * @param fm 指明可用字段,null 表示全部字段可用 * @return Chain 对象,null 表示对象中没有可用字段 * @see org.nutz.dao.FieldMatcher */ public static Chain from(Object obj, FieldMatcher fm) { if (null == obj) return null; Chain c = null; /* * Is Map */ if (obj instanceof Map<?, ?>) { for (Map.Entry<?, ?> en : ((Map<?, ?>) obj).entrySet()) { Object key = en.getKey(); if (null == key) continue; String name = key.toString(); if (null != fm && !fm.match(name)) continue; Object v = en.getValue(); if (null != fm) { if (null == v) { if (fm.isIgnoreNull()) continue; } else if (fm.isIgnoreBlankStr() && v instanceof String) { if (Strings.isBlank((String) v)) continue; } } if (c == null) { c = Chain.make(name, v); } else { c = c.add(name, v); } } } /* * Is POJO */ else { Mirror<?> mirror = Mirror.me(obj.getClass()); for (Field f : mirror.getFields()) { if (null != fm && !fm.match(f.getName())) continue; Object v = mirror.getValue(obj, f.getName()); if (null == v) { if (fm.isIgnoreNull()) continue; } else if (fm.isIgnoreBlankStr() && v instanceof String) { if (Strings.isBlank((String) v)) continue; } if (c == null) { c = Chain.make(f.getName(), v); } else { c = c.add(f.getName(), v); } } } return c; }
@SuppressWarnings("unchecked") private static <T extends Map<String, Object>> void obj2map( Object obj, T map, Map<Object, Object> memo) { if (null == obj || memo.containsKey(obj)) return; memo.put(obj, ""); Mirror<?> mirror = Mirror.me(obj.getClass()); Field[] flds = mirror.getFields(); for (Field fld : flds) { Object v = mirror.getValue(obj, fld); if (null == v) { map.put(fld.getName(), null); continue; } Mirror<?> mr = Mirror.me(fld.getType()); if (mr.isNumber() || mr.isBoolean() || mr.isChar() || mr.isStringLike() || mr.isEnum() || mr.isDateTimeLike()) { map.put(fld.getName(), v); } else if (memo.containsKey(v)) { map.put(fld.getName(), null); } else { T sub; try { sub = (T) map.getClass().newInstance(); } catch (Exception e) { throw Lang.wrapThrow(e); } obj2map(v, sub, memo); map.put(fld.getName(), sub); } } }
/** * 根据一个 Map,和给定的对象类型,创建一个新的 JAVA 对象 * * @param src Map 对象 * @param toType JAVA 对象类型 * @return JAVA 对象 * @throws FailToCastObjectException */ @SuppressWarnings({"unchecked", "rawtypes"}) public static <T> T map2Object(Map<?, ?> src, Class<T> toType) throws FailToCastObjectException { if (null == toType) throw new FailToCastObjectException("target type is Null"); // 类型相同 if (toType == Map.class) return (T) src; // 也是一种 Map if (Map.class.isAssignableFrom(toType)) { Map map; try { map = (Map) toType.newInstance(); map.putAll(src); return (T) map; } catch (Exception e) { throw new FailToCastObjectException("target type fail to born!", e); } } // 数组 if (toType.isArray()) return (T) Lang.collection2array(src.values(), toType.getComponentType()); // List if (List.class == toType) { return (T) Lang.collection2list(src.values()); } // POJO Mirror<T> mirror = Mirror.me(toType); T obj = mirror.born(); for (Field field : mirror.getFields()) { if (src.containsKey(field.getName())) { Object v = src.get(field.getName()); if (null == v) continue; Class<?> ft = field.getType(); Object vv = null; // 集合 if (v instanceof Collection) { Collection c = (Collection) v; // 集合到数组 if (ft.isArray()) { vv = Lang.collection2array(c, ft.getComponentType()); } // 集合到集合 else { // 创建 Collection newCol; Class eleType = Mirror.getGenericTypes(field, 0); if (ft == List.class) { newCol = new ArrayList(c.size()); } else if (ft == Set.class) { newCol = new LinkedHashSet(); } else { try { newCol = (Collection) ft.newInstance(); } catch (Exception e) { throw Lang.wrapThrow(e); } } // 赋值 for (Object ele : c) { newCol.add(Castors.me().castTo(ele, eleType)); } vv = newCol; } } // Map else if (v instanceof Map && Map.class.isAssignableFrom(ft)) { // 创建 final Map map; // Map 接口 if (ft == Map.class) { map = new HashMap(); } // 自己特殊的 Map else { try { map = (Map) ft.newInstance(); } catch (Exception e) { throw new FailToCastObjectException("target type fail to born!", e); } } // 赋值 final Class<?> valType = Mirror.getGenericTypes(field, 1); each( v, new Each<Entry>() { public void invoke(int i, Entry en, int length) { map.put(en.getKey(), Castors.me().castTo(en.getValue(), valType)); } }); vv = map; } // 强制转换 else { vv = Castors.me().castTo(v, ft); } mirror.setValue(obj, field, vv); } } return obj; }
/** * 查找包含某一个特殊注解的字段 * * @param type 类型 * @param ann 注解类型 * @return 字段,null 表示没有找到 */ public static Field findField(Class<?> type, Class<? extends Annotation> ann) { Mirror<?> mirror = Mirror.me(type); for (Field f : mirror.getFields()) if (f.isAnnotationPresent(ann)) return f; return null; }
private void addClass(Class<?> classZ) { if (classZ.isInterface() || classZ.isMemberClass() || classZ.isEnum() || classZ.isAnnotation() || classZ.isAnonymousClass()) return; int modify = classZ.getModifiers(); if (Modifier.isAbstract(modify) || (!Modifier.isPublic(modify))) return; IocBean iocBean = classZ.getAnnotation(IocBean.class); if (iocBean != null) { if (log.isDebugEnabled()) log.debugf("Found a Class with Ioc-Annotation : %s", classZ); // 采用 @IocBean->name String beanName = iocBean.name(); if (Strings.isBlank(beanName)) { // 否则采用 @InjectName InjectName innm = classZ.getAnnotation(InjectName.class); if (null != innm && !Strings.isBlank(innm.value())) { beanName = innm.value(); } // 大哥(姐),您都不设啊!? 那就用 simpleName 吧 else { beanName = Strings.lowerFirst(classZ.getSimpleName()); } } if (map.containsKey(beanName)) throw Lang.makeThrow( IocException.class, "Duplicate beanName=%s, by %s !! Have been define by %s !!", beanName, classZ, map.get(beanName).getClass()); IocObject iocObject = new IocObject(); iocObject.setType(classZ); map.put(beanName, iocObject); iocObject.setSingleton(iocBean.singleton()); if (!Strings.isBlank(iocBean.scope())) iocObject.setScope(iocBean.scope()); // 看看构造函数都需要什么函数 String[] args = iocBean.args(); // if (null == args || args.length == 0) // args = iocBean.param(); if (null != args && args.length > 0) for (String value : args) iocObject.addArg(convert(value)); // 设置Events IocEventSet eventSet = new IocEventSet(); iocObject.setEvents(eventSet); if (!Strings.isBlank(iocBean.create())) eventSet.setCreate(iocBean.create().trim().intern()); if (!Strings.isBlank(iocBean.depose())) eventSet.setDepose(iocBean.depose().trim().intern()); if (!Strings.isBlank(iocBean.fetch())) eventSet.setFetch(iocBean.fetch().trim().intern()); // 处理字段(以@Inject方式,位于字段) List<String> fieldList = new ArrayList<String>(); Mirror<?> mirror = Mirror.me(classZ); Field[] fields = mirror.getFields(Inject.class); for (Field field : fields) { Inject inject = field.getAnnotation(Inject.class); // 无需检查,因为字段名是唯一的 // if(fieldList.contains(field.getName())) // throw duplicateField(classZ,field.getName()); IocField iocField = new IocField(); iocField.setName(field.getName()); IocValue iocValue; if (Strings.isBlank(inject.value())) { iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(field.getName()); } else iocValue = convert(inject.value()); iocField.setValue(iocValue); iocObject.addField(iocField); fieldList.add(iocField.getName()); } // 处理字段(以@Inject方式,位于set方法) Method[] methods; try { methods = classZ.getMethods(); } catch (Exception e) { // 如果获取失败,就忽略之 log.info("Fail to call getMethods(), miss class or Security Limit, ignore it", e); methods = new Method[0]; } for (Method method : methods) { Inject inject = method.getAnnotation(Inject.class); if (inject == null) continue; // 过滤特殊方法 int m = method.getModifiers(); if (Modifier.isAbstract(m) || (!Modifier.isPublic(m)) || Modifier.isStatic(m)) continue; String methodName = method.getName(); if (methodName.startsWith("set") && methodName.length() > 3 && method.getParameterTypes().length == 1) { IocField iocField = new IocField(); iocField.setName(Strings.lowerFirst(methodName.substring(3))); if (fieldList.contains(iocField.getName())) throw duplicateField(classZ, iocField.getName()); IocValue iocValue; if (Strings.isBlank(inject.value())) { iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(Strings.lowerFirst(methodName.substring(3))); } else iocValue = convert(inject.value()); iocField.setValue(iocValue); iocObject.addField(iocField); fieldList.add(iocField.getName()); } } // 处理字段(以@IocBean.field方式) String[] flds = iocBean.fields(); if (flds != null && flds.length > 0) { for (String fieldInfo : flds) { if (fieldList.contains(fieldInfo)) throw duplicateField(classZ, fieldInfo); IocField iocField = new IocField(); if (fieldInfo.contains(":")) { // dao:jndi:dataSource/jdbc形式 String[] datas = fieldInfo.split(":", 2); // 完整形式, 与@Inject完全一致了 iocField.setName(datas[0]); iocField.setValue(convert(datas[1])); iocObject.addField(iocField); } else { // 基本形式, 引用与自身同名的bean iocField.setName(fieldInfo); IocValue iocValue = new IocValue(); iocValue.setType(IocValue.TYPE_REFER); iocValue.setValue(fieldInfo); iocField.setValue(iocValue); iocObject.addField(iocField); } fieldList.add(iocField.getName()); } } } else { if (log.isWarnEnabled()) { Field[] fields = classZ.getDeclaredFields(); for (Field field : fields) if (field.getAnnotation(Inject.class) != null) { log.warnf( "class(%s) don't has @IocBean, but field(%s) has @Inject! Miss @IocBean ??", classZ.getName(), field.getName()); break; } } } }