funutil.java

来自「数据仓库展示程序」· Java 代码 · 共 1,808 行 · 第 1/5 页

JAVA
1,808
字号
/*
// $Id: //open/mondrian/src/main/mondrian/olap/fun/FunUtil.java#64 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2002-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 3 March, 2002
*/
package mondrian.olap.fun;

import mondrian.olap.*;
import mondrian.olap.type.Type;
import mondrian.olap.type.TypeUtil;
import mondrian.resource.MondrianResource;

import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.Set;
import java.io.PrintWriter;

/**
 * <code>FunUtil</code> contains a set of methods useful within the
 * <code>mondrian.olap.fun</code> package.
 **/
public class FunUtil extends Util {

    static final String[] emptyStringArray = new String[0];
    private static final boolean debug = false;

    /**
     * Creates an exception which indicates that an error has occurred while
     * executing a given function.
     */
    public static RuntimeException newEvalException(
            FunDef funDef,
            String message) {
        Util.discard(funDef); // TODO: use this
        return new MondrianEvaluationException(message);
    }

    static Exp getArgNoEval(Exp[] args, int index) {
        return getArgNoEval(args, index, null);
    }

    static Exp getArgNoEval(
            Exp[] args,
            int index,
            Exp defaultValue) {
        return (index >= args.length)
            ? defaultValue
            : args[index];
    }

    static Object getArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        return getArg(evaluator, args, index, null);
    }

    static Object getArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            Object defaultValue) {
        return (index >= args.length)
            ? defaultValue
            : args[index].evaluate(evaluator);
    }

    static String getStringArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            String defaultValue) {
        return (String) getArg(evaluator, args, index, defaultValue);
    }

    /** Returns an argument whose value is a literal. Unlike the other
     * <code>get<i>Xxx</i>Arg</code> methods, an evalutor is not required,
     * and hence this can be called at resolve-time. */
    static String getLiteralArg(
            Exp[] args,
            int i,
            String defaultValue,
            String[] allowedValues,
            FunDef funDef) {
        if (i >= args.length) {
            if (defaultValue == null) {
                throw newEvalException(funDef, "Required argument is missing");
            } else {
                return defaultValue;
            }
        }
        Exp arg = args[i];
        if (!(arg instanceof Literal) ||
                arg.getCategory() != Category.Symbol) {
            throw newEvalException(funDef, "Expected a symbol, found '" + arg + "'");
        }
        String s = (String) ((Literal) arg).getValue();
        StringBuffer sb = new StringBuffer(64);
        for (int j = 0; j < allowedValues.length; j++) {
            String allowedValue = allowedValues[j];
            if (allowedValue.equalsIgnoreCase(s)) {
                return allowedValue;
            }
            if (j > 0) {
                sb.append(", ");
            }
            sb.append(allowedValue);
        }
        throw newEvalException(funDef, "Allowed values are: {" + sb + "}");
    }

    /**
     * Returns the ordinal of a literal argument. If the argument does not
     * belong to the supplied enumeration, returns -1.
     */
    static int getLiteralArg(
            Exp[] args,
            int i,
            int defaultValue,
            EnumeratedValues allowedValues,
            FunDef funDef) {
        final String literal = getLiteralArg(
                args,
                i,
                allowedValues.getName(defaultValue),
                allowedValues.getNames(),
                funDef);
        return (literal == null)
            ? -1
            : allowedValues.getOrdinal(literal);
    }

    /**
     * returns defaultValue, if the expression can not be evaluated because
     * some required operands have not been loaded from the database yet.
     */
    static boolean getBooleanArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            boolean defaultValue) {
        Object o = getArg(evaluator, args, index);
        return (o == null)
            ? defaultValue
            : ((Boolean) o).booleanValue();
    }

    /**
     * returns null, if the expression can not be evaluated because
     * some required operands have not been loaded from the database yet.
     */
    static Boolean getBooleanArg(Evaluator evaluator, Exp[] args, int index) {
        Object o = getArg(evaluator, args, index);
        return (Boolean) o;
    }

    static int getIntArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        Object o = getScalarArg(evaluator, args, index);
        if (o instanceof Number) {
            return ((Number) o).intValue();
        } else if (o instanceof RuntimeException) {
            return 0;
        } else {
            // we need to handle String("5.0")
            String s = o.toString();
            double d = Double.valueOf(s).doubleValue();
            return (int) d;
        }
    }

    static Object getScalarArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        return args[index].evaluateScalar(evaluator);
    }

    static BigDecimal getDecimalArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        Object o = getScalarArg(evaluator, args, index);
        if (o instanceof BigDecimal) {
            return (BigDecimal) o;
        } else if (o instanceof BigInteger) {
            return new BigDecimal((BigInteger) o);
        } else if (o instanceof Number) {
            return new BigDecimal(((Number) o).doubleValue());
        } else {
            throw Util.newInternal(
                    "arg " + o + " cannot be converted to BigDecimal");
        }
    }


    private static final Double nullValue = new Double(0);

    protected static Double getDoubleArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        return getDoubleArg(evaluator, args, index, nullValue);
    }

    static Double getDoubleArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            Double nullValue) {
        Object o = getScalarArg(evaluator, args, index);
        if (o instanceof Double) {
            return (Double) o;
        } else if (o instanceof Number) {
            return new Double(((Number) o).doubleValue());
        } else if (o instanceof Throwable) {
            return new Double(Double.NaN);
        } else if (o == null || o == Util.nullValue) {
            return nullValue;
        } else {
            throw Util.newInternal("arg " + o + " cannot be converted to Double");
        }
    }

    static Member getMemberArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            boolean fail) {
        if (index >= args.length) {
            if (fail) {
                throw newInternal("missing member argument");
            } else {
                return null;
            }
        }
        Exp arg = args[index];
        Object o = arg.evaluate(evaluator);
        if (o instanceof Member) {
            return (Member) o;
        } else if (o instanceof Hierarchy) {
            return evaluator.getContext(((Hierarchy) o).getDimension());
        } else if (o instanceof Dimension) {
            return evaluator.getContext((Dimension) o);
        } else {
            throw newInternal("expecting a member, got " + o);
        }
    }

    /**
     * Evaluates and returns the <code>index</code>th argument, which must
     * be a tuple.
     *
     * @see #getTupleOrMemberArg
     *
     * @param evaluator Evaluation context
     * @param args The arguments to the function call
     * @param index Ordinal of the argument we are seeking
     * @return A tuple, represented as usual by an array of {@link Member}
     *   objects.
     */
    public static Member[] getTupleArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        Exp arg = args[index];
        Object o = arg.evaluate(evaluator);
        return (Member[]) o;
    }

    /**
     * Evaluates and returns the <code>index</code>th argument, which we
     * expect to be either a member or a tuple, as a tuple.
     * If the argument is a member, converts it into a tuple with one member.
     * If the argument is the null tuple, returns null.
     *
     * @see #getTupleArg
     *
     * @param evaluator Evaluation context
     * @param args The arguments to the function call
     * @param index Ordinal of the argument we are seeking
     * @return A tuple, represented as usual by an array of {@link Member}
     *   objects, or null if the tuple is null
     *
     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
     *   range
     */
    public static Member[] getTupleOrMemberArg(
            Evaluator evaluator,
            Exp[] args,
            int index) {
        Exp arg = args[index];
        Object o0 = arg.evaluate(evaluator);
        if (o0 == null) {
            return null;
        } else if (o0 instanceof Member[]) {
            return (Member[]) o0;
        } else if (o0 instanceof Member) {
            return new Member[] { (Member)o0 };
        } else {
            throw Util.newInternal("Expected tuple or member, got " + o0);
        }
    }

    static Level getLevelArg(Evaluator evaluator,
                             Exp[] args,
                             int index,
                             boolean fail) {
        if (index >= args.length) {
            if (fail) {
                throw newInternal("missing level argument");
            } else {
                return null;
            }
        }
        Exp arg = args[index];
        Object o = arg.evaluate(evaluator);
        return (Level) o;
    }

    static Hierarchy getHierarchyArg(
            Evaluator evaluator,
            Exp[] args,
            int index,
            boolean fail) {
        if (index >= args.length) {
            if (fail) {
                throw newInternal("missing hierarchy argument");
            } else {
                return null;
            }
        }
        Exp arg = args[index];
        Object o = arg.evaluate(evaluator);
        if (true) {
            return (Hierarchy) o;
        }
        if (o instanceof Member) {
            return ((Member) o).getHierarchy();
        } else if (o instanceof Level) {
            return ((Level) o).getHierarchy();
        } else if (o instanceof Hierarchy) {
            return (Hierarchy) o;
        } else if (o instanceof Dimension) {
            return ((Dimension) o).getHierarchies()[0];
        } else {
            throw newInternal("expecting a hierarchy, got " + o);
        }
    }

    static Dimension getDimensionArg(

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?