001    package biz.hammurapi.rules.backwardreasoning;
002    
003    import java.util.logging.Logger;
004    
005    import biz.hammurapi.rules.Conclusion;
006    
007    /**
008     * This implementation eliminates facts duplicates. Derivations
009     * of identical conclusions are merged.
010     * @author Pavel
011     *
012     */
013    public class NoDuplicatesBackwardReasoningRulesContainer extends
014                    BackwardReasoningRulesContainer {
015            
016            private static final Logger logger = Logger.getLogger(NoDuplicatesBackwardReasoningRulesContainer.class.getName());
017    
018            protected Accumulator createAccumulator(Class type) {
019                    return new Accumulator(type) {
020                            
021                            /**
022                             * Runs along the chain and compares new element
023                             * with existing before adding.
024                             */
025                            public synchronized void add(Object obj) {
026                                    if (obj == null) {
027                                            throw new NullPointerException(this.getClass().getName()+" does not support null elements.");
028                                    }                               
029                                    
030                                    for (Link link = first.peekNext(); link!=null && link!=END; link = link.peekNext()) {
031                                            if (obj.equals(link.getValue())) {
032                                                    logger.finest("Accumulator "+this+" already contains "+obj);
033                                                    if (obj instanceof Conclusion) {
034                                                            ((Conclusion) link.getValue()).mergeDerivations((Conclusion) obj);
035                                                    }
036                                                    return;
037                                            }
038                                    }
039                                    super.add(obj);
040                            }
041                            
042                            protected void onBlock() {
043                                    logger.finest("Accumulator "+this+" enters blocking state, starting anti-blocking measures");
044                                    onAccumulatorBlock();
045                            }
046                            
047                    };
048            }
049    }