1 |
| package org.drools.reteoo; |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| |
18 |
| |
19 |
| |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| import java.io.Serializable; |
44 |
| import java.util.HashMap; |
45 |
| import java.util.Iterator; |
46 |
| import java.util.Map; |
47 |
| |
48 |
| import org.drools.rule.Rule; |
49 |
| import org.drools.spi.AgendaFilter; |
50 |
| import org.drools.spi.AsyncExceptionHandler; |
51 |
| import org.drools.spi.ConflictResolver; |
52 |
| import org.drools.spi.ConsequenceException; |
53 |
| import org.drools.spi.Duration; |
54 |
| import org.drools.spi.Tuple; |
55 |
| import org.drools.util.PriorityQueue; |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
| class Agenda |
75 |
| implements |
76 |
| Serializable |
77 |
| { |
78 |
| |
79 |
| |
80 |
| |
81 |
| |
82 |
| public static int NONE = 0; |
83 |
| public static int ASSERT = 1; |
84 |
| public static int MODIFY = 2; |
85 |
| public static int RETRACT = 3; |
86 |
| |
87 |
| |
88 |
| private final WorkingMemoryImpl workingMemory; |
89 |
| |
90 |
| |
91 |
| private final PriorityQueue activationQueue; |
92 |
| |
93 |
| |
94 |
| private final Map scheduledItems; |
95 |
| |
96 |
| private final Map itemsToRetract; |
97 |
| |
98 |
| private final Map scheduledItemsToRetract; |
99 |
| |
100 |
| |
101 |
| private AgendaItem item; |
102 |
| |
103 |
| private int mode = 0; |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
| |
110 |
| |
111 |
| |
112 |
| |
113 |
| |
114 |
| |
115 |
| |
116 |
| |
117 |
73
| public Agenda(WorkingMemoryImpl workingMemory,
|
118 |
| ConflictResolver conflictResolver) |
119 |
| { |
120 |
73
| this.workingMemory = workingMemory;
|
121 |
73
| this.activationQueue = new PriorityQueue( conflictResolver );
|
122 |
73
| this.scheduledItems = new HashMap( );
|
123 |
73
| this.itemsToRetract = new HashMap( );
|
124 |
73
| this.scheduledItemsToRetract = new HashMap( );
|
125 |
| } |
126 |
| |
127 |
| |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
| |
133 |
| |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| |
141 |
6156
| void addToAgenda(ReteTuple tuple,
|
142 |
| Rule rule) |
143 |
| { |
144 |
| |
145 |
| |
146 |
| |
147 |
| |
148 |
| |
149 |
6156
| if ( this.item != null && rule.getNoLoop( ) && rule.equals( this.item.getRule( ) ) )
|
150 |
| { |
151 |
1
| return;
|
152 |
| } |
153 |
| |
154 |
6155
| Duration dur = rule.getDuration( );
|
155 |
| |
156 |
6155
| if ( dur != null && dur.getDuration( tuple ) > 0 )
|
157 |
| { |
158 |
| |
159 |
0
| AgendaItem item = null;
|
160 |
0
| if ( !this.itemsToRetract.isEmpty( ) )
|
161 |
| { |
162 |
0
| item = (AgendaItem) this.scheduledItems.get( tuple.getKey( ) );
|
163 |
| } |
164 |
| |
165 |
0
| if ( item == null )
|
166 |
| { |
167 |
0
| item = new AgendaItem( tuple,
|
168 |
| rule ); |
169 |
0
| this.scheduledItems.put( item.getKey( ),
|
170 |
| item ); |
171 |
0
| scheduleItem( item );
|
172 |
0
| this.workingMemory.getEventSupport( ).fireActivationCreated( rule,
|
173 |
| tuple ); |
174 |
| } |
175 |
| } |
176 |
| else |
177 |
| { |
178 |
| |
179 |
6155
| AgendaItem item = null;
|
180 |
6155
| if ( !this.itemsToRetract.isEmpty( ) )
|
181 |
| { |
182 |
12
| item = (AgendaItem) this.itemsToRetract.remove( tuple.getKey( ) );
|
183 |
| } |
184 |
| |
185 |
6155
| if ( item == null )
|
186 |
| { |
187 |
6152
| item = new AgendaItem( tuple,
|
188 |
| rule ); |
189 |
6152
| this.activationQueue.add( item );
|
190 |
6152
| this.workingMemory.getEventSupport( ).fireActivationCreated( rule,
|
191 |
| tuple ); |
192 |
| } |
193 |
| else |
194 |
| { |
195 |
3
| this.activationQueue.add( item );
|
196 |
| } |
197 |
| } |
198 |
| } |
199 |
| |
200 |
| |
201 |
| |
202 |
| |
203 |
| |
204 |
| |
205 |
| |
206 |
| |
207 |
| |
208 |
931
| void removeFromAgenda(TupleKey key,
|
209 |
| Rule rule) |
210 |
| { |
211 |
931
| AgendaItem eachItem;
|
212 |
931
| Tuple tuple;
|
213 |
931
| Iterator itemIter = this.activationQueue.iterator( );
|
214 |
| |
215 |
931
| while ( itemIter.hasNext( ) )
|
216 |
| { |
217 |
22308
| eachItem = (AgendaItem) itemIter.next( );
|
218 |
| |
219 |
22308
| if ( eachItem.getRule( ) == rule && eachItem.getKey( ).containsAll( key ) )
|
220 |
| { |
221 |
5761
| itemIter.remove( );
|
222 |
| |
223 |
| |
224 |
5761
| itemIter = this.activationQueue.iterator( );
|
225 |
| |
226 |
5761
| if ( (this.mode == Agenda.MODIFY) && !this.workingMemory.getEventSupport( ).isEmpty( ) )
|
227 |
| { |
228 |
83
| this.itemsToRetract.put( eachItem.getKey( ),
|
229 |
| eachItem ); |
230 |
| } |
231 |
| else |
232 |
| { |
233 |
5678
| this.workingMemory.getEventSupport( ).fireActivationCancelled( rule,
|
234 |
| eachItem.getTuple( ) ); |
235 |
| } |
236 |
| } |
237 |
| } |
238 |
| |
239 |
931
| itemIter = this.scheduledItems.values( ).iterator( );
|
240 |
| |
241 |
931
| while ( itemIter.hasNext( ) )
|
242 |
| { |
243 |
0
| eachItem = (AgendaItem) itemIter.next( );
|
244 |
| |
245 |
0
| if ( eachItem.getRule( ) == rule && eachItem.getKey( ).containsAll( key ) )
|
246 |
| { |
247 |
0
| if ( (this.mode == Agenda.MODIFY) && !this.workingMemory.getEventSupport( ).isEmpty( ) )
|
248 |
| { |
249 |
0
| this.scheduledItemsToRetract.put( eachItem.getKey( ),
|
250 |
| eachItem ); |
251 |
| } |
252 |
| else |
253 |
| { |
254 |
0
| tuple = eachItem.getTuple( );
|
255 |
| |
256 |
0
| cancelItem( eachItem );
|
257 |
| |
258 |
0
| itemIter.remove( );
|
259 |
| |
260 |
0
| this.workingMemory.getEventSupport( ).fireActivationCancelled( rule,
|
261 |
| tuple ); |
262 |
| } |
263 |
| } |
264 |
| } |
265 |
| } |
266 |
| |
267 |
316
| void removeMarkedItemsFromAgenda()
|
268 |
| { |
269 |
316
| AgendaItem eachItem;
|
270 |
| |
271 |
316
| Iterator itemIter = this.itemsToRetract.values( ).iterator( );
|
272 |
316
| while ( itemIter.hasNext( ) )
|
273 |
| { |
274 |
80
| eachItem = (AgendaItem) itemIter.next( );
|
275 |
80
| this.workingMemory.getEventSupport( ).fireActivationCancelled( eachItem.getRule( ),
|
276 |
| eachItem.getTuple( ) ); |
277 |
80
| itemIter.remove( );
|
278 |
| } |
279 |
| |
280 |
316
| itemIter = this.scheduledItemsToRetract.values( ).iterator( );
|
281 |
316
| while ( itemIter.hasNext( ) )
|
282 |
| { |
283 |
0
| eachItem = (AgendaItem) itemIter.next( );
|
284 |
| |
285 |
0
| cancelItem( eachItem );
|
286 |
| |
287 |
0
| this.workingMemory.getEventSupport( ).fireActivationCancelled( eachItem.getRule( ),
|
288 |
| eachItem.getTuple( ) ); |
289 |
0
| itemIter.remove( );
|
290 |
| } |
291 |
| } |
292 |
| |
293 |
| |
294 |
| |
295 |
| |
296 |
| |
297 |
5
| void clearAgenda()
|
298 |
| { |
299 |
5
| AgendaItem eachItem;
|
300 |
| |
301 |
| |
302 |
5
| Iterator iter = this.activationQueue.iterator( );
|
303 |
5
| while ( iter.hasNext( ) )
|
304 |
| { |
305 |
7
| eachItem = (AgendaItem) iter.next( );
|
306 |
| |
307 |
7
| iter.remove( );
|
308 |
| |
309 |
7
| this.workingMemory.getEventSupport( ).fireActivationCancelled( eachItem.getRule( ),
|
310 |
| eachItem.getTuple( ) ); |
311 |
| } |
312 |
| |
313 |
5
| iter = this.scheduledItems.values( ).iterator( );
|
314 |
| |
315 |
| |
316 |
5
| while ( iter.hasNext( ) )
|
317 |
| { |
318 |
0
| eachItem = (AgendaItem) iter.next( );
|
319 |
| |
320 |
0
| cancelItem( eachItem );
|
321 |
| |
322 |
0
| iter.remove( );
|
323 |
| |
324 |
0
| this.workingMemory.getEventSupport( ).fireActivationCancelled( eachItem.getRule( ),
|
325 |
| eachItem.getTuple( ) ); |
326 |
| } |
327 |
| } |
328 |
| |
329 |
| |
330 |
| |
331 |
| |
332 |
| |
333 |
| |
334 |
| |
335 |
0
| void scheduleItem(AgendaItem item)
|
336 |
| { |
337 |
0
| Scheduler.getInstance( ).scheduleAgendaItem( item,
|
338 |
| this.workingMemory ); |
339 |
| } |
340 |
| |
341 |
| |
342 |
| |
343 |
| |
344 |
| |
345 |
| |
346 |
| |
347 |
0
| void cancelItem(AgendaItem item)
|
348 |
| { |
349 |
0
| Scheduler.getInstance( ).cancelAgendaItem( item );
|
350 |
| } |
351 |
| |
352 |
| |
353 |
| |
354 |
| |
355 |
| |
356 |
| |
357 |
| |
358 |
778
| public boolean isEmpty()
|
359 |
| { |
360 |
778
| return this.activationQueue.isEmpty( );
|
361 |
| } |
362 |
| |
363 |
18
| public int size()
|
364 |
| { |
365 |
18
| return activationQueue.size( );
|
366 |
| } |
367 |
| |
368 |
| |
369 |
| |
370 |
| |
371 |
| |
372 |
| |
373 |
| |
374 |
384
| public void fireNextItem(AgendaFilter filter) throws ConsequenceException
|
375 |
| { |
376 |
384
| if ( isEmpty( ) )
|
377 |
| { |
378 |
0
| return;
|
379 |
| } |
380 |
| |
381 |
384
| item = (AgendaItem) this.activationQueue.remove( );
|
382 |
| |
383 |
384
| try
|
384 |
| { |
385 |
384
| if ( filter == null || filter.accept( item ) )
|
386 |
| { |
387 |
383
| item.fire( this.workingMemory );
|
388 |
| } |
389 |
| } |
390 |
| finally |
391 |
| { |
392 |
384
| item = null;
|
393 |
| } |
394 |
| } |
395 |
| |
396 |
| |
397 |
| |
398 |
| |
399 |
| |
400 |
| |
401 |
| |
402 |
1
| void setAsyncExceptionHandler(AsyncExceptionHandler handler)
|
403 |
| { |
404 |
1
| Scheduler.getInstance( ).setAsyncExceptionHandler( handler );
|
405 |
| } |
406 |
| |
407 |
2484
| void setMode(int mode)
|
408 |
| { |
409 |
2484
| this.mode = mode;
|
410 |
| } |
411 |
| } |