1 13 package mondrian.rolap; 14 15 import mondrian.olap.*; 16 import mondrian.resource.MondrianResource; 17 18 import org.apache.log4j.Logger; 19 20 39 public class HierarchyUsage { 40 private static final Logger LOGGER = Logger.getLogger(HierarchyUsage.class); 41 42 enum Kind { 43 UNKNOWN, 44 SHARED, 45 VIRTUAL, 46 PRIVATE 47 } 48 49 54 protected final MondrianDef.Relation fact; 55 56 60 private final String hierarchyName; 61 62 66 private final String name; 67 68 75 private final String fullName; 76 77 81 private final String foreignKey; 82 83 87 private final String source; 88 89 93 private final String usagePrefix; 94 95 private final String level; 97 100 104 private MondrianDef.Relation joinTable; 105 109 private MondrianDef.Expression joinExp; 110 111 private final Kind kind; 112 113 120 HierarchyUsage(RolapCube cube, 121 RolapHierarchy hierarchy, 122 MondrianDef.CubeDimension cubeDim) { 123 124 assert cubeDim != null : "precondition: cubeDim != null"; 125 126 this.fact = cube.fact; 127 128 this.name = cubeDim.name; 132 this.foreignKey = cubeDim.foreignKey; 133 134 if (cubeDim instanceof MondrianDef.DimensionUsage) { 135 this.kind = Kind.SHARED; 136 137 138 MondrianDef.DimensionUsage du = 142 (MondrianDef.DimensionUsage) cubeDim; 143 if (! du.name.equals(du.source)) { 145 StringBuilder buf = new StringBuilder (); 146 buf.append("Cube \""); 147 buf.append(cube.getName()); 148 buf.append("\": DimensionUsage name (\""); 149 buf.append(du.name); 150 buf.append("\") must equal source (\""); 151 buf.append(du.source); 152 buf.append("\")"); 153 throw new MondrianException(buf.toString()); 154 } 155 156 this.hierarchyName = hierarchy.getName(); 158 int index = this.hierarchyName.indexOf('.'); 159 if (index == -1) { 160 this.fullName = this.name; 161 this.source = du.source; 162 } else { 163 String hname= this.hierarchyName.substring( 164 index+1, this.hierarchyName.length()); 165 166 StringBuilder buf = new StringBuilder (32); 167 buf.append(this.name); 168 buf.append('.'); 169 buf.append(hname); 170 this.fullName = buf.toString(); 171 172 buf.setLength(0); 173 buf.append(du.source); 174 buf.append('.'); 175 buf.append(hname); 176 this.source = buf.toString(); 177 } 178 179 this.level = du.level; 180 this.usagePrefix = du.usagePrefix; 181 182 init(cube, hierarchy, du); 183 184 } else if (cubeDim instanceof MondrianDef.Dimension) { 185 this.kind = Kind.PRIVATE; 186 187 MondrianDef.Dimension d = (MondrianDef.Dimension) cubeDim; 191 192 this.hierarchyName = hierarchy.getName(); 193 this.fullName = this.name; 194 195 this.source = null; 196 this.usagePrefix = d.usagePrefix; 197 this.level = null; 198 199 init(cube, hierarchy, null); 200 201 } else if (cubeDim instanceof MondrianDef.VirtualCubeDimension) { 202 this.kind = Kind.VIRTUAL; 203 204 MondrianDef.VirtualCubeDimension vd = 206 (MondrianDef.VirtualCubeDimension) cubeDim; 207 208 this.hierarchyName = cubeDim.name; 209 this.fullName = this.name; 210 211 this.source = null; 212 this.usagePrefix = null; 213 this.level = null; 214 215 init(cube, hierarchy, null); 216 217 } else { 218 getLogger().warn("HierarchyUsage<init>: Unknown cubeDim=" 219 +cubeDim.getClass().getName()); 220 221 this.kind = Kind.UNKNOWN; 222 223 this.hierarchyName = cubeDim.name; 224 this.fullName = this.name; 225 226 this.source = null; 227 this.usagePrefix = null; 228 this.level = null; 229 230 init(cube, hierarchy, null); 231 } 232 if (getLogger().isDebugEnabled()) { 233 getLogger().debug(toString() 234 + ", cubeDim=" 235 + cubeDim.getClass().getName()); 236 } 237 238 } 239 240 protected Logger getLogger() { 241 return LOGGER; 242 } 243 244 public String getHierarchyName() { 245 return this.hierarchyName; 246 } 247 public String getFullName() { 248 return this.fullName; 249 } 250 public String getName() { 251 return this.name; 252 } 253 public String getForeignKey() { 254 return this.foreignKey; 255 } 256 public String getSource() { 257 return this.source; 258 } 259 public String getLevelName() { 260 return this.level; 261 } 262 public String getUsagePrefix() { 263 return this.usagePrefix; 264 } 265 266 public MondrianDef.Relation getJoinTable() { 267 return this.joinTable; 268 } 269 public MondrianDef.Expression getJoinExp() { 270 return this.joinExp; 271 } 272 273 public Kind getKind() { 274 return this.kind; 275 } 276 public boolean isShared() { 277 return this.kind == Kind.SHARED; 278 } 279 public boolean isVirtual() { 280 return this.kind == Kind.VIRTUAL; 281 } 282 public boolean isPrivate() { 283 return this.kind == Kind.PRIVATE; 284 } 285 286 public boolean equals(Object o) { 287 if (o instanceof HierarchyUsage) { 288 HierarchyUsage other = (HierarchyUsage) o; 289 return (this.kind == other.kind) && 290 Util.equals(this.fact, other.fact) && 291 Util.equalName(this.hierarchyName, other.hierarchyName) && 292 Util.equalName(this.name, other.name) && 293 Util.equalName(this.source, other.source) && 294 Util.equalName(this.foreignKey, other.foreignKey); 295 } else { 296 return false; 297 } 298 } 299 300 public int hashCode() { 301 int h = fact.hashCode(); 302 h = Util.hash(h, hierarchyName); 303 h = Util.hash(h, name); 304 h = Util.hash(h, source); 305 h = Util.hash(h, foreignKey); 306 return h; 307 } 308 309 public String toString() { 310 StringBuilder buf = new StringBuilder (100); 311 buf.append("HierarchyUsage: "); 312 buf.append("kind="); 313 buf.append(this.kind.name()); 314 buf.append(", hierarchyName="); 315 buf.append(this.hierarchyName); 316 buf.append(", fullName="); 317 buf.append(this.fullName); 318 buf.append(", foreignKey="); 319 buf.append(this.foreignKey); 320 buf.append(", source="); 321 buf.append(this.source); 322 buf.append(", level="); 323 buf.append(this.level); 324 buf.append(", name="); 325 buf.append(this.name); 326 327 return buf.toString(); 328 } 329 330 void init(RolapCube cube, 331 RolapHierarchy hierarchy, 332 MondrianDef.DimensionUsage cubeDim) { 333 334 if (cubeDim != null && cubeDim.level != null) { 336 337 RolapLevel joinLevel = (RolapLevel) 339 Util.lookupHierarchyLevel(hierarchy, cubeDim.level); 340 if (joinLevel == null) { 341 throw MondrianResource.instance() 342 .DimensionUsageHasUnknownLevel.ex( 343 hierarchy.getUniqueName(), 344 cube.getUniqueName(), 345 cubeDim.level); 346 } 347 this.joinTable = findJoinTable(hierarchy, joinLevel.getKeyExp().getTableAlias()); 348 this.joinExp = joinLevel.getKeyExp(); 349 } else if (hierarchy.xmlHierarchy != null && 350 hierarchy.xmlHierarchy.primaryKey != null) { 351 this.joinTable = findJoinTable(hierarchy, 355 hierarchy.xmlHierarchy.primaryKeyTable); 356 this.joinExp = new MondrianDef.Column(this.joinTable.getAlias(), 357 hierarchy.xmlHierarchy.primaryKey); 358 } else { 359 final Level[] levels = hierarchy.getLevels(); 362 RolapLevel joinLevel = (RolapLevel) levels[levels.length - 1]; 363 this.joinTable = findJoinTable(hierarchy, 364 joinLevel.getKeyExp().getTableAlias()); 365 this.joinExp = joinLevel.getKeyExp(); 366 } 367 371 372 final boolean inFactTable = this.joinTable.equals(cube.getFact()); 375 if (!inFactTable) { 376 if (this.joinExp == null) { 377 throw MondrianResource.instance() 378 .MustSpecifyPrimaryKeyForHierarchy.ex( 379 hierarchy.getUniqueName(), 380 cube.getUniqueName()); 381 } 382 if (foreignKey == null) { 383 throw MondrianResource.instance() 384 .MustSpecifyForeignKeyForHierarchy.ex( 385 hierarchy.getUniqueName(), 386 cube.getUniqueName()); 387 } 388 } 389 } 390 391 399 private MondrianDef.Relation findJoinTable( 400 RolapHierarchy hierarchy, 401 String tableName) 402 { 403 final MondrianDef.Relation table; 404 if (tableName == null) { 405 table = hierarchy.getUniqueTable(); 406 if (table == null) { 407 throw MondrianResource.instance() 408 .MustSpecifyPrimaryKeyTableForHierarchy.ex( 409 hierarchy.getUniqueName()); 410 } 411 } else { 412 table = hierarchy.getRelation().find(tableName); 413 if (table == null) { 414 throw Util.newError( 416 "no table '" + tableName + 417 "' found in hierarchy " + hierarchy.getUniqueName()); 418 } 419 } 420 return table; 421 } 422 423 } 424 425 | Popular Tags |