package org.nutz.mapl.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 构建新的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 HashMap<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){
keys = "obj." + keys;
this.keys = keys.split("\\.");
val = obj;
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("[]")){
if(key.indexOf('[') >0){
Map<String, Object> map = new HashMap<String, Object>();
if(obj != null){
map = (Map<String, Object>) obj;
}
//有Key的list
String k = key.substring(0, key.indexOf('['));
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 = new HashMap<String, Object>();
String key = keys[i];
if(obj != null){
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));
}
} 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 HashMap<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);
}
}