001    /*
002    // $Id: TraditionalCellSetFormatter.java 482 2012-01-05 23:27:27Z jhyde $
003    //
004    // Licensed to Julian Hyde under one or more contributor license
005    // agreements. See the NOTICE file distributed with this work for
006    // additional information regarding copyright ownership.
007    //
008    // Julian Hyde licenses this file to you under the Apache License,
009    // Version 2.0 (the "License"); you may not use this file except in
010    // compliance with the License. You may obtain a copy of the License at:
011    //
012    // http://www.apache.org/licenses/LICENSE-2.0
013    //
014    // Unless required by applicable law or agreed to in writing, software
015    // distributed under the License is distributed on an "AS IS" BASIS,
016    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017    // See the License for the specific language governing permissions and
018    // limitations under the License.
019    */
020    package org.olap4j.layout;
021    
022    import org.olap4j.*;
023    import org.olap4j.metadata.Member;
024    
025    import java.io.PrintWriter;
026    import java.util.ArrayList;
027    import java.util.List;
028    
029    /**
030     * Formatter that can convert a {@link CellSet} into Mondrian's traditional
031     * layout.
032     *
033     * <p><b>This class is experimental. It is not part of the olap4j
034     * specification and is subject to change without notice.</b></p>
035     *
036     * @author jhyde
037     * @version $Id: TraditionalCellSetFormatter.java 482 2012-01-05 23:27:27Z jhyde $
038     * @since Apr 15, 2009
039     */
040    public class TraditionalCellSetFormatter implements CellSetFormatter {
041        public void format(
042            CellSet cellSet,
043            PrintWriter pw)
044        {
045            print(cellSet, pw);
046        }
047    
048        /**
049         * Prints a cell set.
050         *
051         * @param cellSet Cell set
052         * @param pw Writer
053         */
054        private static void print(CellSet cellSet, PrintWriter pw) {
055            pw.println("Axis #0:");
056            printAxis(pw, cellSet.getFilterAxis());
057            final List<CellSetAxis> axes = cellSet.getAxes();
058            final int axisCount = axes.size();
059            for (int i = 0; i < axisCount; i++) {
060                CellSetAxis axis = axes.get(i);
061                pw.println("Axis #" + (i + 1) + ":");
062                printAxis(pw, axis);
063            }
064            // Usually there are 3 axes: {filter, columns, rows}. Position is a
065            // {column, row} pair. We call printRows with axis=2. When it
066            // recurses to axis=-1, it prints.
067            List<Integer> pos = new ArrayList<Integer>(axisCount);
068            for (int i = 0; i < axisCount; i++) {
069                pos.add(-1);
070            }
071            if (axisCount == 0) {
072                printCell(cellSet, pw, pos);
073            } else {
074                printRows(cellSet, pw, axisCount - 1, pos);
075            }
076        }
077    
078        /**
079         * Prints the rows of cell set.
080         *
081         * @param cellSet Cell set
082         * @param pw Writer
083         * @param axis Axis ordinal
084         * @param pos Partial coordinate
085         */
086        private static void printRows(
087            CellSet cellSet, PrintWriter pw, int axis, List<Integer> pos)
088        {
089            final CellSetAxis _axis = cellSet.getAxes().get(axis);
090            final List<Position> positions = _axis.getPositions();
091            final int positionCount = positions.size();
092            for (int i = 0; i < positionCount; i++) {
093                pos.set(axis, i);
094                if (axis == 0) {
095                    int row =
096                        axis + 1 < pos.size()
097                            ? pos.get(axis + 1)
098                            : 0;
099                    pw.print("Row #" + row + ": ");
100                    printCell(cellSet, pw, pos);
101                    pw.println();
102                } else {
103                    printRows(cellSet, pw, axis - 1, pos);
104                }
105            }
106        }
107    
108        /**
109         * Prints an axis and its members.
110         *
111         * @param pw Print writer
112         * @param axis Axis
113         */
114        private static void printAxis(PrintWriter pw, CellSetAxis axis) {
115            List<Position> positions = axis.getPositions();
116            for (Position position : positions) {
117                boolean firstTime = true;
118                pw.print("{");
119                for (Member member : position.getMembers()) {
120                    if (! firstTime) {
121                        pw.print(", ");
122                    }
123                    pw.print(member.getUniqueName());
124                    firstTime = false;
125                }
126                pw.println("}");
127            }
128        }
129    
130        /**
131         * Prints the formatted value of a Cell at a given position.
132         *
133         * @param cellSet Cell set
134         * @param pw Print writer
135         * @param pos Cell coordinates
136         */
137        private static void printCell(
138            CellSet cellSet, PrintWriter pw, List<Integer> pos)
139        {
140            Cell cell = cellSet.getCell(pos);
141            pw.print(cell.getFormattedValue());
142        }
143    }
144    
145    // End TraditionalCellSetFormatter.java