rolapstar.java

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

JAVA
1,660
字号
         * Extends this 'leg' of the star by adding <code>relation</code>
         * joined by <code>joinCondition</code>. If the same expression is
         * already present, does not create it again.
         */
        synchronized Table addJoin(MondrianDef.Relation relation,
                                   RolapStar.Condition joinCondition) {
            if (relation instanceof MondrianDef.Table ||
                    relation instanceof MondrianDef.View) {
                RolapStar.Table starTable = findChild(relation, joinCondition);
                if (starTable == null) {
                    starTable = new RolapStar.Table(star, relation, this,
                        joinCondition);
                    if (this.children == Collections.EMPTY_LIST) {
                        this.children = new ArrayList();
                    }
                    this.children.add(starTable);
                }
                return starTable;

            } else if (relation instanceof MondrianDef.Join) {
                MondrianDef.Join join = (MondrianDef.Join) relation;
                RolapStar.Table leftTable = addJoin(join.left, joinCondition);
                String leftAlias = join.leftAlias;
                if (leftAlias == null) {
                    leftAlias = join.left.getAlias();
                    if (leftAlias == null) {
                        throw Util.newError(
                                "missing leftKeyAlias in " + relation);
                    }
                }
                assert leftTable.findAncestor(leftAlias) == leftTable;
                // switch to uniquified alias
                leftAlias = leftTable.getAlias();

                String rightAlias = join.rightAlias;
                if (rightAlias == null) {
                    rightAlias = join.right.getAlias();
                    if (rightAlias == null) {
                        throw Util.newError(
                                "missing rightKeyAlias in " + relation);
                    }
                }
                joinCondition = new RolapStar.Condition(
                        new MondrianDef.Column(leftAlias, join.leftKey),
                        new MondrianDef.Column(rightAlias, join.rightKey));
                RolapStar.Table rightTable = leftTable.addJoin(
                        join.right, joinCondition);
                return rightTable;

            } else {
                throw Util.newInternal("bad relation type " + relation);
            }
        }

        /**
         * Returns a child relation which maps onto a given relation, or null if
         * there is none.
         */
        public Table findChild(MondrianDef.Relation relation,
                               Condition joinCondition) {
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                if (child.relation.equals(relation)) {
                    Condition condition = joinCondition;
                    if (!Util.equals(relation.getAlias(), child.alias)) {
                        // Make the two conditions comparable, by replacing
                        // occurrence of this table's alias with occurrences
                        // of the child's alias.
                        AliasReplacer aliasReplacer = new AliasReplacer(
                                relation.getAlias(), child.alias);
                        condition = aliasReplacer.visit(joinCondition);
                    }
                    if (child.joinCondition.equals(condition)) {
                        return child;
                    }
                }
            }
            return null;
        }

        /**
         * Returns a descendant with a given alias, or null if none found.
         */
        public Table findDescendant(String seekAlias) {
            if (getAlias().equals(seekAlias)) {
                return this;
            }
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                Table found = child.findDescendant(seekAlias);
                if (found != null) {
                    return found;
                }
            }
            return null;
        }

        /**
         * Returns an ancestor with a given alias, or null if not found.
         */
        public Table findAncestor(String tableName) {
            for (Table t = this; t != null; t = t.parent) {
                if (t.relation.getAlias().equals(tableName)) {
                    return t;
                }
            }
            return null;
        }
        public boolean equalsTableName(String tableName) {
            if (this.relation instanceof MondrianDef.Table) {
                MondrianDef.Table mt = (MondrianDef.Table) this.relation;
                if (mt.name.equals(tableName)) {
                    return true;
                }
            }
            return false;
        }

        /**
         * Adds this table to the from clause of a query.
         *
         * @param query Query to add to
         * @param failIfExists Pass in false if you might have already added
         *     the table before and if that happens you want to do nothing.
         * @param joinToParent Pass in true if you are constraining a cell
         *     calculcation, false if you are retrieving members.
         */
        public void addToFrom(SqlQuery query,
                              boolean failIfExists,
                              boolean joinToParent) {
            query.addFrom(relation, alias, failIfExists);
            Util.assertTrue((parent == null) == (joinCondition == null));
            if (joinToParent) {
                if (parent != null) {
                    parent.addToFrom(query, failIfExists, joinToParent);
                }
                if (joinCondition != null) {
                    query.addWhere(joinCondition.toString(query));
                }
            }
        }

        /**
         * Return an Iterator over all child tables.
         *
         * @return
         */
        public Iterator getChildren() {
            return children.iterator();
        }
        /**
         * Return an Iterator over all of the table's columns.
         *
         * @return
         */
        public Iterator getColumns() {
            return columnList.iterator();
        }

        /**
         * Find the child table of the fact table with the given columnname
         * used in its left join condition. This is used by the
         * AggTableManager while characterizing the fact table columns.
         *
         * @param columnName
         * @return
         */
        public RolapStar.Table findTableWithLeftJoinCondition(
                final String columnName) {
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                Condition condition = child.joinCondition;
                if (condition != null) {
                    if (condition.left instanceof MondrianDef.Column) {
                        MondrianDef.Column mcolumn =
                            (MondrianDef.Column) condition.left;
                        if (mcolumn.name.equals(columnName)) {
                            return child;
                        }
                    }
                }

            }
            return null;
        }

        /**
         * This is used during aggregate table validation to make sure that the
         * mapping from for the aggregate join condition is valid. It returns
         * the child table with the matching left join condition.
         *
         * @param left
         * @return
         */
        public RolapStar.Table findTableWithLeftCondition(
                final MondrianDef.Expression left) {
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                Condition condition = child.joinCondition;
                if (condition != null) {
                    if (condition.left instanceof MondrianDef.Column) {
                        MondrianDef.Column mcolumn =
                            (MondrianDef.Column) condition.left;
                        if (mcolumn.equals(left)) {
                            return child;
                        }
                    }
                }

            }
            return null;
        }

        /**
         * Note: I do not think that this is ever true.
         *
         * @return
         */
        public boolean isFunky() {
            return (relation == null);
        }
        public boolean equals(Object obj) {
            if (!(obj instanceof Table)) {
                return false;
            }
            Table other = (Table) obj;
            return getAlias().equals(other.getAlias());
        }
        public int hashCode() {
            return getAlias().hashCode();
        }

        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) {
            pw.print(prefix);
            pw.println("Table:");
            String subprefix = prefix + "  ";

            pw.print(subprefix);
            pw.print("alias=");
            pw.println(getAlias());

            if (this.relation != null) {
                pw.print(subprefix);
                pw.print("relation=");
                pw.println(relation);
            }

            pw.print(subprefix);
            pw.println("Columns:");
            String subsubprefix = subprefix + "  ";

            for (Iterator it = getColumns(); it.hasNext(); ) {
                Column column = (Column) it.next();
                column.print(pw, subsubprefix);
                pw.println();
            }

            if (this.joinCondition != null) {
                this.joinCondition.print(pw, subprefix);
            }
            for (Iterator it = getChildren(); it.hasNext(); ) {
                Table child = (Table) it.next();
                child.print(pw, subprefix);
            }
        }

        /**
         * Does this table have a column with the given name.
         *
         * @param columnName
         * @return
         */
        public boolean containsColumn(String columnName) {
            if (relation instanceof MondrianDef.Table) {
                return star.containsColumn(((MondrianDef.Table) relation).name,
                    columnName);
            } else {
                // todo: Deal with join and view.
                return false;
            }
        }
    }

    public static class Condition {
    	private static final Logger LOGGER = Logger.getLogger(Condition.class);

        private final MondrianDef.Expression left;
        private final MondrianDef.Expression right;
        // set in Table constructor
        Table table;

        Condition(MondrianDef.Expression left,
                  MondrianDef.Expression right) {
            Util.assertPrecondition(left != null);
            Util.assertPrecondition(right != null);

            if (!(left instanceof MondrianDef.Column)) {
                // TODO: Will this ever print?? if not then left should be
                // of type MondrianDef.Column.
                LOGGER.debug("Condition.left NOT Column: "
                    +left.getClass().getName());
            }
            this.left = left;
            this.right = right;
        }
        public MondrianDef.Expression getLeft() {
            return left;
        }
        public MondrianDef.Expression getRight() {
            return right;
        }
        public String toString(SqlQuery query) {
            return left.getExpression(query) + " = " + right.getExpression(query);
        }
        public int hashCode() {
            return left.hashCode() ^ right.hashCode();
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof Condition)) {
                return false;
            }
            Condition that = (Condition) obj;
            return (this.left.equals(that.left) &&
                    this.right.equals(that.right));
        }

        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 sqlQueuy = table.getSqlQuery();
            pw.print(prefix);
            pw.println("Condition:");
            String subprefix = prefix + "  ";

            pw.print(subprefix);
            pw.print("left=");
            pw.println(left.getExpression(sqlQueuy));

            pw.print(subprefix);
            pw.print("right=");
            pw.println(right.getExpression(sqlQueuy));
        }
    }

    /**
     * Creates a copy of an expression, everywhere replacing one alias
     * with another.
     */
    public static class AliasReplacer {
        private final String oldAlias;
        private final String newAlias;

        public AliasReplacer(String oldAlias, String newAlias) {
            this.oldAlias = oldAlias;
            this.newAlias = newAlias;
        }

        private Condition visit(Condition condition) {
            if (condition == null) {
                return null;
            }
            if (newAlias.equals(oldAlias)) {
                return condition;
            }
            return new Condition(
                    visit(condition.left),
                    visit(condition.right));
        }

        public MondrianDef.Expression visit(MondrianDef.Expression expression) {
            if (expression == null) {
                return null;
            }
            if (newAlias.equals(oldAlias)) {
                return expression;
            }
            if (expression instanceof MondrianDef.Column) {
                MondrianDef.Column column = (MondrianDef.Column) expression;
                return new MondrianDef.Column(visit(column.table), column.name);
            } else {
                throw Util.newInternal("need to implement " + expression);
            }
        }

        private String visit(String table) {
            return table.equals(oldAlias)
                ? newAlias
                : table;
        }
    }
}

// End RolapStar.java

⌨️ 快捷键说明

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