package org.nutz.mapl.impl; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.nutz.lang.Lang; import org.nutz.lang.Strings; /** * 构建新的MapList结构对象, 根据path重建MapList结构 * * @author juqkai(juqkai@gmail.com) */ public class MaplRebuild { enum Model { add, del, cell } private Model model = Model.add; private String[] keys; private Object val; // 数组索引 private Integer arrayItem; // 数组栈列表 protected LinkedList<Integer> arrayIndex = new LinkedList<Integer>(); // 新MapList结构 private Map<String, Object> newobj = new LinkedHashMap<String, Object>(); private Object cellObj = null; public MaplRebuild() { newobj.put("obj", null); } public MaplRebuild(Object mapl) { newobj.put("obj", mapl); } /** * 添加属性 * * @param path * 路径 * @param obj * 值 */ public void put(String path, Object obj) { init(path, obj); inject(newobj, 0); } /** * 添加属性 * * @param path * 路径 * @param obj * 值 * @param arrayIndex * 索引队列 */ public void put(String path, Object obj, LinkedList<Integer> arrayIndex) { this.arrayIndex = arrayIndex; put(path, obj); } /** * 删除结点 * * @param path */ public void remove(String path) { model = Model.del; init(path, null); inject(newobj, 0); } /** * 访问结点 * * @param path * 路径 */ public Object cell(String path) { model = Model.cell; init(path, null); inject(newobj, 0); return cellObj; } /** * 提取重建后的MapList */ public Object fetchNewobj() { return newobj.get("obj"); } private void init(String keys, Object obj) { this.keys = Lang.arrayFirst("obj", Strings.split(keys, false, '.')); this.val = obj; this.arrayItem = 0; } /** * 注入 * * @param obj * @param i */ @SuppressWarnings("unchecked") private Object inject(Object obj, int i) { String key = keys[i]; // 根数组 if (key.indexOf('[') == 0) { List<Object> list = new ArrayList<Object>(); if (obj != null) { list = (List<Object>) obj; } injectList(list, i, fetchIndex(key)); return list; } // 数组 // if(key.endsWith("[]")){ int pos = key.indexOf('['); if (pos > 0) { Map<String, Object> map = new LinkedHashMap<String, Object>(); if (obj != null) { map = (Map<String, Object>) obj; } // 有Key的list String k = key.substring(0, pos); if (!map.containsKey(k)) { map.put(k, new ArrayList<Object>()); } int index = fetchIndex(key.substring(key.indexOf('['), key.length())); injectList((List<Object>) map.get(k), i, index); return map; } if (obj instanceof List) { try { int index = Integer.parseInt(keys[i]); injectList((List<Object>) obj, i, index); return obj; } catch (Exception e) { throw new RuntimeException("路径格式不正确!"); } } return injectMap(obj, i); } private int fetchIndex(String val) { int index = 0; if (val.indexOf(']') == 1) { // []格式的路径, 即索引放在arrayIndex里面的. if (arrayIndex.size() > arrayItem) { index = arrayIndex.get(arrayItem++); } } else { // [1]格式, 路径上自带索引 index = Integer.parseInt(val.substring(1, val.length() - 1)); } return index; } /** * 注入MAP * * @param obj * @param i */ @SuppressWarnings("unchecked") private Object injectMap(Object obj, int i) { Map<String, Object> map; String key = keys[i]; if (obj == null) { map = new LinkedHashMap<String, Object>(); } else { map = (Map<String, Object>) obj; } if (model == Model.add) { if (i == keys.length - 1) { map.put(key, val); return map; } if (!map.containsKey(key) || map.get(key) == null) { map.put(key, inject(null, i + 1)); return map; } } else if (model == Model.del) { if (i == keys.length - 1) { map.remove(key); return map; } if (!map.containsKey(key) || map.get(key) == null) { return map; } } else if (model == Model.cell) { if (i == keys.length - 1) { cellObj = map.get(key); return map; } if (!map.containsKey(key) || map.get(key) == null) { return map; } } if (map.containsKey(key) && map.get(key) != null) { inject(map.get(key), i + 1); } return map; } /** * 注入List * * @param list * @param i */ @SuppressWarnings("unchecked") private void injectList(List<Object> list, int i, int index) { // 添加模式 if (model == Model.add) { if (i == keys.length - 1) { if (val instanceof Collection) { list.addAll((Collection<? extends Object>) val); } else { list.add(index, val); } return; } if (list.size() <= index) { list.add(index, new LinkedHashMap<String, Object>()); } } else if (model == Model.del) { if (i == keys.length - 1) { if (list.size() > index) { list.remove(index); } return; } if (list.size() <= index) { return; } } else if (model == Model.cell) { if (i == keys.length - 1) { if (list.size() > index) { cellObj = list.get(index); } return; } if (list.size() <= index) { return; } } inject((Map<String, Object>) list.get(index), i + 1); } }