View Javadoc

1   /*
2    * $Id: Drools.java 20895 2011-01-05 13:16:57Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.drools;
12  
13  import org.mule.api.config.ConfigurationException;
14  import org.mule.config.i18n.CoreMessages;
15  import org.mule.config.i18n.MessageFactory;
16  import org.mule.module.bpm.MessageService;
17  import org.mule.module.bpm.Rules;
18  import org.mule.module.bpm.RulesEngine;
19  import org.mule.util.IOUtils;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.Collection;
24  
25  import org.drools.KnowledgeBase;
26  import org.drools.KnowledgeBaseConfiguration;
27  import org.drools.KnowledgeBaseFactory;
28  import org.drools.builder.KnowledgeBuilder;
29  import org.drools.builder.KnowledgeBuilderFactory;
30  import org.drools.builder.ResourceType;
31  import org.drools.conf.EventProcessingOption;
32  import org.drools.conf.KnowledgeBaseOption;
33  import org.drools.io.ResourceFactory;
34  import org.drools.logger.KnowledgeRuntimeLogger;
35  import org.drools.runtime.StatefulKnowledgeSession;
36  import org.drools.runtime.rule.FactHandle;
37  import org.drools.runtime.rule.WorkingMemoryEntryPoint;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  public class Drools implements RulesEngine
42  {
43      /** An optional logical name for the Rules Engine. */
44      private String name;
45  
46      /** A callback to generate Mule messages from Drools */
47      private MessageService messageService;
48  
49      protected static final Logger logger = LoggerFactory.getLogger(Drools.class);
50  
51      /**
52       * @return DroolsSessionData - contains the KnowledgeSession plus any other stateful information
53       */
54      public Object createSession(Rules rules) throws Exception
55      {
56          KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(null, Thread.currentThread().getContextClassLoader()));
57          
58          String rulesFile = rules.getResource();
59          InputStream is = IOUtils.getResourceAsStream(rulesFile, getClass());
60          if (is == null)
61          {
62              throw new IOException(CoreMessages.cannotLoadFromClasspath(rulesFile).getMessage());
63          }
64          kbuilder.add(ResourceFactory.newInputStreamResource(is), ResourceType.DRL);
65          if (kbuilder.hasErrors())
66          {
67              throw new ConfigurationException(MessageFactory.createStaticMessage("Errors while parsing ruleset defined in file " + rulesFile + " : " + kbuilder.getErrors().toString()));
68          }        
69  
70          KnowledgeBaseConfiguration conf = 
71              KnowledgeBaseFactory.newKnowledgeBaseConfiguration(null, Thread.currentThread().getContextClassLoader());
72          if (rules.getConfiguration() != null)
73          {
74              conf.setOption((KnowledgeBaseOption) rules.getConfiguration());
75          }
76          else if (rules.isCepMode())
77          {
78              conf.setOption(EventProcessingOption.STREAM);
79          }
80          KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(conf);
81          kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());            
82          
83          if (rules.isStateless())
84          {
85              // TODO Add support for stateless sessions, for now we assume all sessions are stateful.
86              throw new ConfigurationException(MessageFactory.createStaticMessage("Stateless sessions are not yet supported"));
87          }
88          StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();
89          KnowledgeRuntimeLogger droolsLogger = new WorkingMemorySLF4JLogger(session, logger);
90          
91          if (messageService == null)
92          {
93              throw new ConfigurationException(MessageFactory.createStaticMessage("MessageService is not available"));
94          }
95          session.setGlobal("mule", messageService);
96          
97          session.fireAllRules();
98          
99          return new DroolsSessionData(session, droolsLogger);
100     }
101     
102     public void disposeSession(Object sessionData) throws Exception
103     {
104         ((DroolsSessionData) sessionData).getSession().dispose();
105         ((DroolsSessionData) sessionData).getLogger().close();
106     }
107     
108     public Object assertFact(Rules rules, Object fact) throws Exception
109     {
110         StatefulKnowledgeSession session = ((DroolsSessionData) rules.getSessionData()).getSession();
111         FactHandle handle = session.getFactHandle(fact);
112         if (handle != null)
113         {
114             session.update(handle, fact);
115             session.fireAllRules();
116         }
117         else
118         {
119             handle = session.insert(fact);
120             session.fireAllRules();
121         }
122         return handle;
123     }
124     
125     public void retractFact(Rules rules, Object fact) throws Exception
126     {
127         StatefulKnowledgeSession session = ((DroolsSessionData) rules.getSessionData()).getSession();
128         FactHandle handle = session.getFactHandle(fact);
129         if (handle != null)
130         {
131             session.retract(handle);
132             session.fireAllRules();
133         }
134         else
135         {
136             logger.warn("Unable to retract fact " + fact + " because it is not in the knowledge base");
137         }
138     }
139     
140     public Object assertEvent(Rules rules, Object event, String entryPoint) throws Exception
141     {
142         StatefulKnowledgeSession session = ((DroolsSessionData) rules.getSessionData()).getSession();
143         WorkingMemoryEntryPoint wmEntryPoint;
144         if (entryPoint != null)
145         {
146             wmEntryPoint = session.getWorkingMemoryEntryPoint(entryPoint);
147         }
148         else
149         {
150             Collection entryPoints = session.getWorkingMemoryEntryPoints();
151             if (entryPoints.size() > 1)
152             {
153                 throw new ConfigurationException(MessageFactory.createStaticMessage("Rules contain more than one entry point but none has been specified"));
154             }
155             wmEntryPoint = (WorkingMemoryEntryPoint) entryPoints.iterator().next();
156         }
157         
158         FactHandle handle = session.getFactHandle(event);
159         if (handle != null)
160         {
161             wmEntryPoint.update(handle, event);
162         }
163         else
164         {
165             handle = wmEntryPoint.insert(event);
166         }
167         session.fireAllRules();
168         return handle;
169     }
170     
171     public void setMessageService(MessageService messageService)
172     {
173         this.messageService = messageService;
174     }
175 
176     public void setName(String name)
177     {
178         this.name = name;
179     }
180 
181     public String getName()
182     {
183         return name;
184     }
185 }
186 
187