001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/type/LevelType.java#9 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2005-2008 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.olap.type;
011    
012    import mondrian.olap.Level;
013    import mondrian.olap.Dimension;
014    import mondrian.olap.Hierarchy;
015    import mondrian.olap.Util;
016    
017    /**
018     * The type of an expression which represents a level.
019     *
020     * @author jhyde
021     * @since Feb 17, 2005
022     * @version $Id: //open/mondrian/src/main/mondrian/olap/type/LevelType.java#9 $
023     */
024    public class LevelType implements Type {
025        private final Dimension dimension;
026        private final Hierarchy hierarchy;
027        private final Level level;
028        private final String digest;
029    
030        public static final LevelType Unknown = new LevelType(null, null, null);
031    
032        /**
033         * Creates a type representing a level.
034         *
035         * @param dimension Dimension which values of this type must belong to, or
036         *   null if not known
037         * @param hierarchy Hierarchy which values of this type must belong to, or
038         *   null if not known
039         * @param level Level which values of this type must belong to, or null if
040         */
041        public LevelType(Dimension dimension, Hierarchy hierarchy, Level level) {
042            this.dimension = dimension;
043            this.hierarchy = hierarchy;
044            this.level = level;
045            if (level != null) {
046                Util.assertPrecondition(hierarchy != null, "hierarchy != null");
047                Util.assertPrecondition(level.getHierarchy() == hierarchy,
048                        "level.getHierarchy() == hierarchy");
049            }
050            if (hierarchy != null) {
051                Util.assertPrecondition(dimension != null, "dimension != null");
052                Util.assertPrecondition(hierarchy.getDimension() == dimension,
053                        "hierarchy.getDimension() == dimension");
054            }
055            StringBuilder buf = new StringBuilder("LevelType<");
056            if (level != null) {
057                buf.append("level=").append(level.getUniqueName());
058            } else if (hierarchy != null) {
059                buf.append("hierarchy=").append(hierarchy.getUniqueName());
060            } else if (dimension != null) {
061                buf.append("dimension=").append(dimension.getUniqueName());
062            }
063            buf.append(">");
064            this.digest = buf.toString();
065        }
066    
067        public static LevelType forType(Type type) {
068            return new LevelType(
069                type.getDimension(),
070                type.getHierarchy(),
071                type.getLevel());
072        }
073    
074        public static LevelType forLevel(Level level) {
075            return new LevelType(
076                level.getDimension(),
077                level.getHierarchy(),
078                level);
079        }
080    
081        public boolean usesDimension(Dimension dimension, boolean definitely) {
082            return this.dimension == dimension ||
083                (!definitely && this.dimension == null);
084        }
085    
086        public Dimension getDimension() {
087            return dimension;
088        }
089    
090        public Hierarchy getHierarchy() {
091            return hierarchy;
092        }
093    
094        public Level getLevel() {
095            return level;
096        }
097    
098        public String toString() {
099            return digest;
100        }
101    
102        public int hashCode() {
103            return digest.hashCode();
104        }
105    
106        public boolean equals(Object obj) {
107            if (obj instanceof LevelType) {
108                LevelType that = (LevelType) obj;
109                return Util.equals(this.level, that.level)
110                    && Util.equals(this.hierarchy, that.hierarchy)
111                    && Util.equals(this.dimension, that.dimension);
112            }
113            return false;
114        }
115    
116        public Type computeCommonType(Type type, int[] conversionCount) {
117            if (!(type instanceof LevelType)) {
118                return null;
119            }
120            LevelType that = (LevelType) type;
121            if (this.getLevel() != null
122                && this.getLevel().equals(that.getLevel())) {
123                return this;
124            }
125            if (this.getHierarchy() != null
126                && this.getHierarchy().equals(that.getHierarchy())) {
127                return new LevelType(
128                    this.getDimension(),
129                    this.getHierarchy(),
130                    null);
131            }
132            if (this.getDimension() != null
133                && this.getDimension().equals(that.getDimension())) {
134                return new LevelType(
135                    this.getDimension(),
136                    null,
137                    null);
138            }
139            return LevelType.Unknown;
140        }
141    }
142    
143    // End LevelType.java