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*/
020package org.olap4j.layout;
021
022import org.olap4j.*;
023import org.olap4j.metadata.Member;
024
025import java.io.PrintWriter;
026import java.util.ArrayList;
027import 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 */
040public 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