001/*
002// $Id: MemberType.java 482 2012-01-05 23:27:27Z jhyde $
003//
004// Licensed to Julian Hyde under one or more contributor license
005// agreements. See the NOTICE file distributed with this work for
006// additional information regarding copyright ownership.
007//
008// Julian Hyde licenses this file to you under the Apache License,
009// Version 2.0 (the "License"); you may not use this file except in
010// compliance with the License. You may obtain a copy of the License at:
011//
012// http://www.apache.org/licenses/LICENSE-2.0
013//
014// Unless required by applicable law or agreed to in writing, software
015// distributed under the License is distributed on an "AS IS" BASIS,
016// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017// See the License for the specific language governing permissions and
018// limitations under the License.
019*/
020package org.olap4j.type;
021
022import org.olap4j.OlapException;
023import org.olap4j.metadata.*;
024
025/**
026 * The type of an expression which represents a member.
027 *
028 * @author jhyde
029 * @since Feb 17, 2005
030 * @version $Id: MemberType.java 482 2012-01-05 23:27:27Z jhyde $
031 */
032public class MemberType implements Type {
033    private final Hierarchy hierarchy;
034    private final Dimension dimension;
035    private final Level level;
036    private final Member member;
037    private final String digest;
038
039    // not part of public olap4j public API
040    private static final MemberType Unknown =
041        new MemberType(null, null, null, null);
042
043    /**
044     * Creates a type representing a member.
045     *
046     * @param dimension Dimension the member belongs to, or null if not known.
047     *
048     * @param hierarchy Hierarchy the member belongs to, or null if not known.
049     *
050     * @param level Level the member belongs to, or null if not known
051     *
052     * @param member The precise member, or null if not known
053     */
054    public MemberType(
055        Dimension dimension,
056        Hierarchy hierarchy,
057        Level level,
058        Member member)
059    {
060        this.dimension = dimension;
061        this.hierarchy = hierarchy;
062        this.level = level;
063        this.member = member;
064        if (member != null) {
065            assert level != null;
066            assert member.getLevel().equals(level);
067        }
068        if (level != null) {
069            assert hierarchy != null;
070            assert level.getHierarchy().equals(hierarchy);
071        }
072        if (hierarchy != null) {
073            assert dimension != null;
074            assert hierarchy.getDimension().equals(dimension);
075        }
076        StringBuilder buf = new StringBuilder("MemberType<");
077        if (member != null) {
078            buf.append("member=").append(member.getUniqueName());
079        } else if (level != null) {
080            buf.append("level=").append(level.getUniqueName());
081        } else if (hierarchy != null) {
082            buf.append("hierarchy=").append(hierarchy.getUniqueName());
083        } else if (dimension != null) {
084            buf.append("dimension=").append(dimension.getUniqueName());
085        }
086        buf.append(">");
087        this.digest = buf.toString();
088    }
089
090    public String toString() {
091        return digest;
092    }
093
094    public Hierarchy getHierarchy() {
095        return hierarchy;
096    }
097
098    public Level getLevel() {
099        return level;
100    }
101
102    /**
103     * Returns the member of this type, or null if not known.
104     *
105     * @return member of this type
106     */
107    public Member getMember() {
108        return member;
109    }
110
111    public boolean usesDimension(Dimension dimension, boolean maybe) {
112        if (this.dimension == null) {
113            return maybe;
114        } else {
115            return this.dimension.equals(dimension);
116        }
117    }
118
119    // not part of public olap4j API
120    Type getValueType() {
121        // todo: when members have more type information (double vs. integer
122        // vs. string), return better type if member != null.
123        return new ScalarType();
124    }
125
126    public Dimension getDimension() {
127        return dimension;
128    }
129
130    // not part of public olap4j API
131    static MemberType forType(Type type) throws OlapException {
132        if (type instanceof MemberType) {
133            return (MemberType) type;
134        } else {
135            return new MemberType(
136                type.getDimension(),
137                type.getHierarchy(),
138                type.getLevel(),
139                null);
140        }
141    }
142}
143
144// End MemberType.java
145