1 package org.drools.reteoo.impl;
2
3 /*
4 $Id: AgendaImpl.java,v 1.4 2002/08/22 07:42:39 bob Exp $
5
6 Copyright 2002 (C) The Werken Company. All Rights Reserved.
7
8 Redistribution and use of this software and associated documentation
9 ("Software"), with or without modification, are permitted provided
10 that the following conditions are met:
11
12 1. Redistributions of source code must retain copyright
13 statements and notices. Redistributions must also contain a
14 copy of this document.
15
16 2. Redistributions in binary form must reproduce the
17 above copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
20
21 3. The name "drools" must not be used to endorse or promote
22 products derived from this Software without prior written
23 permission of The Werken Company. For written permission,
24 please contact bob@werken.com.
25
26 4. Products derived from this Software may not be called "drools"
27 nor may "drools" appear in their names without prior written
28 permission of The Werken Company. "drools" is a registered
29 trademark of The Werken Company.
30
31 5. Due credit should be given to The Werken Company.
32 (http://drools.werken.com/).
33
34 THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
35 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
36 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
37 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
38 THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
39 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
45 OF THE POSSIBILITY OF SUCH DAMAGE.
46
47 */
48
49 import org.drools.WorkingMemory;
50
51 import org.drools.reteoo.Agenda;
52 import org.drools.rule.Rule;
53 import org.drools.spi.ConsequenceException;
54
55 import java.util.Set;
56 import java.util.HashSet;
57 import java.util.Iterator;
58
59 /*** Rule-firing Agenda.
60 *
61 * <p>
62 * Since many rules may be matched by a single assertObject(...)
63 * all scheduled actions are placed into the <code>Agenda</code>.
64 * </p>
65 *
66 * <p>
67 * While processing a scheduled action, it may modify or retract
68 * objects in other scheduled actions, which must then be removed
69 * from the agenda. Non-invalidated actions are left on the agenda,
70 * and are executed in turn.
71 * </p>
72 *
73 * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
74 */
75 public class AgendaImpl implements Agenda
76 {
77 // ------------------------------------------------------------
78 // Instance members
79 // ------------------------------------------------------------
80
81 /*** Working memory of this Agenda. */
82 private WorkingMemory workingMemory;
83
84 /*** Items in the agenda. */
85 private PriorityQueue items;
86
87 /*** Items time-delayed. */
88 private Set scheduledItems;
89
90 // ------------------------------------------------------------
91 // Constructors
92 // ------------------------------------------------------------
93
94 /*** Construct.
95 *
96 * @param workingMemory The <code>WorkingMemory</code> of this agenda.
97 */
98 public AgendaImpl(WorkingMemory workingMemory)
99 {
100 this.workingMemory = workingMemory;
101
102 this.items = new PriorityQueue();
103 this.scheduledItems = new HashSet();
104 }
105
106 // ------------------------------------------------------------
107 // Instance methods
108 // ------------------------------------------------------------
109
110 /*** Schedule a rule action invokation on this <code>Agenda</code>.
111 *
112 * @param tuple The matching <code>Tuple</code>.
113 * @param rule The rule to fire.
114 * @param priority The rule-firing priority.
115 */
116 void addToAgenda(ReteTuple tuple,
117 Rule rule,
118 int priority)
119 {
120 if ( rule == null )
121 {
122 return;
123 }
124
125 AgendaItem item = new AgendaItem( tuple,
126 rule );
127 if ( rule.getDuration( tuple ) > 0 )
128 {
129 this.scheduledItems.add( item );
130 scheduleItem( item );
131 }
132 else
133 {
134 this.items.add( item,
135 priority );
136 }
137 }
138
139 /*** Remove a tuple from the agenda.
140 *
141 * @param key The key to the tuple to be removed.
142 * @param rule The rule to remove.
143 */
144 void removeFromAgenda(TupleKey key,
145 Rule rule)
146 {
147 if ( rule == null )
148 {
149 return;
150 }
151
152 Iterator itemIter = this.items.iterator();
153 AgendaItem eachItem = null;
154
155 while ( itemIter.hasNext() )
156 {
157 eachItem = (AgendaItem) itemIter.next();
158
159 if ( eachItem.getRule() == rule )
160 {
161 if ( eachItem.getTuple().getKey().containsAll( key ) )
162 {
163 itemIter.remove();
164 }
165 }
166 }
167
168 itemIter = this.scheduledItems.iterator();
169 eachItem = null;
170
171 while ( itemIter.hasNext() )
172 {
173 eachItem = (AgendaItem) itemIter.next();
174
175 if ( eachItem.getRule() == rule )
176 {
177 if ( eachItem.getTuple().getKey().containsAll( key ) )
178 {
179 cancelItem( eachItem );
180 itemIter.remove();
181 }
182 }
183 }
184 }
185
186 /*** Modify the agenda.
187 *
188 * @param trigger The triggering root object.
189 * @param newTuples New tuples from the modification.
190 * @param rule The rule.
191 * @param priority Firing priority.
192 */
193 void modifyAgenda(Object trigger,
194 TupleSet newTuples,
195 Rule rule,
196 int priority)
197 {
198 Iterator itemIter = this.items.iterator();
199 AgendaItem eachItem = null;
200 ReteTuple eachTuple = null;
201
202 while ( itemIter.hasNext() )
203 {
204 eachItem = (AgendaItem) itemIter.next();
205
206 if ( eachItem.getRule() == rule )
207 {
208 eachTuple = eachItem.getTuple();
209
210 if ( eachTuple.dependsOn( trigger ) )
211 {
212 if ( ! newTuples.containsTuple( eachTuple.getKey() ) )
213 {
214 itemIter.remove();
215 }
216 else
217 {
218 eachItem.setTuple( newTuples.getTuple( eachTuple.getKey() ) );
219 newTuples.removeTuple( eachTuple.getKey() );
220 }
221 }
222 }
223 }
224
225 itemIter = this.scheduledItems.iterator();
226 eachItem = null;
227
228 while ( itemIter.hasNext() )
229 {
230 eachItem = (AgendaItem) itemIter.next();
231
232 if ( eachItem.getRule() == rule )
233 {
234 eachTuple = eachItem.getTuple();
235
236 if ( eachTuple.dependsOn( trigger ) )
237 {
238 if ( ! newTuples.containsTuple( eachTuple.getKey() ) )
239 {
240 cancelItem( eachItem );
241 itemIter.remove();
242 }
243
244 else
245 {
246 eachItem.setTuple( newTuples.getTuple( eachTuple.getKey() ) );
247 newTuples.removeTuple( eachTuple.getKey() );
248 }
249 }
250 }
251 }
252
253 Iterator tupleIter = newTuples.iterator();
254
255 while ( tupleIter.hasNext() )
256 {
257 eachTuple = (ReteTuple) tupleIter.next();
258
259 addToAgenda( eachTuple,
260 rule,
261 priority );
262 }
263 }
264
265 /*** Schedule an agenda item for delayed firing.
266 *
267 * @param item The item to schedule.
268 */
269 void scheduleItem(AgendaItem item)
270 {
271 Scheduler.getInstance().scheduleAgendaItem( item,
272 this.workingMemory );
273 }
274
275 /*** Cancel a scheduled agenda item for delayed firing.
276 *
277 * @param item The item to cancel.
278 */
279 void cancelItem(AgendaItem item)
280 {
281 Scheduler.getInstance().cancelAgendaItem( item );
282 }
283
284 /*** Determine if this <code>Agenda</code> has any
285 * scheduled items.
286 *
287 * @return <code>true<code> if the agenda is empty, otherwise
288 * <code>false</code>.
289 */
290 public boolean isEmpty()
291 {
292 return this.items.isEmpty();
293 }
294
295 /*** Fire the next scheduled <code>Agenda</code> item.
296 *
297 * @throws ConsequenceException If an error occurs while
298 * firing an agenda item.
299 */
300 public void fireNextItem() throws ConsequenceException
301 {
302 if ( isEmpty() )
303 {
304 return;
305 }
306
307 AgendaItem item = (AgendaItem) this.items.removeFirst();
308
309 item.fire( this.workingMemory );
310 }
311 }
This page was automatically generated by Maven