zoukankan      html  css  js  c++  java
  • 基于drools创建自己的关系操作符

     

    我们知道drools提供了12种关系操作符

    但是有些时候这12种操作符依然不能满足我们的业务需求,我们可以扩展自己的操作符,下面是为某一航空公司做项目时扩展了操作符,在这分享下


    首先,我们要实现的逻辑是对航班记录 frFfpTravelDetail的票价级别etFareBasis属性做比配(逻辑:票价级别 去除非英文和数字字符后,第二位开始包含“ID**”或“DG**”或“AD**”(**为数字)),这个逻辑太复杂,用以上12种关系操作符都不能满足,为此要进行扩展。
    第一步:新增CsairEvaluatorDefinition类
    package com.csair.cbd.rules.drools.services.impl;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import org.drools.base.ValueType;
    import org.drools.base.evaluators.EvaluatorDefinition;
    import org.drools.base.evaluators.Operator;
    import org.drools.spi.Evaluator;


    public class CsairEvaluatorDefinition implements EvaluatorDefinition {


    public static final Operator STR_COMPARE = Operator.addOperatorToRegistry(
    "csair", false);
    public static final Operator NOT_STR_COMPARE = Operator
    .addOperatorToRegistry("csair", true);
    private static final String[] SUPPORTED_IDS = { STR_COMPARE
    .getOperatorString() };


    public enum Operations {
    FbInculde
    }


    private Evaluator[] evaluator;


    public Evaluator getEvaluator(ValueType type, Operator operator) {
    return this.getEvaluator(type, operator.getOperatorString(), operator
    .isNegated(), null);
    }


    public Evaluator getEvaluator(ValueType type, Operator operator,
    String parameterText) {
    return this.getEvaluator(type, operator.getOperatorString(), operator
    .isNegated(), parameterText);
    }


    public Evaluator getEvaluator(ValueType type, String operatorId,
    boolean isNegated, String parameterText) {
    return getEvaluator(type, operatorId, isNegated, parameterText,
    Target.FACT, Target.FACT);
    }


    public Evaluator getEvaluator(ValueType type, String operatorId,
    boolean isNegated, String parameterText, Target leftTarget,
    Target rightTarget) {
    CsairEvaluator evaluator = new CsairEvaluator(type, isNegated);
    evaluator.setParameterText(parameterText);
    return evaluator;
    }


    public String[] getEvaluatorIds() {
    return SUPPORTED_IDS;
    }


    public Target getTarget() {
    return Target.FACT;
    }


    public boolean isNegatable() {
    return true;
    }


    public boolean supportsType(ValueType arg0) {
    return true;
    }


    public void readExternal(ObjectInput in) throws IOException,
    ClassNotFoundException {
    evaluator = (Evaluator[]) in.readObject();


    }


    public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(evaluator);
    }


    }

    第二步骤,新增CsairEvaluator类

    package com.csair.cbd.rules.drools.services.impl;


    import org.drools.base.BaseEvaluator;
    import org.drools.base.ValueType;
    import org.drools.common.InternalWorkingMemory;
    import org.drools.rule.VariableRestriction.VariableContextEntry;
    import org.drools.spi.FieldValue;
    import org.drools.spi.InternalReadAccessor;


    import com.csair.cbd.rules.drools.services.impl.CsairEvaluatorDefinition.Operations;


    public class CsairEvaluator extends BaseEvaluator {


    private Operations parameter;


    public void setParameterText(String parameterText) {
    this.parameter = Operations.valueOf(parameterText);
    }


    public Operations getParameter() {
    return parameter;
    }

    public CsairEvaluator(final ValueType type, final boolean isNegated) {
      super(type, isNegated ?  CsairEvaluatorDefinition.NOT_STR_COMPARE: CsairEvaluatorDefinition.STR_COMPARE);
    }


    public boolean evaluate(InternalWorkingMemory workingMemory,
    InternalReadAccessor extractor, Object object, FieldValue value) {
    final Object objectValue = extractor.getValue(workingMemory, object);
    switch (parameter) {
    case FbInculde:
    String sObjectValue = String.valueOf(objectValue);
    String sObjectValueTrim = sObjectValue.replaceAll("[^a-zA-Z0-9]","");
    String sFieldvalue  = String.valueOf(value.getValue());
    boolean ret =sObjectValueTrim.substring(1).matches("^.*["+sFieldvalue+"][0-9]+.*$");
    return  ret;
    default:
    throw new IllegalAccessError("Illegal str comparison parameter");
    }
    }


    public boolean evaluate(InternalWorkingMemory arg0,
    InternalReadAccessor arg1, Object arg2, InternalReadAccessor arg3,
    Object arg4) {
    return false;
    }


    public boolean evaluateCachedLeft(InternalWorkingMemory arg0,
    VariableContextEntry arg1, Object arg2) {
    return false;
    }


    public boolean evaluateCachedRight(InternalWorkingMemory arg0,
    VariableContextEntry arg1, Object arg2) {
    return false;
    }


    }

    第三步骤,配置使drools规则引擎能够识别你定制的逻辑操作符
        System.setProperty("drools.dateformat", "yyyy-MM-dd");
                System.setProperty("drools.dialect.java.compiler", "JANINO");
    //修改默认Java Dialect编译器
    Properties props = new Properties();
    //set default java compiler
    //TODO use a file property to allow configuration
    props.setProperty("drools.dialect.java.compiler", "JANINO");

    PackageBuilderConfiguration pkgBuilderCfg = new PackageBuilderConfiguration(props);
    //扩展csair条件比配操作符,caozhiping
    pkgBuilderCfg.setOption(EvaluatorOption.get("csair",new CsairEvaluatorDefinition()));

    // 声明新的KnowledgeBuilder对象
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
    .newKnowledgeBuilder(pkgBuilderCfg);


    经过以上三步后,你就可以正常使用你自己的关系操作符csair[FBInculde]了,这里贴上项目中的规则

    rule "MingZhuKa-KeDuiHuanLiCheng-500000000001751-p20130727013"
    salience 1          
    no-loop false 
    activation-group "1" 
    ruleflow-group "1" 
     
        when 
            mileages : ArrayList() 
            mileageRuleMiddleValue : MileageRuleMiddleValue() 
            and frFfpTravelDetail : FrFfpTravelDetail(cumulateCabin == "E") 
            and FrFfpTravelDetail(this == frFfpTravelDetail &&
    etFareBasis csair[FbInculde] "(ID)|(DG)|(AD)"
     
        then 
            Date[] dates = ruleGlobalUtil.getMileageRuleCalculate().getValidBeginEndDatesFromTheDate(55,mileageRuleMiddleValue.getBeginValidDate());
            Mileage mileage = new Mileage("000001", "000001", mileageRuleMiddleValue.getBaseMileage()*44*0.01, mileageRuleMiddleValue.getRemark(),"ruleId", dates[0], dates[1], "travel-basic-award-1");
            mileages.add(mileage); 
    end 
     
  • 相关阅读:
    087 类的继承
    086 一切皆对象
    085 对象的绑定方法
    在菜鸟教程学 HTML(一)
    生成输出 URL(16.2)
    创建分部视图(7.6.3)
    显示页面链接(7.5.1)
    NuGet 控制台代码
    浏览器对应用程序的根URL发出请求时所发生的情况(结合 DI)
    第 6 章 —— 依赖项注入(DI)容器 —— Ninject
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3221770.html
Copyright © 2011-2022 走看看