EMMA Coverage Report (generated Thu Jan 20 11:39:44 EST 2011)
[all classes][com.hammurapi.eventbus]

COVERAGE SUMMARY FOR SOURCE FILE [PredicatedInferenceNode.java]

nameclass, %method, %block, %line, %
PredicatedInferenceNode.java67%  (4/6)69%  (25/36)70%  (1265/1819)70%  (205.2/293)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PredicatedInferenceNode$10%   (0/1)0%   (0/2)0%   (0/30)0%   (0/8)
PredicatedInferenceNode$1 (PredicatedInferenceNode): void 0%   (0/1)0%   (0/6)0%   (0/2)
compare (Predicate, Predicate): int 0%   (0/1)0%   (0/24)0%   (0/6)
     
class PredicatedInferenceNode$20%   (0/1)0%   (0/2)0%   (0/30)0%   (0/8)
PredicatedInferenceNode$2 (PredicatedInferenceNode): void 0%   (0/1)0%   (0/6)0%   (0/2)
compare (Predicate, Predicate): int 0%   (0/1)0%   (0/24)0%   (0/6)
     
class PredicatedInferenceNode$CONTEXT_DEPENDENCY100% (1/1)50%  (2/4)70%  (49/70)83%  (5/6)
valueOf (String): PredicatedInferenceNode$CONTEXT_DEPENDENCY 0%   (0/1)0%   (0/5)0%   (0/1)
values (): PredicatedInferenceNode$CONTEXT_DEPENDENCY [] 0%   (0/1)0%   (0/16)0%   (0/1)
<static initializer> 100% (1/1)100% (44/44)100% (5/5)
PredicatedInferenceNode$CONTEXT_DEPENDENCY (String, int): void 100% (1/1)100% (5/5)100% (1/1)
     
