我正试图从规则中获取新的插入事实:
import com.neu.als.thesis.db.beans.FLTBean
import com.neu.als.thesis.db.beans.StudentBean
rule "Excellent"
no-loop
when
$m: FLTBean ( listeningScore > 85 && listeningScore < 101 )
then
StudentBean studentBean = new StudentBean();
studentBean.setKnowledgeLevel( "Excellent" );
insert( studentBean );
end
要从有状态会话中获取内容,我应该这样做:
protected Collection<Object> findFacts( final StatefulKnowledgeSession session, final String factClass )
{
ObjectFilter filter = new ObjectFilter()
{
@Override
public boolean accept( Object object )
{
return object.getClass().equals( factClass );
}
};
Collection<Object> results = session.getObjects( filter );
return results;
}
鉴于我已经将代码设置为读取规则,我所做的下一步是:
protected void processFacts( KnowledgeBase aKnowledgeBase, Object aBean )
{
StatefulKnowledgeSession ksession = aKnowledgeBase.newStatefulKnowledgeSession();
ksession.insert( aBean );
ksession.fireAllRules();
Collection<Object> result = findFacts( ksession, "StudentBean" );
ksession.dispose();
for( Object test : result )
{
System.out.println( test == null );
System.out.println( test );
}
}
为什么我没有得到对象的任何回复?它不打印任何东西。没有堆栈跟踪,没有错误。我甚至检查它是否为null。但仍然没有回应。我做错了什么?
更新
这是读取.drl文件的方法。
protected KnowledgeBase readKnowledgeBase( String aRuleFileName ) throws Exception
{
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource( aRuleFileName, 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;
}
调用processFacts方法的是
public String evaluateConceptKnowledgeLevel( double FLTmark )
{
String knowledgeLevel = null;
// test
InferenceEngine ie = new InferenceEngine();
KnowledgeBase kbase;
try
{
kbase = ie.readKnowledgeBase( "KnowledgeLevel.drl" );
FLTBean bean = new FLTBean();
bean.setListeningScore( FLTmark );
ie.processFacts( kbase, bean );
}
catch( Exception e )
{
e.printStackTrace();
}
// up to here
return knowledgeLevel;
}
答案 0 :(得分:1)
一些选择......
传入简单名称而不是完整的班级名称。
更改
Collection<Object> result = findFacts( ksession, "com.neu.als.thesis.db.beans.StudentBean" );
到
Collection<Object> result = findFacts( ksession, "StudentBean" );
更改'accept'方法以比较完整的班级名称。
更改
public boolean accept( Object object ) {
return object.getClass().getSimpleName().equals( factClass );
}
到
public boolean accept( Object object ) {
return object.getClass().getName().equals( factClass );
}
更改findFacts方法,将实际的类作为参数并与之比较。
更改
protected Collection<Object> findFacts(
final StatefulKnowledgeSession session,
final String factClass ) {
ObjectFilter filter = new ObjectFilter() {
@Override
public boolean accept( Object object ) {
return object.getClass().getSimpleName().equals( factClass );
}
};
Collection<Object> results = session.getObjects( filter );
return results;
}
到
protected Collection<Object> findFacts(
final StatefulKnowledgeSession session,
final Class factClass ) {
ObjectFilter filter = new ObjectFilter() {
@Override
public boolean accept( Object object ) {
return object.getClass().equals( factClass );
}
};
Collection<Object> results = session.getObjects( filter );
return results;
}
假设您的事实都是Java类,那么比较该类的第3个选项是更好的选择。如果使用声明的类型,那么简单名称很有用,因为您不太可能引用Drools生成的实际类。
当您测试这些内容时,Drools API还提供了没有参数的session.getObjects()方法。通过调用,您将获得对工作记忆中所有事实的引用,无论它们是什么。在编写过滤器时,使用它来向自己证明预期的事实在工作记忆中,然后添加过滤,这样你就可以根据它们的类和属性选择特定的事实,这不是一个坏主意。