Ognl表达式引擎之抽象语法树(ASTs)

1.说明:结合ASTs演示Ognl取值机制,“此SAMPLE演示数据流转中的其中一环”
2.能力有限,有误差的请包含或指证
3.目的:抛砖引玉
4.内容:以下为主代码内容,javaBean(User和Company)就不贴出来了,看代码里的setter就可以构造出javaBean了
Ognl表达式引擎之抽象语法树(ASTs)_第1张图片

Ognl表达式引擎之抽象语法树(ASTs)_第2张图片



import java.util.HashMap;
import java.util.Map;

import ognl.Ognl;
import ognl.OgnlException;

/**
 * 此SAMPLE主要演示表达式解析:Ognl.parseExpression(param)
 * 用到了抽象语法树abstract systax trees (ASTs)
 * JJTree interface for AST nodes:
 *      1.ASTProperty-->PropertyAccessor
 *      2.ASTVarRef
 *      3.ASTChain
 *      4.ASTEval
 *      5.ASTStaticMethod
 *      6.ASTStaticFiled
 *      7.ExceptioinNode等
 *  
 * AST Nodes作用:在节点之间提供一种构建父子关系的机制
 * 
 * 思路:通过传递的参数param进行解析,构建相应的Node节点,
 *      然后节点处理最终数值获取的业务逻辑(附流程图JJTree.jpg和Ognl取值流程图.jpg)
 * @author 拈花为何不一笑
 * @since   3/21/2018
 */
public class OgnlExpEngine2 {

    /**
     * 单元测试
     * @param args
     */
    public static void main(String[] args) {
//      testForMapAndObject();
//      testOgnlExpressCalc();
        testOgnlMapping();
    }

    /**
     * Ognl表达式与对象关系之间的映射
     *  如:comh.companyName = "网络穷举大法科技有限公司"
     *  应用场景:也许你会在View层的表单中使用user.username进行数据传递
     *      而这种显示层的弱类型数据是如何与java对象(或对象之间的关系)进行
     *      数据映射的。通过此方法就可以得到其背后机制
     *  
     *  源码片段(把调用逻辑集中在for中为了演示说明,实际是分散开来的):
     *      1.首先通过ASTs构建Node节点
     *      2.其次,使用这些节点处理取值的逻辑,如下:
     *          SimpleNode: getValueBody(context, source)此抽象方法由子类实现
     *                  for(int i = 0, ilast = _children.length - 1; i <= ilast; ++i){
     *                        //(i)通过当前Node:ASTConst,找到字符串常量"comh"
     *                          ASTProperty(comh):_children[i].getValue(context, result);
     *                          //使用一个Node(ASTProperty)获取company实例,target=user,name="comh"
     *                          ASTProperty:OgnlRuntime.getProperty(context, source, property)
     *                          ObjectPropertyAccessor:getPossibleProperty(context, target, name)
     *                          
     *                       //(ii)再通过当前Node:ASTConst找到字符串常量"companyName":
     *                          ASTProperty(companyName):_children[i].getValue(context, result);
     *                       // 再使用一个Node(ASTProperty)获取companyName值,target=company,name="companyName"
     *                       ASTProperty:OgnlRuntime.getProperty(context, source, property)
     *                       ObjectPropertyAccessor:getPossibleProperty(context, target, name)
     *                  }
     *      
     *      
     */
    private static void testOgnlMapping() {

        User user = new User();
        user.setId(1001);
        user.setName("刘思成");
        Company company = new Company();
        company.setCompanyName("网络穷举大法科技有限公司");
        user.setComh(company);

        Object mappingResult = null;
        try {
            mappingResult = Ognl.getValue("comh.companyName", user);
            System.out.println("Ognl表达式与对象关系之间的映射comh.companyName:" + mappingResult );
        } catch (OgnlException e) {
            e.printStackTrace();
        }
    }

    /**
     * Ognl表达式计算
     *  源码片段:通过Ognl.parseExpression(param)方法运用抽象语法树,
     *        构建三个Node,node之间并且构建成父子关系的树型结构
     *     
     *       ASTAdd下面有二个子节点:ASTVarRef/ASTProperty
     *      (ASTAdd(父)-->ASTProperty(子); ASTAdd-->ASTVarRef-->ASTConst)
     * 通过节点:ASTAdd,分别调用两个子节点,然后进行加法运算(有数字加法和非数字加法)
     *  
     */
    private static void testOgnlExpressCalc() {
        Map map = new HashMap();
        map.put("describe", "风景好美");

        User user = new User();
        user.setId(168);
        user.setName("妞妞");
        Object calcResult = null;
        try {

            calcResult = Ognl.getValue(Ognl.parseExpression("#describe + name"), map, user);
                    //Ognl.getValue(Ognl.parseExpression("#describe + id + name"), map, user);
            System.out.println("Ognl表达式计算: "+ calcResult);
        } catch (OgnlException e) {
            e.printStackTrace();
        }

    }

    /**
     * Ognl访问MAP和OBJECT
     * 
     *   源码片段:ASTs(3000多行代码这里就略过了,思路注释OgnlExpEngine2类上)
     *              
     */
    private static void testForMapAndObject() {

        Map map = new HashMap();
        map.put("describe", "风景好美");

        User user = new User();
        user.setId(168);
        user.setName("妞妞");

        try {
            Object describe = Ognl.getValue(Ognl.parseExpression("describe"), map);
            Object describe1 = Ognl.getValue(Ognl.parseExpression("#describe"), map,new Object());
            System.out.println("Ognl访问map中的元素: " + describe1);

            Object name = Ognl.getValue(Ognl.parseExpression("name"), user);
            System.out.println("Ognl访问对象:" + name);
        } catch (OgnlException e) {
            e.printStackTrace();
        }

    }

}

你可能感兴趣的:(java,Ognl框架)