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