001 /* 002 // This software is subject to the terms of the Common Public License 003 // Agreement, available at the following URL: 004 // http://www.opensource.org/licenses/cpl.html. 005 // Copyright (C) 2007-2007 Julian Hyde 006 // All Rights Reserved. 007 // You must accept the terms of that agreement to use this software. 008 */ 009 package mondrian.olap4j; 010 011 import org.olap4j.CellSetAxisMetaData; 012 import org.olap4j.Axis; 013 import org.olap4j.metadata.Hierarchy; 014 import org.olap4j.metadata.Property; 015 import org.olap4j.metadata.Dimension; 016 import mondrian.olap.*; 017 import mondrian.olap.type.*; 018 019 import java.util.*; 020 021 /** 022 * Implementation of {@link org.olap4j.CellSetMetaData} 023 * for the Mondrian OLAP engine. 024 * 025 * @author jhyde 026 * @version $Id: //open/mondrian/src/main/mondrian/olap4j/MondrianOlap4jCellSetAxisMetaData.java#3 $ 027 * @since Nov 17, 2007 028 */ 029 class MondrianOlap4jCellSetAxisMetaData implements CellSetAxisMetaData { 030 private final QueryAxis queryAxis; 031 private final MondrianOlap4jCellSetMetaData cellSetMetaData; 032 private final List<Property> propertyList = new ArrayList<Property>(); 033 034 MondrianOlap4jCellSetAxisMetaData( 035 MondrianOlap4jCellSetMetaData cellSetMetaData, 036 QueryAxis queryAxis) 037 { 038 if (queryAxis == null) { 039 queryAxis = new QueryAxis( 040 false, null, AxisOrdinal.SLICER, 041 QueryAxis.SubtotalVisibility.Undefined); 042 } 043 this.queryAxis = queryAxis; 044 this.cellSetMetaData = cellSetMetaData; 045 046 // populate property list 047 for (Id id : queryAxis.getDimensionProperties()) { 048 propertyList.add( 049 Property.StandardMemberProperty.valueOf( 050 id.toStringArray()[0])); 051 } 052 } 053 054 public Axis getAxisOrdinal() { 055 switch (queryAxis.getAxisOrdinal()) { 056 case SLICER: 057 return Axis.FILTER; 058 default: 059 return Axis.valueOf(queryAxis.getAxisOrdinal().name()); 060 } 061 } 062 063 public List<Hierarchy> getHierarchies() { 064 if (queryAxis.getAxisOrdinal() == AxisOrdinal.SLICER) { 065 // Slicer contains all dimensions not mentioned on other axes. 066 // The list contains the default hierarchy of 067 // each dimension not already in the slicer or in another axes. 068 Set<Dimension> dimensionSet = new HashSet<Dimension>(); 069 for (CellSetAxisMetaData cellSetAxisMetaData 070 : cellSetMetaData.getAxesMetaData()) { 071 for (Hierarchy hierarchy 072 : cellSetAxisMetaData.getHierarchies()) { 073 dimensionSet.add(hierarchy.getDimension()); 074 } 075 } 076 List<Hierarchy> hierarchyList = 077 new ArrayList<Hierarchy>(); 078 for (Dimension dimension 079 : cellSetMetaData.getCube().getDimensions()) { 080 if (dimensionSet.add(dimension)) { 081 hierarchyList.add(dimension.getDefaultHierarchy()); 082 } 083 } 084 // In case a dimension has multiple hierarchies, return the 085 // declared type of the slicer expression. For example, if the 086 // WHERE clause contains [Time].[Weekly].[1997].[Week 6], the 087 // slicer should contain [Time].[Weekly] not the default hierarchy 088 // [Time]. 089 for (Hierarchy hierarchy : getHierarchiesNonFilter()) { 090 if (hierarchy.getDimension().getHierarchies().size() == 1) { 091 continue; 092 } 093 for (int i = 0; i < hierarchyList.size(); i++) { 094 Hierarchy hierarchy1 = hierarchyList.get(i); 095 if (hierarchy1.getDimension().equals( 096 hierarchy.getDimension()) 097 && hierarchy1 != hierarchy) 098 { 099 hierarchyList.set(i, hierarchy); 100 } 101 } 102 } 103 return hierarchyList; 104 } else { 105 return getHierarchiesNonFilter(); 106 } 107 } 108 109 private List<Hierarchy> getHierarchiesNonFilter() { 110 final Exp exp = queryAxis.getSet(); 111 if (exp == null) { 112 return Collections.emptyList(); 113 } 114 Type type = exp.getType(); 115 if (type instanceof SetType) { 116 type = ((SetType) type).getElementType(); 117 } 118 final MondrianOlap4jConnection olap4jConnection = 119 cellSetMetaData.olap4jStatement.olap4jConnection; 120 if (type instanceof TupleType) { 121 final TupleType tupleType = (TupleType) type; 122 List<Hierarchy> hierarchyList = 123 new ArrayList<Hierarchy>(); 124 for (Type elementType : tupleType.elementTypes) { 125 hierarchyList.add( 126 olap4jConnection.toOlap4j( 127 elementType.getHierarchy())); 128 } 129 return hierarchyList; 130 } else { 131 return Collections.singletonList( 132 (Hierarchy) olap4jConnection.toOlap4j( 133 type.getHierarchy())); 134 } 135 } 136 137 public List<Property> getProperties() { 138 return propertyList; 139 } 140 } 141 142 // End MondrianOlap4jCellSetAxisMetaData.java