class PredicatedInferenceNode100% (1/1)83%  (19/23)71%  (1139/1607)72%  (190.9/266)
getAllHandlers (): Collection 0%   (0/1)0%   (0/50)0%   (0/8)
getId (): Object 0%   (0/1)0%   (0/3)0%   (0/1)
isRoot (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
rebuild (): void 0%   (0/1)0%   (0/20)0%   (0/3)
addHandler (EventHandlerWrapper, LinkedList): boolean 100% (1/1)63%  (269/427)67%  (47.7/71)
migrate (LinkedList): boolean 100% (1/1)66%  (62/94)75%  (12/16)
compare (EventHandlerWrapper): PredicatedInferenceNode$CR 100% (1/1)66%  (240/363)68%  (43.5/64)
collectHandlers (Map, ExecutorService, AtomicReference, Object): void 100% (1/1)71%  (20/28)71%  (5/7)
remove (List, List, boolean, Iterable): boolean 100% (1/1)74%  (89/121)70%  (16.8/24)
$SWITCH_TABLE$com$hammurapi$extract$ComparisonResult$Type (): int [] 100% (1/1)88%  (85/97)87%  (0.9/1)
takeSnapshot (AbstractEventBus$Snapshot, Set): void 100% (1/1)88%  (107/122)87%  (16.4/19)
reset (): void 100% (1/1)89%  (51/57)84%  (7.6/9)
$SWITCH_TABLE$com$hammurapi$eventbus$PredicatedInferenceNode$Target (): int [] 100% (1/1)90%  (37/41)90%  (0.9/1)
migrateChildren (LinkedList): void 100% (1/1)95%  (35/37)91%  (10/11)
<static initializer> 100% (1/1)100% (5/5)100% (2/2)
PredicatedInferenceNode (PredicatedInferenceNode, PredicateChainingMatcher, P... 100% (1/1)100% (35/35)100% (10/10)
collectHandlers (Map, Collection, Object): void 100% (1/1)100% (68/68)100% (10/10)
getContext (): Object 100% (1/1)100% (3/3)100% (1/1)
getMatcher (): PredicateChainingMatcher 100% (1/1)100% (3/3)100% (1/1)
getNodePath (): LinkedList 100% (1/1)100% (3/3)100% (1/1)
getPredicate (): Predicate 100% (1/1)100% (3/3)100% (1/1)
isEmpty (): boolean 100% (1/1)100% (20/20)100% (4/4)
setRoot (boolean): void 100% (1/1)100% (4/4)100% (2/2)
     
class PredicatedInferenceNode$Target100% (1/1)75%  (3/4)93%  (65/70)96%  (5.8/6)
valueOf (String): PredicatedInferenceNode$Target 0%   (0/1)0%   (0/5)0%   (0/1)
<static initializer> 100% (1/1)100% (44/44)100% (5/5)
PredicatedInferenceNode$Target (String, int): void 100% (1/1)100% (5/5)100% (1/1)
values (): PredicatedInferenceNode$Target [] 100% (1/1)100% (16/16)100% (1/1)
     
class PredicatedInferenceNode$CR100% (1/1)100% (1/1)100% (12/12)100% (4/4)
PredicatedInferenceNode$CR (PredicatedInferenceNode, Predicate, PredicatedInf... 100% (1/1)100% (12/12)100% (4/4)

1package com.hammurapi.eventbus;
2 
3import java.lang.reflect.Array;
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.Iterator;
9import java.util.LinkedList;
10import java.util.List;
11import java.util.Map;
12import java.util.Set;
13import java.util.concurrent.Callable;
14import java.util.concurrent.ExecutorService;
15import java.util.concurrent.Future;
16import java.util.concurrent.atomic.AtomicReference;
17import java.util.logging.Logger;
18 
19import com.hammurapi.extract.And;
20import com.hammurapi.extract.CommutativeAnd;
21import com.hammurapi.extract.ComparisonResult;
22import com.hammurapi.extract.Extractor;
23import com.hammurapi.extract.False;
24import com.hammurapi.extract.Predicate;
25import com.hammurapi.extract.True;
26 
27/**
28 * 
29 * @author Pavel Vlasov.
30 *
31 * @param <E>
32 * @param <P>
33 * @param <C>
34 */
35public abstract class PredicatedInferenceNode<E, P extends Comparable<P>, C, K, H extends EventBus.Handle<E,P,C>, S extends EventStore<E,P,C,H,S>> implements InferenceNode<E, P, C, K, H, S> {
36        private static final Logger logger = Logger.getLogger(PredicatedInferenceNode.class.getName());
37        
38        protected abstract List<PredicatedInferenceNode<E, P, C, K, H, S>> getFalseChildren();
39 
40        protected abstract List<PredicatedInferenceNode<E, P, C, K, H, S>> getTrueChildren();
41 
42        protected abstract List<EventHandlerWrapper<E, P, C, K, H, S>> getFalseHandlers();
43 
44        protected abstract List<EventHandlerWrapper<E, P, C, K, H, S>> getTrueHandlers();
45        
46        protected PredicateChainingMatcher<E, P, C, K, H, S> getMatcher() {
47                return matcher;
48        }
49        
50        protected abstract Callable<Collection<EventHandlerWrapper<E, P, C, K, H, S>>> createCollectorTask(
51                        Map<C, Map<Extractor<E, ? super Boolean, C>, ? super Boolean>> cache,
52                        ExecutorService executor,
53                        AtomicReference<Collection<Future<Collection<EventHandlerWrapper<E, P, C, K, H, S>>>>> collector,
54                        E event);
55        
56        private Predicate<E, C> predicate;        
57        
58        private C context;
59 
60        private K id;
61 
62        private boolean isRoot;
63 
64        private LinkedList<PredicatedInferenceNode<E, P, C, K, H, S>> nodePath;
65 
66        protected PredicateChainingMatcher<E, P, C, K, H, S> matcher;
67        
68        public void setRoot(boolean isRoot) {
69                this.isRoot = isRoot;
70        }
71        
72        public boolean isRoot() {
73                return isRoot;
74        }
75 
76        public PredicatedInferenceNode(
77                        PredicatedInferenceNode<E,P,C,K,H,S> parent, 
78                        PredicateChainingMatcher<E,P,C,K,H,S> matcher,
79                        Predicate<E, C> predicate, 
80                        C context, 
81                        K id) {
82                this.predicate = predicate;
83                this.context = context;
84                this.id = id;
85                if (parent==null) {
86                        this.nodePath = new LinkedList<PredicatedInferenceNode<E,P,C,K,H,S>>();
87                } else {
88                        this.nodePath = new LinkedList<PredicatedInferenceNode<E,P,C,K,H,S>>(parent.getNodePath());
89                }
90                this.nodePath.add(this);
91                this.matcher = matcher;
92        }
93        
94        LinkedList<PredicatedInferenceNode<E, P, C, K, H, S>> getNodePath() {
95                return nodePath;
96        }
97        
98        public K getId() {
99                return id;
100        }
101        
102        public Predicate<E,C> getPredicate() {
103                return predicate;
104        }
105        
106        public C getContext() {
107                return context;
108        }
109        
110        /**
111         * Returns true if the handler was incorporated into the node.
112         * @param handler
113         * @param nodePath If not null, only nodes from the path are considered.
114         * @return
115         */
116        boolean addHandler(EventHandlerWrapper<E, P, C, K, H, S> handler, LinkedList<PredicatedInferenceNode<E,P,C,K,H,S>> nodePath) {
117                if (nodePath!=null) {
118                        if (nodePath.getFirst()!=this) {                                
119                                return false;
120                        }
121                        
122                        if (nodePath.size()==1) {
123                                nodePath = null;
124                        } else {
125                                nodePath = new LinkedList<PredicatedInferenceNode<E,P,C,K,H,S>>(nodePath);
126                                nodePath.removeFirst();
127                        }
128                }
129                
130                if (handler.getCardinality()!=1) {
131                        throw new IllegalArgumentException("Only handlers with cardinality 1 can be added to predicated inference node: "+handler);
132                }
133                                
134                if (handler.getPredicate()!=null && !(handler.getPredicate() instanceof True) && !(handler.getPredicate() instanceof False) && !Collections.singleton(0).equals(handler.getPredicate().parameterIndices())) {
135                        throw new IllegalArgumentException("Only predicates with parameter indices [0] can be added to predicated inference node: "+predicate);
136                }
137                
138                // Less expensive predicates cannot be chained after more expensive.
139                if (!isRoot && this.predicate.getCost()>handler.getPredicate().getCost()) {
140                        return false;
141                }
142                
143                CR cr = compare(handler);
144                
145                if (cr==null) {
146                        return false; // Predicates are incompatible.
147                }
148                
149                EventHandlerWrapperFilter<E,P,C,K,H,S> subHandler = new EventHandlerWrapperFilter<E,P,C,K,H,S>(handler, cr.subPredicate);
150                switch (cr.target) {
151                case THIS_TRUE:
152                        getTrueHandlers().add(handler);
153                        return true;
154                case THIS_FALSE:
155                        getFalseHandlers().add(handler);
156                        return true;
157                case SUB_TRUE:
158                        for (PredicatedInferenceNode<E, P, C, K, H, S> trueChild: getTrueChildren()) {
159                                if (trueChild.addHandler(subHandler, nodePath)) {
160                                        return true;
161                                }
162                        }
163                        
164                        if (nodePath!=null) {
165                                return false;
166                        }
167                        
168                        if (cr.subPredicate instanceof And && ((And<E,C>) cr.subPredicate).getParts().size()>1) {
169                                PredicatedInferenceNode<E, P, C, K, H, S> newTrueChild = getMatcher().createPredicatedInferenceNode(this, ((And<E,C>) cr.subPredicate).getParts().get(0), handler.getContext());
170                                getTrueChildren().add(newTrueChild);
171                                if (!newTrueChild.addHandler(subHandler, nodePath)) {
172                                        throw new IllegalStateException("Should never happen!!!");
173                                }
174                                migrateChildren(newTrueChild.getNodePath());
175                        } else if (cr.subPredicate instanceof CommutativeAnd && ((CommutativeAnd<E,C>) cr.subPredicate).getParts().size()>1) {
176                                List<Predicate<E,C>> parts = new ArrayList<Predicate<E,C>>(((CommutativeAnd<E,C>) cr.subPredicate).getParts());
177                                Collections.sort(parts, new Comparator<Predicate<E,C>>() {
178 
179                                        @Override
180                                        public int compare(Predicate<E, C> o1, Predicate<E, C> o2) {
181                                                double delta =  o1.getCost() - o2.getCost();
182                                                if (delta < -Double.MIN_VALUE) {
183                                                        return -1;
184                                                } 
185                                                
186                                                if (delta > Double.MIN_VALUE) {
187                                                        return 1;
188                                                }
189                                                return o1.hashCode() - o2.hashCode();
190                                        }
191                                        
192                                });
193                                
194                                PredicatedInferenceNode<E, P, C, K, H, S> newTrueChild = getMatcher().createPredicatedInferenceNode(this, parts.get(0), handler.getContext());
195                                getTrueChildren().add(newTrueChild);
196                                if (!newTrueChild.addHandler(subHandler, nodePath)) {
197                                        throw new IllegalStateException("Should never happen!!!");
198                                }
199                                migrateChildren(newTrueChild.getNodePath());                                
200                        } else {
201                                PredicatedInferenceNode<E, P, C, K, H, S> newTrueChild = getMatcher().createPredicatedInferenceNode(this, cr.subPredicate, handler.getContext());
202                                newTrueChild.getTrueHandlers().add(subHandler);
203                                getTrueChildren().add(newTrueChild);
204                                
205                                // Try to migrate existing nodes under the new one.
206                                migrateChildren(newTrueChild.getNodePath());
207                        }
208                        
209                        return true;
210                case SUB_FALSE:
211                        for (PredicatedInferenceNode<E, P, C, K, H, S> falseChild: getFalseChildren()) {
212                                if (falseChild.addHandler(subHandler, nodePath)) {
213                                        return true;
214                                }
215                        }
216                        
217                        if (nodePath!=null) {
218                                return false;
219                        }
220                        
221                        if (cr.subPredicate instanceof And && ((And<E,C>) cr.subPredicate).getParts().size()>1) {
222                                PredicatedInferenceNode<E, P, C, K, H, S> newFalseChild = getMatcher().createPredicatedInferenceNode(this, ((And<E,C>) cr.subPredicate).getParts().get(0), handler.getContext());
223                                getFalseChildren().add(newFalseChild);
224                                if (!newFalseChild.addHandler(subHandler, nodePath)) {
225                                        throw new IllegalStateException("Should never happen!!!");
226                                }
227                                migrateChildren(newFalseChild.getNodePath());
228                        } else if (cr.subPredicate instanceof CommutativeAnd && ((CommutativeAnd<E,C>) cr.subPredicate).getParts().size()>1) {
229                                List<Predicate<E,C>> parts = new ArrayList<Predicate<E,C>>(((CommutativeAnd<E,C>) cr.subPredicate).getParts());
230                                Collections.sort(parts, new Comparator<Predicate<E,C>>() {
231 
232                                        @Override
233                                        public int compare(Predicate<E, C> o1, Predicate<E, C> o2) {
234                                                double delta =  o1.getCost() - o2.getCost();
235                                                if (delta < -Double.MIN_VALUE) {
236                                                        return -1;
237                                                } 
238                                                
239                                                if (delta > Double.MIN_VALUE) {
240                                                        return 1;
241                                                }
242                                                return o1.hashCode() - o2.hashCode();
243                                        }
244                                        
245                                });
246                                
247                                PredicatedInferenceNode<E, P, C, K, H, S> newFalseChild = getMatcher().createPredicatedInferenceNode(this, parts.get(0), handler.getContext());
248                                getFalseChildren().add(newFalseChild);
249                                if (!newFalseChild.addHandler(subHandler, nodePath)) {
250                                        throw new IllegalStateException("Should never happen!!!");
251                                }
252                                migrateChildren(newFalseChild.getNodePath());                                
253                        } else {
254                                PredicatedInferenceNode<E, P, C, K, H, S> newFalseChild = getMatcher().createPredicatedInferenceNode(this, cr.subPredicate, handler.getContext());
255                                newFalseChild.getTrueHandlers().add(subHandler);
256                                getFalseChildren().add(newFalseChild);
257                                
258                                // Try to migrate existing nodes under the new one.
259                                migrateChildren(newFalseChild.getNodePath());
260                        }
261                                                                        
262                        return true;
263                default:
264                        throw new IllegalArgumentException("Unexpected target: "+cr.target);                                
265                }
266                
267        }
268        
269        /**
270         * Rebuilds inference network.
271         */
272        public void rebuild() {                
273                for (EventHandlerWrapper<E, P, C, K, H, S> h: getAllHandlers()) {
274                        addHandler(EventHandlerWrapperFilter.peel(h), nodePath);
275                }                
276        }
277        
278        /**
279         * Attempts to migrate this node and child nodes' handlers to the node
280         * specified by the nodePath parameter.
281         * @param nodePath
282         * @return true if the node was fully migrated (empty).
283         */
284        boolean migrate(LinkedList<PredicatedInferenceNode<E,P,C,K,H,S>> nodePath) {
285                if (nodePath.containsAll(this.nodePath)) {
286                        return isEmpty(); // Self migration.
287                }
288                Iterator<EventHandlerWrapper<E, P, C, K, H, S>> thit = getTrueHandlers().iterator();
289                while (thit.hasNext()) {
290                        EventHandlerWrapper<E, P, C, K, H, S> th = thit.next();
291                        if (this.nodePath.getFirst().addHandler(th, nodePath)) {
292                                logger.info("Handler "+th+" migrated from "+this.nodePath+" to "+nodePath);                                
293                                thit.remove();
294                        }
295                }
296                
297                Iterator<EventHandlerWrapper<E, P, C, K, H, S>> fhit = getFalseHandlers().iterator();
298                while (fhit.hasNext()) {
299                        EventHandlerWrapper<E, P, C, K, H, S> fh = fhit.next();
300                        if (this.nodePath.getFirst().addHandler(fh, nodePath)) {
301                                logger.info("Handler "+fh+" migrated from "+this.nodePath+" to "+nodePath);                                
302                                fhit.remove();
303                        }
304                }
305                
306                migrateChildren(nodePath);
307                
308                return isEmpty();
309        }
310 
311        private void migrateChildren(LinkedList<PredicatedInferenceNode<E, P, C, K, H, S>> nodePath) {
312                Iterator<PredicatedInferenceNode<E, P, C, K, H, S>> tcit = getTrueChildren().iterator();
313                while (tcit.hasNext()) {
314                        PredicatedInferenceNode<E, P, C, K, H, S> tc = tcit.next();
315                        if (tc.migrate(nodePath)) {
316                                tcit.remove();
317                        }
318                }
319                
320                Iterator<PredicatedInferenceNode<E, P, C, K, H, S>> fcit = getTrueChildren().iterator();
321                while (fcit.hasNext()) {
322                        PredicatedInferenceNode<E, P, C, K, H, S> fc = fcit.next();
323                        if (fc.migrate(nodePath)) {
324                                fcit.remove();
325                        }
326                }
327        }
328        
329        private enum Target {
330                // Predicates equal, add to this true
331                THIS_TRUE,
332                // Predicates opposite, add to this false.
333                THIS_FALSE,
334                // Parameter predicate is more restrictive than this predicate or
335                // composite with extracted part for this predicate, add (merge) to true children.
336                SUB_TRUE,
337                // Parameter predicate is composite with opposite part extracted, 
338                // or this predicate is opposite less restrictive than parameter predicate
339                // add (merge) to false children.
340                SUB_FALSE
341        }
342        
343        private class CR {
344                
345                // Predicate for sub-node.
346                Predicate<E, C> subPredicate;
347                
348                Target target;
349 
350                public CR(Predicate<E, C> subPredicate, Target target) {
351                        this.subPredicate = subPredicate;
352                        this.target = target;
353                }
354                
355        }
356        
357        private enum CONTEXT_DEPENDENCY {
358                BOTH,
359                NODE,
360                HANDLER,
361                NONE
362        }        
363        
364        /**
365         * Compares parameter predicate with this predicate.
366         * @param predicate
367         * @return
368         */
369        private CR compare(EventHandlerWrapper<E, P, C, K, H, S> handler) {
370                if (this.predicate==handler.getPredicate()) { 
371                        return new CR(null, Target.THIS_TRUE);
372                }
373                
374                if (this.predicate.isContextDependent() && !handler.getPredicate().isContextDependent()) {
375                        return null; // This predicate is automatically more restrictive because it is context dependent.
376                }
377                
378                CONTEXT_DEPENDENCY contextDependency;
379                if (this.predicate.isContextDependent()) {
380                        if (handler.getPredicate().isContextDependent()) {
381                                contextDependency = CONTEXT_DEPENDENCY.BOTH;
382                        } else {
383                                contextDependency = CONTEXT_DEPENDENCY.NODE;
384                        }                        
385                } else {
386                        if (handler.getPredicate().isContextDependent()) {
387                                contextDependency = CONTEXT_DEPENDENCY.HANDLER;
388                        } else {
389                                contextDependency = CONTEXT_DEPENDENCY.NONE;
390                        }
391                }
392                
393                if (CONTEXT_DEPENDENCY.BOTH.equals(contextDependency)) {
394                        if (this.context==null) {
395                                if (handler.getContext()!=null) {
396                                        return null;
397                                }                                
398                        } else {
399                                if (!this.context.equals(handler.getContext())) {
400                                        return null;
401                                }
402                        }
403                }
404                
405                // Both are context independent or
406                // contexts are both null or equal.
407                Predicate<E, C> handlerPredicate = handler.getPredicate();
408//                System.out.println("Comparing ---\n\t"+this.predicate+"\n\t"+handlerPredicate);
409                ComparisonResult cr = this.predicate.compareTo(handlerPredicate);
410                if (cr!=null && cr.isOneToOneMapping()) {
411//                        System.out.println("\t"+cr.getType());
412                        switch (cr.getType()) {
413                        case EQUAL:
414                                return new CR(null, Target.THIS_TRUE);
415                        case OPPOSITE:
416                                return new CR(null, Target.THIS_FALSE);
417                        case LESS_RESTRICTIVE:
418                                if (handlerPredicate instanceof And) {
419                                        Predicate<E,C> firstPart = ((And<E,C>) handlerPredicate).getParts().get(0);
420                                        ComparisonResult pcr = firstPart.compareTo(this.predicate);
421                                        if (ComparisonResult.EQUAL_NM.equals(pcr)) {
422                                                return new CR(((And<E,C>) handlerPredicate).remove(firstPart), Target.SUB_TRUE);
423                                        }
424                                } else if (handlerPredicate instanceof CommutativeAnd) {
425                                        for (Predicate<E,C> part: ((CommutativeAnd<E, C>) handlerPredicate).getParts()) {
426                                                if (ComparisonResult.EQUAL_NM.equals(part.compareTo(this.predicate))) {
427                                                        return new CR(((CommutativeAnd<E,C>) handlerPredicate).remove(part), Target.SUB_TRUE);
428                                                }                                        
429                                        }
430                                }
431                                
432                                return new CR(handlerPredicate, Target.SUB_TRUE);
433                        case OPPOSITE_LESS_RESTRICTIVE:
434                                if (handlerPredicate instanceof And) {
435                                        Predicate<E,C> firstPart = ((And<E,C>) handlerPredicate).getParts().get(0);
436                                        if (ComparisonResult.OPPOSITE_NM.equals(firstPart.compareTo(this.predicate))) {
437                                                return new CR(((And<E,C>) handlerPredicate).remove(firstPart), Target.SUB_FALSE);
438                                        }
439                                } else if (handlerPredicate instanceof CommutativeAnd) {
440                                        for (Predicate<E,C> part: ((CommutativeAnd<E, C>) handlerPredicate).getParts()) {
441                                                if (ComparisonResult.OPPOSITE_NM.equals(part.compareTo(this.predicate))) {
442                                                        return new CR(((And<E,C>) handlerPredicate).remove(part), Target.SUB_FALSE);
443                                                }                                        
444                                        }
445                                }
446                                                        
447                                return new CR(handlerPredicate, Target.SUB_FALSE);                        
448                        }
449                }
450                
451                if (handlerPredicate instanceof And) {
452                        // Should have at least one part if reached here
453                        And<E,C> ahp = (And<E,C>) handlerPredicate;
454                        Predicate<E, C> firstPart = ahp.getParts().get(0);
455                        cr = this.predicate.compareTo(firstPart);
456                        if (cr!=null && cr.isOneToOneMapping()) {
457//                                System.out.println("\t firstPart "+cr.getType());
458                                switch (cr.getType()) {
459                                case EQUAL:
460                                        return new CR(ahp.remove(firstPart), Target.SUB_TRUE);
461                                case LESS_RESTRICTIVE:
462                                        return new CR(ahp, Target.SUB_TRUE);
463                                case OPPOSITE:
464                                        return new CR(ahp.remove(firstPart), Target.SUB_FALSE);
465                                case OPPOSITE_LESS_RESTRICTIVE:
466                                        return new CR(ahp, Target.SUB_FALSE);
467                                }                                
468                        }
469                } else if (handlerPredicate instanceof CommutativeAnd) {
470                        // Should have at least one part if reached here
471                        CommutativeAnd<E,C> cahp = (CommutativeAnd<E,C>) handlerPredicate;
472                        for (Predicate<E, C> part: cahp.getParts()) {
473                                cr = this.predicate.compareTo(part);
474                                if (cr!=null && cr.isOneToOneMapping()) {
475//                                        System.out.println("\t part "+cr.getType());
476                                        switch (cr.getType()) {
477                                        case EQUAL:
478                                                return new CR(cahp.remove(part), Target.SUB_TRUE);
479                                        case LESS_RESTRICTIVE:
480                                                return new CR(cahp, Target.SUB_TRUE);
481                                        case OPPOSITE:
482                                                return new CR(cahp.remove(part), Target.SUB_FALSE);
483                                        case OPPOSITE_LESS_RESTRICTIVE:
484                                                return new CR(cahp, Target.SUB_FALSE);
485                                        }                                
486                                }
487                        }
488                }
489                return null;
490        }
491                
492        boolean isEmpty() {
493                return getTrueChildren().isEmpty() 
494                        && getTrueHandlers().isEmpty()
495                        && getFalseChildren().isEmpty()
496                        && getFalseHandlers().isEmpty();
497        }
498 
499        /**
500         * Collects handlers synchronously.
501         */
502        @Override
503        public void collectHandlers(
504                        Map<C, Map<Extractor<E, ? super Boolean, C>, ? super Boolean>> cache,
505                        Collection<EventHandlerWrapper<E, P, C, K, H, S>> collector,
506                        E event) {
507                
508                @SuppressWarnings("unchecked")
509                E[] events = (E[]) Array.newInstance(matcher.getEventBus().getEventType(), 1);
510                events[0] = event;
511                
512                if (getPredicate().extract(getContext(), cache, events)) {
513                        for (PredicatedInferenceNode<E, P, C, K, H, S> trueChild: getTrueChildren()) {
514                                trueChild.collectHandlers(cache, collector, event);
515                        }
516                        collector.addAll(getTrueHandlers());
517                } else {
518                        for (PredicatedInferenceNode<E, P, C, K, H, S> falseChild: getFalseChildren()) {
519                                falseChild.collectHandlers(cache, collector, event);
520                        }
521                        collector.addAll(getFalseHandlers());                                        
522                }                                                
523        }
524        
525        /**
526         * Collects handlers asynchronously.
527         */
528        @Override
529        public void collectHandlers(
530                        final Map<C, Map<Extractor<E, ? super Boolean, C>, ? super Boolean>> cache,
531                        final ExecutorService executor,
532                        final AtomicReference<Collection<Future<Collection<EventHandlerWrapper<E, P, C, K, H, S>>>>> collector,
533                        final E event) {
534                
535                // Evaluates predicate and submits tasks for sub-nodes.
536                Callable<Collection<EventHandlerWrapper<E, P, C, K, H, S>>> task = createCollectorTask(cache, executor, collector, event);
537                Collection<Future<Collection<EventHandlerWrapper<E, P, C, K, H, S>>>> c = collector.get();
538                if (c==null) {
539                        logger.severe("Collecting handlers after join()");
540                        throw new EventBusException("Collecting handlers after join()");
541                } 
542                c.add(executor.submit(task));
543                
544        }
545 
546        @Override
547        public boolean remove(List<PredicatedInferenceNode<E, P, C, K, H, S>> parentTrueChildren, List<PredicatedInferenceNode<E, P, C, K, H, S>> parentFalseChildren, boolean isTrueChild, Iterable<K> keys) {
548                for (K key: keys) {
549                        Iterator<EventHandlerWrapper<E, P, C, K, H, S>> tit = getTrueHandlers().iterator();
550                        while (tit.hasNext()) {
551                                EventHandlerWrapper<E, P, C, K, H, S> eh = tit.next();
552                                if (eh.getRegistrationKeys().remove(key)) {
553                                        if (eh.getRegistrationKeys().isEmpty()) {
554                                                tit.remove();
555                                        }
556                                }
557                        }
558                        Iterator<EventHandlerWrapper<E, P, C, K, H, S>> fit = getFalseHandlers().iterator();
559                        while (fit.hasNext()) {
560                                EventHandlerWrapper<E, P, C, K, H, S> eh = fit.next();
561                                if (eh.getRegistrationKeys().remove(key)) {
562                                        if (eh.getRegistrationKeys().isEmpty()) {
563                                                fit.remove();
564                                        }
565                                }
566                        }
567                        
568                        Iterator<PredicatedInferenceNode<E, P, C, K, H, S>> tcit = getTrueChildren().iterator();
569                        while (tcit.hasNext()) {
570                                if (!tcit.next().remove(getTrueChildren(), getFalseChildren(), true, keys)) {
571                                        tcit.remove();
572                                }
573                        }
574                        
575                        Iterator<PredicatedInferenceNode<E, P, C, K, H, S>> fcit = getFalseChildren().iterator();
576                        while (fcit.hasNext()) {
577                                if (!fcit.next().remove(getTrueChildren(), getFalseChildren(), false, keys)) {
578                                        fcit.remove();
579                                }
580                        }
581                }
582                
583                if (!getTrueHandlers().isEmpty() || !getFalseHandlers().isEmpty()) {
584                        return true;
585                }
586                
587                // TODO implement sub-node promotion to parent. Two-phase - a) collect. b) if nothing remains - promote.                                
588                
589                return !getTrueChildren().isEmpty() || !getFalseChildren().isEmpty();
590        }
591 
592        @Override
593        public void reset() {
594                for (EventHandlerWrapper<E, P, C, K, H, S> eh: getTrueHandlers()) {
595                        eh.reset();
596                }
597                for (EventHandlerWrapper<E, P, C, K, H, S> eh: getFalseHandlers()) {
598                        eh.reset();
599                }
600                for (PredicatedInferenceNode<E, P, C, K, H, S> child: getTrueChildren()) {
601                        child.reset();
602                }
603                for (PredicatedInferenceNode<E, P, C, K, H, S> child: getFalseChildren()) {
604                        child.reset();
605                }
606        }        
607 
608        void takeSnapshot(AbstractEventBus.Snapshot<E, P, C, K, H, S> snapshot, Set<K> taken) {
609                if (taken.add(id)) {
610                        Collection<K> trueChildrenIds = new ArrayList<K>();
611                        for (PredicatedInferenceNode<E, P, C, K, H, S> tc: getTrueChildren()) {
612                                tc.takeSnapshot(snapshot, taken);
613                                trueChildrenIds.add(tc.id);
614                        }
615                        
616                        Collection<K> trueHandlersIds = new ArrayList<K>();
617                        for (EventHandlerWrapper<E, P, C, K, H, S> th: getTrueHandlers()) {
618                                th.takeSnapshot(snapshot, taken);
619                                trueHandlersIds.addAll(getMatcher().extractHandlerIds(th));
620                        }
621                        
622                        Collection<K> falseChildrenIds = new ArrayList<K>();
623                        for (PredicatedInferenceNode<E, P, C, K, H, S> fc: getFalseChildren()) {
624                                fc.takeSnapshot(snapshot, taken);
625                                falseChildrenIds.add(fc.id);
626                        }
627                        
628                        Collection<K> falseHandlersIds = new ArrayList<K>();
629                        for (EventHandlerWrapper<E, P, C, K, H, S> fh: getFalseHandlers()) {
630                                fh.takeSnapshot(snapshot, taken);
631                                falseHandlersIds.addAll(getMatcher().extractHandlerIds(fh));
632                        }
633                        
634                        snapshot.predicateNode(id, predicate, trueChildrenIds, trueHandlersIds, falseChildrenIds, falseHandlersIds, isRoot);
635                }                
636        }
637        
638        @Override
639        public Collection<EventHandlerWrapper<E, P, C, K, H, S>> getAllHandlers() {
640                Collection<EventHandlerWrapper<E, P, C, K, H, S>> ret = new LinkedList<EventHandlerWrapper<E,P,C,K,H,S>>();
641 
642                ret.addAll(getTrueHandlers());
643                ret.addAll(getFalseHandlers());
644                
645                for (PredicatedInferenceNode<E, P, C, K, H, S> tc: getTrueChildren()) {
646                        ret.addAll(tc.getAllHandlers());
647                }
648                
649                for (PredicatedInferenceNode<E, P, C, K, H, S> fc: getFalseChildren()) {
650                        ret.addAll(fc.getAllHandlers());
651                }
652                
653                return ret;
654        }
655}

[all classes][com.hammurapi.eventbus]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov