package org.nutz.el.parse; import java.io.Reader; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.nutz.el.ElException; import org.nutz.el.Parse; import org.nutz.el.obj.Elobj; import org.nutz.el.obj.FieldObj; import org.nutz.el.obj.IdentifierObj; import org.nutz.el.obj.MethodObj; import org.nutz.el.opt.arithmetic.LBracketOpt; import org.nutz.el.opt.arithmetic.NegativeOpt; import org.nutz.el.opt.arithmetic.RBracketOpt; import org.nutz.el.opt.arithmetic.SubOpt; import org.nutz.el.opt.object.AccessOpt; import org.nutz.el.opt.object.CommaOpt; import org.nutz.el.opt.object.InvokeMethodOpt; import org.nutz.el.opt.object.MethodOpt; import org.nutz.lang.Lang; /** * 转换器,也就是用来将字符串转换成队列. TODO 这个类的名字不知道取什么好... * * @author juqkai(juqkai@gmail.com) * */ public class Converter { private final List<Parse> parses = new ArrayList<Parse>(); // 表达式字符队列 private CharQueue exp; // 表达式项 private LinkedList<Object> itemCache; // 方法栈 private LinkedList<MethodOpt> methods = new LinkedList<MethodOpt>(); // 上一个数据 private Object prev = null; public Converter(CharQueue reader) { this.exp = reader; itemCache = new LinkedList<Object>(); skipSpace(); initParse(); } public Converter(String val) { this(Lang.inr(val)); } public Converter(Reader reader) { this(new CharQueueDefault(reader)); } /** * 初始化解析器 */ private void initParse() { parses.add(new OptParse()); parses.add(new StringParse()); parses.add(new IdentifierParse()); parses.add(new ValParse()); } /** * 重新设置解析器 */ public void setParse(List<Parse> val) { parses.addAll(val); } /** * 初始化EL项 */ public void initItems() { while (!exp.isEmpty()) { Object obj = parseItem(); // 处理数组的情况 if (obj.getClass().isArray()) { for (Object o : (Object[]) obj) { itemCache.add(o); } continue; } itemCache.add(obj); } itemCache = clearUp(itemCache); } /** * 清理转换后的结果, 主要做一些标识性的转换 * * @param rpn * @return */ private LinkedList<Object> clearUp(LinkedList<Object> rpn) { LinkedList<Object> dest = new LinkedList<Object>(); while (!rpn.isEmpty()) { if (!(rpn.getFirst() instanceof Elobj)) { dest.add(rpn.removeFirst()); continue; } Elobj obj = (Elobj) rpn.removeFirst(); // 方法对象 if (!rpn.isEmpty() && rpn.getFirst() instanceof MethodOpt) { dest.add(new MethodObj(obj.getVal())); continue; } // 属性对象 if (dest.size() > 0 && dest.getLast() instanceof AccessOpt && rpn.size() > 0 && rpn.getFirst() instanceof AccessOpt) { dest.add(new FieldObj(obj.getVal())); continue; } // //普通的对象 // if(!(dest.getLast() instanceof AccessOpt) && !(rpn.peekFirst() // instanceof MethodOpt)){ // continue; // } dest.add(new IdentifierObj(obj.getVal())); } return dest; } /** * 解析数据 */ private Object parseItem() { Object obj = Parse.nullobj; for (Parse parse : parses) { obj = parse.fetchItem(exp); if (obj != Parse.nullobj) { skipSpace(); return parseItem(obj); } } throw new ElException("无法解析!"); } /** * 转换数据,主要是转换负号,方法执行 */ private Object parseItem(Object item) { // 处理参数个数 if (methods.peek() != null) { MethodOpt opt = methods.peek(); if (opt.getSize() <= 0) { if (!(item instanceof CommaOpt) && !(item instanceof RBracketOpt)) { opt.setSize(1); } } else { if (item instanceof CommaOpt) { opt.setSize(opt.getSize() + 1); } } } // 左括号 if (item instanceof LBracketOpt) { if (prev instanceof Elobj) { MethodOpt prem = new MethodOpt(); item = new Object[]{prem, new LBracketOpt()}; methods.addFirst(prem); } else { methods.addFirst(null); } } // 右括号 if (item instanceof RBracketOpt) { if (methods.poll() != null) { item = new Object[]{new RBracketOpt(), new InvokeMethodOpt()}; } } // 转换负号'-' if (item instanceof SubOpt && NegativeOpt.isNegetive(prev)) { item = new NegativeOpt(); } prev = item; return item; } /** * 跳过空格,并返回是否跳过空格(是否存在空格) */ private boolean skipSpace() { boolean space = false; while (!exp.isEmpty() && Character.isWhitespace(exp.peek())) { space = true; exp.poll(); } return space; } /** * 取得一个有效数据 */ public Object fetchItem() { return itemCache.poll(); } /** * 是否结束 */ public boolean isEnd() { return itemCache.isEmpty(); } }