规则引擎编辑中的最重要的两个部分就是:模型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; } }
这样,后台和数据层的交道就差不多了,下一篇我们介绍如何在前端实现增强的效果。
相关推荐
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规则引擎的开发应用,艾建锋,,规则引擎技术是一项很有吸引力的技术。本文首先介绍了规则引擎的相关概念及其基本组成。然后重点介绍了Java规则引擎技术的规范和��
Drools 规则引擎的介绍及应用,全面介绍了Drools的规则集文件语法
从基础讲起,结合应用场景,由浅到深细化讲解drools规则引擎的的相关知识,并结合具体实例,演示功能的使用和注意事项。后面通过搭建具体的项目并结合springboot框架联合使用Drools的相关知识包括决策表的使用,囊括...
Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete 算法;提供了强大的Eclipse Plugin开发支持; 通过使用其中的DSL(Domain Specific Language),可以实现用自然语言方式来描述业务规则,使得业务分析...
基于Drools的规则引擎实例(完整、可运行eclipse工程)。 Drools 规则引擎
在网上看了基于Drools的规则流的应用,但是在处理.RF文件时遇到了空指针问题,因此没有用规则流的方法,解决了相同的规则匹配。
drools规则引擎在促销系统中的应用.pdf
基于Drools规则引擎开发的一个规则验证样例系统,包含java代码源码、规则源码及所依赖的jar包。
Drools规则引擎及教程,需在jdk1.6下运行,不缺jar包
drools整合apollo实现动态规则引擎,可以在不停服的情况下动态调整规则。无需数据库等存储,自动推送
Drools规则引擎是一种嵌套在应用程序中的组件, 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。 它实现了将业务规则从程序代码忠分离出来,规则引擎使用特定的语法编写业务规则,规则引擎...
drools规则引擎,了解规则匹配,专家系统的可以学习一下,java的同学也可以学习一下,各大厂也在用哦
drools规则引擎系统概要设计.pdf
一个关于drools规则引擎的说明文档,说明的很详细,包括对drools的简介,运行方式介绍,语言编写教程,集成和测试教程,同时包括一些案例,应该是由外文文档进行的翻译
描述Drools规则引擎的相关内容,并讲述java环境下如何集成drools工具实现规则的推理
基于Drools规则引擎的丝绸辅助设计Web专家系统.pdf
Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete算法;提供了强大的EclipsePlugin开发支持;通过使用其中的DSL(DomainSpecificLanguage),可以实现用自然语言方式来描述业务规则,使得业务分析人员也...