001/* 002// Licensed to Julian Hyde under one or more contributor license 003// agreements. See the NOTICE file distributed with this work for 004// additional information regarding copyright ownership. 005// 006// Julian Hyde licenses this file to you under the Apache License, 007// Version 2.0 (the "License"); you may not use this file except in 008// compliance with the License. You may obtain a copy of the License at: 009// 010// http://www.apache.org/licenses/LICENSE-2.0 011// 012// Unless required by applicable law or agreed to in writing, software 013// distributed under the License is distributed on an "AS IS" BASIS, 014// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015// See the License for the specific language governing permissions and 016// limitations under the License. 017*/ 018package org.olap4j.metadata; 019 020import org.olap4j.OlapException; 021 022import java.util.List; 023 024/** 025 * Group of {@link Member} objects in a {@link Hierarchy}, 026 * all with the same attributes and at the same depth in the hierarchy. 027 * 028 * @author jhyde 029 * @since Aug 23, 2006 030 */ 031public interface Level extends MetadataElement { 032 /** 033 * Returns the depth of this <code>Level</code>. 034 * 035 * <p>Note #1: In an access-controlled context, the first visible level of 036 * a hierarchy may not have a depth of 0.</p> 037 * 038 * <p>Note #2: In a parent-child hierarchy, the depth of a member (as 039 * returned by may not be the same as the depth of its level. 040 * 041 * @return depth of this level 042 */ 043 int getDepth(); 044 045 /** 046 * Returns the {@link Hierarchy} this <code>Level</code> belongs to. 047 * 048 * @return hierarchy this level belongs to 049 */ 050 Hierarchy getHierarchy(); 051 052 /** 053 * Returns the Dimension this <code>Level</code> belongs to. 054 * (Always equivalent to <code>getHierarchy().getDimension()</code>.) 055 * 056 * @return dimension this level belongs to 057 */ 058 Dimension getDimension(); 059 060 /** 061 * Returns the type of this <code>Level</code>. 062 * 063 * @return level type 064 */ 065 Level.Type getLevelType(); 066 067 /** 068 * Returns whether the level is calculated. 069 * 070 * @return Whether this level is calculated 071 */ 072 boolean isCalculated(); 073 074 /** 075 * Returns a list of definitions for the properties available to members 076 * of this <code>Level</code>. 077 * 078 * <p>The caller should assume that the list is immutable; 079 * if the caller modifies the list, behavior is undefined.</p> 080 * 081 * @see org.olap4j.OlapDatabaseMetaData#getProperties 082 * 083 * @return properties of this Level 084 */ 085 NamedList<Property> getProperties(); 086 087 /** 088 * Returns a list of {@link Member} objects that belong to this Level. 089 * 090 * <p>The list does not include calculated members.</p> 091 * 092 * <p>Some levels have a very many members. In this case, calling this 093 * method may be expensive in space and/or time and is not recommended.</p> 094 * 095 * <p>If you need to include calculated members, or if you need to query 096 * specific members or subsets of members in a level, consider instead 097 * generating and executing an MDX query with a single axis. MDX functions 098 * {@code AddCalculatedMembers}, {@code Filter} and {@code Order} are 099 * especially useful. For example, 100 * 101 * <pre>with member [Measures].[Zero] as 0 102 * select AddCalculatedMembers([Time].[Month].Members) on 0 103 * from [Sales] 104 * where [Measures].[Zero]</pre> 105 * 106 * returns the {@code [Month]} level including calculated members. The 107 * {@code [Measures].[Zero]} calculated member saves the OLAP server the 108 * effort of retrieving cell values.</p> 109 * 110 * <p>The members of a level do not have unique names, so unlike 111 * {@link Hierarchy#getRootMembers()} and 112 * {@link Member#getChildMembers()} the result type 113 * is a {@link List} not a {@link NamedList}. 114 * 115 * @return List of members in this Level 116 * 117 * @throws OlapException if database error occurs 118 */ 119 List<Member> getMembers() throws OlapException; 120 121 /** 122 * Returns the number of members in this Level. 123 * 124 * @return number of members 125 */ 126 int getCardinality(); 127 128 /** 129 * Enumeration of the types of a {@link Level}. 130 * 131 * <p>Several of the values are defined by OLE DB for OLAP and/or XML/A, 132 * sans the "MDLEVEL_TYPE_" prefix to their name. For example, 133 * {@link #GEO_CONTINENT} corresponds to 134 * the value <code>MDLEVEL_TYPE_GEO_CONTINENT</code> for the 135 * <code>LEVEL_TYPE</code> property in the <code>MDSCHEMA_LEVELS</code> 136 * schema rowset. 137 * 138 * <p>Some of the values are specified by OLE DB for OLAP: 139 * <ul> 140 * <li>MDLEVEL_TYPE_REGULAR (0x0000) 141 * <li>MDLEVEL_TYPE_ALL (0x0001) 142 * <li>MDLEVEL_TYPE_TIME_YEARS (0x0014) 143 * <li>MDLEVEL_TYPE_TIME_HALF_YEAR (0x0024) 144 * <li>MDLEVEL_TYPE_TIME_QUARTERS (0x0044) 145 * <li>MDLEVEL_TYPE_TIME_MONTHS (0x0084) 146 * <li>MDLEVEL_TYPE_TIME_WEEKS (0x0104) 147 * <li>MDLEVEL_TYPE_TIME_DAYS (0x0204) 148 * <li>MDLEVEL_TYPE_TIME_HOURS (0x0304) 149 * <li>MDLEVEL_TYPE_TIME_MINUTES (0x0404) 150 * <li>MDLEVEL_TYPE_TIME_SECONDS (0x0804) 151 * <li>MDLEVEL_TYPE_TIME_UNDEFINED (0x1004) 152 * </ul> 153 * 154 * Some of the OLE DB for OLAP values are as flags, and do not become 155 * values of the enumeration: 156 * <ul> 157 * <li>MDLEVEL_TYPE_UNKNOWN (0x0000) signals that no other flags are set. 158 * Use {@link #REGULAR} 159 * <li>MDLEVEL_TYPE_CALCULATED (0x0002) indicates that the level is 160 * calculated. Use {@link Level#isCalculated}. 161 * <li>MDLEVEL_TYPE_TIME (0x0004) indicates that the level is time-related. 162 * Use {@link #isTime}. 163 * <li>MDLEVEL_TYPE_RESERVED1 (0x0008) is reserved for future use. 164 * </ul> 165 * 166 * <p>Some of the values are specified by XMLA: 167 * <ul> 168 * <li>MDLEVEL_TYPE_GEO_CONTINENT (0x2001) 169 * <li>MDLEVEL_TYPE_GEO_REGION (0x2002) 170 * <li>MDLEVEL_TYPE_GEO_COUNTRY (0x2003) 171 * <li>MDLEVEL_TYPE_GEO_STATE_OR_PROVINCE (0x2004) 172 * <li>MDLEVEL_TYPE_GEO_COUNTY (0x2005) 173 * <li>MDLEVEL_TYPE_GEO_CITY (0x2006) 174 * <li>MDLEVEL_TYPE_GEO_POSTALCODE (0x2007) 175 * <li>MDLEVEL_TYPE_GEO_POINT (0x2008) 176 * <li>MDLEVEL_TYPE_ORG_UNIT (0x1011) 177 * <li>MDLEVEL_TYPE_BOM_RESOURCE (0x1012) 178 * <li>MDLEVEL_TYPE_QUANTITATIVE (0x1013) 179 * <li>MDLEVEL_TYPE_ACCOUNT (0x1014) 180 * <li>MDLEVEL_TYPE_CUSTOMER (0x1021) 181 * <li>MDLEVEL_TYPE_CUSTOMER_GROUP (0x1022) 182 * <li>MDLEVEL_TYPE_CUSTOMER_HOUSEHOLD (0x1023) 183 * <li>MDLEVEL_TYPE_PRODUCT (0x1031) 184 * <li>MDLEVEL_TYPE_PRODUCT_GROUP (0x1032) 185 * <li>MDLEVEL_TYPE_SCENARIO (0x1015) 186 * <li>MDLEVEL_TYPE_UTILITY (0x1016) 187 * <li>MDLEVEL_TYPE_PERSON (0x1041) 188 * <li>MDLEVEL_TYPE_COMPANY (0x1042) 189 * <li>MDLEVEL_TYPE_CURRENCY_SOURCE (0x1051) 190 * <li>MDLEVEL_TYPE_CURRENCY_DESTINATION (0x1052) 191 * <li>MDLEVEL_TYPE_CHANNEL (0x1061) 192 * <li>MDLEVEL_TYPE_REPRESENTATIVE (0x1062) 193 * <li>MDLEVEL_TYPE_PROMOTION (0x1071) 194 * </ul> 195 * 196 * @see Level#getLevelType 197 * @see org.olap4j.OlapDatabaseMetaData#getLevels 198 */ 199 public enum Type implements XmlaConstant { 200 201 /** 202 * Indicates that the level is not related to time. 203 * 204 * <p>Corresponds to the OLE DB for OLAP constant 205 * <code>MDLEVEL_TYPE_REGULAR(0x0000)</code>.</p> 206 */ 207 REGULAR(0x0000), 208 209 /** 210 * Indicates that the level contains the 'all' member of its hierarchy. 211 * 212 * <p>Corresponds to the OLE DB for OLAP constant 213 * <code>MDLEVEL_TYPE_ALL(0x0001)</code>.</p> 214 */ 215 ALL(0x0001), 216 217 /** 218 * Indicates that a level holds the null member. Does not correspond to 219 * an XMLA or OLE DB value. 220 */ 221 NULL(-1), 222 223 /** 224 * Indicates that a level refers to years. 225 * 226 * <p>Corresponds to the OLE DB for OLAP constant 227 * <code>MDLEVEL_TYPE_TIME_YEARS(0x0014)</code>.</p> 228 * 229 * <p>It must be used in a dimension whose type is 230 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 231 */ 232 TIME_YEARS(0x0014), 233 234 /** 235 * Indicates that a level refers to half years. 236 * 237 * <p>Corresponds to the OLE DB for OLAP constant 238 * <code>MDLEVEL_TYPE_TIME_HALF_YEAR(0x0304)</code>.</p> 239 * 240 * <p>It must be used in a dimension whose type is 241 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 242 */ 243 TIME_HALF_YEAR(0x0024), 244 245 /** 246 * Indicates that a level refers to quarters. 247 * 248 * <p>Corresponds to the OLE DB for OLAP constant 249 * <code>MDLEVEL_TYPE_TIME_QUARTERS(0x0044)</code>.</p> 250 * 251 * <p>It must be used in a dimension whose type is 252 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 253 */ 254 TIME_QUARTERS(0x0044), 255 256 /** 257 * Indicates that a level refers to months. 258 * 259 * <p>Corresponds to the OLE DB for OLAP constant 260 * <code>MDLEVEL_TYPE_TIME_MONTHS(0x0084)</code>.</p> 261 * 262 * <p>It must be used in a dimension whose type is 263 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 264 */ 265 TIME_MONTHS(0x0084), 266 267 /** 268 * Indicates that a level refers to weeks. 269 * 270 * <p>Corresponds to the OLE DB for OLAP constant 271 * <code>MDLEVEL_TYPE_TIME_WEEKS(0x0104)</code>.</p> 272 * 273 * <p>It must be used in a dimension whose type is 274 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 275 */ 276 TIME_WEEKS(0x0104), 277 278 /** 279 * Indicates that a level refers to days. 280 * 281 * <p>Corresponds to the OLE DB for OLAP constant 282 * <code>MDLEVEL_TYPE_TIME_DAYS(0x0204)</code>.</p> 283 * 284 * <p>It must be used in a dimension whose type is 285 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 286 */ 287 TIME_DAYS(0x0204), 288 289 /** 290 * Indicates that a level refers to hours. 291 * 292 * <p>Corresponds to the OLE DB for OLAP constant 293 * <code>MDLEVEL_TYPE_TIME_HOURS(0x0304)</code>.</p> 294 * 295 * <p>It must be used in a dimension whose type is 296 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 297 */ 298 TIME_HOURS(0x0304), 299 300 /** 301 * Indicates that a level refers to minutes. 302 * 303 * <p>Corresponds to the OLE DB for OLAP constant 304 * <code>MDLEVEL_TYPE_TIME_MINUTES(0x0404)</code>.</p> 305 * 306 * <p>It must be used in a dimension whose type is 307 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 308 */ 309 TIME_MINUTES(0x0404), 310 311 /** 312 * Indicates that a level refers to seconds. 313 * 314 * <p>Corresponds to the OLE DB for OLAP constant 315 * <code>MDLEVEL_TYPE_TIME_SECONDS(0x0804)</code>.</p> 316 * 317 * <p>It must be used in a dimension whose type is 318 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 319 */ 320 TIME_SECONDS(0x0804), 321 322 /** 323 * Indicates that a level refers to an unspecified time unit. 324 * 325 * <p>Corresponds to the OLE DB for OLAP constant 326 * <code>MDLEVEL_TYPE_TIME_UNDEFINED(0x1004)</code>.</p> 327 * 328 * <p>It must be used in a dimension whose type is 329 * {@link org.olap4j.metadata.Dimension.Type#TIME}.</p> 330 */ 331 TIME_UNDEFINED(0x1004), 332 333 /** Corresponds to XMLA constant 334 * <code>MDLEVEL_TYPE_GEO_CONTINENT(0x2001)</code>. */ 335 GEO_CONTINENT(0x2001), 336 337 /** Corresponds to XMLA constant 338 * <code>MDLEVEL_TYPE_GEO_REGION(0x2002)</code>. */ 339 GEO_REGION(0x2002), 340 341 /** Corresponds to XMLA constant 342 * <code>MDLEVEL_TYPE_GEO_COUNTRY(0x2003)</code>. */ 343 GEO_COUNTRY(0x2003), 344 345 /** Corresponds to XMLA constant 346 * <code>MDLEVEL_TYPE_GEO_STATE_OR_PROVINCE(0x2004)</code>. */ 347 GEO_STATE_OR_PROVINCE(0x2004), 348 349 /** Corresponds to XMLA constant 350 * <code>MDLEVEL_TYPE_GEO_COUNTY(0x2005)</code>. */ 351 GEO_COUNTY(0x2005), 352 353 /** Corresponds to XMLA constant 354 * <code>MDLEVEL_TYPE_GEO_CITY(0x2006)</code>. */ 355 GEO_CITY(0x2006), 356 357 /** Corresponds to XMLA constant 358 * <code>MDLEVEL_TYPE_GEO_POSTALCODE(0x2007)</code>. */ 359 GEO_POSTALCODE(0x2007), 360 361 /** Corresponds to XMLA constant 362 * <code>MDLEVEL_TYPE_GEO_POINT(0x2008)</code>. */ 363 GEO_POINT(0x2008), 364 365 /** Corresponds to XMLA constant 366 * <code>MDLEVEL_TYPE_ORG_UNIT(0x1011)</code>. */ 367 ORG_UNIT(0x1011), 368 369 /** Corresponds to XMLA constant 370 * <code>MDLEVEL_TYPE_BOM_RESOURCE(0x1012)</code>. */ 371 BOM_RESOURCE(0x1012), 372 373 /** Corresponds to XMLA constant 374 * <code>MDLEVEL_TYPE_QUANTITATIVE(0x1013)</code>. */ 375 QUANTITATIVE(0x1013), 376 377 /** Corresponds to XMLA constant 378 * <code>MDLEVEL_TYPE_ACCOUNT(0x1014)</code>. */ 379 ACCOUNT(0x1014), 380 381 /** Corresponds to XMLA constant 382 * <code>MDLEVEL_TYPE_CUSTOMER(0x1021)</code>. */ 383 CUSTOMER(0x1021), 384 385 /** Corresponds to XMLA constant 386 * <code>MDLEVEL_TYPE_CUSTOMER_GROUP(0x1022)</code>. */ 387 CUSTOMER_GROUP(0x1022), 388 389 /** Corresponds to XMLA constant 390 * <code>MDLEVEL_TYPE_CUSTOMER_HOUSEHOLD(0x1023)</code>. */ 391 CUSTOMER_HOUSEHOLD(0x1023), 392 393 /** Corresponds to XMLA constant 394 * <code>MDLEVEL_TYPE_PRODUCT(0x1031)</code>. */ 395 PRODUCT(0x1031), 396 397 /** Corresponds to XMLA constant 398 * <code>MDLEVEL_TYPE_PRODUCT_GROUP(0x1032)</code>. */ 399 PRODUCT_GROUP(0x1032), 400 401 /** Corresponds to XMLA constant 402 * <code>MDLEVEL_TYPE_SCENARIO(0x1015)</code>. */ 403 SCENARIO(0x1015), 404 405 /** Corresponds to XMLA constant 406 * <code>MDLEVEL_TYPE_UTILITY(0x1016)</code>. */ 407 UTILITY(0x1016), 408 409 /** Corresponds to XMLA constant 410 * <code>MDLEVEL_TYPE_PERSON(0x1041)</code>. */ 411 PERSON(0x1041), 412 413 /** Corresponds to XMLA constant 414 * <code>MDLEVEL_TYPE_COMPANY(0x1042)</code>. */ 415 COMPANY(0x1042), 416 417 /** Corresponds to XMLA constant 418 * <code>MDLEVEL_TYPE_CURRENCY_SOURCE(0x1051)</code>. */ 419 CURRENCY_SOURCE(0x1051), 420 421 /** Corresponds to XMLA constant 422 * <code>MDLEVEL_TYPE_CURRENCY_DESTINATION(0x1052)</code>. */ 423 CURRENCY_DESTINATION(0x1052), 424 425 /** Corresponds to XMLA constant 426 * <code>MDLEVEL_TYPE_CHANNEL(0x1061)</code>. */ 427 CHANNEL(0x1061), 428 429 /** Corresponds to XMLA constant 430 * <code>MDLEVEL_TYPE_REPRESENTATIVE(0x1062)</code>. */ 431 REPRESENTATIVE(0x1062), 432 433 /** Corresponds to XMLA constant 434 * <code>MDLEVEL_TYPE_PROMOTION(0x1071)</code>. */ 435 PROMOTION(0x1071); 436 437 private final int xmlaOrdinal; 438 439 private static final Dictionary<Type> DICTIONARY = 440 DictionaryImpl.forClass(Type.class); 441 442 /** 443 * Per {@link org.olap4j.metadata.XmlaConstant}, returns a dictionary 444 * of all values of this enumeration. 445 * 446 * @return Dictionary of all values 447 */ 448 public static Dictionary<Type> getDictionary() { 449 return DICTIONARY; 450 } 451 452 /** 453 * Creates a level type. 454 * 455 * @param xmlaOrdinal Ordinal code in XMLA or OLE DB for OLAP 456 * specification 457 */ 458 private Type(int xmlaOrdinal) { 459 this.xmlaOrdinal = xmlaOrdinal; 460 } 461 462 public String xmlaName() { 463 return "MDLEVEL_TYPE_" + name(); 464 } 465 466 public String getDescription() { 467 return ""; 468 } 469 470 public int xmlaOrdinal() { 471 return xmlaOrdinal; 472 } 473 474 /** 475 * Returns whether this is a time-related level 476 * ({@link #TIME_YEARS}, 477 * {@link #TIME_HALF_YEAR}, 478 * {@link #TIME_QUARTERS}, 479 * {@link #TIME_MONTHS}, 480 * {@link #TIME_WEEKS}, 481 * {@link #TIME_DAYS}, 482 * {@link #TIME_HOURS}, 483 * {@link #TIME_MINUTES}, 484 * {@link #TIME_SECONDS}, 485 * {@link #TIME_UNDEFINED}). 486 * 487 * @return whether this is a time-related level 488 */ 489 public boolean isTime() { 490 switch (this) { 491 case TIME_YEARS: 492 case TIME_HALF_YEAR: 493 case TIME_QUARTERS: 494 case TIME_MONTHS: 495 case TIME_WEEKS: 496 case TIME_DAYS: 497 case TIME_HOURS: 498 case TIME_MINUTES: 499 case TIME_SECONDS: 500 case TIME_UNDEFINED: 501 return true; 502 default: 503 return false; 504 } 505 } 506 } 507} 508 509// End Level.java