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

基于Drools规则引擎的企业级应用系列(五)

 
阅读更多

     规则引擎编辑中的最重要的两个部分就是:模型model和商务规则business rule。比如说你的业务系统现在要增加一个字段fieldA,就会引起model的变化,新的规则就需要能够动态发现fieldA,并且能够支持fieldA的数据录入和校验,这样才算是动态的系统。

     model的动态原理上很简单,就是动态生成Java类,drools中通过declare model来实现。原始的模型比较简单,效果如下:

我希望达到的效果是这样:


 支持从XML Schema中选择对应的节点,同时在属性上能够更加丰富,支持正则表达式。为了达到这个效果,同时保持对原有的兼容,就需要创建一个新的资产(Asset)类型。

    新增资产类型首先在contenthandler.properties文件中定义

# for models
model.drl=org.drools.guvnor.server.contenthandler.drools.FactModelContentHandler

# for new models
mymodel.drl=org.drools.guvnor.server.contenthandler.drools.MyModelContentHandler

 新定义的MyModelContentHandler是用来控制model和持久数据之间的访问的,参考FactModelContentHandler的写法,编写自己的实现。

public class MyModelContentHandler extends ContentHandler
    implements
    ICanRenderSource {

    private static final LoggingHelper log = LoggingHelper.getLogger( FactModelContentHandler.class );

    @Override
    public void retrieveAssetContent(Asset asset,
                                     AssetItem item) throws SerializationException {
        try {
            List<FactMetaModel> models = unmarshall( item.getContent() );
            FactModels ms = new FactModels();
            ms.models = models;
            asset.setContent( ms );
        } catch ( Exception e ) {
            log.error( "Unable to parse the MyModel for the model - falling back to text (" + e.getMessage() + ")" );
            RuleContentText text = new RuleContentText();
            text.content = item.getContent();
            asset.setContent( text );
        }

    }

    @Override
    public void storeAssetContent(Asset asset,
                                  AssetItem repoAsset)
                                                      throws SerializationException {
        if ( asset.getContent() instanceof FactModels ) {
            FactModels fm = (FactModels) asset.getContent();
            repoAsset.updateContent( marshall( fm.models ) );
        } else {
            RuleContentText text = (RuleContentText) asset.getContent();
            repoAsset.updateContent( text.content );
        }

    }

    public void assembleSource(PortableObject assetContent,
                               StringBuilder stringBuilder) {
    	FactModels fms = (FactModels) assetContent;
        for ( FactMetaModel fm : fms.models ) {
            stringBuilder.append( toDRL( fm ) );
            stringBuilder.append( "\n\n" );
        }
    }


    List<FactMetaModel> toModel(String drl) throws DroolsParserException {
        if ( drl != null && (drl.startsWith( "#advanced" ) || drl.startsWith( "//advanced" )) ) {
            throw new DroolsParserException( "Using advanced editor" );
        }
        DrlParser parser = new DrlParser();
        PackageDescr pkg = parser.parse( drl );
        if ( parser.hasErrors() ) {
            throw new DroolsParserException( "The model drl " + drl + " is not valid" );
        }

        if ( pkg == null ) return new ArrayList<FactMetaModel>();
        List<TypeDeclarationDescr> types = pkg.getTypeDeclarations();
        List<FactMetaModel> list = new ArrayList<FactMetaModel>( types.size() );
        for ( TypeDeclarationDescr td : types ) {
            FactMetaModel mm = new FactMetaModel();
            mm.setName( td.getTypeName() );
            mm.setSuperType( td.getSuperTypeName() );

            Map<String, TypeFieldDescr> fields = td.getFields();
            for ( Map.Entry<String, TypeFieldDescr> en : fields.entrySet() ) {
                String fieldName = en.getKey();
                TypeFieldDescr descr = en.getValue();
                FieldMetaModel fm = new FieldMetaModel( fieldName,
                                                        descr.getPattern().getObjectType(), 
                                                        null,
                                                        null,
                                                        null,
                                                        null);

                mm.getFields().add( fm );
            }

            list.add( mm );
        }
        return list;
    }
    
    public String marshall(List<FactMetaModel> models){
    	MyModelPersistence persistence = MyModelPersistence.getInstance();
    	StringBuilder sb = new StringBuilder();
    	sb.append("<Model>");
        for ( FactMetaModel factMetaModel : models ) {
            String str = persistence.marshal( factMetaModel );
            sb.append( str ).append( "\n\n" );
        }
        sb.append("</Model>");
        return sb.toString().trim();
    }
    
    public static List<FactMetaModel> unmarshall(String content){
    	
    	String xml = content.replaceAll("<Model>", "").replace("</Model>", "");
    	
    	MyModelPersistence persistence = MyModelPersistence.getInstance();
    	if(content == null || content.trim().length() == 0){
    		return new ArrayList<FactMetaModel>();
    	}
    	String[] strs = xml.split("\n\n");
    	List<FactMetaModel> list = new ArrayList<FactMetaModel>( strs.length );
        for ( String str : strs ) {
            FactMetaModel mm = persistence.unmarshal(str);
            list.add( mm );
        }
        return list;
    }
    
    public static String toDRL(String content) {
    	List<FactMetaModel> models = unmarshall( content );
        StringBuilder sb = new StringBuilder();
        for ( FactMetaModel factMetaModel : models ) {
            String drl = toDRL( factMetaModel );
            sb.append( drl ).append( "\n\n" );
        }
        return sb.toString().trim();
    }
    /*
    * 获得模型中的字段对应的中文显示名称
    */    
    public static Map<String, String> getDisplayNames(AssetItem item){
    	Map<String, String> displayNames = new HashMap<String, String>();
    	List<FactMetaModel> models = unmarshall( item.getContent() );
        for ( FactMetaModel factMetaModel : models ) {
        	displayNames.put(factMetaModel.getName(), factMetaModel.getDisplayName());
        	for ( int i = 0; i < factMetaModel.getFields().size(); i++ ) {
                FieldMetaModel f = factMetaModel.getFields().get( i );
                displayNames.put(factMetaModel.getName() + "." + f.name, f.displayName);
            }
        }
    	return displayNames;
    }
    /*
     * 获得模型中每个字段的限制正则表达式
     */    
    public static Map<String, String> getRestrictions(AssetItem item){
    	Map<String, String> regexs = new HashMap<String, String>();
    	List<FactMetaModel> models = unmarshall( item.getContent() );
        for ( FactMetaModel factMetaModel : models ) {
        	for ( int i = 0; i < factMetaModel.getFields().size(); i++ ) {
                FieldMetaModel f = factMetaModel.getFields().get( i );
                regexs.put(factMetaModel.getName() + "." + f.name, f.regex);
            }
        }
    	return regexs;
    }
    /*
    * 将FactMetaModel翻译成DRL文件
    */
    static String toDRL(FactMetaModel mm) {
        StringBuilder sb = new StringBuilder();
        sb.append( "declare " ).append( mm.getName() );
        if ( mm.hasSuperType() ) {
            sb.append( " extends " );
            sb.append( mm.getSuperType() );
        }
        for ( int i = 0; i < mm.getFields().size(); i++ ) {
            FieldMetaModel f = mm.getFields().get( i );
            sb.append( "\n\t" );
            sb.append( f.name ).append( ": " ).append( f.type );
        }
        sb.append( "\nend" );
        return sb.toString();
    }
    /*
    * 获得模型中每个字段的修饰操作标记,可以是可读写的、只读、只写状态
    */
    public static Map<String, FieldAccessorsAndMutators> getAccessorsAndMutators(
			AssetItem as) {
    	Map<String, FieldAccessorsAndMutators> fieldAccessors = new HashMap<String, FieldAccessorsAndMutators>();
    	List<FactMetaModel> models = unmarshall( as.getContent() );
        for ( FactMetaModel factMetaModel : models ) {
        	for ( int i = 0; i < factMetaModel.getFields().size(); i++ ) {
                FieldMetaModel f = factMetaModel.getFields().get( i );
                FieldAccessorsAndMutators accessor;
                if(f.scope.equals("when")){
                	accessor = FieldAccessorsAndMutators.ACCESSOR;
                }else if(f.scope.equals("then")){
                	accessor = FieldAccessorsAndMutators.MUTATOR;
                }else{
                	accessor = FieldAccessorsAndMutators.BOTH;
                }
                fieldAccessors.put(factMetaModel.getName() + "." + f.name, accessor);
            }
        }
    	return fieldAccessors;
	}
    
}

 相应的模型定义为

