Package cn.wanghaomiao.xpath.core

Source Code of cn.wanghaomiao.xpath.core.NodeTreeBuilderStateMachine

package cn.wanghaomiao.xpath.core;

import cn.wanghaomiao.xpath.model.Node;
import cn.wanghaomiao.xpath.model.Predicate;
import cn.wanghaomiao.xpath.util.EmMap;

/**
* 用于生成xpath语法树的有限状态机
* @author 汪浩淼 [et.tw@163.com]
* @since 13-12-26 下午3:48
*/
public class NodeTreeBuilderStateMachine {
    BuilderState state = BuilderState.SCOPE;
    XContext context = new XContext();
    int cur=0;
    StringBuilder accum = new StringBuilder();
    enum BuilderState {
        SCOPE {
            @Override
            public void parser(NodeTreeBuilderStateMachine stateMachine, char[] xpath) {
                 while (stateMachine.cur<xpath.length){
                     if (!(xpath[stateMachine.cur]=='/'||xpath[stateMachine.cur]=='.')){
                         stateMachine.state = AXIS;
                         Node xn = new Node();
                         stateMachine.context.xpathTr.add(xn);
                         xn.setScopeEm(EmMap.getInstance().scopeEmMap.get(stateMachine.accum.toString()));
                         stateMachine.accum=new StringBuilder();
                         break;
                     }
                     stateMachine.accum.append(xpath[stateMachine.cur]);
                     stateMachine.cur+=1;
                 }
            }
        },
        AXIS {
            @Override
            public void parser(NodeTreeBuilderStateMachine stateMachine, char[] xpath) {
                int curtmp = stateMachine.cur;
                StringBuilder accumTmp=new StringBuilder();
                while (curtmp<xpath.length&&xpath[curtmp]!='['&&xpath[curtmp]!='/'){
                    if (xpath[curtmp]==':'){
                        stateMachine.context.xpathTr.getLast().setAxis(accumTmp.toString());
                        stateMachine.cur=curtmp+2;
                        stateMachine.state = TAG;
                        break;
                    }
                    accumTmp.append(xpath[curtmp]);
                    curtmp+=1;
                }
                stateMachine.state = TAG;
            }
        },
        TAG {
            @Override
            public void parser(NodeTreeBuilderStateMachine stateMachine, char[] xpath) {
                while (stateMachine.cur<xpath.length&&xpath[stateMachine.cur]!='['&&xpath[stateMachine.cur]!='/'){
                    stateMachine.accum.append(xpath[stateMachine.cur]);
                    stateMachine.cur+=1;
                }
                stateMachine.context.xpathTr.getLast().setTagName(stateMachine.accum.toString());
                stateMachine.accum = new StringBuilder();
                if (stateMachine.cur==xpath.length){
                    stateMachine.state =END;
                }else if (xpath[stateMachine.cur]=='/'){
                    stateMachine.state = SCOPE;
                }else if (xpath[stateMachine.cur]=='['){
                    stateMachine.state = PREDICATE;
                }
            }
        },
        PREDICATE{
            @Override
            public void parser(NodeTreeBuilderStateMachine stateMachine, char[] xpath) {
                int deep = 0;
                stateMachine.cur+=1;
                while (!(xpath[stateMachine.cur]==']'&&deep==0)){
                    if (xpath[stateMachine.cur]=='['){
                        deep+=1;
                    }
                    if (xpath[stateMachine.cur]==']'){
                        deep-=1;
                    }
                    stateMachine.accum.append(xpath[stateMachine.cur]);
                    stateMachine.cur+=1;
                }
                Predicate predicate = stateMachine.genPredicate(stateMachine.accum.toString());
                stateMachine.context.xpathTr.getLast().setPredicate(predicate);
                stateMachine.accum = new StringBuilder();
                if (stateMachine.cur<xpath.length-1){
                    stateMachine.cur+=1;
                    stateMachine.state = SCOPE;
                }else {
                    stateMachine.state = END;
                }
            }
        },
        END{
            @Override
            public void parser(NodeTreeBuilderStateMachine stateMachine, char[] xpath) {
            }
        };
        public void parser(NodeTreeBuilderStateMachine stateMachine,char[] xpath){}
    }

    /**
     * 根据谓语字符串初步生成谓语体
     * @param pre
     * @return
     */
    public Predicate genPredicate(String pre){
        StringBuilder op = new StringBuilder();
        StringBuilder left = new StringBuilder();
        StringBuilder right = new StringBuilder();
        Predicate predicate = new Predicate();
        char[] preArray = pre.toCharArray();
        int index = preArray.length-1;
        int argDeep = 0;
        int opFlag = 0;
        if (pre.matches(".+(\\+|=|-|>|<|>=|<=|^=|\\*=|$=|~=|!=)'.+'")){
            while (index>=0){
                char tmp = preArray[index];
                if (tmp=='\''){
                    argDeep+=1;
                }
                if (argDeep==1&&tmp!='\''){
                    right.insert(0,tmp);
                }else if (argDeep==2&&EmMap.getInstance().commOpChar.contains(tmp)){
                    op.insert(0,tmp);
                    opFlag=1;
                }else if (argDeep>=2&&opFlag>0){
                    argDeep++;//取完操作符后剩下的都属于left
                    left.insert(0,tmp);
                }
                index-=1;
            }
        }else if (pre.matches(".+(\\+|=|-|>|<|>=|<=|^=|\\*=|$=|~=|!=)[^']+")){
            while (index>=0){
                char tmp = preArray[index];
                if (opFlag==0&&EmMap.getInstance().commOpChar.contains(tmp)){
                    op.insert(0,tmp);
                }else {
                    if (op.length()>0){
                        left.insert(0,tmp);
                        opFlag=1;
                    }else {
                        right.insert(0,tmp);
                    }
                }
                index-=1;
            }
        }

        predicate.setOpEm(EmMap.getInstance().opEmMap.get(op.toString()));
        predicate.setLeft(left.toString());
        predicate.setRight(right.toString());
        predicate.setValue(pre);
        return predicate;
    }
}
TOP

Related Classes of cn.wanghaomiao.xpath.core.NodeTreeBuilderStateMachine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.