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) 2007-2012 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap4j; 011 012import mondrian.olap.*; 013import mondrian.rolap.RolapConnection; 014import mondrian.server.Locus; 015 016import org.olap4j.OlapException; 017import org.olap4j.impl.ArrayNamedListImpl; 018import org.olap4j.impl.Named; 019import org.olap4j.metadata.Dimension; 020import org.olap4j.metadata.Hierarchy; 021import org.olap4j.metadata.Level; 022import org.olap4j.metadata.Member; 023import org.olap4j.metadata.*; 024import org.olap4j.metadata.Property; 025 026import java.util.*; 027 028/** 029 * Implementation of {@link Level} 030 * for the Mondrian OLAP engine. 031 * 032 * @author jhyde 033 * @since May 25, 2007 034 */ 035class MondrianOlap4jLevel 036 extends MondrianOlap4jMetadataElement 037 implements Level, Named 038{ 039 final MondrianOlap4jSchema olap4jSchema; 040 final mondrian.olap.Level level; 041 042 /** 043 * Creates a MondrianOlap4jLevel. 044 * 045 * @param olap4jSchema Schema 046 * @param level Mondrian level 047 */ 048 MondrianOlap4jLevel( 049 MondrianOlap4jSchema olap4jSchema, 050 mondrian.olap.Level level) 051 { 052 this.olap4jSchema = olap4jSchema; 053 this.level = level; 054 } 055 056 public boolean equals(Object obj) { 057 return obj instanceof MondrianOlap4jLevel 058 && level.equals(((MondrianOlap4jLevel) obj).level); 059 } 060 061 public int hashCode() { 062 return level.hashCode(); 063 } 064 065 public int getDepth() { 066 return level.getDepth() - getDepthOffset(); 067 } 068 069 private int getDepthOffset() { 070 final Role.HierarchyAccess accessDetails = 071 olap4jSchema.olap4jCatalog.olap4jDatabaseMetaData.olap4jConnection 072 .getMondrianConnection2().getRole().getAccessDetails( 073 level.getHierarchy()); 074 if (accessDetails == null) { 075 return 0; 076 } 077 return accessDetails.getTopLevelDepth(); 078 } 079 080 public Hierarchy getHierarchy() { 081 return new MondrianOlap4jHierarchy(olap4jSchema, level.getHierarchy()); 082 } 083 084 public Dimension getDimension() { 085 return new MondrianOlap4jDimension(olap4jSchema, level.getDimension()); 086 } 087 088 public boolean isCalculated() { 089 return false; 090 } 091 092 public Type getLevelType() { 093 if (level.isAll()) { 094 return Type.ALL; 095 } 096 switch (level.getLevelType()) { 097 case Regular: 098 return Type.REGULAR; 099 case TimeDays: 100 return Type.TIME_DAYS; 101 case TimeHalfYears: 102 return Type.TIME_HALF_YEAR; 103 case TimeHours: 104 return Type.TIME_HOURS; 105 case TimeMinutes: 106 return Type.TIME_MINUTES; 107 case TimeMonths: 108 return Type.TIME_MONTHS; 109 case TimeQuarters: 110 return Type.TIME_QUARTERS; 111 case TimeSeconds: 112 return Type.TIME_SECONDS; 113 case TimeUndefined: 114 return Type.TIME_UNDEFINED; 115 case TimeWeeks: 116 return Type.TIME_WEEKS; 117 case TimeYears: 118 return Type.TIME_YEARS; 119 case Null: 120 default: 121 throw Util.unexpected(level.getLevelType()); 122 } 123 } 124 125 public NamedList<Property> getProperties() { 126 return getProperties(true); 127 } 128 129 /** 130 * Returns a list of this level's properties, optionally including standard 131 * properties that are available on every level. 132 * 133 * <p>NOTE: Not part of the olap4j API. 134 * 135 * @param includeStandard Whether to include standard properties 136 * @return List of properties 137 */ 138 NamedList<Property> getProperties(boolean includeStandard) { 139 final NamedList<Property> list = new ArrayNamedListImpl<Property>() { 140 public String getName(Object property) { 141 return ((Property)property).getName(); 142 } 143 }; 144 // standard properties first 145 if (includeStandard) { 146 list.addAll( 147 Arrays.asList(Property.StandardMemberProperty.values())); 148 list.addAll(MondrianOlap4jProperty.MEMBER_EXTENSIONS.values()); 149 } 150 // then level-specific properties 151 for (mondrian.olap.Property property : level.getProperties()) { 152 list.add(new MondrianOlap4jProperty(property)); 153 } 154 return list; 155 } 156 157 public List<Member> getMembers() throws OlapException { 158 final MondrianOlap4jConnection olap4jConnection = 159 olap4jSchema.olap4jCatalog.olap4jDatabaseMetaData.olap4jConnection; 160 final RolapConnection mondrianConnection = 161 olap4jConnection.getMondrianConnection(); 162 return Locus.execute( 163 mondrianConnection, 164 "Reading members of level", 165 new Locus.Action<List<Member>>() { 166 public List<Member> execute() { 167 final mondrian.olap.SchemaReader schemaReader = 168 mondrianConnection.getSchemaReader().withLocus(); 169 final List<mondrian.olap.Member> levelMembers = 170 schemaReader.getLevelMembers(level, true); 171 return new AbstractList<Member>() { 172 public Member get(int index) { 173 return olap4jConnection.toOlap4j( 174 levelMembers.get(index)); 175 } 176 177 public int size() { 178 return levelMembers.size(); 179 } 180 }; 181 } 182 }); 183 } 184 185 public String getName() { 186 return level.getName(); 187 } 188 189 public String getUniqueName() { 190 return level.getUniqueName(); 191 } 192 193 public String getCaption() { 194 return level.getLocalized( 195 OlapElement.LocalizedProperty.CAPTION, 196 olap4jSchema.getLocale()); 197 } 198 199 public String getDescription() { 200 return level.getLocalized( 201 OlapElement.LocalizedProperty.DESCRIPTION, 202 olap4jSchema.getLocale()); 203 } 204 205 public int getCardinality() { 206 return level.getApproxRowCount(); 207 } 208 209 public boolean isVisible() { 210 return level.isVisible(); 211 } 212 213 protected OlapElement getOlapElement() { 214 return level; 215 } 216} 217 218// End MondrianOlap4jLevel.java