Package org.apache.poi.hssf.record.formula.functions

Source Code of org.apache.poi.hssf.record.formula.functions.XYNumericFunction

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Created on May 29, 2005
*
*/
package org.apache.poi.hssf.record.formula.functions;

import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.RefEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;

/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
public abstract class XYNumericFunction extends NumericFunction {
    protected static final int X = 0;
    protected static final int Y = 1;

    private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR =
        new ValueEvalToNumericXlator((short) (
                  ValueEvalToNumericXlator.BOOL_IS_PARSED 
                | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED 
                | ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED 
              //| ValueEvalToNumericXlator.STRING_IS_PARSED 
                | ValueEvalToNumericXlator.REF_STRING_IS_PARSED 
                | ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED 
              //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED 
              //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED 
              //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE 
              //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE 
                ));

    /**
     * this is the default impl for the factory method getXlator
     * of the super class NumericFunction. Subclasses can override this method
     * if they desire to return a different ValueEvalToNumericXlator instance
     * than the default.
     */
    protected ValueEvalToNumericXlator getXlator() {
        return DEFAULT_NUM_XLATOR;
    }
   
    protected int getMaxNumOperands() {
        return 30;
    }

    /**
     * Returns a double array that contains values for the numeric cells
     * from among the list of operands. Blanks and Blank equivalent cells
     * are ignored. Error operands or cells containing operands of type
     * that are considered invalid and would result in #VALUE! error in
     * excel cause this function to return null.
     *
     * @param operands
     * @param srcRow
     * @param srcCol
     * @return
     */
    protected double[][] getNumberArray(Eval[] xops, Eval[] yops, int srcRow, short srcCol) {
        double[][] retval = new double[2][30];
        int count = 0;
       
        if (xops.length > getMaxNumOperands()
                || yops.length > getMaxNumOperands()
                || xops.length != yops.length) {
            retval = null;
        }
        else {
           
            for (int i=0, iSize=xops.length; i<iSize; i++) {
                Eval xEval = xops[i];
                Eval yEval = yops[i];
               
                if (isNumberEval(xEval) && isNumberEval(yEval)) {
                    retval[X] = ensureCapacity(retval[X], count);
                    retval[Y] = ensureCapacity(retval[Y], count);
                    retval[X][count] = getDoubleValue(xEval);
                    retval[Y][count] = getDoubleValue(yEval);
                    if (Double.isNaN(retval[X][count]) || Double.isNaN(retval[Y][count])) {
                        retval = null;
                        break;
                    }
                    count++;
                }
            }
        }
       
        if (retval != null) {
            double[][] temp = retval;
            retval[X] = trimToSize(retval[X], count);
            retval[Y] = trimToSize(retval[Y], count);
        }
       
        return retval;
    }
   
    protected double[][] getValues(Eval[] operands, int srcCellRow, short srcCellCol) {
        double[][] retval = null;
       
        outer: do {
            if (operands.length == 2) {
                Eval[] xEvals = new Eval[1];
                Eval[] yEvals = new Eval[1];
                if (operands[X] instanceof AreaEval) {
                    AreaEval ae = (AreaEval) operands[0];
                    xEvals = ae.getValues();
                }
                else if (operands[X] instanceof ErrorEval) {
                    break outer;
                }
                else {
                    xEvals[0] = operands[X];
                }
               
                if (operands[Y] instanceof AreaEval) {
                    AreaEval ae = (AreaEval) operands[Y];
                    yEvals = ae.getValues();
                }
                else if (operands[Y] instanceof ErrorEval) {
                    break outer;
                }
                else {
                    yEvals[0] = operands[Y];
                }
               
                retval = getNumberArray(xEvals, yEvals, srcCellRow, srcCellCol);
            }
        } while (false);
       
        return retval;
    }
   

    protected static double[] ensureCapacity(double[] arr, int pos) {
        double[] temp = arr;
        while (pos >= arr.length) {
            arr = new double[arr.length << 2];
        }
        if (temp.length != arr.length)
            System.arraycopy(temp, 0, arr, 0, temp.length);
        return arr;
    }
   
    protected static double[] trimToSize(double[] arr, int len) {
        double[] tarr = arr;
        if (arr.length > len) {
            tarr = new double[len];
            System.arraycopy(arr, 0, tarr, 0, len);
        }
        return tarr;
    }
   
    protected static boolean isNumberEval(Eval eval) {
        boolean retval = false;
       
        if (eval instanceof NumberEval) {
            retval = true;
        }
        else if (eval instanceof RefEval) {
            RefEval re = (RefEval) eval;
            ValueEval ve = re.getInnerValueEval();
            retval = (ve instanceof NumberEval);
        }
       
        return retval;
    }
   
    protected static double getDoubleValue(Eval eval) {
        double retval = 0;
        if (eval instanceof NumberEval) {
            NumberEval ne = (NumberEval) eval;
            retval = ne.getNumberValue();
        }
        else if (eval instanceof RefEval) {
            RefEval re = (RefEval) eval;
            ValueEval ve = re.getInnerValueEval();
                retval = (ve instanceof NumberEval)
                    ? ((NumberEval) ve).getNumberValue()
                    : Double.NaN;
        }
        else if (eval instanceof ErrorEval) {
            retval = Double.NaN;
        }
        return retval;
    }
}
TOP

Related Classes of org.apache.poi.hssf.record.formula.functions.XYNumericFunction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.