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) 2001-2005 Julian Hyde 008// Copyright (C) 2005-2013 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.olap; 012 013import mondrian.resource.MondrianResource; 014 015import java.util.List; 016 017/** 018 * <code>CubeBase</code> is an abstract implementation of {@link Cube}. 019 * 020 * @author jhyde 021 * @since 6 August, 2001 022 */ 023public abstract class CubeBase extends OlapElementBase implements Cube { 024 025 /** constraints indexes for adSchemaMembers 026 * 027 * http://msdn.microsoft.com/library/psdk/dasdk/mdx8h4k.htm 028 * check "Restrictions in the MEMBER Rowset" under MEMBER Rowset section 029 */ 030 public static final int CATALOG_NAME = 0; 031 public static final int SCHEMA_NAME = 1; 032 public static final int CUBE_NAME = 2; 033 public static final int DIMENSION_UNIQUE_NAME = 3; 034 public static final int HIERARCHY_UNIQUE_NAME = 4; 035 public static final int LEVEL_UNIQUE_NAME = 5; 036 public static final int LEVEL_NUMBER = 6; 037 public static final int MEMBER_NAME = 7; 038 public static final int MEMBER_UNIQUE_NAME = 8; 039 public static final int MEMBER_CAPTION = 9; 040 public static final int MEMBER_TYPE = 10; 041 public static final int Tree_Operator = 11; 042 public static final int maxNofConstraintsForAdSchemaMember = 12; 043 public static final int MDTREEOP_SELF = 0; 044 public static final int MDTREEOP_CHILDREN = 1; 045 public static final int MDPROP_USERDEFINED0 = 19; 046 047 protected final String name; 048 private final String uniqueName; 049 private final String description; 050 protected Dimension[] dimensions; 051 052 /** 053 * Creates a CubeBase. 054 * 055 * @param name Name 056 * @param caption Caption 057 * @param description Description 058 * @param dimensions List of dimensions 059 */ 060 protected CubeBase( 061 String name, 062 String caption, 063 boolean visible, 064 String description, 065 Dimension[] dimensions) 066 { 067 this.name = name; 068 this.caption = caption; 069 this.visible = visible; 070 this.description = description; 071 this.dimensions = dimensions; 072 this.uniqueName = Util.quoteMdxIdentifier(name); 073 } 074 075 // implement OlapElement 076 public String getName() { 077 return name; 078 } 079 080 public String getUniqueName() { 081 // return e.g. '[Sales Ragged]' 082 return uniqueName; 083 } 084 085 public String getQualifiedName() { 086 return MondrianResource.instance().MdxCubeName.str(getName()); 087 } 088 089 public Dimension getDimension() { 090 return null; 091 } 092 093 public Hierarchy getHierarchy() { 094 return null; 095 } 096 097 public String getDescription() { 098 return description; 099 } 100 101 public Dimension[] getDimensions() { 102 return dimensions; 103 } 104 105 public Hierarchy lookupHierarchy(Id.NameSegment s, boolean unique) { 106 for (Dimension dimension : dimensions) { 107 Hierarchy[] hierarchies = dimension.getHierarchies(); 108 for (Hierarchy hierarchy : hierarchies) { 109 String name = unique 110 ? hierarchy.getUniqueName() : hierarchy.getName(); 111 if (name.equals(s.getName())) { 112 return hierarchy; 113 } 114 } 115 } 116 return null; 117 } 118 119 public OlapElement lookupChild( 120 SchemaReader schemaReader, 121 Id.Segment s, 122 MatchType matchType) 123 { 124 Dimension mdxDimension = lookupDimension(s); 125 if (mdxDimension != null) { 126 return mdxDimension; 127 } 128 129 final List<Dimension> dimensions = schemaReader.getCubeDimensions(this); 130 131 // Look for hierarchies named '[dimension.hierarchy]'. 132 if (s instanceof Id.NameSegment) { 133 Hierarchy hierarchy = lookupHierarchy((Id.NameSegment)s, false); 134 if (hierarchy != null) { 135 return hierarchy; 136 } 137 } 138 139 // Try hierarchies, levels and members. 140 for (Dimension dimension : dimensions) { 141 OlapElement mdxElement = dimension.lookupChild( 142 schemaReader, s, matchType); 143 if (mdxElement != null) { 144 if (mdxElement instanceof Member 145 && MondrianProperties.instance().NeedDimensionPrefix.get()) 146 { 147 // With this property setting, don't allow members to be 148 // referenced without at least a dimension prefix. We 149 // allow [Store].[USA].[CA] or even [Store].[CA] but not 150 // [USA].[CA]. 151 continue; 152 } 153 return mdxElement; 154 } 155 } 156 return null; 157 } 158 159 /** 160 * Looks up a dimension in this cube based on a component of its name. 161 * 162 * @param s Name segment 163 * @return Dimension, or null if not found 164 */ 165 public Dimension lookupDimension(Id.Segment s) { 166 if (!(s instanceof Id.NameSegment)) { 167 return null; 168 } 169 final Id.NameSegment nameSegment = (Id.NameSegment) s; 170 for (Dimension dimension : dimensions) { 171 if (Util.equalName(dimension.getName(), nameSegment.name)) { 172 return dimension; 173 } 174 } 175 return null; 176 } 177 178 // ------------------------------------------------------------------------ 179 180 /** 181 * Returns the first level of a given type in this cube. 182 * 183 * @param levelType Level type 184 * @return First level of given type, or null 185 */ 186 private Level getTimeLevel(LevelType levelType) { 187 for (Dimension dimension : dimensions) { 188 if (dimension.getDimensionType() == DimensionType.TimeDimension) { 189 Hierarchy[] hierarchies = dimension.getHierarchies(); 190 for (Hierarchy hierarchy : hierarchies) { 191 Level[] levels = hierarchy.getLevels(); 192 for (Level level : levels) { 193 if (level.getLevelType() == levelType) { 194 return level; 195 } 196 } 197 } 198 } 199 } 200 return null; 201 } 202 203 public Level getYearLevel() { 204 return getTimeLevel(LevelType.TimeYears); 205 } 206 207 public Level getQuarterLevel() { 208 return getTimeLevel(LevelType.TimeQuarters); 209 } 210 211 public Level getMonthLevel() { 212 return getTimeLevel(LevelType.TimeMonths); 213 } 214 215 public Level getWeekLevel() { 216 return getTimeLevel(LevelType.TimeWeeks); 217 } 218} 219 220// End CubeBase.java