001/* 002// $Id: Level.java 485 2012-01-17 06:57:57Z 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.metadata; 021 022import org.olap4j.OlapException; 023 024import java.util.List; 025 026/** 027 * Group of {@link Member} objects in a {@link Hierarchy}, 028 * all with the same attributes and at the same depth in the hierarchy. 029 * 030 * @author jhyde 031 * @version $Id: Level.java 485 2012-01-17 06:57:57Z jhyde $ 032 * @since Aug 23, 2006 033 */ 034public interface Level extends MetadataElement { 035 /** 036 * Returns the depth of this <code>Level</code>. 037 * 038 * <p>Note #1: In an access-controlled context, the first visible level of 039 * a hierarchy may not have a depth of 0.</p> 040 * 041 * <p>Note #2: In a parent-child hierarchy, the depth of a member (as 042 * returned by may not be the same as the depth of its level. 043 * 044 * @return depth of this level 045 */ 046 int getDepth(); 047 048 /** 049 * Returns the {@link Hierarchy} this <code>Level</code> belongs to. 050 * 051 * @return hierarchy this level belongs to 052 */ 053 Hierarchy getHierarchy(); 054 055 /** 056 * Returns the Dimension this <code>Level</code> belongs to. 057 * (Always equivalent to <code>getHierarchy().getDimension()</code>.) 058 * 059 * @return dimension this level belongs to 060 */ 061 Dimension getDimension(); 062 063 /** 064 * Returns the type of this <code>Level</code>. 065 * 066 * @return level type 067 */ 068 Level.Type getLevelType(); 069 070 /** 071 * Returns whether the level is calculated. 072 * 073 * @return Whether this level is calculated 074 */ 075 boolean isCalculated(); 076 077 /** 078 * Returns a list of definitions for the properties available to members 079 * of this <code>Level</code>. 080 * 081 * <p>The caller should assume that the list is immutable; 082 * if the caller modifies the list, behavior is undefined.</p> 083 * 084 * @see org.olap4j.OlapDatabaseMetaData#getProperties 085 * 086 * @return properties of this Level 087 */ 088 NamedList<Property> getProperties(); 089 090 /** 091 * Returns a list of {@link Member} objects that belong to this Level. 092 * 093 * <p>The list does not include calculated members.</p> 094 * 095 * <p>Some levels have a very many members. In this case, calling this 096 * method may be expensive in space and/or time and is not recommended.</p> 097 * 098 * <p>If you need to include calculated members, or if you need to query 099 * specific members or subsets of members in a level, consider instead 100 * generating and executing an MDX query with a single axis. MDX functions 101 * {@code AddCalculatedMembers}, {@code Filter} and {@code Order} are 102 * especially useful. For example, 103 * 104 * <pre>with member [Measures].[Zero] as 0 105 * select AddCalculatedMembers([Time].[Month].Members) on 0 106 * from [Sales] 107 * where [Measures].[Zero]</pre> 108 * 109 * returns the {@code [Month]} level including calculated members. The 110 * {@code [Measures].[Zero]} calculated member saves the OLAP server the 111 * effort of retrieving cell values.</p> 112 * 113 * <p>The members of a level do not have unique names, so unlike 114 * {@link Hierarchy#getRootMembers()} and 115 * {@link Member#getChildMembers()} the result type 116 * is a {@link List} not a {@link NamedList}. 117 * 118 * @return List of members in this Level 119 * 120 * @throws OlapException if database error occurs 121 */ 122 List<Member> getMembers() throws OlapException; 123 124 /** 125 * Returns the number of members in this Level. 126 * 127 * @return number of members 128 */ 129 int getCardinality(); 130 131 /** 132 * Enumeration of the types of a {@link Level}. 133 * 134 * <p>Several of the values are defined by OLE DB for OLAP and/or XML/A, 135 * sans the "MDLEVEL_TYPE_" prefix to their name. For example, 136 * {@link #GEO_CONTINENT} corresponds to 137 * the value <code>MDLEVEL_TYPE_GEO_CONTINENT</code> for the 138 * <code>LEVEL_TYPE</code> property in the <code>MDSCHEMA_LEVELS</code> 139 * schema rowset. 140 * 141 * <p>Some of the values are specified by OLE DB for OLAP: 142 * <ul> 143 * <li>MDLEVEL_TYPE_REGULAR (0x0000) 144 * <li>MDLEVEL_TYPE_ALL (0x0001) 145 * <li>MDLEVEL_TYPE_TIME_YEARS (0x0014) 146 * <li>MDLEVEL_TYPE_TIME_HALF_YEAR (0x0024) 147 * <li>MDLEVEL_TYPE_TIME_QUARTERS (0x0044) 148 * <li>MDLEVEL_TYPE_TIME_MONTHS (0x0084) 149 * <li>MDLEVEL_TYPE_TIME_WEEKS (0x0104) 150 * <li>MDLEVEL_TYPE_TIME_DAYS (0x0204) 151 * <li>MDLEVEL_TYPE_TIME_HOURS (0x0304) 152 * <li>MDLEVEL_TYPE_TIME_MINUTES (0x0404) 153 * <li>MDLEVEL_TYPE_TIME_SECONDS (0x0804) 154 * <li>MDLEVEL_TYPE_TIME_UNDEFINED (0x1004) 155 * </ul> 156 * 157 * Some of the OLE DB for OLAP values are as flags, and do not become 158 * values of the enumeration: 159 * <ul> 160 * <li>MDLEVEL_TYPE_UNKNOWN (0x0000) signals that no other flags are set. 161 * Use {@link #REGULAR} 162 * <li>MDLEVEL_TYPE_CALCULATED (0x0002) indicates that the level is 163 * calculated. Use {@link Level#isCalculated}. 164 * <li>MDLEVEL_TYPE_TIME (0x0004) indicates that the level is time-related. 165 * Use {@link #isTime}. 166 * <li>MDLEVEL_TYPE_RESERVED1 (0x0008) is reserved for future use. 167 * </ul> 168 * 169 * <p>Some of the values are specified by XMLA: 170 * <ul> 171 * <li>MDLEVEL_TYPE_GEO_CONTINENT (0x2001) 172 * <li>MDLEVEL_TYPE_GEO_REGION (0x2002) 173 * <li>MDLEVEL_TYPE_GEO_COUNTRY (0x2003) 174 * <li>MDLEVEL_TYPE_GEO_STATE_OR_PROVINCE (0x2004) 175 * <li>MDLEVEL_TYPE_GEO_COUNTY (0x2005) 176 * <li>MDLEVEL_TYPE_GEO_CITY (0x2006) 177 * <li>MDLEVEL_TYPE_GEO_POSTALCODE (0x2007) 178 * <li>MDLEVEL_TYPE_GEO_POINT (0x2008) 179 * <li>MDLEVEL_TYPE_ORG_UNIT (0x1011) 180 * <li>MDLEVEL_TYPE_BOM_RESOURCE (0x1012) 181 * <li>MDLEVEL_TYPE_QUANTITATIVE (0x1013) 182 * <li>MDLEVEL_TYPE_ACCOUNT (0x1014) 183 * <li>MDLEVEL_TYPE_CUSTOMER (0x1021) 184 * <li>MDLEVEL_TYPE_CUSTOMER_GROUP (0x1022) 185 * <li>MDLEVEL_TYPE_CUSTOMER_HOUSEHOLD (0x1023) 186 * <li>MDLEVEL_TYPE_PRODUCT (0x1031) 187 * <li>MDLEVEL_TYPE_PRODUCT_GROUP (0x1032) 188 * <li>MDLEVEL_TYPE_SCENARIO (0x1015) 189 * <li>MDLEVEL_TYPE_UTILITY (0x1016) 190 * <li>MDLEVEL_TYPE_PERSON (0x1041) 191 * <li>MDLEVEL_TYPE_COMPANY (0x1042) 192 * <li>MDLEVEL_TYPE_CURRENCY_SOURCE (0x1051) 193 * <li>MDLEVEL_TYPE_CURRENCY_DESTINATION (0x1052) 194 * <li>MDLEVEL_TYPE_CHANNEL (0x1061) 195 * <li>MDLEVEL_TYPE_REPRESENTATIVE (0x1062) 196 * <li>MDLEVEL_TYPE_PROMOTION (0x1071) 197 * </ul> 198 * 199 * @see Level#getLevelType 200 * @see org.olap4j.OlapDatabaseMetaData#getLevels 201 */ 202 public enum Type implements XmlaConstant { 203 204 /** 205 * Indicates that the level is not related to time. 206 */ 207 REGULAR(0x0000), 208 209 /** 210 * Indicates that the level contains the 'all' member of its hierarchy. 211 */ 212 ALL(0x0001), 213 214 /** 215 * Indicates that a level holds the null member. Does not correspond to 216 * an XMLA or OLE DB value. 217 */ 218 NULL(-1), 219 220 /** 221 * Indicates that a level refers to years. 222 * It must be used in a dimension whose type is 223 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 224 */ 225 TIME_YEARS(0x0014), 226 227 /** 228 * Indicates that a level refers to half years. 229 * It must be used in a dimension whose type is 230 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 231 */ 232 TIME_HALF_YEAR(0x0024), 233 234 /** 235 * Indicates that a level refers to quarters. 236 * It must be used in a dimension whose type is 237 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 238 */ 239 TIME_QUARTERS(0x0044), 240 241 /** 242 * Indicates that a level refers to months. 243 * It must be used in a dimension whose type is 244 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 245 */ 246 TIME_MONTHS(0x0084), 247 248 /** 249 * Indicates that a level refers to weeks. 250 * It must be used in a dimension whose type is 251 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 252 */ 253 TIME_WEEKS(0x0104), 254 255 /** 256 * Indicates that a level refers to days. 257 * It must be used in a dimension whose type is 258 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 259 */ 260 TIME_DAYS(0x0204), 261 262 /** 263 * Indicates that a level refers to hours. 264 * It must be used in a dimension whose type is 265 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 266 */ 267 TIME_HOURS(0x0304), 268 269 /** 270 * Indicates that a level refers to minutes. 271 * It must be used in a dimension whose type is 272 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 273 */ 274 TIME_MINUTES(0x0404), 275 276 /** 277 * Indicates that a level refers to seconds. 278 * It must be used in a dimension whose type is 279 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 280 */ 281 TIME_SECONDS(0x0804), 282 283 /** 284 * Indicates that a level refers to days. 285 * It must be used in a dimension whose type is 286 * {@link org.olap4j.metadata.Dimension.Type#TIME}. 287 */ 288 TIME_UNDEFINED(0x1004), 289 290 GEO_CONTINENT(0x2001), 291 GEO_REGION(0x2002), 292 GEO_COUNTRY(0x2003), 293 GEO_STATE_OR_PROVINCE(0x2004), 294 GEO_COUNTY(0x2005), 295 GEO_CITY(0x2006), 296 GEO_POSTALCODE(0x2007), 297 GEO_POINT(0x2008), 298 ORG_UNIT(0x1011), 299 BOM_RESOURCE(0x1012), 300 QUANTITATIVE(0x1013), 301 ACCOUNT(0x1014), 302 CUSTOMER(0x1021), 303 CUSTOMER_GROUP(0x1022), 304 CUSTOMER_HOUSEHOLD(0x1023), 305 PRODUCT(0x1031), 306 PRODUCT_GROUP(0x1032), 307 SCENARIO(0x1015), 308 UTILITY(0x1016), 309 PERSON(0x1041), 310 COMPANY(0x1042), 311 CURRENCY_SOURCE(0x1051), 312 CURRENCY_DESTINATION(0x1052), 313 CHANNEL(0x1061), 314 REPRESENTATIVE(0x1062), 315 PROMOTION(0x1071); 316 317 private final int xmlaOrdinal; 318 319 private static final Dictionary<Type> DICTIONARY = 320 DictionaryImpl.forClass(Type.class); 321 322 /** 323 * Per {@link org.olap4j.metadata.XmlaConstant}, returns a dictionary 324 * of all values of this enumeration. 325 * 326 * @return Dictionary of all values 327 */ 328 public static Dictionary<Type> getDictionary() { 329 return DICTIONARY; 330 } 331 332 /** 333 * Creates a level type. 334 * 335 * @param xmlaOrdinal Ordinal code in XMLA or OLE DB for OLAP 336 * specification 337 */ 338 private Type(int xmlaOrdinal) { 339 this.xmlaOrdinal = xmlaOrdinal; 340 } 341 342 public String xmlaName() { 343 return "MDLEVEL_TYPE_" + name(); 344 } 345 346 public String getDescription() { 347 return ""; 348 } 349 350 public int xmlaOrdinal() { 351 return xmlaOrdinal; 352 } 353 354 /** 355 * Returns whether this is a time-related level 356 * ({@link #TIME_YEARS}, 357 * {@link #TIME_HALF_YEAR}, 358 * {@link #TIME_QUARTERS}, 359 * {@link #TIME_MONTHS}, 360 * {@link #TIME_WEEKS}, 361 * {@link #TIME_DAYS}, 362 * {@link #TIME_HOURS}, 363 * {@link #TIME_MINUTES}, 364 * {@link #TIME_SECONDS}, 365 * {@link #TIME_UNDEFINED}). 366 * 367 * @return whether this is a time-related level 368 */ 369 public boolean isTime() { 370 switch (this) { 371 case TIME_YEARS: 372 case TIME_HALF_YEAR: 373 case TIME_QUARTERS: 374 case TIME_MONTHS: 375 case TIME_WEEKS: 376 case TIME_DAYS: 377 case TIME_HOURS: 378 case TIME_MINUTES: 379 case TIME_SECONDS: 380 case TIME_UNDEFINED: 381 return true; 382 default: 383 return false; 384 } 385 } 386 } 387} 388 389// End Level.java