rolapstar.java

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

JAVA
1,660
字号
                    return expr + " is null";
                case 1:
                    // Special case -- one not-null value, and null, for
                    // example "(x = 1 or x is null)".
                    buf = new StringBuffer(64);
                    buf.append('(');
                    buf.append(expr);
                    buf.append(" = ");
                    quoteValue(constraints[0].getValue(), buf, isNumeric);
                    buf.append(" or ");
                    buf.append(expr);
                    buf.append(" is null)");
                    return buf.toString();
                default:
                    // Nulls and values, for example,
                    // "(x in (1, 2) or x IS NULL)".
                    buf = new StringBuffer(64);
                    buf.append('(');
                    buf.append(sb.toString());
                    buf.append(" or ");
                    buf.append(expr);
                    buf.append(" is null)");
                    return buf.toString();
                }
            } else {
                // No nulls. Return, for example, "x in (1, 2, 3)".
                return sb.toString();
            }
        }

        public String toString() {
            StringWriter sw = new StringWriter(256);
            PrintWriter pw = new PrintWriter(sw);
            print(pw, "");
            pw.flush();
            return sw.toString();
        }

        /**
         * Prints this table and its children.
         */
        public void print(PrintWriter pw, String prefix) {
            SqlQuery sqlQuery = getSqlQuery();
            pw.print(prefix);
            pw.print(getName());
            pw.print(" (");
            pw.print(getBitPosition());
            pw.print("): ");
            pw.print(getExpression(sqlQuery));
        }
    }

    /**
     * Definition of a measure in a star schema.
     *
     * <p>A measure is basically just a column; except that its
     * {@link #aggregator} defines how it is to be rolled up.
     */
    public static class Measure extends Column {
        private final RolapAggregator aggregator;

        private Measure(String name,
                        RolapAggregator aggregator,
                        Table table,
                        MondrianDef.Expression expression,
                        boolean isNumeric) {
            super(name, table, expression, isNumeric);
            this.aggregator = aggregator;
        }
        public RolapAggregator getAggregator() {
            return aggregator;
        }

        public boolean equals(Object obj) {
            if (! super.equals(obj)) {
                return false;
            }
            if (! (obj instanceof RolapStar.Measure)) {
                return false;
            }
            RolapStar.Measure other = (RolapStar.Measure) obj;
            // Note: both measure have to have the same aggregator
            return (other.aggregator == this.aggregator);
        }

        /**
         * Prints this table and its children.
         */
        public void print(PrintWriter pw, String prefix) {
            SqlQuery sqlQuery = getSqlQuery();
            pw.print(prefix);
            pw.print(getName());
            pw.print(" (");
            pw.print(getBitPosition());
            pw.print("): ");
            pw.print(aggregator.getExpression(getExpression(sqlQuery)));
        }
    }

    /**
     * Definition of a table in a star schema.
     *
     * <p>A 'table' is defined by a {@link MondrianDef.Relation} so may, in
     * fact, be a view.
     *
     * <p>Every table in the star schema except the fact table has a parent
     * table, and a condition which specifies how it is joined to its parent.
     * So the star schema is, in effect, a hierarchy with the fact table at
     * its root.
     */
    public static class Table {
        private final RolapStar star;
        private final MondrianDef.Relation relation;
        private final List columnList;
        private final Table parent;
        private List children;
        /** Condition with which it is connected to its parent. **/
        private final Condition joinCondition;
        private final String alias;

        private Table(RolapStar star,
                      MondrianDef.Relation relation,
                      Table parent,
                      Condition joinCondition) {
            this.star = star;
            this.relation = relation;
            Util.assertTrue(
                    relation instanceof MondrianDef.Table ||
                    relation instanceof MondrianDef.View,
                    "todo: allow dimension which is not a Table or View, [" +
                    relation + "]");
            this.alias = chooseAlias();
            this.parent = parent;
            final AliasReplacer aliasReplacer =
                    new AliasReplacer(relation.getAlias(), this.alias);
            this.joinCondition = aliasReplacer.visit(joinCondition);
            if (this.joinCondition != null) {
                this.joinCondition.table = this;
            }
            this.columnList = new ArrayList();
            this.children = Collections.EMPTY_LIST;
            Util.assertTrue((parent == null) == (joinCondition == null));
        }
        public Condition getCondition() {
            return joinCondition;
        }
        public Table getParentTable() {
            return parent;
        }

        private void addColumn(Column column) {
            columnList.add(column);
        }

        public void loadColumns(BitKey bitKey, List list) {
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                if (bitKey.isSetByPos(column.getBitPosition())) {
                    list.add(column);
                }
            }
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                child.loadColumns(bitKey, list);
            }

        }

        public Column[] lookupColumns(String columnName) {
            List l = new ArrayList();
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                if (column.getExpression() instanceof MondrianDef.Column) {
                    MondrianDef.Column columnExpr =
                        (MondrianDef.Column) column.getExpression();
                    if (columnExpr.name.equals(columnName)) {
                        l.add(column);
                    }
                }
            }
            return (Column[]) l.toArray(new Column[0]);
        }
        public Column lookupColumn(String columnName) {
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                if (column.getExpression() instanceof MondrianDef.Column) {
                    MondrianDef.Column columnExpr =
                        (MondrianDef.Column) column.getExpression();
                    if (columnExpr.name.equals(columnName)) {
                        return column;
                    }
                }
            }
            return null;
        }

        /**
         * Given a MondrianDef.Expression return a column with that expression
         * or null.
         *
         * @param xmlExpr
         * @return
         */
        public Column lookupColumnByExpression(MondrianDef.Expression xmlExpr) {
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                if (column.getExpression().equals(xmlExpr)) {
                    return column;
                }
            }
            return null;
        }
        public boolean containsColumn(Column column) {
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column other = (Column) it.next();
                if (column.equals(other)) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Look up a RolapStar.Measure by its name returning null if none are
         * found.
         *
         * @param name
         * @return
         */
        public Measure lookupMeasureByName(String name) {
            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                if (column instanceof Measure) {
                    Measure measure = (Measure) column;
                    if (measure.getName().equals(name)) {
                        return measure;
                    }
                }
            }
            return null;
        }

        RolapStar getStar() {
            return star;
        }
        private SqlQuery getSqlQuery() {
            return getStar().getSqlQuery();
        }
        public MondrianDef.Relation getRelation() {
            return relation;
        }

        /** Chooses an alias which is unique within the star. */
        private String chooseAlias() {
            List aliasList = star.getAliasList();
            for (int i = 0;; ++i) {
                String candidateAlias = relation.getAlias();
                if (i > 0) {
                    candidateAlias += "_" + i;
                }
                if (!aliasList.contains(candidateAlias)) {
                    return candidateAlias;
                }
            }
        }

        public String getAlias() {
            return alias;
        }

        /**
         * Sometimes one need to get to the "real" name when the table has
         * been given an alias.
         *
         * @return
         */
        public String getTableName() {
            if (relation instanceof MondrianDef.Table) {
                MondrianDef.Table t = (MondrianDef.Table) relation;
                return t.name;
            } else {
                return null;
            }
        }
        synchronized void makeMeasure(RolapStoredMeasure storedMeasure) {
            RolapStar.Measure measure = new RolapStar.Measure(
                storedMeasure.getName(),
                storedMeasure.getAggregator(),
                this,
                storedMeasure.getMondrianDefExpression(),
                true);

            storedMeasure.setStarMeasure(measure); // reverse mapping

            if (containsColumn(measure)) {
                star.decrementColumnCount();
            } else {
                addColumn(measure);
            }
        }

        /**
         * This is only called by RolapCube. If the RolapLevel has a non-null
         * name expression then two columns will be made, otherwise only one.
         *
         * @param cube
         * @param level
         * @param parentColumn
         */
        synchronized Column makeColumns(
                RolapCube cube,
                RolapLevel level,
                Column parentColumn,
                String usagePrefix) {

            Column nameColumn = null;
            if (level.getNameExp() != null) {
                // make a column for the name expression
                nameColumn = makeColumnForLevelExpr(
                    cube,
                    level,
                    level.getName(),
                    level.getNameExp(),
                    false,
                    null,
                    null,
                    null);
            }

            // select the column's name depending upon whether or not a
            // "named" column, above, has been created.
            String name = (level.getNameExp() == null)
                ? level.getName()
                : level.getName() + " (Key)";

            // If the nameColumn is not null, then it is associated with this
            // column.
            Column column = makeColumnForLevelExpr(
                cube,
                level,
                name,
                level.getKeyExp(),
                (level.getFlags() & RolapLevel.NUMERIC) != 0,
                nameColumn,
                parentColumn,
                usagePrefix);

            if (column != null) {
                Map map = star.getMapLevelToColumn(cube);
                map.put(level, column);
            }

            return column;
        }

        private Column makeColumnForLevelExpr(
                RolapCube cube,
                RolapLevel level,
                String name,
                MondrianDef.Expression xmlExpr,
                boolean isNumeric,
                Column nameColumn,
                Column parentColumn,
                String usagePrefix) {
            Table table = this;
            if (xmlExpr instanceof MondrianDef.Column) {
                final MondrianDef.Column xmlColumn =
                    (MondrianDef.Column) xmlExpr;

                String tableName = xmlColumn.table;
                table = findAncestor(tableName);
                if (table == null) {
                    throw Util.newError(
                            "Level '" + level.getUniqueName()
                            + "' of cube '"
                            + this
                            + "' is invalid: table '" + tableName
                            + "' is not found in current scope"
                            + Util.nl
                            + ", star:"
                            + Util.nl
                            + getStar());
                }
                RolapStar.AliasReplacer aliasReplacer =
                        new RolapStar.AliasReplacer(tableName, table.getAlias());
                xmlExpr = aliasReplacer.visit(xmlExpr);
            }
            // does the column already exist??
            Column c = lookupColumnByExpression(xmlExpr);

            RolapStar.Column column = null;
            if (c != null) {
                // Yes, well just reuse it
                // You might wonder why the column need be returned if it
                // already exists. Well, it might have been created for one
                // cube, but for another cube using the same fact table, it
                // still needs to be put into the cube level to column map.
                // Trust me, return null and a junit test fails.
                column = c;
            } else {
                // Make a new column and add it
                column = new RolapStar.Column(name,
                                              table,
                                              xmlExpr,
                                              isNumeric,
                                              nameColumn,
                                              parentColumn,
                                              usagePrefix);
                addColumn(column);
            }
            return column;
        }


        /**

⌨️ 快捷键说明

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