2013-06-11 4 views
4

DRL에서 수동으로 작성된 일부 규칙을 단순화하여 유지 관리하기가 어려워졌습니다.Drools 복잡한 사실

google을 통해 검색하면 "의사 결정 테이블이 최선의 방법"이라는 결론을 얻었습니다.

그러나 불행하게도 우리의 사실은

그래서 첫 번째 질문은 개발자가 일반적으로이 샘 지식에 매우 복잡한 사실을 처리하는 처리 어떻게하고, 순간 spreadsheetconverter을 Drools가에 그래서, 사실에 너무 많은 복잡성을 처리 할 수없는, 매우 복잡 베이스?

예를 들어 우리는 지금은 규칙을 작성해야 사람이 자신의 보험 청구에 대한 나쁜 역사를 가지고 말을

Person->List<Cars>->List<Insurances>->Each insurance Has List<History> 

같은 사실이있다. 그럼 난 매우 diffcult speadsheet에 넣어 어디로 쉽게 수동 으로이 규칙을 작성하는 drl 파일에 찾으십시오.

도움 주셔서 감사합니다. 위의 예에 대한 도움도 매우 좋습니다.

+0

다시 모든 수취인을 기재하십시오. – user1224036

+0

안녕하세요, 알고 싶다 방법이 거기에 그것을 달성 aroun 무엇입니까? – user1224036

답변

3

이와 같은 복잡한 규칙의 경우 Drools 템플릿을 사용합니다. 필드가 채워지는 매개 변수 확장을 사용하여 규칙 템플릿을 작성하고 실제 값이 어디에서 유래하여 골격 규칙을 채우는 지 훨씬 더 융통성있게 처리 할 수 ​​있습니다.

이 기능은 Drools Guvnor에 내장되어 있지만 GUI를 통해 복잡한 규칙 템플릿을 작성하는 것은 다소 지루합니다. 또한 독립형 Java를 작성하여 등록 정보 파일에서 가져온 값 목록에서 템플릿 drl 파일을 채우고 사용자가 규칙 값을 채우고 DRL을 생성 할 수있는 SmartGWT 웹 앱을 개발했습니다.

편집 : 샘플 프로그램 추가. DroolsTemplateBuilder는 Test.drl의 템플릿 키에 매핑되는 필드가있는 TestType 개체의 목록을 만듭니다. 생성 된 DRL이 인쇄되고 Test.pkg라는 파일에 기록되는 pkg로 컴파일됩니다.

라이브러리 : antlr-3.3.jar, antlr-runtime-3.3.jar, drools-compiler-5.2.0.Final.jar, drools-core-5.2.0.Final.jar, drools-templates-5.2. 0.Final.jar, ecj-4.2.jar, knowledge-api-5.2.0.Final.jar, mvel2-2.1.0.drools.jar (모두 필요하지는 않음).

참고 :이 예제는 5.2.0 라이브러리를 사용하며 최신 릴리스에서는 일부 기능이 다를 수 있습니다. build.xml은 프로젝트 구조화 방법을 명확히해야합니다.

DroolsTemplateBuilder.java :

package some.test.pkg; 

import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.ObjectOutputStream; 
import java.io.OutputStream; 
import java.io.Reader; 
import java.io.StringReader; 
import java.util.ArrayList; 
import java.util.Collection; 

import org.drools.builder.KnowledgeBuilder; 
import org.drools.builder.KnowledgeBuilderError; 
import org.drools.builder.KnowledgeBuilderFactory; 
import org.drools.builder.ResourceType; 
import org.drools.common.DroolsObjectOutputStream; 
import org.drools.definitions.impl.KnowledgePackageImp; 
import org.drools.io.ResourceFactory; 
import org.drools.template.ObjectDataCompiler; 

public class DroolsTemplateBuilder { 

    private String filePath; 
    private String drl; 

    public static void main(String[] args) { 
     DroolsTemplateBuilder test = new DroolsTemplateBuilder(); 
     test.filePath = args[0] + File.separator + "Test.drl"; 
     test.runTest(); 
    } 

    public void runTest() { 
     buildPackage(); 
     writeRulePackageToFile(); 
    } 

    public void buildPackage() { 

     Collection<Object> templateList = new ArrayList<Object>(); 
     templateList.add(new TestType(1, "John", "Manager")); 
     templateList.add(new TestType(2, "Peter", "CEO")); 
     templateList.add(new TestType(3, "Kate", "Engineer")); 

     try { 
      ObjectDataCompiler converter = new ObjectDataCompiler(); 
      InputStream templateStream = new FileInputStream(filePath); 

      String myDrl = inputStreamToString(templateStream, 200); 
      // I use this ##### replacement instead of just a newline in the 
      // template 
      // because of windows/linux issues with newline and carriage return. 
      // Drools template 
      // builder, at least in 5.2.0, was very picky about the template 
      // structure, including 
      // where newlines are expected. 
      myDrl = myDrl.replaceAll("#####", "\n"); 

      InputStream tempStream = new ByteArrayInputStream(myDrl.getBytes()); 

      drl = converter.compile(templateList, tempStream); 
      System.out.println(drl); 
     } catch (Exception e) { 
      System.out.println("Exception: " + e.getMessage()); 
     } 

    } 

