001    /*
002    // $Id:$
003    // This software is subject to the terms of the Eclipse Public License v1.0
004    // Agreement, available at the following URL:
005    // http://www.eclipse.org/legal/epl-v10.html.
006    // Copyright (C) 2009-2009 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package org.olap4j.layout;
011    
012    import org.olap4j.*;
013    import org.olap4j.metadata.Member;
014    
015    import java.io.PrintWriter;
016    import java.util.List;
017    import java.util.ArrayList;
018    
019    /**
020     * Formatter that can convert a {@link CellSet} into Mondrian's traditional
021     * layout.
022     *
023     * <p><b>This class is experimental. It is not part of the olap4j
024     * specification and is subject to change without notice.</b></p>
025     *
026     * @author jhyde
027     * @version $Id:$
028     * @since Apr 15, 2009
029     */
030    public class TraditionalCellSetFormatter implements CellSetFormatter {
031        public void format(
032            CellSet cellSet,
033            PrintWriter pw)
034        {
035            print(cellSet, pw);
036        }
037    
038        /**
039         * Prints a cell set.
040         *
041         * @param cellSet Cell set
042         * @param pw Writer
043         */
044        private static void print(CellSet cellSet, PrintWriter pw) {
045            pw.println("Axis #0:");
046            printAxis(pw, cellSet.getFilterAxis());
047            final List<CellSetAxis> axes = cellSet.getAxes();
048            final int axisCount = axes.size();
049            for (int i = 0; i < axisCount; i++) {
050                CellSetAxis axis = axes.get(i);
051                pw.println("Axis #" + (i + 1) + ":");
052                printAxis(pw, axis);
053            }
054            // Usually there are 3 axes: {filter, columns, rows}. Position is a
055            // {column, row} pair. We call printRows with axis=2. When it
056            // recurses to axis=-1, it prints.
057            List<Integer> pos = new ArrayList<Integer>(axisCount);
058            for (int i = 0; i < axisCount; i++) {
059                pos.add(-1);
060            }
061            printRows(cellSet, pw, axisCount - 1, pos);
062        }
063    
064        /**
065         * Prints the rows of cell set.
066         *
067         * @param cellSet Cell set
068         * @param pw Writer
069         * @param axis Axis ordinal
070         * @param pos Partial coordinate
071         */
072        private static void printRows(
073            CellSet cellSet, PrintWriter pw, int axis, List<Integer> pos)
074        {
075            CellSetAxis _axis = axis < 0
076                ? cellSet.getFilterAxis()
077                : cellSet.getAxes().get(axis);
078            List<Position> positions = _axis.getPositions();
079            final int positionCount = positions.size();
080            for (int i = 0; i < positionCount; i++) {
081                if (axis < 0) {
082                    if (i > 0) {
083                        pw.print(", ");
084                    }
085                    printCell(cellSet, pw, pos);
086                } else {
087                    pos.set(axis, i);
088                    if (axis == 0) {
089                        int row =
090                            axis + 1 < pos.size()
091                                ? pos.get(axis + 1)
092                                : 0;
093                        pw.print("Row #" + row + ": ");
094                    }
095                    printRows(cellSet, pw, axis - 1, pos);
096                    if (axis == 0) {
097                        pw.println();
098                    }
099                }
100            }
101        }
102    
103        /**
104         * Prints an axis and its members.
105         *
106         * @param pw Print writer
107         * @param axis Axis
108         */
109        private static void printAxis(PrintWriter pw, CellSetAxis axis) {
110            List<Position> positions = axis.getPositions();
111            for (Position position : positions) {
112                boolean firstTime = true;
113                pw.print("{");
114                for (Member member : position.getMembers()) {
115                    if (! firstTime) {
116                        pw.print(", ");
117                    }
118                    pw.print(member.getUniqueName());
119                    firstTime = false;
120                }
121                pw.println("}");
122            }
123        }
124    
125        /**
126         * Prints the formatted value of a Cell at a given position.
127         *
128         * @param cellSet Cell set
129         * @param pw Print writer
130         * @param pos Cell coordinates
131         */
132        private static void printCell(
133            CellSet cellSet, PrintWriter pw, List<Integer> pos)
134        {
135            Cell cell = cellSet.getCell(pos);
136            pw.print(cell.getFormattedValue());
137        }
138    }
139    
140    // End TraditionalCellSetFormatter.java