package org.nutz.mapl.impl.convert; import java.io.Reader; import java.util.HashMap; import java.util.List; import java.util.Map; import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.Streams; import org.nutz.mapl.MaplConvert; import org.nutz.mapl.impl.MaplEach; import org.nutz.mapl.impl.MaplRebuild; /** * MapList结构转换. * <p> 将一种MapList结构转换成另外一种MapList结构.例: * <pre> * { * "age":"123", * "name":"juqkai" * } * 转换成: * { * "年龄":"123", * "姓名":"juqkai" * } * </pre> * <p>要进行这样的转换需要预先配置一个对应关系的配置, 具体的配置关系说明如下: * <ul> * <li>使用原MapList一样的结构 * <li>有数组的, 只写第一个元素的结构 * <li>原结构中的值, 以字符串或字符串数组做为目标结构的对应关系 * <li>对应关系可以为数组 * <li>有数组的, 目标结构以key[].abc来代替数组 * <li>原结构数组层次强制限定一致, 目标结构中'[]'的索引按原结构中出现先后顺序进行匹配. * <li>如果原结果不存在, 那默认为0 * <li>未在模板中申明的不做转换 * </ul> * <p> 例: * <pre> * 例1: * { * "age":"user.年龄", * "name":["user.name", "user.姓名"] * } * 例2(原json:[{"name":"nutz"},{"name":"juqkai"}]): * [{ * "name":"[].姓名" * }] * 例3: * { * users:[ * { * "name":["people[].name", "users[].name"], * "age":"users[].name" * } * ] * } * </pre> * @author juqkai(juqkai@gmail.com) */ public class StructureConvert extends MaplEach implements MaplConvert{ //关系 private Map<String, List<String>> relation = new HashMap<String, List<String>>(); private MaplRebuild structure = new MaplRebuild(); /** * * @param path 模板文件路径 */ public StructureConvert(String path){ Object obj = Json.fromJson(Streams.fileInr(path)); loadRelation(obj, ""); } /** * * @param reader 模板流 */ public StructureConvert(Reader reader){ Object obj = Json.fromJson(reader); loadRelation(obj, ""); } /** * * @param obj 模板的Map, List结构 */ public StructureConvert(Object obj){ loadRelation(obj, ""); } /** * 转换 * @param obj 目标对象 */ public Object convert(Object obj){ each(obj); return structure.fetchNewobj(); } protected void LRD(String path, Object item) {} /** * 重建新对象 */ protected void DLR(String path, Object object) { if(relation.containsKey(path)){ List<String> dests = relation.get(path); for(String dest : dests){ if(dest.equals("")){ structure.put(path, object, arrayIndex); continue; } structure.put(dest, object, arrayIndex); } } } /** * 解析配置信息 * @param obj * @param path */ private void loadRelation(Object obj, String path) { if(obj instanceof Map){ loadMapRelation((Map<?, ?>) obj, path); } else if(obj instanceof List){ loadListRelation((List<?>) obj, path); } else { throw new RuntimeException("无法识别的类型!"); } } /** * 解析List配置信息 * @param obj * @param path */ @SuppressWarnings("unchecked") private void loadListRelation(List<?> obj, String path) { if(obj.size() <= 0){ return; } if(obj.get(0) instanceof String){ relation.put(path, (List<String>) obj); return; } loadRelation(obj.get(0), path + "[]"); } /** * 解析MAP配置信息 * @param obj * @param path */ private void loadMapRelation(Map<?, ?> obj, String path) { for(Object key : obj.keySet()){ Object val = obj.get(key); if(val instanceof String){ relation.put(path + space(path) + key.toString(), Lang.list(val.toString())); continue; } loadRelation(obj.get(key), path + space(path) + key.toString()); } } private String space(String path){ return "".equals(path) ? "" : "."; } }