    public void writeRulePackageToFile() { 
     try { 
      KnowledgeBuilder kBuilder = KnowledgeBuilderFactory 
        .newKnowledgeBuilder(); 

      Reader rdr = new StringReader(drl); 

      kBuilder.add(ResourceFactory.newReaderResource(rdr), 
        ResourceType.DRL); 

      if (kBuilder.hasErrors()) { 
       System.out.println("Drools blew up on"); 
       for (KnowledgeBuilderError err : kBuilder.getErrors()) { 
        System.out.println(err.getMessage()); 
       } 
      } else { 
       String outFile = filePath.replaceFirst("\\.drl", ".pkg"); 
       OutputStream os = new FileOutputStream(outFile); 
       ObjectOutputStream oos = new DroolsObjectOutputStream(os); 
       KnowledgePackageImp kPackage = (KnowledgePackageImp) kBuilder 
         .getKnowledgePackages().iterator().next(); 
       oos.writeObject(kPackage); 
       oos.close(); 
      } 
     } catch (Exception e) { 
      System.out.println("Exception " + e.getMessage()); 
     } 
    } 

    public String inputStreamToString(final InputStream is, final int bufferSize) { 
     final char[] buffer = new char[bufferSize]; 
     final StringBuilder out = new StringBuilder(); 
     try { 
      final Reader in = new InputStreamReader(is, "UTF-8"); 
      try { 
       for (;;) { 
        int rsz = in.read(buffer, 0, buffer.length); 
        if (rsz < 0) 
         break; 
        out.append(buffer, 0, rsz); 
       } 
      } finally { 
       in.close(); 
      } 
     } catch (Exception ex) { 
      System.out.println("Something went wrong: " + ex.getMessage()); 
     } 
     return out.toString(); 
    } 

} 

test.drl 파일 :

template header 
id 
name 
title 
##### 
package some.test.pkg; 

template "sampleTemplate" 

rule "id [email protected]{row.rowNumber}" 
no-loop true 
dialect "java" 
when 
    $t : TestType(id=="@{id}") 
then 
    System.out.println("Doing something special..."); 
end 

end template 

template "anotherSample" 

rule "another [email protected]{row.rowNumber}" 
no-loop true 
dialect "java" 
when 
    $t : TestType((name=="@{name}") || (title=="@{title}")) 
then 
    System.out.println("Doing something else..."); 
end 

end template 

TestType.java :

package some.test.pkg; 

public class TestType { 

    private int id; 
    private String name; 
    private String title; 

    public TestType(int id, String name, String title) { 
     this.id = id; 
     this.name = name; 
     this.title = title; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

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

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

} 

의 build.xml은 :

<project name="TemplateTest" basedir="." default="jar"> 

    <property name="src.dir" value="src" /> 

    <property name="build.dir" value="build" /> 
    <property name="drl.dir" value="${basedir}/drl" /> 
    <property name="classes.dir" value="${build.dir}/classes" /> 
    <property name="jar.dir" value="${build.dir}/jar" /> 
    <property name="lib.dir" value="${basedir}/lib" /> 

    <path id="compile.classpath"> 
     <fileset dir="${lib.dir}" includes="*.jar" /> 
    </path> 

    <path id="run.classpath"> 
     <fileset dir="${jar.dir}" includes="*.jar" /> 
     <fileset dir="${lib.dir}" includes="*.jar" /> 
    </path> 

    <target name="clean"> 
     <delete dir="${classes.dir}" /> 
     <delete dir="${jar.dir}" /> 
    </target> 

    <target name="compile" depends="clean"> 
     <mkdir dir="${classes.dir}" /> 
     <mkdir dir="${jar.dir}" /> 
     <javac includeantruntime="false" srcdir="${src.dir}" classpathref="compile.classpath" destdir="${classes.dir}" /> 
    </target> 

    <target name="jar" depends="compile"> 
     <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"> 
     </jar> 
    </target> 

    <target name="run" depends="jar" description="run"> 
     <java classpathref="run.classpath" classname="some.test.pkg.DroolsTemplateBuilder" fork="true"> 
      <arg value="${drl.dir}" /> 
     </java> 
    </target> 

</project> 
+1

예제가 있습니까? 부디 – user1224036

0

우리는 또한 템플릿 및 우리의 사실 (및 결과 규칙)를 사용은 매우 복잡하다.템플릿 테이블의 값은 메서드 호출 규칙, 규칙 "옵션"설정, 타이머 값 등에 사용됩니다.

템플릿 매개 변수가 표 형식으로 제공되는 경우 템플릿이 도움이됩니다. 액세스 제어가 걱정된다면 동일한 논리를 가진 여러 템플릿을 필요로 할 수 있습니다. (그냥 첫 번째 템플릿을 복사하여 guvnor에서 쉽게).