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