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-release/3.0/src/main/mondrian/olap4j/MondrianOlap4jCellSetAxisMetaData.java#2 $
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