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