    001    package com.hammurapi.reasoning.impl;
    002
    003    import java.util.ArrayList;
    004    import java.util.Collection;
    005    import java.util.Collections;
    006    import java.util.List;
    007    import java.util.concurrent.Future;
    008
    009    import com.hammurapi.config.bootstrap.ConfigurationException;
    010    import com.hammurapi.flow.runtime.Invocable;
    011    import com.hammurapi.flow.runtime.Invoker;
    012    import com.hammurapi.flow.runtime.ProcessingPathElement;
    013    import com.hammurapi.flow.runtime.PropertySet;
    014    import com.hammurapi.flow.runtime.impl.Inlineable;
    015    import com.hammurapi.flow.runtime.impl.Joiner.InputConsumer;
    016    import com.hammurapi.util.Context;
    017
    018    /**
    019     * Transition which doesn't do any processing - it simply passes invocation from source to targets.
    020     * @author Pavel Vlasov
    021     */
    022    public class ReasoningPassThroughNode<F> extends ReasoningNodeBase<F> implements Inlineable {
    023
    024            private List<Output<F>> outputs = new ArrayList<Output<F>>();
    025
    026            private Invocable<KnowledgeBase<F>,InferenceToken<F>> invocable = new Invocable<KnowledgeBase<F>,InferenceToken<F>>() {
    027
    028                    @Override
    029                    public Collection<Future<?>> invoke(
    030                                    KnowledgeBase<F> flowState,
    031                                    InferenceToken<F>[] args,
    032                                    PropertySet properties,
    033                                    Context context,
    034                                    List<ProcessingPathElement> processingPath)
    035                                    throws Exception {
    036                            Collection<Future<?>> ret = new ArrayList<Future<?>>();
    037                            for (Output<F> o: outputs) {
    038                                    Collection<Future<?>> invokeResult = o.invocable.invoke(flowState, args, properties, context, processingPath);
    039                                    if (invokeResult!=null) {
    040                                            ret.addAll(invokeResult);
    041                                    }
    042                            }
    043                            return ret;
    044                    }
    045
    046            };
    047
    048            @Override
    049            public Invocable<KnowledgeBase<F>,InferenceToken<F>> getInvocable(String pinName, Integer connectKey) {
    050                    return invocable;
    051            }
    052
    053            @Override
    054            public Invoker<KnowledgeBase<F>,InferenceToken<F>> getInvoker(String pinName, Integer connectKey) {
    055                    Output<F> ret = new Output<F>(null, connectKey);
    056                    outputs.add(ret);
    057                    return ret;
    058            }
    059
    060            @Override
    061            public void beforeConnect() throws ConfigurationException {
    062                    // NOP
    063            }
    064
    065            @Override
    066            public void afterConnect() throws ConfigurationException {
    067                    Collections.sort(outputs);
    068            }
    069
    070            @Override
    071            public void addPin(String pinName, List<?> pin) {
    072                    // NOP - pass-through node doesn't care about pin configuration.
    073
    074            }
    075
    076            @Override
    077            public boolean inline() {
    078                    return true;
    079            }
    080
    081            @Override
    082            protected Collection<Future<?>> process(
    083                            KnowledgeBase<F> knowledgeBase,
    084                            List<InferenceToken<F>>[] inputs,
    085                            PropertySet properties,
    086                            Context context, List<ProcessingPathElement> processingPath,
    087                            InputConsumer consumer,
    088                            int activator) throws Exception {
    089                    // Should never be invoked.
    090                    throw new UnsupportedOperationException();
    091            }
    092    }