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);
}
}