rolapcube.java

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

JAVA
1,687
字号
     */
    private void createCalcMembersAndNamedSets(
            MondrianDef.CalculatedMember[] xmlCalcMembers,
            MondrianDef.NamedSet[] xmlNamedSets,
            List memberList,
            List formulaList) {
        // If there are no objects to create, our generated SQL will so silly
        // the parser will laugh.
        if (xmlCalcMembers.length == 0 &&
                xmlNamedSets.length == 0) {
            return;
        }

        StringBuffer buf = new StringBuffer(256);
        buf.append("WITH").append(Util.nl);

        // Check the members individually, and generate SQL.
        for (int i = 0; i < xmlCalcMembers.length; i++) {
            preCalcMember(xmlCalcMembers, i, buf);
        }

        // Check the named sets individually (for uniqueness) and generate SQL.
        Set nameSet = new HashSet();
        for (int i = 0; i < namedSets.length; i++) {
            Formula namedSet = namedSets[i];
            nameSet.add(namedSet.getName());
        }
        for (int i = 0; i < xmlNamedSets.length; i++) {
            preNamedSet(xmlNamedSets[i], nameSet, buf);
        }

        buf.append("SELECT FROM ")
            .append(Util.quoteMdxIdentifier(getUniqueName()));

        // Parse and validate this huge MDX query we've created.
        final String queryString = buf.toString();
        final Query queryExp;
        try {
            RolapConnection conn = schema.getInternalConnection();
            queryExp = conn.parseQuery(queryString);
        } catch (Exception e) {
            throw MondrianResource.instance().UnknownNamedSetHasBadFormula.ex(
                getUniqueName(), e);
        }
        queryExp.resolve();

        // Now pick through the formulas.
        Util.assertTrue(queryExp.formulas.length ==
                xmlCalcMembers.length + xmlNamedSets.length);
        for (int i = 0; i < xmlCalcMembers.length; i++) {
            postCalcMember(xmlCalcMembers, i, queryExp, memberList);
        }
        for (int i = 0; i < xmlNamedSets.length; i++) {
            postNamedSet(xmlNamedSets, xmlCalcMembers.length, i, queryExp, formulaList);
        }
    }

    private void postNamedSet(
            MondrianDef.NamedSet[] xmlNamedSets,
            final int offset, int i,
            final Query queryExp,
            List formulaList) {
        MondrianDef.NamedSet xmlNamedSet = xmlNamedSets[i];
        Util.discard(xmlNamedSet);
        Formula formula = queryExp.formulas[offset + i];
        namedSets = (Formula[]) RolapUtil.addElement(namedSets, formula);
        formulaList.add(formula);
    }

    private void preNamedSet(
            MondrianDef.NamedSet xmlNamedSet,
            Set nameSet,
            StringBuffer buf) {
        if (!nameSet.add(xmlNamedSet.name)) {
            throw MondrianResource.instance().NamedSetNotUnique.ex(
                    xmlNamedSet.name, getUniqueName());
        }

        buf.append("SET ")
                .append(Util.makeFqName(xmlNamedSet.name))
                .append(Util.nl)
                .append(" AS '")
                .append(xmlNamedSet.getFormula())
                .append("'")
                .append(Util.nl);
    }

    private void postCalcMember(
            MondrianDef.CalculatedMember[] xmlCalcMembers,
            int i,
            final Query queryExp,
            List memberList) {
        MondrianDef.CalculatedMember xmlCalcMember = xmlCalcMembers[i];
        final Formula formula = queryExp.formulas[i];

        calculatedMembers = (Formula[])
                RolapUtil.addElement(calculatedMembers, formula);

        Member member = formula.getMdxMember();

        Boolean visible = xmlCalcMember.visible;
        if (visible == null) {
            visible = Boolean.TRUE;
        }
        member.setProperty(Property.VISIBLE.name, visible);

        if ((xmlCalcMember.caption != null) &&
                xmlCalcMember.caption.length() > 0) {
            member.setProperty(
                    Property.CAPTION.name,
                    xmlCalcMember.caption);
        }

        memberList.add(formula.getMdxMember());
    }

    private void preCalcMember(
            MondrianDef.CalculatedMember[] xmlCalcMembers,
            int j,
            StringBuffer buf) {
        MondrianDef.CalculatedMember xmlCalcMember = xmlCalcMembers[j];

        // Lookup dimension
        final Dimension dimension =
                (Dimension) lookupDimension(xmlCalcMember.dimension);
        if (dimension == null) {
            throw MondrianResource.instance().CalcMemberHasBadDimension.ex(
                    xmlCalcMember.dimension, xmlCalcMember.name,
                    getUniqueName());
        }

        // Check there isn't another calc member with the same name and
        // dimension.
        for (int i = 0; i < calculatedMembers.length; i++) {
            Formula formula = calculatedMembers[i];
            if (formula.getName().equals(xmlCalcMember.name) &&
                    formula.getMdxMember().getDimension().getName() ==
                    dimension.getName()) {

                throw MondrianResource.instance().CalcMemberNotUnique.ex(
                        Util.makeFqName(dimension, xmlCalcMember.name),
                        getUniqueName());
            }
        }

        // Check this calc member doesn't clash with one earlier in this
        // batch.
        for (int k = 0; k < j; k++) {
            MondrianDef.CalculatedMember xmlCalcMember2 = xmlCalcMembers[k];
            if (xmlCalcMember2.name.equals(xmlCalcMember.name) &&
                    xmlCalcMember2.dimension.equals(xmlCalcMember.dimension)) {
                throw MondrianResource.instance().CalcMemberNotUnique.ex(
                        Util.makeFqName(dimension, xmlCalcMember.name),
                        getUniqueName());
            }
        }

        final String memberUniqueName = Util.makeFqName(
                dimension.getUniqueName(), xmlCalcMember.name);
        final MondrianDef.CalculatedMemberProperty[] xmlProperties =
                xmlCalcMember.memberProperties;
        List propNames = new ArrayList();
        List propExprs = new ArrayList();
        validateMemberProps(xmlProperties, propNames, propExprs,
                xmlCalcMember.name);

        // Generate SQL.
        assert memberUniqueName.startsWith("[");
        buf.append("MEMBER ").append(memberUniqueName)
                .append(Util.nl)
                .append("  AS ").append(xmlCalcMember.getFormula());

        assert propNames.size() == propExprs.size();

        for (int i = 0; i < propNames.size(); i++) {
            String name = (String) propNames.get(i);
            String expr = (String) propExprs.get(i);
            buf.append(",").append(Util.nl)
                    .append(name).append(" = ").append(expr);
        }
        buf.append(Util.nl);
    }

    /**
     * Validates an array of member properties, and populates a list of names
     * and expressions, one for each property.
     *
     * @param xmlProperties Array of property definitions.
     * @param propNames Output array of property names.
     * @param propExprs Output array of property expressions.
     * @param memberName Name of member which the properties belong to.
     */
    private void validateMemberProps(
            final MondrianDef.CalculatedMemberProperty[] xmlProperties,
            List propNames,
            List propExprs,
            String memberName) {

        MemberProperty[] properties = new MemberProperty[xmlProperties.length];
        for (int i = 0; i < properties.length; i++) {
            final MondrianDef.CalculatedMemberProperty xmlProperty =
                    xmlProperties[i];
            if (xmlProperty.expression == null &&
                xmlProperty.value == null) {

                throw MondrianResource.instance()
                    .NeitherExprNorValueForCalcMemberProperty.ex(
                        xmlProperty.name,
                        memberName,
                        getUniqueName());
            }
            if (xmlProperty.expression != null &&
                xmlProperty.value != null) {

                throw MondrianResource.instance()
                    .ExprAndValueForMemberProperty.ex(
                        xmlProperty.name,
                        memberName,
                        getUniqueName());
            }
            propNames.add(xmlProperty.name);
            if (xmlProperty.expression != null) {
                propExprs.add(xmlProperty.expression);
            } else {
                propExprs.add(Util.quoteForMdx(xmlProperty.value));
            }
        }
    }


    public Schema getSchema() {
        return schema;
    }

    /**
     * Returns the schema reader which enforces the appropriate access-control
     * context.
     *
     * @post return != null
     * @see #getSchemaReader(Role)
     */
    public synchronized SchemaReader getSchemaReader() {
        if (schemaReader == null) {
            schemaReader = getSchemaReader(null);
        }
        return schemaReader;
    }

    public SchemaReader getSchemaReader(Role role) {
        if (role == null) {
            role = schema.getDefaultRole().makeMutableClone();
            role.grant(this, Access.ALL);
        }
        return new RolapCubeSchemaReader(role);
    }

    MondrianDef.CubeDimension lookup(
            MondrianDef.CubeDimension[] xmlDimensions,
            String name) {
        for (int i = 0; i < xmlDimensions.length; i++) {
            MondrianDef.CubeDimension cd = xmlDimensions[i];
            if (name.equals(cd.name)) {
                return cd;
            }
        }
        // TODO: this ought to be a fatal error.
        return null;
    }

    private void init(MondrianDef.CubeDimension[] xmlDimensions) {
        int max = -1;
        for (int i = 0; i < dimensions.length; i++) {
            final RolapDimension dimension = (RolapDimension) dimensions[i];
            dimension.init(this, lookup(xmlDimensions, dimension.getName()));
            max = Math.max(max, dimension.getGlobalOrdinal());
        }
        this.localDimensionOrdinals = new int[max + 1];
        Arrays.fill(localDimensionOrdinals, -1);
        for (int i = 0; i < dimensions.length; i++) {
            final RolapDimension dimension = (RolapDimension) dimensions[i];
            final int globalOrdinal = dimension.getGlobalOrdinal();
/*
When the same Dimension is in two or more DimensionUsages, then this
assert is not true.
            Util.assertTrue(
                    localDimensionOrdinals[globalOrdinal] == -1,
                    "duplicate dimension globalOrdinal " + globalOrdinal);
*/
            localDimensionOrdinals[globalOrdinal] = i;
        }
        register();
    }

    private void register() {
        if (isVirtual()) {
            return;
        }
        List list = new ArrayList();
        Member[] measures = getMeasures();
        for (int i = 0; i < measures.length; i++) {
            if (measures[i] instanceof RolapStoredMeasure) {
                list.add(measures[i]);
            }
        }
        RolapStoredMeasure[] storedMeasures = (RolapStoredMeasure[])
                list.toArray(new RolapStoredMeasure[list.size()]);

        RolapStar star = getStar();
        RolapStar.Table table = star.getFactTable();

        // create measures (and stars for them, if necessary)
        for (int i = 0; i < storedMeasures.length; i++) {
            RolapStoredMeasure storedMeasure = storedMeasures[i];
            table.makeMeasure(storedMeasure);
        }

        // create dimension tables
        Dimension[] dimensions = this.getDimensions();
        for (int j = 0; j < dimensions.length; j++) {
            registerDimension(dimensions[j]);
        }
    }

    int getOrdinal(int globalOrdinal) {
        return this.localDimensionOrdinals[globalOrdinal];
    }

    CellReader getCellReader() {
        return this.cellReader;
    }

    public boolean isCache() {
        return (isVirtual()) ? true : star.isCacheAggregations();
    }

    public void setCache(boolean cache) {
        if (! isVirtual()) {
            star.setCacheAggregations(cache);

⌨️ 快捷键说明

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