query.java

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

JAVA
1,168
字号
        if (slicer == null) {
            ;
        } else if (slicer instanceof FunCall &&
                   ((FunCall) slicer).isCallToTuple()) {
            ;
        } else {
            slicer = new FunCall(
                "()", Syntax.Parentheses, new Exp[] {slicer});
        }
    }

    public Exp getSlicer() {
        return slicer;
    }

    /** Returns an enumeration, each item of which is an Ob containing a
     * dimension which does not appear in any Axis or in the slicer. */
    public Iterator unusedDimensions() {
        Dimension[] mdxDimensions = cube.getDimensions();
        return Arrays.asList(mdxDimensions).iterator();
    }

    /**
     * Adds a level to an axis expression.
     *
     * @pre AxisOrdinal.enumeration.isValid(axis)
     * @pre axis < axes.length
     */
    public void addLevelToAxis(int axis, Level level) {
        Util.assertPrecondition(AxisOrdinal.enumeration.isValid(axis),
                "AxisOrdinal.enumeration.isValid(axis)");
        Util.assertPrecondition(axis < axes.length, "axis < axes.length");
        axes[axis].addLevel(level);
    }

    /**
     * Returns the hierarchies in an expression.
     */
    private Hierarchy[] collectHierarchies(Exp queryPart) {
        Type type = queryPart.getTypeX();
        if (type instanceof SetType) {
            type = ((SetType) type).getElementType();
        }
        if (type instanceof TupleType) {
            final Type[] types = ((TupleType) type).elementTypes;
            ArrayList hierarchyList = new ArrayList();
            for (int i = 0; i < types.length; i++) {
                final Hierarchy hierarchy = types[i].getHierarchy();
                hierarchyList.add(hierarchy);
            }
            return (Hierarchy[])
                    hierarchyList.toArray(new Hierarchy[hierarchyList.size()]);
        }
        return new Hierarchy[] {type.getHierarchy()};
    }

    /**
     * Assigns a value to the parameter with a given name.
     *
     * @throws RuntimeException if there is not parameter with the given name
     */
    public void setParameter(String parameterName, String value) {
        Parameter param = lookupParam(parameterName);
        if (param == null) {
            throw MondrianResource.instance().MdxParamNotFound.ex(parameterName);
        }
        final Exp exp = param.quickParse(value, this);
        param.setValue(exp);
    }

    /**
     * Swaps the x- and y- axes.
     * Does nothing if the number of axes != 2.
     */
    public void swapAxes() {
        if (axes.length == 2) {
            Exp e0 = axes[0].set;
            boolean nonEmpty0 = axes[0].nonEmpty;
            Exp e1 = axes[1].set;
            boolean nonEmpty1 = axes[1].nonEmpty;
            axes[1].set = e0;
            axes[1].nonEmpty = nonEmpty0;
            axes[0].set = e1;
            axes[0].nonEmpty = nonEmpty1;
            // showSubtotals ???
        }
    }

    /**
     * Returns a parameter with a given name, or <code>null</code> if there is
     * no such parameter.
     */
    public Parameter lookupParam(String parameterName) {
        for (int i = 0; i < parameters.length; i++) {
            if (parameters[i].getName().equals(parameterName)) {
                return parameters[i];
            }
        }
        return null;
    }

    /**
     * Validates each parameter, calculates their usage, and removes unused
     * parameters.
     * @return the array of parameter usage counts
     */
    private int[] resolveParameters() {
        //validate definitions
        for (int i = 0; i < parameters.length; i++) {
            parameters[i].validate(this);
        }
        int[] usageCount = new int[parameters.length];
        Walker queryElements = new Walker(this);
        while (queryElements.hasMoreElements()) {
            Object queryElement = queryElements.nextElement();
            if (queryElement instanceof Parameter) {
                boolean found = false;
                for (int i = 0; i < parameters.length; i++) {
                    if (parameters[i].equals(queryElement)) {
                        usageCount[i]++;
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    throw MondrianResource.instance().MdxParamNotFound.ex(
                        ((Parameter) queryElement).getName());
                }
            }
        }
        return usageCount;
    }

    /**
     * Returns the parameters used in this query.
     **/
    public Parameter[] getParameters() {
        int[] usageCount = resolveParameters();
        // count the parameters which are currently used
        int nUsed = 0;
        for (int i = 0; i < usageCount.length; i++) {
            if (usageCount[i] > 0) {
              nUsed++;
            }
        }
        Parameter[] usedParameters = new Parameter[nUsed];
        nUsed = 0;
            for (int i = 0; i < parameters.length; i++) {
                if (usageCount[i] > 0) {
                usedParameters[nUsed++] = parameters[i];
                }
        }
        return usedParameters;
    }

    public Cube getCube() {
        return cube;
    }

    public SchemaReader getSchemaReader(boolean accessControlled) {
        final Role role = accessControlled
            ? getConnection().getRole()
            : null;
        final SchemaReader cubeSchemaReader = cube.getSchemaReader(role);
        return new QuerySchemaReader(cubeSchemaReader);
    }

    /**
     * Looks up a member whose unique name is <code>s</code> from cache.
     * If the member is not in cache, returns null.
     **/
    public Member lookupMemberFromCache(String s) {
        // first look in defined members
        Iterator definedMembers = getDefinedMembers().iterator();
        while (definedMembers.hasNext()) {
            Member mdxMember = (Member) definedMembers.next();
            if (Util.equals(mdxMember.getUniqueName(), s)) {
                return mdxMember;
            }
        }
        return null;
    }

    /**
     * Looks up a named set.
     */
    private NamedSet lookupNamedSet(String name) {
        for (int i = 0; i < formulas.length; i++) {
            Formula formula = formulas[i];
            if (!formula.isMember() &&
                    formula.getElement() != null &&
                    formula.getName().equals(name)) {
                return (NamedSet) formula.getElement();
            }
        }
        return null;
    }

    /**
     * Returns an array of the formulas used in this query.
     */
    public Formula[] getFormulas() {
        return formulas;
    }

    /**
     * Returns an array of this query's axes.
     */
    public QueryAxis[] getAxes() {
        return axes;
    }

    /**
     * Remove a formula from the query. If <code>failIfUsedInQuery</code> is
     * true, checks and throws an error if formula is used somewhere in the
     * query.
     */
    public void removeFormula(String uniqueName, boolean failIfUsedInQuery) {
        Formula formula = findFormula(uniqueName);
        if (failIfUsedInQuery && formula != null) {
            OlapElement mdxElement = formula.getElement();
            //search the query tree to see if this formula expression is used
            //anywhere (on the axes or in another formula)
            Walker walker = new Walker(this);
            while (walker.hasMoreElements()) {
                Object queryElement = walker.nextElement();
                if (!queryElement.equals(mdxElement)) {
                    continue;
                }
                // mdxElement is used in the query. lets find on on which axis
                // or formula
                String formulaType = formula.isMember()
                    ? MondrianResource.instance().CalculatedMember.str()
                    : MondrianResource.instance().CalculatedSet.str();

                int i = 0;
                Object parent = walker.getAncestor(i);
                Object grandParent = walker.getAncestor(i+1);
                while ((parent != null) && (grandParent != null)) {
                    if (grandParent instanceof Query) {
                        if (parent instanceof Axis) {
                            throw MondrianResource.instance().MdxCalculatedFormulaUsedOnAxis.ex(
                                formulaType,
                                uniqueName,
                                ((QueryAxis) parent).getAxisName());

                        } else if (parent instanceof Formula) {
                            String parentFormulaType =
                                ((Formula) parent).isMember()
                                    ? MondrianResource.instance().CalculatedMember.str()
                                    : MondrianResource.instance().CalculatedSet.str();
                            throw MondrianResource.instance().MdxCalculatedFormulaUsedInFormula.ex(
                                formulaType, uniqueName, parentFormulaType,
                                ((Formula) parent).getUniqueName());

                        } else {
                            throw MondrianResource.instance().MdxCalculatedFormulaUsedOnSlicer.ex(
                                formulaType, uniqueName);
                        }
                    }
                    ++i;
                    parent = walker.getAncestor(i);
                    grandParent = walker.getAncestor(i+1);
                }
                throw MondrianResource.instance().MdxCalculatedFormulaUsedInQuery.ex(
                    formulaType, uniqueName, this.toMdx());
            }
        }

        // remove formula from query
        List formulaList = new ArrayList();
        for (int i = 0; i < formulas.length; i++) {
            if (!formulas[i].getUniqueName().equalsIgnoreCase(uniqueName)) {
                formulaList.add(formulas[i]);
            }
        }

        // it has been found and removed
        this.formulas = (Formula[]) formulaList.toArray(new Formula[0]);
    }

    /**
     * Check, whether a formula can be removed from the query.
     */
    public boolean canRemoveFormula(String uniqueName) {
        Formula formula = findFormula(uniqueName);
        if (formula == null) {
            return false;
        }

        OlapElement mdxElement = formula.getElement();
        //search the query tree to see if this formula expression is used
        //anywhere (on the axes or in another formula)
        Walker walker = new Walker(this);
        while (walker.hasMoreElements()) {
            Object queryElement = walker.nextElement();
            if (!queryElement.equals(mdxElement)) {
                continue;
            }
            return false;
        }
        return true;
    }

    /** finds calculated member or set in array of formulas */
    public Formula findFormula(String uniqueName) {
        for (int i = 0; i < formulas.length; i++) {
            if (formulas[i].getUniqueName().equalsIgnoreCase(uniqueName)) {
                return formulas[i];
            }
        }
        return null;
    }

    /** finds formula by name and renames it to new name */
    public void renameFormula(String uniqueName, String newName) {
        Formula formula = findFormula(uniqueName);
        if (formula == null) {
            throw MondrianResource.instance().MdxFormulaNotFound.ex(
                "formula", uniqueName, toMdx());
        }
        formula.rename(newName);
    }

    List getDefinedMembers() {
        List definedMembers = new ArrayList();
        for (int i = 0; i < formulas.length; i++) {
            if (formulas[i].isMember() && formulas[i].getElement() != null && getConnection().getRole().canAccess(formulas[i].getElement())) {
                definedMembers.add(formulas[i].getElement());
            }
        }
        return definedMembers;
    }

    /** finds axis by index and sets flag to show empty cells on that axis*/
    public void setAxisShowEmptyCells(int axis, boolean showEmpty) {
        if (axis >= axes.length) {
            throw MondrianResource.instance().MdxAxisShowSubtotalsNotSupported.ex(
                    new Integer(axis));
        }
        axes[axis].nonEmpty = !showEmpty;
    }

    /**
     * Returns <code>Hierarchy[]</code> used on <code>axis</code>. It calls
     * {@link #collectHierarchies}.
     */
    public Hierarchy[] getMdxHierarchiesOnAxis(int axis) {
        if (axis >= axes.length) {
            throw MondrianResource.instance().MdxAxisShowSubtotalsNotSupported.ex(
                    new Integer(axis));
        }
        return collectHierarchies(
                (axis == AxisOrdinal.SlicerOrdinal) ?
                slicer :
                axes[axis].set);
    }

    /**
     * Default implementation of {@link Validator}.
     *
     * <p>Uses a stack to help us guess the type of our parent expression
     * before we've completely resolved our children -- necessary,
     * unfortunately, when figuring out whether the "*" operator denotes
     * multiplication or crossjoin.
     *
     * <p>Keeps track of which nodes have already been resolved, so we don't
     * try to resolve nodes which have already been resolved. (That would not
     * be wrong, but can cause resolution to be an <code>O(2^N)</code>
     * operation.)
     */
    private class StackValidator implements Validator {
        private final Stack stack = new Stack();
        private final FunTable funTable;
        private boolean haveCollectedParameters;
        private final Map resolvedNodes = new HashMap();
        private final Object placeHolder = "dummy";

        /**
         * Creates a StackValidator.
         *
         * @pre funTable != null
         */
        public StackValidator(FunTable funTable) {
            Util.assertPrecondition(funTable != null, "funTable != null");
            this.funTable = funTable;
        }

        public Query getQuery() {
            return Query.this;

⌨️ 快捷键说明

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