001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.drools;
018
019 import java.util.Map;
020
021 import javax.jbi.messaging.MessageExchange;
022
023 import org.apache.servicemix.drools.model.JbiHelper;
024 import org.drools.StatefulSession;
025 import org.drools.WorkingMemory;
026 import org.drools.event.ActivationCreatedEvent;
027 import org.drools.event.DefaultAgendaEventListener;
028
029 /**
030 * Represents the execution context of the Drools rules for a single {@link MessageExchange}
031 */
032 public class DroolsExecutionContext extends DefaultAgendaEventListener {
033
034 private final StatefulSession memory;
035 private final JbiHelper helper;
036 private int rulesFired;
037 private MessageExchange exchange;
038
039 public static final String JBI_HELPER_KEY = "jbi";
040
041 /**
042 * Start a new execution context for the specified exchange.
043 *
044 * This will create and fill {@link WorkingMemory} and register listeners on it to keep track of things.
045 *
046 * @param endpoint
047 * @param exchange
048 */
049 public DroolsExecutionContext(DroolsEndpoint endpoint, MessageExchange exchange) {
050 super();
051 this.memory = endpoint.getRuleBase().newStatefulSession();
052 this.memory.addEventListener(this);
053 this.exchange = exchange;
054 this.helper = new JbiHelper(endpoint, exchange, memory);
055 populateWorkingMemory(endpoint);
056 }
057
058 private void populateWorkingMemory(DroolsEndpoint endpoint) {
059 memory.setGlobal(JBI_HELPER_KEY, helper);
060 if (endpoint.getAssertedObjects() != null) {
061 for (Object o : endpoint.getAssertedObjects()) {
062 memory.insert(o);
063 }
064 }
065 if (endpoint.getGlobals() != null) {
066 for (Map.Entry<String, Object> e : endpoint.getGlobals().entrySet()) {
067 memory.setGlobal(e.getKey(), e.getValue());
068 }
069 }
070 }
071
072 /**
073 * Start the execution context.
074 * This will fire all rules in the rule base.
075 */
076 public void start() {
077 memory.fireAllRules();
078 }
079
080 /**
081 * Update the working memory, potentially triggering additional rules
082 */
083 public void update() {
084 helper.update();
085 }
086
087 /**
088 * Stop the context, disposing of all event listeners and working memory contents
089 */
090 public void stop() {
091 memory.removeEventListener(this);
092 memory.dispose();
093 }
094
095 /**
096 * Get the number of rules that were fired
097 */
098 public int getRulesFired() {
099 return rulesFired;
100 }
101
102 /**
103 * Returns <code>true</code> if the {@link MessageExchange} was handled by the rules themselves
104 * (e.g. by answering or faulting the exchange}
105 */
106 public boolean isExchangeHandled() {
107 return helper.isExchangeHandled();
108 }
109
110 /**
111 * Return the {@link MessageExchange} we are evaluating rules on
112 */
113 public MessageExchange getExchange() {
114 return exchange;
115 }
116
117 // event handler callbacks
118 @Override
119 public void activationCreated(ActivationCreatedEvent event, WorkingMemory workingMemory) {
120 rulesFired++;
121 }
122
123 /**
124 * Access the JbiHelper object that is being exposed to the .drl file
125 */
126 public JbiHelper getHelper() {
127 return helper;
128 }
129 }