Search in sources :

Example 6 with AbstractFunctionPtg

use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.

the class OperandClassTransformer method isSimpleValueFunction.

private static boolean isSimpleValueFunction(Ptg token) {
    if (token instanceof AbstractFunctionPtg) {
        AbstractFunctionPtg aptg = (AbstractFunctionPtg) token;
        if (aptg.getDefaultOperandClass() != Ptg.CLASS_VALUE) {
            return false;
        }
        int numberOfOperands = aptg.getNumberOfOperands();
        for (int i = numberOfOperands - 1; i >= 0; i--) {
            if (aptg.getParameterClass(i) != Ptg.CLASS_VALUE) {
                return false;
            }
        }
        return true;
    }
    return false;
}
Also used : AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)

Example 7 with AbstractFunctionPtg

use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.

the class OperandClassTransformer method transformNode.

/**
	 * @param callerForceArrayFlag <code>true</code> if one of the current node's parents is a
	 * function Ptg which has been changed from default 'V' to 'A' type (due to requirements on
	 * the function return value).
	 */
private void transformNode(ParseNode node, byte desiredOperandClass, boolean callerForceArrayFlag) {
    Ptg token = node.getToken();
    ParseNode[] children = node.getChildren();
    boolean isSimpleValueFunc = isSimpleValueFunction(token);
    if (isSimpleValueFunc) {
        boolean localForceArray = desiredOperandClass == Ptg.CLASS_ARRAY;
        for (int i = 0; i < children.length; i++) {
            transformNode(children[i], desiredOperandClass, localForceArray);
        }
        setSimpleValueFuncClass((AbstractFunctionPtg) token, desiredOperandClass, callerForceArrayFlag);
        return;
    }
    if (isSingleArgSum(token)) {
        // Need to process the argument of SUM with transformFunctionNode below
        // so make a dummy FuncVarPtg for that call.
        token = FuncVarPtg.SUM;
    // Note - the tAttrSum token (node.getToken()) is a base
    // token so does not need to have its operand class set
    }
    if (token instanceof ValueOperatorPtg || token instanceof ControlPtg || token instanceof MemFuncPtg || token instanceof MemAreaPtg || token instanceof UnionPtg || token instanceof IntersectionPtg) {
        // Value Operator Ptgs and Control are base tokens, so token will be unchanged
        // but any child nodes are processed according to desiredOperandClass and callerForceArrayFlag
        // As per OOO documentation Sec 3.2.4 "Token Class Transformation", "Step 1"
        // All direct operands of value operators that are initially 'R' type will
        // be converted to 'V' type.
        byte localDesiredOperandClass = desiredOperandClass == Ptg.CLASS_REF ? Ptg.CLASS_VALUE : desiredOperandClass;
        for (int i = 0; i < children.length; i++) {
            transformNode(children[i], localDesiredOperandClass, callerForceArrayFlag);
        }
        return;
    }
    if (token instanceof AbstractFunctionPtg) {
        transformFunctionNode((AbstractFunctionPtg) token, children, desiredOperandClass, callerForceArrayFlag);
        return;
    }
    if (children.length > 0) {
        if (token == RangePtg.instance) {
            // TODO is any token transformation required under the various ref operators?
            return;
        }
        throw new IllegalStateException("Node should not have any children");
    }
    if (token.isBaseToken()) {
        // nothing to do
        return;
    }
    token.setClass(transformClass(token.getPtgClass(), desiredOperandClass, callerForceArrayFlag));
}
Also used : AttrPtg(org.apache.poi.ss.formula.ptg.AttrPtg) Ptg(org.apache.poi.ss.formula.ptg.Ptg) UnionPtg(org.apache.poi.ss.formula.ptg.UnionPtg) ValueOperatorPtg(org.apache.poi.ss.formula.ptg.ValueOperatorPtg) FuncVarPtg(org.apache.poi.ss.formula.ptg.FuncVarPtg) RangePtg(org.apache.poi.ss.formula.ptg.RangePtg) MemAreaPtg(org.apache.poi.ss.formula.ptg.MemAreaPtg) ControlPtg(org.apache.poi.ss.formula.ptg.ControlPtg) IntersectionPtg(org.apache.poi.ss.formula.ptg.IntersectionPtg) AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg) MemFuncPtg(org.apache.poi.ss.formula.ptg.MemFuncPtg) MemFuncPtg(org.apache.poi.ss.formula.ptg.MemFuncPtg) ValueOperatorPtg(org.apache.poi.ss.formula.ptg.ValueOperatorPtg) ControlPtg(org.apache.poi.ss.formula.ptg.ControlPtg) MemAreaPtg(org.apache.poi.ss.formula.ptg.MemAreaPtg) IntersectionPtg(org.apache.poi.ss.formula.ptg.IntersectionPtg) UnionPtg(org.apache.poi.ss.formula.ptg.UnionPtg) AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)

