query.java

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

JAVA
1,168
字号
        }

        public Exp validate(Exp exp, boolean scalar) {
            Exp resolved = (Exp) resolvedNodes.get(exp);
            if (resolved != null) {
                // Expression has already been resolved.
                return scalar ? convertToScalar(resolved) : resolved;
            }
            stack.push(exp);
            try {
                // Put in a placeholder while we're resolving to prevent
                // recursion.
                resolvedNodes.put(exp, placeHolder);
                resolved = exp.accept(this);
                if (scalar) {
                    resolved = convertToScalar(resolved);
                }
                resolvedNodes.put(exp, resolved);
                return resolved;
            } finally {
                stack.pop();
            }
        }

        private Exp convertToScalar(Exp exp) {
            return funTable.createValueFunCall(exp, this);
        }

        public Parameter validate(Parameter parameter) {
            Parameter resolved = (Parameter) resolvedNodes.get(parameter);
            if (resolved != null) {
                return parameter; // already resolved
            }
            stack.push(parameter);
            try {
                resolvedNodes.put(parameter, placeHolder);
                resolved = (Parameter) parameter.accept(this);
                resolvedNodes.put(parameter, resolved);
                return resolved;
            } finally {
                stack.pop();
            }
        }

        public void validate(MemberProperty memberProperty) {
            if (resolvedNodes.put(memberProperty, placeHolder) != null) {
                return; // already resolved
            }
            stack.push(memberProperty);
            try {
                memberProperty.resolve(this);
            } finally {
                stack.pop();
            }
        }

        public void validate(QueryAxis axis) {
            if (resolvedNodes.put(axis, placeHolder) != null) {
                return; // already resolved
            }
            stack.push(axis);
            try {
                axis.resolve(this);
            } finally {
                stack.pop();
            }
        }

        public void validate(Formula formula) {
            if (resolvedNodes.put(formula, placeHolder) != null) {
                return; // already resolved
            }
            stack.push(formula);
            try {
                formula.accept(this);
            } finally {
                stack.pop();
            }
        }

        public boolean canConvert(Exp fromExp, int to, int[] conversionCount) {
            return FunUtil.canConvert(fromExp, to, conversionCount);
        }

        public Exp convert(Exp fromExp, int to) {
            return FunUtil.convert(fromExp, to, this);
        }

        public boolean requiresExpression() {
            return requiresExpression(stack.size() - 1);
        }

        private boolean requiresExpression(int n) {
            if (n < 1) {
                return false;
            }
            final Object parent = stack.get(n - 1);
            if (parent instanceof Formula) {
                return ((Formula) parent).isMember();
            } else if (parent instanceof FunCall) {
                final FunCall funCall = (FunCall) parent;
                if (funCall.isCallToTuple()) {
                    return requiresExpression(n - 1);
                } else {
                    int k = whichArg(funCall, stack.get(n));
                    if (k < 0) {
                        // Arguments of call have mutated since call was placed
                        // on stack. Presumably the call has already been
                        // resolved correctly, so the answer we give here is
                        // irrelevant.
                        return false;
                    }
                    return funTable.requiresExpression(funCall, k, this);
                }
            } else {
                return false;
            }
        }

        public FunTable getFunTable() {
            return funTable;
        }

        public Parameter createOrLookupParam(FunCall funCall) {
            Util.assertTrue(funCall.getArg(0) instanceof Literal,
                "The name of parameter must be a quoted string");
            String name = (String) ((Literal) funCall.getArg(0)).getValue();
            Parameter param = lookupParam(name);
            ParameterFunDef funDef = (ParameterFunDef) funCall.getFunDef();
            if (funDef.getName().equals("Parameter")) {
                if (param != null) {
                    if (param.getDefineCount() > 0) {
                        throw Util.newInternal("Parameter '" + name +
                                "' is defined more than once");
                    } else {
                        param.incrementDefineCount();
                        return param;
                    }
                }
                final Exp arg1 = funCall.getArg(1);
                final Type type;
                final int category = funCall.getCategory();
                switch (category) {
                case Category.Member:
                    Dimension dimension = (Dimension) arg1;
                    type = new MemberType(dimension.getHierarchy(), null, null);
                    break;
                case Category.String:
                    type = new StringType();
                    break;
                case Category.Numeric:
                    type = new NumericType();
                    break;
                case Category.Integer:
                    type = new DecimalType(Integer.MAX_VALUE, 0);
                    break;
                default:
                    throw Category.instance.badValue(category);
                }
                param = new Parameter(
                        funDef.parameterName, category,
                        funDef.exp, funDef.parameterDescription, type);

                // Append it to the array of known parameters.
                Parameter[] old = parameters;
                final int count = old.length;
                parameters = new Parameter[count + 1];
                System.arraycopy(old, 0, parameters, 0, count);
                parameters[count] = param;
                return param;
            } else {
                if (param != null) {
                    return param;
                }
                // We're looking at a ParamRef("p"), and its defining
                // Parameter("p") hasn't been seen yet. Just this once, walk
                // over the entire query finding parameter definitions.
                if (!haveCollectedParameters) {
                    haveCollectedParameters = true;
                    collectParameters();
                    param = lookupParam(name);
                    if (param != null) {
                        return param;
                    }
                }
                throw Util.newInternal("Parameter '" + name +
                        "' is referenced but never defined");
            }
        }

        private void collectParameters() {
            final Walker walker = new Walker(Query.this);
            while (walker.hasMoreElements()) {
                final Object o = walker.nextElement();
                if (o instanceof Parameter) {
                    // Parameter has already been resolved.
                    ;
                } else if (o instanceof FunCall) {
                    final FunCall call = (FunCall) o;
                    if (call.getFunName().equalsIgnoreCase("Parameter")) {
                        // Parameter definition which has not been resolved
                        // yet. Resolve it and add it to the list of parameters.
                        // Because we're resolving out out of the proper order,
                        // the resolver doesn't hold the correct ancestral
                        // context, but it should be OK.
                        final Parameter param = (Parameter) validate(call, false);
                        param.resetDefineCount();
                    }
                }
            }
        }

        /*
        private void replace(QueryPart oldChild, QueryPart newChild) {
            QueryPart parent = (QueryPart) stack.get(stack.size() - 2);
            int childIndex = whichArg(parent, oldChild);
            Util.assertTrue(childIndex >= 0);
            parent.replaceChild(childIndex, newChild);
        }
*/

        private int whichArg(final Object node, final Object arg) {
            if (node instanceof Walkable) {
                final Object[] children = ((Walkable) node).getChildren();
                for (int i = 0; i < children.length; i++) {
                    if (children[i] == arg) {
                        return i;
                    }
                }
            }
            return -1;
        }
    }

    /**
     * Source of metadata within the scope of a query.
     *
     * <p>Note especially that {@link #getCalculatedMember(String[])}
     * returns the calculated members defined in this query.
     */
    private class QuerySchemaReader extends DelegatingSchemaReader {

        public QuerySchemaReader(SchemaReader cubeSchemaReader) {
            super(cubeSchemaReader);
        }

        public Member getMemberByUniqueName(
                String[] uniqueNameParts,
                boolean failIfNotFound) {
            final String uniqueName = Util.implode(uniqueNameParts);
            Member member = lookupMemberFromCache(uniqueName);
            if (member == null) {
                // Not a calculated member in the query, so go to the cube.
                member = schemaReader.getMemberByUniqueName(uniqueNameParts,
                    failIfNotFound);
            }
        	if (getRole().canAccess(member)) {
        		return member;
        	} else {
        		return null;
        	}
        }

        public Member getCalculatedMember(String[] nameParts) {
            final String uniqueName = Util.implode(nameParts);
            return lookupMemberFromCache(uniqueName);
        }

        public List getCalculatedMembers(Hierarchy hierarchy) {
            List definedMembers = getDefinedMembers();
            List result = new ArrayList();
            for (int i = 0; i < definedMembers.size(); i++) {
                Member member = (Member) definedMembers.get(i);
                if (member.getHierarchy().equals(hierarchy)) {
                    result.add(member);
                }
            }
            return result;
        }

        public List getCalculatedMembers(Level level) {
            List hierachyMembers = getCalculatedMembers(level.getHierarchy());
            List result = new ArrayList();
            for (int i = 0; i < hierachyMembers.size(); i++) {
                Member member = (Member) hierachyMembers.get(i);
                if (member.getLevel().equals(level)) {
                    result.add(member);
                }
            }
            return result;
        }

        public List getCalculatedMembers() {
            return getDefinedMembers();
        }
        
        public OlapElement getElementChild(OlapElement parent, String s) {
            // first look in cube
            OlapElement mdxElement = schemaReader.getElementChild(parent, s);
            if (mdxElement != null) {
                return mdxElement;
            }
            // then look in defined members (removed sf#1084651)

            // then in defined sets
            for (int i = 0; i < formulas.length; i++) {
                Formula formula = formulas[i];
                if (formula.isMember()) {
                    continue;       // have already done these
                }
                if (Util.equals(formula.getNames()[0], s)) {
                    return formula.getNamedSet();
                }
            }

            return mdxElement;
        }

        public OlapElement lookupCompound(
                OlapElement parent,
                String[] names,
                boolean failIfNotFound,
                int category) {
            // First look to ourselves.
            switch (category) {
            case Category.Unknown:
            case Category.Member:
                if (parent == cube) {
                    final Member calculatedMember = getCalculatedMember(names);
                    if (calculatedMember != null) {
                        return calculatedMember;
                    }
                }
            }
            switch (category) {
            case Category.Unknown:
            case Category.Set:
                if (parent == cube) {
                    final NamedSet namedSet = getNamedSet(names);
                    if (namedSet != null) {
                        return namedSet;
                    }
                }
            }
            // Then delegate to the next reader.
            OlapElement olapElement = super.lookupCompound(
                    parent, names, failIfNotFound, category);
            if (olapElement instanceof Member) {
                Member member = (Member) olapElement;
                final Formula formula = (Formula)
                    member.getPropertyValue(Property.FORMULA.name);
                if (formula != null) {
                    // This is a calculated member defined against the cube.
                    // Create a free-standing formula using the same
                    // expression, then use the member defined in that formula.
                    final Formula formulaClone = (Formula) formula.clone();
                    formulaClone.createElement(Query.this);
                    formulaClone.accept(createValidator());
                    olapElement = formulaClone.getMdxMember();
                }
            }
            return olapElement;
        }

        public NamedSet getNamedSet(String[] nameParts) {
            if (nameParts.length != 1) {
                return null;
            }
            return lookupNamedSet(nameParts[0]);
        }
    }

    /**
     * PrintWriter used for unparsing queries. Remembers which parameters have
     * been printed. The first time, they print themselves as "Parameter";
     * subsequent times as "ParamRef".
     */
    static class QueryPrintWriter extends PrintWriter {
        final HashSet parameters = new HashSet();

        QueryPrintWriter(Writer writer) {
            super(writer);
        }
    }
}

// End Query.java

⌨️ 快捷键说明

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