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