Example 8 with AbstractFunctionPtg

use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.

the class OperationEvaluatorFactory method evaluate.

/**
	 * returns the OperationEval concrete impl instance corresponding
	 * to the supplied operationPtg
	 */
public static ValueEval evaluate(OperationPtg ptg, ValueEval[] args, OperationEvaluationContext ec) {
    if (ptg == null) {
        throw new IllegalArgumentException("ptg must not be null");
    }
    Function result = _instancesByPtgClass.get(ptg);
    if (result != null) {
        return result.evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex());
    }
    if (ptg instanceof AbstractFunctionPtg) {
        AbstractFunctionPtg fptg = (AbstractFunctionPtg) ptg;
        int functionIndex = fptg.getFunctionIndex();
        switch(functionIndex) {
            case FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
                return Indirect.instance.evaluate(args, ec);
            case FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
                return UserDefinedFunction.instance.evaluate(args, ec);
        }
        return FunctionEval.getBasicFunction(functionIndex).evaluate(args, ec.getRowIndex(), (short) ec.getColumnIndex());
    }
    throw new RuntimeException("Unexpected operation ptg class (" + ptg.getClass().getName() + ")");
}
Also used : Function(org.apache.poi.ss.formula.functions.Function) AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)

Example 9 with AbstractFunctionPtg

use of org.apache.poi.ss.formula.ptg.AbstractFunctionPtg in project poi by apache.

the class TestOperandClassTransformer method confirmFuncClass.

private void confirmFuncClass(Ptg[] ptgs, int i, String expectedFunctionName, byte operandClass) {
    confirmTokenClass(ptgs, i, operandClass);
    AbstractFunctionPtg afp = (AbstractFunctionPtg) ptgs[i];
    assertEquals(expectedFunctionName, afp.getName());
}
Also used : AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)

Aggregations

AbstractFunctionPtg (org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)9 Ptg (org.apache.poi.ss.formula.ptg.Ptg)5 FuncVarPtg (org.apache.poi.ss.formula.ptg.FuncVarPtg)4 AttrPtg (org.apache.poi.ss.formula.ptg.AttrPtg)3 FuncPtg (org.apache.poi.ss.formula.ptg.FuncPtg)3 IntersectionPtg (org.apache.poi.ss.formula.ptg.IntersectionPtg)3 MemAreaPtg (org.apache.poi.ss.formula.ptg.MemAreaPtg)3 MemFuncPtg (org.apache.poi.ss.formula.ptg.MemFuncPtg)3 RangePtg (org.apache.poi.ss.formula.ptg.RangePtg)3 StringPtg (org.apache.poi.ss.formula.ptg.StringPtg)3 HSSFWorkbook (org.apache.poi.hssf.usermodel.HSSFWorkbook)2 AddPtg (org.apache.poi.ss.formula.ptg.AddPtg)2 AreaPtg (org.apache.poi.ss.formula.ptg.AreaPtg)2 ArrayPtg (org.apache.poi.ss.formula.ptg.ArrayPtg)2 BoolPtg (org.apache.poi.ss.formula.ptg.BoolPtg)2 ConcatPtg (org.apache.poi.ss.formula.ptg.ConcatPtg)2 DividePtg (org.apache.poi.ss.formula.ptg.DividePtg)2 EqualPtg (org.apache.poi.ss.formula.ptg.EqualPtg)2 ErrPtg (org.apache.poi.ss.formula.ptg.ErrPtg)2 GreaterThanPtg (org.apache.poi.ss.formula.ptg.GreaterThanPtg)2