我们知道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 
 

基于drools创建自己的关系操作符的更多相关文章

  1. 用C#基于WCF创建TCP的Service供Client端调用

    本文将详细讲解用C#基于WCF创建TCP的Service供Client端调用的详细过程 1):首先创建一个Windows Service的工程 2):生成的代码工程结构如下所示 3):我们将Servi ...

  2. 对于python,一切事物都是对象,对象基于类创建

    新建列表.新建string字符串 li1 = [1, 2, 3, 4] li2 = list([1, 2, 3]) s1 = "abc" s2 = str("abc&qu ...

  3. 基于catalog 创建RMAN存储脚本

    --============================== -- 基于catalog 创建RMAN存储脚本 --============================== 简言之,将rman的 ...

  4. 基于eclipse创建android的helloworld工程

    基于eclipse创建android的helloworld工程 之前用过Android studio感觉很慢,决定采用eclipse来学习Android开发.下面来看是怎么创建的. 选择File--- ...

  5. asp.net core 系列 20 EF基于数据模型创建数据库

    一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...

  6. C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载(极速,简洁)

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  7. 基于qml创建最简单的图像处理程序(3)-使用opencv&qml进行图像处理

    <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...

  8. 基于qml创建最简单的图像处理程序(2)-使用c++&qml进行图像处理

     <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/8 ...

  9. 基于qml创建最简单的图像处理程序(1)-基于qml创建界面

    <基于qml创建最简单的图像处理程序>系列课程及配套代码基于qml创建最简单的图像处理程序(1)-基于qml创建界面http://www.cnblogs.com/jsxyhelu/p/83 ...

随机推荐

  1. AJAX的概念介绍

    AJAX学习 1.XMLHttpRequest对象创建 var request= new XMLHttpRequest(); 兼容ie6.ie5 var request; if(windoe.XMLH ...

  2. c# 操作PPT

    前段时间要做一个把指定图片放到新建的ppt的东西,在网上找了点资料看了一下,发现用C#做好像是最简单的一个,一下是在网上找的一段代码,直接贴进去就能够执行,可是在执行之前一定要加入dll支持:  项目 ...

  3. Jquery autocomplete 插件使用

    轻松实现类似百度输入框联想功能: autocomplete 是一个很厉害的插件,该插件基于jquery,在jquery官网能下载到最新版本. 首先,jQuery UI 是基于 jQuery 的,所以, ...

  4. extJs项目实战

    extjs是因为在公司用到一次,也是公司唯一一个extjs的项目,当时拿到这个需求的时候,我有点懵逼,这他妈的什么鬼,参加工作两年不到的纯小白,没办法,这是工作,必须要完成的.硬着头皮做吧,好在最后弄 ...

  5. jquery之前后台交互

    //js文件 function getMinatoSingleGoodsCategorys(type){ $("#"+type+"MinatoGoodsCategoryI ...

  6. XtraBackup做mysql主从同步

    一.背景: 线上一个主库压力比较大,所以增加一个从库,但是不能重启或者停止主库的正常运行,不能锁库锁表影响业务的正常运行.所以这里想到了XtraBackup 二.XtraBackup介绍: Xtrab ...

  7. Android(工具・集成)

    ■ NDK Android从始(2009)至终是支持JNI的. 只不过一开始没有NDK.需要自己安装交叉编译器创建so,然后放到assert之类捆绑so发布. 有了NDK.有了什么? libc lib ...

  8. Ganglia 监控Hadoop

    Ganglia监控Hadoop集群的安装部署 一. 安装环境 Ubuntu server 12.04 安装gmetad的机器:192.168.52.105 安装gmond的机 器:192.168.52 ...

  9. git使用笔记(三)(图文说明) 图解提交更改内容的不同方式,涉及代码

    此步之前的工作和示例请参考以下帖子: git使用笔记(一)Git的下载与配置 git使用笔记(二) 如何把GitHub上项目同步到本地 -------------------------------- ...

  10. 转载:Tomcat多数据源配置方法

    转载网址:http://blog.sina.com.cn/s/blog_53803b7b010144u5.html 关于在TOMCAT下配置多数据源,网上有很多方式,但是感觉也很混乱,俺只说俺们使用的 ...