    001    package com.hammurapi.reasoning.impl;
    002
    003    import java.util.Collections;
    004    import java.util.Comparator;
    005    import java.util.Iterator;
    006    import java.util.List;
    007
    008    import com.hammurapi.reasoning.ExceptionHandler;
    009
    010    public class AcceptMethodConditionNode<F> extends ConditionNode<F> {
    011
    012
    013            private List<Integer> parameterMap;
    014
    015            public void setParameterMap(List<Integer> parameterMap) {
    016                    this.parameterMap = parameterMap;
    017            }
    018
    019            /**
    020             * Evaluate condition as soon as all condition arguments are available.
    021             */
    022            @SuppressWarnings("unchecked")
    023            @Override
    024            protected boolean partialJoin(List<com.hammurapi.reasoning.impl.InferenceToken<F>>[] inputs, int index) throws Exception {
    025                    if (index==lastConditionPin) {
    026                            Object[] cArgs = new Object[parameterTypes.length];
    027                            Iterator<Integer> pmit = parameterMap.iterator();
    028                            Z: for (int i=0; pmit.hasNext(); ++i) {
    029                                    Integer pIdx = pmit.next();
    030                                    for (int j=0; j<=index; ++j) {
    031                                            List<TokenInfo> pinConfig = (List<TokenInfo>) getInputPins().get(j).config;
    032                                            if (pinConfig.size()!=inputs[j].size()) {
    033                                                    throw new IllegalArgumentException("Number of input tokens is different from number of token infos");
    034                                            }
    035                                            for (int k=0, l=pinConfig.size(); k<l; ++k) {
    036                                                    TokenInfo ti = pinConfig.get(k);
    037                                                    if (ti.getParameterIndex() == pIdx) {
    038                                                            InferenceToken<F> it = inputs[j].get(k);
    039                                                            if (it.isConsumed()) {
    040                                                                    return false;
    041                                                            }
    042
    043                                                            cArgs[i] = knowledgeBase.get(it.getHandle());
    044                                                            if (cArgs[i]==null) {
    045                                                                    return false;
    046                                                            }
    047                                                            continue Z;
    048                                                    }
    049                                            }
    050                                    }
    051                            }
    052
    053                            try {
    054                                    return Boolean.TRUE.equals(method.invoke(rule, cArgs));
    055                            } catch (Exception e) {
    056                                    ExceptionHandler exceptionHandler = knowledgeBase.getExceptionHandler();
    057                                    if (exceptionHandler==null) {
    058                                            throw e;
    059                                    }
    060                                    exceptionHandler.handleException(e);
    061                                    return false;
    062                            }
    063                    }
    064
    065                    return true;
    066            }
    067
    068            private boolean hasConditionArgument(PinEntry<F> pin) {
    069                    for (Object o: pin.config) {
    070                            TokenInfo ti = (TokenInfo) o;
    071                            for (Integer pIdx: parameterMap) {
    072                                    if (pIdx==ti.getParameterIndex()) {
    073                                            return true;
    074                                    }
    075                            }
    076                    }
    077
    078                    return false;
    079            }
    080
    081            private int lastConditionPin=-1;
    082
    083            /**
    084             * Sort input pins to move pins with conditon arguments to first positions.
    085             */
    086            @Override
    087            protected void sortInputs() {
    088                    Collections.sort(getInputPins(), new Comparator<PinEntry<F>>() {
    089
    090                            @Override
    091                            public int compare(PinEntry<F> pe1, PinEntry<F> pe2) {
    092                                    if (hasConditionArgument(pe1)) {
    093                                            if (hasConditionArgument(pe2)) {
    094                                                    return pe1.index-pe2.index;
    095                                            }
    096                                            return -1; // pe1 shall be before pe2
    097                                    }
    098
    099                                    if (hasConditionArgument(pe2)) {
    100                                            return 1; // pe1 shall be after pe2.
    101                                    }
    102
    103                                    return pe1.index - pe2.index;
    104                            }
    105                    });
    106
    107                    for (int i=0; i<getInputPins().size(); ++i) {
    108                            if (hasConditionArgument(getInputPins().get(i))) {
    109                                    lastConditionPin = i;
    110                            }
    111                    }
    112            }
    113
    114    }