Search in sources :

Example 1 with FunctionMetadata

use of org.apache.poi.ss.formula.function.FunctionMetadata in project poi by apache.

the class FormulaParser method getFunction.

/**
     * Generates the variable function ptg for the formula.
     * <p>
     * For IF Formulas, additional PTGs are added to the tokens
     * @param name a {@link NamePtg} or {@link NameXPtg} or <code>null</code>
     * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this function
     */
private ParseNode getFunction(String name, Ptg namePtg, ParseNode[] args) {
    FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByName(name.toUpperCase(Locale.ROOT));
    int numArgs = args.length;
    if (fm == null) {
        if (namePtg == null) {
            throw new IllegalStateException("NamePtg must be supplied for external functions");
        }
        // must be external function
        ParseNode[] allArgs = new ParseNode[numArgs + 1];
        allArgs[0] = new ParseNode(namePtg);
        System.arraycopy(args, 0, allArgs, 1, numArgs);
        return new ParseNode(FuncVarPtg.create(name, numArgs + 1), allArgs);
    }
    if (namePtg != null) {
        throw new IllegalStateException("NamePtg no applicable to internal functions");
    }
    boolean isVarArgs = !fm.hasFixedArgsLength();
    int funcIx = fm.getIndex();
    if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.length == 1) {
        // POI does the same for consistency, but this is not critical
        return new ParseNode(AttrPtg.getSumSingle(), args);
    // The code below would encode tFuncVar(SUM) which seems to do no harm
    }
    validateNumArgs(args.length, fm);
    AbstractFunctionPtg retval;
    if (isVarArgs) {
        retval = FuncVarPtg.create(name, numArgs);
    } else {
        retval = FuncPtg.create(funcIx);
    }
    return new ParseNode(retval, args);
}
Also used : FunctionMetadata(org.apache.poi.ss.formula.function.FunctionMetadata) AbstractFunctionPtg(org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)

Example 2 with FunctionMetadata

use of org.apache.poi.ss.formula.function.FunctionMetadata in project poi by apache.

the class FunctionEval method getNotSupportedFunctionNames.

/**
     * Returns an array of function names NOT implemented by POI.
     *
     * @return an array of not supported functions
     * @since 3.8 beta6
     */
public static Collection<String> getNotSupportedFunctionNames() {
    Collection<String> lst = new TreeSet<String>();
    for (int i = 0; i < functions.length; i++) {
        Function func = functions[i];
        if (func != null && (func instanceof NotImplementedFunction)) {
            FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByIndex(i);
            lst.add(metaData.getName());
        }
    }
    // INDIRECT is a special case
    lst.remove("INDIRECT");
    return Collections.unmodifiableCollection(lst);
}
Also used : FunctionMetadata(org.apache.poi.ss.formula.function.FunctionMetadata) TreeSet(java.util.TreeSet)

Example 3 with FunctionMetadata

use of org.apache.poi.ss.formula.function.FunctionMetadata in project poi by apache.

the class FunctionEval method getSupportedFunctionNames.

/**
     * Returns a collection of function names implemented by POI.
     *
     * @return an array of supported functions
     * @since 3.8 beta6
     */
public static Collection<String> getSupportedFunctionNames() {
    Collection<String> lst = new TreeSet<String>();
    for (int i = 0; i < functions.length; i++) {
        Function func = functions[i];
        FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByIndex(i);
        if (func != null && !(func instanceof NotImplementedFunction)) {
            lst.add(metaData.getName());
        }
    }
    // INDIRECT is a special case
    lst.add("INDIRECT");
    return Collections.unmodifiableCollection(lst);
}
Also used : FunctionMetadata(org.apache.poi.ss.formula.function.FunctionMetadata) TreeSet(java.util.TreeSet)

Example 4 with FunctionMetadata

use of org.apache.poi.ss.formula.function.FunctionMetadata in project poi by apache.

the class FunctionEval method registerFunction.

/**
     * Register a new function in runtime.
     *
     * @param name  the function name
     * @param func  the functoin to register
     * @throws IllegalArgumentException if the function is unknown or already  registered.
     * @since 3.8 beta6
     */
public static void registerFunction(String name, Function func) {
    FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByName(name);
    if (metaData == null) {
        if (AnalysisToolPak.isATPFunction(name)) {
            throw new IllegalArgumentException(name + " is a function from the Excel Analysis Toolpack. " + "Use AnalysisToolpack.registerFunction(String name, FreeRefFunction func) instead.");
        }
        throw new IllegalArgumentException("Unknown function: " + name);
    }
    int idx = metaData.getIndex();
    if (functions[idx] instanceof NotImplementedFunction) {
        functions[idx] = func;
    } else {
        throw new IllegalArgumentException("POI already implememts " + name + ". You cannot override POI's implementations of Excel functions");
    }
}
Also used : FunctionMetadata(org.apache.poi.ss.formula.function.FunctionMetadata)

Example 5 with FunctionMetadata

use of org.apache.poi.ss.formula.function.FunctionMetadata in project poi by apache.

the class AnalysisToolPak method registerFunction.

/**
     * Register a ATP function in runtime.
     *
     * @param name  the function name
     * @param func  the functoin to register
     * @throws IllegalArgumentException if the function is unknown or already  registered.
     * @since 3.8 beta6
     */
public static void registerFunction(String name, FreeRefFunction func) {
    AnalysisToolPak inst = (AnalysisToolPak) instance;
    if (!isATPFunction(name)) {
        FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByName(name);
        if (metaData != null) {
            throw new IllegalArgumentException(name + " is a built-in Excel function. " + "Use FunctoinEval.registerFunction(String name, Function func) instead.");
        }
        throw new IllegalArgumentException(name + " is not a function from the Excel Analysis Toolpack.");
    }
    FreeRefFunction f = inst.findFunction(name);
    if (f != null && !(f instanceof NotImplemented)) {
        throw new IllegalArgumentException("POI already implememts " + name + ". You cannot override POI's implementations of Excel functions");
    }
    // FIXME: inconsistent case-sensitivity
    inst._functionsByName.put(name, func);
}
Also used : FunctionMetadata(org.apache.poi.ss.formula.function.FunctionMetadata) FreeRefFunction(org.apache.poi.ss.formula.functions.FreeRefFunction)

Aggregations

FunctionMetadata (org.apache.poi.ss.formula.function.FunctionMetadata)6 TreeSet (java.util.TreeSet)2 FreeRefFunction (org.apache.poi.ss.formula.functions.FreeRefFunction)1 AbstractFunctionPtg (org.apache.poi.ss.formula.ptg.AbstractFunctionPtg)1