KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > olap > QueryAxis


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/QueryAxis.java#24 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 1998-2002 Kana Software, Inc.
7 // Copyright (C) 2001-2007 Julian Hyde and others
8 // All Rights Reserved.
9 // You must accept the terms of that agreement to use this software.
10 //
11 // jhyde, 20 January, 1999
12 */

13
14 package mondrian.olap;
15
16 import mondrian.calc.Calc;
17 import mondrian.calc.ExpCompiler;
18 import mondrian.calc.ExpCompiler.ResultStyle;
19 import mondrian.mdx.*;
20 import mondrian.olap.type.Type;
21 import mondrian.olap.type.TypeUtil;
22 import mondrian.resource.MondrianResource;
23
24 import java.io.PrintWriter JavaDoc;
25
26 /**
27  * An axis in an MDX query. For example, the typical MDX query has two axes,
28  * which appear as the "ON COLUMNS" and "ON ROWS" clauses.
29  *
30  * @version $Id: //open/mondrian/src/main/mondrian/olap/QueryAxis.java#24 $
31  */

32 public class QueryAxis extends QueryPart {
33
34     private boolean nonEmpty;
35     private Exp exp;
36     private final AxisOrdinal axisOrdinal;
37
38     /**
39      * Whether to show subtotals on this axis.
40      * The "(show\hide)Subtotals" operation changes its valud.
41      */

42     private SubtotalVisibility subtotalVisibility;
43     private final Id[] dimensionProperties;
44
45     /**
46      * Creates an axis.
47      *
48      * @param nonEmpty Whether to filter out members of this axis whose cells
49      * are all empty
50      * @param set Expression to populate the axis
51      * @param axisDef Which axis (ROWS, COLUMNS, etc.)
52      * @param subtotalVisibility Whether to show subtotals
53      * @param dimensionProperties List of dimension properties
54      */

55     public QueryAxis(
56             boolean nonEmpty,
57             Exp set,
58             AxisOrdinal axisDef,
59             SubtotalVisibility subtotalVisibility,
60             Id[] dimensionProperties) {
61         assert dimensionProperties != null;
62         this.nonEmpty = nonEmpty ||
63             MondrianProperties.instance().EnableNonEmptyOnAllAxis.get();
64         this.exp = set;
65         this.axisOrdinal = axisDef;
66         this.subtotalVisibility = subtotalVisibility;
67         this.dimensionProperties = dimensionProperties;
68     }
69
70     /**
71      * Creates an axis with no dimension properties.
72      *
73      * @see #QueryAxis(boolean,Exp,AxisOrdinal,mondrian.olap.QueryAxis.SubtotalVisibility,Id[])
74      */

75     public QueryAxis(
76             boolean nonEmpty,
77             Exp set,
78             AxisOrdinal axisDef,
79             SubtotalVisibility subtotalVisibility) {
80         this(nonEmpty, set, axisDef, subtotalVisibility, new Id[0]);
81     }
82
83     public Object JavaDoc clone() {
84         return new QueryAxis(nonEmpty, exp.clone(), axisOrdinal,
85             subtotalVisibility, dimensionProperties.clone());
86     }
87
88     static QueryAxis[] cloneArray(QueryAxis[] a) {
89         QueryAxis[] a2 = new QueryAxis[a.length];
90         for (int i = 0; i < a.length; i++) {
91             a2[i] = (QueryAxis) a[i].clone();
92         }
93         return a2;
94     }
95
96     public Object JavaDoc accept(MdxVisitor visitor) {
97         final Object JavaDoc o = visitor.visit(this);
98
99         // visit the expression which forms the axis
100
exp.accept(visitor);
101
102         return o;
103     }
104
105     public Calc compile(ExpCompiler compiler, ResultStyle[] resultStyles) {
106         Exp exp = this.exp;
107         if (axisOrdinal == AxisOrdinal.SLICER) {
108             exp = normalizeSlicerExpression(exp);
109             exp = exp.accept(compiler.getValidator());
110         }
111         return compiler.compile(exp, resultStyles);
112     }
113
114     private static Exp normalizeSlicerExpression(Exp exp) {
115         Exp slicer = exp;
116         if (slicer instanceof LevelExpr ||
117             slicer instanceof HierarchyExpr ||
118             slicer instanceof DimensionExpr) {
119
120             slicer = new UnresolvedFunCall(
121                     "DefaultMember", Syntax.Property, new Exp[] {
122                         slicer});
123         }
124         if (slicer == null) {
125             ;
126         } else if (slicer instanceof FunCall &&
127                    ((FunCall) slicer).getSyntax() == Syntax.Parentheses) {
128             slicer = new UnresolvedFunCall(
129                     "{}", Syntax.Braces, new Exp[] {
130                         slicer});
131         } else {
132             slicer = new UnresolvedFunCall(
133                     "{}", Syntax.Braces, new Exp[] {
134                         new UnresolvedFunCall(
135                                 "()", Syntax.Parentheses, new Exp[] {
136                                     slicer})});
137         }
138
139         return slicer;
140     }
141
142     public String JavaDoc getAxisName() {
143         return axisOrdinal.name();
144     }
145
146     /**
147      * Returns the ordinal of this axis, for example {@link AxisOrdinal#ROWS}.
148      */

149     public AxisOrdinal getAxisOrdinal() {
150         return axisOrdinal;
151     }
152
153     /**
154      * Returns whether the axis has the <code>NON EMPTY</code> property set.
155      */

156     public boolean isNonEmpty() {
157         return nonEmpty;
158     }
159
160     /**
161      * Sets whether the axis has the <code>NON EMPTY</code> property set.
162      * See {@link #isNonEmpty()}.
163      */

164     public void setNonEmpty(boolean nonEmpty) {
165         this.nonEmpty = nonEmpty;
166     }
167
168     /**
169      * Returns the expression which is used to compute the value of this axis.
170      */

171     public Exp getSet() {
172         return exp;
173     }
174
175     /**
176      * Sets the expression which is used to compute the value of this axis.
177      * See {@link #getSet()}.
178      */

179     public void setSet(Exp set) {
180         this.exp = set;
181     }
182
183     public void resolve(Validator validator) {
184         exp = validator.validate(exp, false);
185         final Type type = exp.getType();
186         if (!TypeUtil.isSet(type)) {
187             throw MondrianResource.instance().MdxAxisIsNotSet.ex(axisOrdinal.name());
188         }
189     }
190
191     public Object JavaDoc[] getChildren() {
192         return new Object JavaDoc[] {exp};
193     }
194
195     public void unparse(PrintWriter JavaDoc pw) {
196         if (nonEmpty) {
197             pw.print("NON EMPTY ");
198         }
199         if (exp != null) {
200             exp.unparse(pw);
201         }
202         if (dimensionProperties.length > 0) {
203             pw.print(" DIMENSION PROPERTIES ");
204             for (int i = 0; i < dimensionProperties.length; i++) {
205                 Id dimensionProperty = dimensionProperties[i];
206                 if (i > 0) {
207                     pw.print(", ");
208                 }
209                 dimensionProperty.unparse(pw);
210             }
211         }
212         if (axisOrdinal != AxisOrdinal.SLICER) {
213             pw.print(" ON " + axisOrdinal);
214         }
215     }
216
217     public void addLevel(Level level) {
218         Util.assertTrue(level != null, "addLevel needs level");
219         exp = new UnresolvedFunCall("Crossjoin", Syntax.Function, new Exp[]{
220             exp,
221             new UnresolvedFunCall("Members", Syntax.Property, new Exp[]{
222                 new LevelExpr(level)})});
223     }
224
225     void setSubtotalVisibility(boolean bShowSubtotals) {
226         subtotalVisibility = bShowSubtotals ?
227             SubtotalVisibility.Show :
228             SubtotalVisibility.Hide;
229     }
230
231     public SubtotalVisibility getSubtotalVisibility() {
232         return subtotalVisibility;
233     }
234
235     public void resetSubtotalVisibility() {
236         this.subtotalVisibility = SubtotalVisibility.Undefined;
237     }
238
239     public void validate(Validator validator) {
240         if (axisOrdinal == AxisOrdinal.SLICER) {
241             if (exp != null) {
242                 exp = validator.validate(exp, false);
243             }
244         }
245     }
246
247     public Id[] getDimensionProperties() {
248         return dimensionProperties;
249     }
250
251     /**
252      * <code>SubtotalVisibility</code> enumerates the allowed values of
253      * whether subtotals are visible.
254      */

255     public enum SubtotalVisibility {
256         Undefined,
257         Hide,
258         Show;
259     }
260
261 }
262
263 // End QueryAxis.java
264
Popular Tags