`
Tonyguxu
  • 浏览: 270392 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【决策表管理系统】表达式解析

 
阅读更多

由condition expression生成方法体MethodBody

例:

expression1 = service.isInBlacklist(context.getOriginalMOId(),4)

expression2 = (currentTime-lastActiveDate(context))/1000/60/60/24>=%{day}

expression3 = inboundSMS.getAttribute("MODE_CODES")=="QF"

expression4 = results.getResults()== null || results.getResults().isEmpty()

 

 

Step1. 从表达式里获得参数名(ParameterNames)

——正则表达式处理

 

Step2. CompilingContext、ValueExpression、JavaDomainResolver

 

CompilingContext compilingContext = new CompilingContext();
ValueExpression val = new ValueExpression();
compilingContext.setValue(val);
JavaDomainResolver resolver = ctx.getAppContext().createDomainResolver(artifactType);
compilingContext.setResolver(resolver);

CompilingContext

 

ValueExpression

 

JavaDomainResolver

 

Step3. 将表达式里的%{paramName}换成__paramName

 

 

Step4. 将表达式解析(parse)java 代码

 

SimpleNode node = (SimpleNode) ELParser.parse("#{" + expr + "}");
//生成一个树,该node是根节点
String varName = compilingContext.getNextVarName();
val.setVarName(varName);
node.jjtAccept(new JavaDialect(), compilingContext);
//遍历树,每个节点接收visitor,visitor访问该节点;生成代码
StringBuffer code = new StringBuffer();
val.generateJavaCode(compilingContext, code);
//生成代码

   

 

Step5. 添加return语句

 

if(artifactType.equals(Constants.ARTIFACT_TYPE_CONDITION)){
if (val.getType() == Void.class ||val.getType()==void.class) {

} else if (val.getType().isPrimitive()) {
code.append("\nreturn ").append(getWrapper(val)).append(";\n");
} else {
code.append("\nreturn ").append(val.getVarName()).append(";\n");
}
}

 

expression=attrs.getAttribute("NEW2OLD_NEEDED_TX")!=null

&&attrs.getAttribute("NEW2OLD_NEEDED_TX")==true

将该表达式解析后的java代码如下:

boolean bool1 = false;
    Object localObject1 = ((UserAttributes)getData("attrs")).getAttribute("NEW2OLD_NEEDED_TX");
    int i = (localObject1 != null) ? 1 : 0;
    if (i == 0) {
      bool1 = false;
    } else {
      Object localObject2 = ((UserAttributes)getData("attrs")).getAttribute("NEW2OLD_NEEDED_TX");
      boolean bool2 = localObject2.equals(Boolean.valueOf(true));
      if (bool2)
        bool1 = true;
      else {
        bool1 = false;
      }
    }

    return new Boolean(bool1).booleanValue();

 

问题1:上面step4中代码

 

 

SimpleNode node = (SimpleNode) ELParser.parse("#{" + expr + "}");
ELParserVisitor visitor = new JavaDialect();
node.jjtAccept(visitor, compilingContext);

 

 

 

??SimpleNode、ELParser.parser()。。。

 

Node.java如下

 

/* Generated By:JJTree: Do not edit this line. Node.java Version 4.3 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=false,NODE_PREFIX=Ast,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.wxxr.el.parser;

/* All AST nodes must implement this interface.  It provides basic
   machinery for constructing the parent and child relationships
   between nodes. */

public
interface Node {

  /** This method is called after the node has been made the current
    node.  It indicates that child nodes can now be added to it. */
  public void jjtOpen();

  /** This method is called after all the child nodes have been
    added. */
  public void jjtClose();

  /** This pair of methods are used to inform the node of its
    parent. */
  public void jjtSetParent(Node n);
  public Node jjtGetParent();

  /** This method tells the node to add its argument to the node's
    list of children.  */
  public void jjtAddChild(Node n, int i);

  /** This method returns a child node.  The children are numbered
     from zero, left to right. */
  public Node jjtGetChild(int i);

  /** Return the number of children the node has. */
  public int jjtGetNumChildren();

  /** Accept the visitor. **/
  public Object jjtAccept(ELParserVisitor visitor, Object data);
}
/* JavaCC - OriginalChecksum=fc35c6181f3c693be7a513484d1166bc (do not edit this line) */




》》》》研究Node、SimpleNode、Visitor、

JJTree Reference Documentation 写道
Visitor Support

JJTree provides some basic support for the visitor design pattern. If the VISITOR option is set to true JJTree will insert an jjtAccept() method into all of the node classes it generates, and also generate a visitor interface that can be implemented and passed to the nodes to accept.

The name of the visitor interface is constructed by appending Visitor to the name of the parser. The interface is regenerated every time that JJTree is run, so that it accurately represents the set of nodes used by the parser. This will cause compile time errors if the implementation class has not been updated for the new nodes. This is a feature.

 

访问者模式(Visitor design pattern)的应用

抽象节点角色:Node(提供accept(visitor)方法)

具体节点角色:SimpleNode(部分方法提供默认实现)、AstAnd等(具体节点)

抽象访问者角色:ELParserVisitor(提供visit(node)方法)

具体访问者角色:JavaDialect

 

 

??ValueExpresion里的javaStatement从哪儿来??

 ??ELParser.parse("#{" + expr + "}")生成的Node是什么类型??
JavaDialect里
public Object visit(SimpleNode node, Object data) {
      return null;
}


visitor(访问者)visit(访问)node(节点),
node(节点)accept(接收)visitor(访问者)
visitor(访问者)里为每个node(节点)都准备一个visit(访问)操作


com.wxxr.common.descion.table.spi.IRuleApplication
子类:ZjhzApplication,MockRuleApplication

com.wxxr.common.descion.table.spi.IAppCompileContext
--Dependency[] getDependencies()获取某个应用(如ZjhzApplication)所依赖的jar文件的URL

com.wxxr.common.descion.table.spi.AbstractAppCompileContext
在ZjhzApplication中有具体子类

com.wxxr.common.descion.table.IRuleCompileContext
在DesicionTableRegistryImpl中有具体子类

 

 

 

 

注:以getNextVarName(获得下一个变量名)为例,体会JDK6RuleCompiler中如何通过CompilingContext获得值?

在CompilingContext中持有JavaDomainResolver引用。

 

  • 大小: 5.5 KB
  • 大小: 22.3 KB
  • 大小: 6.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics