简体   繁体   English

将Drools变量读取为Java代码

[英]Read Drools variable to Java code

I'm new to drools and what I'm trying to do is to get a value from the rules 我是流口水的新手,我想做的就是从规则中获取价值

I used the code from the project sample of drools which is: 我使用了流口水的项目样本中的代码,该代码是:

Reading the DRL file: 读取DRL文件:

KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource( "path.drl", getClass() ), ResourceType.DRL );
KnowledgeBuilderErrors errors = kbuilder.getErrors();

if( errors.size() > 0 )
{
     for( KnowledgeBuilderError error : errors )
     {
          System.err.println( error );
     }
     throw new IllegalArgumentException( "Could not parse knowledge." );
}

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
return kbase;

Inserting object and firing the rules 插入对象并触发规则

Bean bean = new Bean();
StatefulKnowledgeSession ksession = aKnowledgeBase.newStatefulKnowledgeSession();
// planning to insert a double
ksession.insert( bean );
ksession.fireAllRules();

What I want to do is to get a value from the rules , What I tried so far is using query which is I'm not sure if it is the proper way of doing it: 我想做的就是从规则中获取值 ,到目前为止,我一直在尝试使用query ,但我不确定这是否是正确的方法:

global String $test;

rule "Excellent"

    when
        // I'm planning to replace the bean with just a double is that possible?
        $m: bean ( listeningScore > 85 ) 
        $p: bean ( listeningScore < 101 )
    then
        $test = "Excellent";
        System.out.println( $test );

end

query "Knowledge" 
     $result : $test
end

Also this produce an error which I really don't know how to fix. 这也会产生一个错误,我真的不知道该如何解决。 Here is the stacktrace: 这是堆栈跟踪:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[24,0]: [ERR 102] Line 24:0 mismatched input 'end' in query
[0,0]: Parser returned a null Package
java.lang.IllegalArgumentException: Could not parse knowledge.
    at com.neu.als.thesis.units.InferenceEngine.readKnowledgeBase(InferenceEngine.java:61)
    at com.neu.als.thesis.units.EvaluationUnit.evaluateConceptKnowledgeLevel(EvaluationUnit.java:187)
    at com.neu.als.thesis.web.controllers.FLTController.evaluateFLT(FLTController.java:108)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:444)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:432)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:946)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:848)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:822)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Firstly, that exception means that the DRL code won't compile. 首先,该异常意味着DRL代码将无法编译。 I suspect this is because your query is referencing a bound variable from another rule, but it could be something else. 我怀疑这是因为您的查询引用了另一个规则中的绑定变量,但这可能是其他原因。 Check out the docs on syntax for queries. 查看有关查询语法的文档。

However, I tend to use one of two mechanisms for getting rule responses into the Java code. 但是,我倾向于使用两种机制之一将规则响应输入Java代码。

  1. In a stateless session have rules modify the inserted fact(s). 在无状态会话中,规则会修改插入的事实。 After rules execution, just look at the fact that you inserted. 执行规则后,只需查看插入的事实即可。
  2. In a stateful session you can additionally use session.getObjects() or session.getObjects(ObjectFilter) to get references to the facts that are in the working memory after rules execution. 在有状态会话中,您还可以使用session.getObjects()或session.getObjects(ObjectFilter)获取对规则执行后工作内存中的事实的引用。

Here's an example of the first pattern, modifying the inserted fact: 这是第一个模式的示例,它修改了插入的事实:

rule "Reject a request"
when
    $req: PaymentValidationRequest()
then
    $req.setValid(false);
    update($req);
end

PaymentValidationRequest request = new PaymentValidationRequest(payment);
request.setPayment(payment);
List<Object> facts = new ArrayList<Object>();
facts.add(request);     
ksession.execute(facts);
...
boolean isValid = request.isValid()
List<ValidationAnnotation> annotations = request.getAnnotations();

Here's an example of the second pattern, when your rules have inserted or modified facts: 这是您的规则插入或修改事实时第二种模式的示例:

    ObjectFilter filter = new ObjectFilter() {
        @Override
        public boolean accept(Object object) {
            return object.getClass().getSimpleName().equals("MyFact");
        }
    };

    for (FactHandle handle : session.getFactHandles(filter)) {
        Object fact = session.getObject(handle);
        // Do something with the fact you just found in working memory.
        // ...
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM