funtableimpl.java

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

JAVA
533
字号
            if (value instanceof Resolver[]) {
                continue; // has already been converted
            }
            List v2 = (List) value;
            mapNameToResolvers.put(key, v2.toArray(new Resolver[v2.size()]));
        }
    }

    /**
     * This method is called from the constructor, to define the set of
     * functions and reserved words recognized.
     *
     * <p>Each function is declared by calling {@link #define}. Each reserved
     * word is declared by calling {@link #defineReserved(String)}.
     *
     * <p>Derived class can override this method to add more functions.
     **/
    protected abstract void defineFunctions();

    /**
     * Wrapper which evaluates an expression to a tuple, sets the current
     * context from that tuple, and converts it to a scalar expression.
     */
    private static class TupleScalarExp extends ExpBase {
        private final Exp exp;

        TupleScalarExp(Exp exp) {
            this.exp = exp;
            assert exp.getTypeX() instanceof TupleType;
        }

        public Object[] getChildren() {
            return new Object[] {exp};
        }

        public void unparse(PrintWriter pw) {
            exp.unparse(pw);
        }

        public Object clone() {
            return this;
        }

        public int getCategory() {
            return exp.getCategory();
        }

        public Type getTypeX() {
            return new ScalarType();
        }

        public Exp accept(Validator validator) {
            final Exp exp2 = validator.validate(exp, false);
            if (exp2 == exp) {
                //return this;
            }
            final FunTable funTable = validator.getFunTable();
            return funTable.createValueFunCall(exp2, validator);
        }

        public boolean dependsOn(Dimension dimension) {
            // The value at the current context by definition depends upon
            // all dimensions.
            return true;
        }

        public Object evaluate(Evaluator evaluator) {
            return exp.evaluateScalar(evaluator);
        }
    }

    /**
     * Wrapper which evaluates an expression to a dimensional context and
     * converts it to a scalar expression.
     */
    private static class MemberScalarExp extends ExpBase {
        private final Exp exp;

        public MemberScalarExp(Exp exp) {
            this.exp = exp;
        }

        public Object[] getChildren() {
            return new Object[] {exp};
        }

        public void unparse(PrintWriter pw) {
            exp.unparse(pw);
        }

        public Object clone() {
            return this;
        }

        public int getCategory() {
            return exp.getCategory();
        }

        public Type getTypeX() {
            return new ScalarType();
        }

        public Exp accept(Validator validator) {
            final Exp exp2 = validator.validate(exp, false);
            if (exp2 == exp) {
                return this;
            }
            final FunTable funTable = validator.getFunTable();
            return funTable.createValueFunCall(exp2, validator);
        }

        public boolean dependsOn(Dimension dimension) {
            // If the expression has type dimension
            // but does not depend on dimension
            // then this expression does not dimension on dimension.
            // Otherwise it depends on everything.
            final Type type = exp.getTypeX();
            if (type.usesDimension(dimension)) {
                return exp.dependsOn(dimension);
            } else {
                return true;
            }
        }

        public Object evaluate(Evaluator evaluator) {
            final Member member = (Member) exp.evaluate(evaluator);
            if (member == null ||
                    member.isNull()) {
                return null;
            }
            Member old = evaluator.setContext(member);
            Object value = evaluator.evaluateCurrent();
            evaluator.setContext(old);
            return value;
        }
    }

    /**
     * An expression which yields the current value of the current member.
     */
    private static class ScalarExp extends ExpBase {

        ScalarExp() {
        }

        public void unparse(PrintWriter pw) {
            pw.print("$Value()");
        }

        public Object clone() {
            return this;
        }

        public int getCategory() {
            return Category.Numeric;
        }

        public Type getTypeX() {
            return new NumericType();
        }

        public Exp accept(Validator validator) {
            return this;
        }

        public boolean dependsOn(Dimension dimension) {
            // The value at the current context by definition depends upon
            // all dimensions.
            return true;
        }

        public Object evaluate(Evaluator evaluator) {
            return evaluator.evaluateCurrent();
        }
    }

    /**
     * An expression which evaluates a list of members, sets the context to
     * these members, then evaluates the current measure as a scalar
     * expression.
     *
     * <p>A typical expression which would be evaluated in this way is:
     * <blockquote><code>WITH MEMBER [Measures].[Female Sales] AS
     * ' ( [Measures].[Unit Sales], [Gender].[F] ) '</code></blockquote>
     *
     * @see TupleScalarExp
     */
    private static class MemberListScalarExp extends ExpBase {
        private final Exp[] exps;

        MemberListScalarExp(Exp[] exps) {
            this.exps = exps;
            for (int i = 0; i < exps.length; i++) {
                assert exps[i].getTypeX() instanceof MemberType;
            }
        }

        public void unparse(PrintWriter pw) {
            unparseList(pw, exps, "(", ", ", ")");
        }

        public Object[] getChildren() {
            return exps;
        }

        public Object clone() {
            return this;
        }

        public int getCategory() {
            return Category.Numeric;
        }

        public Type getTypeX() {
            return new NumericType();
        }

        public Exp accept(Validator validator) {
            return this;
        }

        public boolean dependsOn(Dimension dimension) {
            // This expression depends upon dimension
            // if none of the sub-expressions returns a member of dimension
            // or if one of the sub-expressions is dependent upon dimension.
            //
            // Examples:
            //
            //   ( [Gender].[M], [Marital Status].CurrentMember )
            //
            // does not depend upon [Gender], because one of the members is
            // of the [Gender] dimension, yet none of the expressions depends
            // upon [Gender].
            //
            //   ( [Store].[USA], [Marital Status].CurrentMember )
            //
            // depends upon [Gender], because none of the members is of
            // the [Gender] dimension.
            boolean uses = false;
            for (int i = 0; i < exps.length; i++) {
                Exp exp = exps[i];
                if (exp.dependsOn(dimension)) {
                    return true;
                }
                final Type type = exp.getTypeX();
                if (type.usesDimension(dimension)) {
                    uses = true;
                }
            }
            return !uses;
        }

        public Object evaluate(Evaluator evaluator) {
            Evaluator evaluator2 = evaluator.push();
            for (int i = 0; i < exps.length; i++) {
                Exp exp = exps[i];
                final Member member = (Member) exp.evaluate(evaluator);
                evaluator2.setContext(member);
            }
            return evaluator2.evaluateCurrent();
        }
    }
}

// End FunTableImpl.java

⌨️ 快捷键说明

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