/**
 * Represents the GUI data for a fact model definition.
 */
public class FactMetaModel
    implements
        PortableObject {

    private static final long         serialVersionUID = 510L;

    private String                    name;
    private String	          displayName;
    private String                    superType;
    private List<FieldMetaModel> fields = new ArrayList<FieldMetaModel>();
    //List reference schema by this fact
    private List<String[]>      schemas  = new ArrayList<String[]>();
    
    public List<String[]> getSchemas() {
        return schemas;
    }

    public void setSchemas(List<String[]> schemas) {
         this.schemas = schemas;
    }

    public FactMetaModel() {
    }

    public FactMetaModel(String name, String displayName) {
        this.name = name;
        this.displayName = displayName;
    }

    public FactMetaModel(String name,
                         String displayName,
                         List<FieldMetaModel> fields) {
        this.name = name;
        this.displayName = displayName;
        this.fields = fields;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }
 
    public List<FieldMetaModel> getFields() {
        return fields;
    }

    public void setFields(List<FieldMetaModel> fields) {
        this.fields = fields;
    }

    public void setSuperType(String superType) {
        this.superType = superType;
    }

    public String getSuperType() {
        return this.superType;
    }

    public boolean hasSuperType() {
        return this.superType != null;
    }
}

 

这样,后台和数据层的交道就差不多了,下一篇我们介绍如何在前端实现增强的效果。

 

  • 大小: 7.6 KB
  • 大小: 30.6 KB
