001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2005-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho
009// All Rights Reserved.
010*/
011package mondrian.olap.type;
012
013import mondrian.olap.*;
014
015/**
016 * The type of an expression which represents a Dimension.
017 *
018 * @author jhyde
019 * @since Feb 17, 2005
020 */
021public class DimensionType implements Type {
022    private final Dimension dimension;
023    private final String digest;
024
025    public static final DimensionType Unknown = new DimensionType(null);
026
027    /**
028     * Creates a type representing a dimension.
029     *
030     * @param dimension Dimension that values of this type must belong to, or
031     *   null if the dimension is unknown
032     */
033    public DimensionType(Dimension dimension) {
034        this.dimension = dimension;
035        StringBuilder buf = new StringBuilder("DimensionType<");
036        if (dimension != null) {
037            buf.append("dimension=").append(dimension.getUniqueName());
038        }
039        buf.append(">");
040        this.digest = buf.toString();
041    }
042
043    public static DimensionType forDimension(Dimension dimension) {
044        return new DimensionType(dimension);
045    }
046
047    public static DimensionType forType(Type type) {
048        return new DimensionType(type.getDimension());
049    }
050
051    public boolean usesDimension(Dimension dimension, boolean definitely) {
052        // REVIEW: Should be '!definitely'?
053        return this.dimension == dimension
054            || (definitely && this.dimension == null);
055    }
056
057    public boolean usesHierarchy(Hierarchy hierarchy, boolean definitely) {
058        // If hierarchy belongs to this type's dimension, we might use it.
059        return hierarchy.getDimension() == this.dimension
060            && !definitely;
061    }
062
063    public Hierarchy getHierarchy() {
064        return dimension == null
065            ? null
066            : dimension.getHierarchies().length > 1
067            ? null
068            : dimension.getHierarchies()[0];
069    }
070
071    public Level getLevel() {
072        return null;
073    }
074
075    public Dimension getDimension() {
076        return dimension;
077    }
078
079    public int hashCode() {
080        return digest.hashCode();
081    }
082
083    public boolean equals(Object obj) {
084        if (obj instanceof DimensionType) {
085            DimensionType that = (DimensionType) obj;
086            return Util.equals(this.getDimension(), that.getDimension());
087        }
088        return false;
089    }
090
091    public String toString() {
092        return digest;
093    }
094
095    public Type computeCommonType(Type type, int[] conversionCount) {
096        if (conversionCount != null && type instanceof HierarchyType) {
097            HierarchyType hierarchyType = (HierarchyType) type;
098            if (Util.equals(hierarchyType.getDimension(), dimension)) {
099                ++conversionCount[0];
100                return this;
101            }
102            return null;
103        }
104        if (!(type instanceof DimensionType)) {
105            return null;
106        }
107        DimensionType that = (DimensionType) type;
108        if (this.getDimension() != null
109            && this.getDimension().equals(that.getDimension()))
110        {
111            return new DimensionType(
112                this.getDimension());
113        }
114        return DimensionType.Unknown;
115    }
116
117    public boolean isInstance(Object value) {
118        return value instanceof Dimension
119            && (dimension == null
120                || value.equals(dimension));
121    }
122
123    public int getArity() {
124        return 1;
125    }
126}
127
128// End DimensionType.java