funutil.java

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

JAVA
1,808
字号
            Evaluator evaluator,
            Exp[] args,
            int index,
            boolean fail) {
        if (index >= args.length) {
            if (fail) {
                throw newInternal("missing dimension argument");
            } else {
                return null;
            }
        }
        Exp arg = args[index];
        Object o = arg.evaluate(evaluator);
        if (true) {
            return (Dimension) o;
        }
        if (o instanceof Member) {
            return ((Member) o).getDimension();
        } else if (o instanceof Level) {
            return ((Level) o).getDimension();
        } else if (o instanceof Hierarchy) {
            return ((Hierarchy) o).getDimension();
        } else if (o instanceof Dimension) {
            return (Dimension) o;
        } else {
            throw newInternal("expecting a dimension, got " + o);
        }
    }

    /**
     * Throws an error if the expressions don't have the same hierarchy.
     * @param left
     * @param right
     * @throws MondrianEvaluationException if expressions don't have the same
     *     hierarchy
     */
    static void checkCompatible(Exp left, Exp right, FunDef funDef) {
        final Type leftType = TypeUtil.stripSetType(left.getTypeX());
        final Type rightType = TypeUtil.stripSetType(right.getTypeX());
        if (!TypeUtil.isUnionCompatible(leftType, rightType)) {
            throw newEvalException(funDef, "Expressions must have the same hierarchy");
        }
    }

    /**
     * Returns <code>true</code> if the mask in <code>flag</code> is set.
     * @param value The value to check.
     * @param mask The mask within value to look for.
     * @param strict If <code>true</code> all the bits in mask must be set. If
     * <code>false</code> the method will return <code>true</code> if any of the
     * bits in <code>mask</code> are set.
     * @return <code>true</code> if the correct bits in <code>mask</code> are set.
     */
    static boolean checkFlag(int value, int mask, boolean strict) {
        return (strict)
            ? ((value & mask) == mask)
            : ((value & mask) != 0);
    }

    /**
     * Adds every element of <code>right</code> which is not in <code>set</code>
     * to both <code>set</code> and <code>left</code>.
     **/
    static void addUnique(List left, List right, Set set) {
        if (right == null) {
            return;
        }
        for (int i = 0, n = right.size(); i < n; i++) {
            Object o = right.get(i),
                    p = o;
            if (o instanceof Object[]) {
                p = new ArrayHolder((Object[]) o);
            }
            if (set.add(p)) {
                left.add(o);
            }
        }
    }

    static List addMembers(
            SchemaReader schemaReader,
            List members,
            Hierarchy hierarchy) {
        // only add accessible levels
        Level[] levels = schemaReader.getHierarchyLevels(hierarchy);
        for (int i = 0; i < levels.length; i++) {
            addMembers(schemaReader, members, levels[i]);
        }
        return members;
    }

    static List addMembers(
            SchemaReader schemaReader,
            List members,
            Level level) {
        Member[] levelMembers = schemaReader.getLevelMembers(level);
        addAll(members, levelMembers);
        return members;
    }

    /**
     * Removes every member from a list which is calculated.
     * The list must not be null, and must consist only of members.
     */
    static void removeCalculatedMembers(List memberList)
    {
        for (int i = 0; i < memberList.size(); i++) {
            Member member = (Member) memberList.get(i);
            if (member.isCalculated()) {
                memberList.remove(i);
                --i;
            }
        }
    }

    /**
     * Returns whether <code>m0</code> is an ancestor of <code>m1</code>.
     *
     * @param strict if true, a member is not an ancestor of itself
     **/
    static boolean isAncestorOf(Member m0, Member m1, boolean strict) {
        if (strict) {
            if (m1 == null) {
                return false;
            }
            m1 = m1.getParentMember();
        }
        while (m1 != null) {
            if (m1 == m0) {
                return true;
            }
            m1 = m1.getParentMember();
        }
        return false;
    }

    /**
     * @pre exp != null
     */
    static Map evaluateMembers(Evaluator evaluator,
                               ExpBase exp,
                               List members,
                               boolean parentsToo) {
        Member[] constantTuple = exp.isConstantTuple();
        return (constantTuple == null)
            ? _evaluateMembers(evaluator.push(), exp, members, parentsToo)
            // exp is constant -- add it to the context before the loop, rather
            // than at every step
            : evaluateMembers(evaluator.push(constantTuple),
                members, parentsToo);
    }

    private static Map _evaluateMembers(Evaluator evaluator,
                                        ExpBase exp,
                                        List members,
                                        boolean parentsToo) {
        Map mapMemberToValue = new HashMap();
        for (int i = 0, count = members.size(); i < count; i++) {
            Member member = (Member) members.get(i);
            while (true) {
                evaluator.setContext(member);
                Object result = exp.evaluateScalar(evaluator);
                mapMemberToValue.put(member, result);
                if (!parentsToo) {
                    break;
                }
                member = member.getParentMember();
                if (member == null) {
                    break;
                }
                if (mapMemberToValue.containsKey(member)) {
                    break;
                }
            }
        }
        return mapMemberToValue;
    }

    static Map evaluateMembers(Evaluator evaluator,
                               List members,
                               boolean parentsToo) {
        Map mapMemberToValue = new HashMap();
        for (int i = 0, count = members.size(); i < count; i++) {
            Member member = (Member) members.get(i);
            while (true) {
                evaluator.setContext(member);
                Object result = evaluator.evaluateCurrent();
                mapMemberToValue.put(member, result);
                if (!parentsToo) {
                    break;
                }
                member = member.getParentMember();
                if (member == null) {
                    break;
                }
                if (mapMemberToValue.containsKey(member)) {
                    break;
                }
            }
        }
        return mapMemberToValue;
    }

    /**
     * Helper function to sort a list of members according to an expression.
     *
     * <p>NOTE: This function does not preserve the contents of the validator.
     */
    static void sort(
            Evaluator evaluator,
            List members,
            ExpBase exp,
            boolean desc,
            boolean brk) {
        if (members.isEmpty()) {
            return;
        }
        Object first = members.get(0);
        Comparator comparator;
        Map mapMemberToValue = null;
        if (first instanceof Member) {
            final boolean parentsToo = !brk;
            mapMemberToValue = evaluateMembers(evaluator, exp, members, parentsToo);
            if (brk) {
                comparator = new BreakMemberComparator(mapMemberToValue, desc);
            } else {
                comparator = new HierarchicalMemberComparator(mapMemberToValue, desc);
            }
        } else {
            Util.assertTrue(first instanceof Member[]);
            final int arity = ((Member[]) first).length;
            if (brk) {
                comparator = new BreakArrayComparator(evaluator, exp, arity);
                if (desc) {
                    comparator = new ReverseComparator(comparator);
                }
            } else {
                comparator = new HierarchicalArrayComparator(evaluator, exp, arity, desc);
            }
        }
        Collections.sort(members, comparator);
        if (debug) {
            final PrintWriter pw = new PrintWriter(System.out);
            for (int i = 0; i < members.size(); i++) {
                Object o = members.get(i);
                pw.print(i);
                pw.print(": ");
                if (mapMemberToValue != null) {
                    pw.print(mapMemberToValue.get(o));
                    pw.print(": ");
                }
                pw.println(o);
            }
            pw.flush();
        }
    }

    static void hierarchize(List members, boolean post) {
        if (members.isEmpty()) {
            return;
        }
        Object first = members.get(0);
        Comparator comparator;
        if (first instanceof Member) {
            comparator = new HierarchizeComparator(post);
        } else {
            Util.assertTrue(first instanceof Member[]);
            final int arity = ((Member[]) first).length;
            comparator = new HierarchizeArrayComparator(arity, post);
        }
        Collections.sort(members, comparator);
    }

    static int sign(double d) {
        return (d == 0)
            ? 0
            : (d < 0)
                ? -1
                : 1;
    }

    static int compareValues(double d1, double d2) {
        return (d1 == d2)
            ? 0
            : (d1 < d2)
                ? -1
                : 1;
    }

    static int compareValues(int i, int j) {
        return (i == j)
            ? 0
            : (i < j)
                ? -1
                : 1;
    }

    /**
     * Compares two cell values.
     *
     * <p>Nulls compare last, exceptions (including the
     * object which indicates the the cell is not in the cache yet) next,
     * then numbers and strings are compared by value.
     *
     * @param value0 First cell value
     * @param value1 Second cell value
     * @return -1, 0, or 1, depending upon whether first cell value is less
     *   than, equal to, or greater than the second
     */
    static int compareValues(Object value0, Object value1) {
        if (value0 == value1) {
            return 0;
        }
        // null is less than anything else
        if (value0 == null) {
            return -1;
        }
        if (value1 == null) {
            return 1;
        }
        if (value0 instanceof RuntimeException ||
            value1 instanceof RuntimeException) {
            // one of the values is not in cache; continue as best as we can
            return 0;
        } else if (value0 == Util.nullValue) {
            return -1; // null == -infinity
        } else if (value1 == Util.nullValue) {
            return 1; // null == -infinity
        } else if (value0 instanceof String) {
            return ((String) value0).compareTo((String) value1);
        } else if (value0 instanceof Number) {
            return FunUtil.compareValues(
                    ((Number) value0).doubleValue(),
                    ((Number) value1).doubleValue());
        } else {
            throw Util.newInternal("cannot compare " + value0);
        }
    }

    /**
     * Turns the mapped values into relative values (percentages) for easy
     * use by the general topOrBottom function. This might also be a useful
     * function in itself.
     */
    static void toPercent(List members, Map mapMemberToValue) {
        double total = 0;
        int numMembers = members.size();
        for (int i = 0; i < numMembers; i++) {
            Object o = mapMemberToValue.get(members.get(i));
            if (o instanceof Number) {
                total += ((Number) o).doubleValue();
            }
        }
        for (int i = 0; i < numMembers; i++) {
            Object member = members.get(i);
            Object o = mapMemberToValue.get(member);
            if (o instanceof Number) {
                double d = ((Number) o).doubleValue();
                mapMemberToValue.put(
                    member,
                    new Double(d / total * (double) 100));
            }

⌨️ 快捷键说明

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