分享到:
评论

相关推荐

    Drools规则引擎从入门到精通

    1 Drools简介1.1 Drools的作用1.2 使用规则引擎的优势1.3 规则引擎应用场景2 Drools初体验2.1 构建项目2.2 案例描述 2.3 代码实现3 Drools语法介绍3.1 规则文件的组成3.2 规则体语法结构3.3 Pattern模式匹配 ...

    论文研究-Drools规则引擎的开发应用 .pdf

    Drools规则引擎的开发应用,艾建锋,,规则引擎技术是一项很有吸引力的技术。本文首先介绍了规则引擎的相关概念及其基本组成。然后重点介绍了Java规则引擎技术的规范和��

    Drools 规则引擎的介绍及应用

    Drools 规则引擎的介绍及应用,全面介绍了Drools的规则集文件语法

    Drools规则引擎从入门到精通源码

    从基础讲起,结合应用场景,由浅到深细化讲解drools规则引擎的的相关知识,并结合具体实例,演示功能的使用和注意事项。后面通过搭建具体的项目并结合springboot框架联合使用Drools的相关知识包括决策表的使用,囊括...

    Drools规则引擎Drools规则引擎

    Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete 算法;提供了强大的Eclipse Plugin开发支持; 通过使用其中的DSL(Domain Specific Language),可以实现用自然语言方式来描述业务规则,使得业务分析...

    基于Drools的规则引擎实例(完整、可运行eclipse工程)

    基于Drools的规则引擎实例(完整、可运行eclipse工程)。 Drools 规则引擎

    基于Drools规则引擎的实例

    在网上看了基于Drools的规则流的应用,但是在处理.RF文件时遇到了空指针问题,因此没有用规则流的方法,解决了相同的规则匹配。

    drools规则引擎在促销系统中的应用.pdf

    drools规则引擎在促销系统中的应用.pdf

    Drools规则引擎样例系统

    基于Drools规则引擎开发的一个规则验证样例系统,包含java代码源码、规则源码及所依赖的jar包。

    Drools规则引擎及教程

    Drools规则引擎及教程,需在jdk1.6下运行,不缺jar包

    drools整合apollo实现动态规则引擎

    drools整合apollo实现动态规则引擎,可以在不停服的情况下动态调整规则。无需数据库等存储,自动推送

    Drools规则引擎实现原理及示例

    Drools规则引擎是一种嵌套在应用程序中的组件, 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。 它实现了将业务规则从程序代码忠分离出来,规则引擎使用特定的语法编写业务规则,规则引擎...

    Drools规则引擎介绍.ppt

    drools规则引擎,了解规则匹配,专家系统的可以学习一下,java的同学也可以学习一下,各大厂也在用哦

    drools规则引擎系统概要设计.pdf

    drools规则引擎系统概要设计.pdf

    Drools规则引擎手册.zip

    一个关于drools规则引擎的说明文档,说明的很详细,包括对drools的简介,运行方式介绍,语言编写教程,集成和测试教程,同时包括一些案例,应该是由外文文档进行的翻译

    Drools规则引擎

    描述Drools规则引擎的相关内容,并讲述java环境下如何集成drools工具实现规则的推理

    基于Drools规则引擎的丝绸辅助设计Web专家系统.pdf

    基于Drools规则引擎的丝绸辅助设计Web专家系统.pdf

    Drools规则引擎介绍

    Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete算法;提供了强大的EclipsePlugin开发支持;通过使用其中的DSL(DomainSpecificLanguage),可以实现用自然语言方式来描述业务规则,使得业务分析人员也...

Global site tag (gtag.js) - Google Analytics