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    }