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 hierarchy.
017 *
018 * @author jhyde
019 * @since Feb 17, 2005
020 */
021public class HierarchyType implements Type {
022    private final Dimension dimension;
023    private final Hierarchy hierarchy;
024    private final String digest;
025
026    public static final HierarchyType Unknown = new HierarchyType(null, null);
027
028    /**
029     * Creates a type representing a hierarchy.
030     *
031     * @param dimension Dimension that values of this type must belong to, or
032     *   null if the dimension is unknown
033     * @param hierarchy Hierarchy that values of this type must belong to,
034     *   null if the hierarchy is unknown
035     */
036    public HierarchyType(Dimension dimension, Hierarchy hierarchy) {
037        this.dimension = dimension;
038        this.hierarchy = hierarchy;
039        StringBuilder buf = new StringBuilder("HierarchyType<");
040        if (hierarchy != null) {
041            buf.append("hierarchy=").append(hierarchy.getUniqueName());
042        } else if (dimension != null) {
043            buf.append("dimension=").append(dimension.getUniqueName());
044        }
045        buf.append(">");
046        this.digest = buf.toString();
047    }
048
049    public static HierarchyType forHierarchy(Hierarchy hierarchy) {
050        return new HierarchyType(hierarchy.getDimension(), hierarchy);
051    }
052
053    public static HierarchyType forType(Type type) {
054        return new HierarchyType(type.getDimension(), type.getHierarchy());
055    }
056
057    public boolean usesDimension(Dimension dimension, boolean definitely) {
058        return this.dimension == dimension
059            || (!definitely && this.dimension == null);
060    }
061
062    public boolean usesHierarchy(Hierarchy hierarchy, boolean definitely) {
063        return this.hierarchy == hierarchy
064            || (!definitely
065                && this.hierarchy == null
066                && (this.dimension == null
067                    || this.dimension == hierarchy.getDimension()));
068    }
069
070    public Dimension getDimension() {
071        return dimension;
072    }
073
074    public Hierarchy getHierarchy() {
075        return hierarchy;
076    }
077
078    public Level getLevel() {
079        return null;
080    }
081
082    public String toString() {
083        return digest;
084    }
085
086    public int hashCode() {
087        return digest.hashCode();
088    }
089
090    public boolean equals(Object obj) {
091        if (obj instanceof HierarchyType) {
092            HierarchyType that = (HierarchyType) obj;
093            return Util.equals(this.hierarchy, that.hierarchy)
094                && Util.equals(this.dimension, that.dimension);
095        }
096        return false;
097    }
098
099    public Type computeCommonType(Type type, int[] conversionCount) {
100        if (!(type instanceof HierarchyType)) {
101            return null;
102        }
103        HierarchyType that = (HierarchyType) type;
104        if (this.getHierarchy() != null
105            && this.getHierarchy().equals(that.getHierarchy()))
106        {
107            return this;
108        }
109        if (this.getDimension() != null
110            && this.getDimension().equals(that.getDimension()))
111        {
112            return new HierarchyType(
113                this.getDimension(),
114                null);
115        }
116        return HierarchyType.Unknown;
117    }
118
119    public boolean isInstance(Object value) {
120        return value instanceof Hierarchy
121            && (hierarchy == null
122                || value.equals(hierarchy))
123            && (dimension == null
124                || ((Hierarchy) value).getDimension().equals(dimension));
125    }
126
127    public int getArity() {
128        return 1;
129    }
130}
131
132// End HierarchyType.java