001    package com.hammurapi.reasoning.impl;
002    
003    import java.util.Collection;
004    import java.util.Collections;
005    import java.util.List;
006    import java.util.concurrent.Future;
007    
008    import com.hammurapi.flow.runtime.Invocable;
009    import com.hammurapi.flow.runtime.Invoker;
010    import com.hammurapi.flow.runtime.ProcessingPathElement;
011    import com.hammurapi.flow.runtime.PropertySet;
012    import com.hammurapi.flow.runtime.impl.Inlineable;
013    import com.hammurapi.util.Context;
014    
015    /**
016     * This transition passes through only invocations with single parameter of specified type.
017     * @author Pavel Vlasov
018     *
019     */
020    public class TypeFilterTransition<F> extends ReasoningTransitionBase<F> implements Inlineable {
021            
022            private Class<F> type;
023    
024            public void setType(Class<F> type) {
025                    this.type = type;
026            }
027    
028            @Override
029            public Invocable<KnowledgeBase<F>,InferenceToken<F>> getInvocable() {
030                    return invocable;
031            }
032            
033            private Invocable<KnowledgeBase<F>,InferenceToken<F>> next;
034            
035            private Invoker<KnowledgeBase<F>,InferenceToken<F>> invoker = new Invoker<KnowledgeBase<F>,InferenceToken<F>>() {
036    
037                    @Override
038                    public void setInvocable(Invocable<KnowledgeBase<F>,InferenceToken<F>> invocable) {
039                            next = invocable;                       
040                    }
041                    
042            };
043            
044            private Invocable<KnowledgeBase<F>,InferenceToken<F>> invocable = new Invocable<KnowledgeBase<F>,InferenceToken<F>>() {
045    
046                    @Override
047                    public Collection<Future<?>> invoke(
048                                    KnowledgeBase<F> flowState,
049                                    InferenceToken<F>[] args,                         
050                                    PropertySet properties,
051                                    Context context, 
052                                    List<ProcessingPathElement> processingPath) throws Exception {
053                            
054                            if (args!=null 
055                                            && args.length==1 
056                                            && !args[0].isConsumed()
057                                            && type.isInstance(knowledgeBase.get(args[0].getHandle()))) {
058                                    return next.invoke(flowState, args, properties, context, processingPath);
059                            }
060                            return Collections.emptySet();
061                    }
062                    
063            };
064    
065            @Override
066            public Invoker<KnowledgeBase<F>,InferenceToken<F>> getInvoker() {
067                    return invoker;
068            }
069    
070            @Override
071            public boolean inline() {
072                    return true;
073            }
074    
075    }