KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > rolap > RolapAggregator


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/rolap/RolapAggregator.java#16 $
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) 2003-2006 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10 package mondrian.rolap;
11
12 import mondrian.calc.Calc;
13 import mondrian.olap.*;
14 import mondrian.olap.fun.FunUtil;
15
16 import java.util.List JavaDoc;
17
18 /**
19  * Describes an aggregation operator, such as "sum" or "count".
20  *
21  * @author jhyde
22  * @since Jul 9, 2003
23  * @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapAggregator.java#16 $
24  */

25 public abstract class RolapAggregator
26         extends EnumeratedValues.BasicValue
27         implements Aggregator {
28
29     private static int index = 0;
30
31     public static final RolapAggregator Sum =
32             new RolapAggregator("sum", index++, false) {
33                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
34                     return FunUtil.sum(evaluator, members, exp);
35                 }
36             };
37
38     public static final RolapAggregator Count =
39             new RolapAggregator("count", index++, false) {
40                 public Aggregator getRollup() {
41                     return Sum;
42                 }
43                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
44                     return FunUtil.count(evaluator, members, false);
45                 }
46             };
47
48     public static final RolapAggregator Min =
49             new RolapAggregator("min", index++, false) {
50                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
51                     return FunUtil.min(evaluator, members, exp);
52                 }
53             };
54
55     public static final RolapAggregator Max =
56             new RolapAggregator("max", index++, false) {
57                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
58                     return FunUtil.max(evaluator, members, exp);
59                 }
60             };
61
62     public static final RolapAggregator Avg =
63             new RolapAggregator("avg", index++, false) {
64                 public Aggregator getRollup() {
65                     return null;
66                 }
67                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
68                     return FunUtil.avg(evaluator, members, exp);
69                 }
70             };
71
72     public static final RolapAggregator DistinctCount =
73             new RolapAggregator("distinct-count", index++, true) {
74                 public Aggregator getRollup() {
75                     // Distinct counts cannot always be rolled up, when they can,
76
// it's using Sum.
77
return Sum;
78                 }
79                 public RolapAggregator getNonDistinctAggregator() {
80                     return Count;
81                 }
82                 public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
83                     throw new UnsupportedOperationException JavaDoc();
84                 }
85                 public String JavaDoc getExpression(String JavaDoc operand) {
86                     return "count(distinct " + operand + ")";
87                 }
88             };
89
90     /**
91      * List of all valid aggregation operators.
92      */

93     public static final EnumeratedValues<RolapAggregator> enumeration =
94         new EnumeratedValues<RolapAggregator> (
95             new RolapAggregator[] {Sum, Count, Min, Max, Avg, DistinctCount});
96
97     /**
98      * This is the base class for implementing aggregators over sum and
99      * average columns in an aggregate table. These differ from the above
100      * aggregators in that these require not oly the operand to create
101      * the aggregation String expression, but also, the aggregate table's
102      * fact count column expression.
103      * These aggregators are NOT singletons like the above aggregators; rather,
104      * each is different because of the fact count column expression.
105      */

106     protected abstract static class BaseAggor extends RolapAggregator {
107         protected final String JavaDoc factCountExpr;
108
109         protected BaseAggor(final String JavaDoc name, final String JavaDoc factCountExpr) {
110             super(name, index++, false);
111             this.factCountExpr = factCountExpr;
112         }
113         public Object JavaDoc aggregate(Evaluator evaluator, List JavaDoc members, Calc exp) {
114             throw new UnsupportedOperationException JavaDoc();
115         }
116     }
117
118     /**
119      * Aggregator used for aggregate tables implementing the
120      * average aggregator.
121      *
122      * <p>It uses the aggregate table fact_count column
123      * and a sum measure to create the query used to generate an average:
124      * <blockquote>
125      * <code>
126      * avg == sum(column_sum) / sum(factcount).
127      * </code>
128      * </blockquote>
129      *
130      * <p>If the fact table has both a sum and average over the same column and
131      * the aggregate table only has a sum and fact count column, then the
132      * average aggregator can be generated using this aggregator.
133      */

134     public static class AvgFromSum extends BaseAggor {
135         public AvgFromSum(String JavaDoc factCountExpr) {
136             super("AvgFromSum", factCountExpr);
137         }
138         public String JavaDoc getExpression(String JavaDoc operand) {
139             StringBuilder JavaDoc buf = new StringBuilder JavaDoc(64);
140             buf.append("sum(");
141             buf.append(operand);
142             buf.append(") / sum(");
143             buf.append(factCountExpr);
144             buf.append(')');
145             return buf.toString();
146         }
147     }
148
149     /**
150      * Aggregator used for aggregate tables implementing the
151      * average aggregator.
152      *
153      * <p>It uses the aggregate table fact_count column
154      * and an average measure to create the query used to generate an average:
155      * <blockquote>
156      * <code>
157      * avg == sum(column_sum * factcount) / sum(factcount).
158      * </code>
159      * </blockquote>
160      *
161      * <p>If the fact table has both a sum and average over the same column and
162      * the aggregate table only has a average and fact count column, then the
163      * average aggregator can be generated using this aggregator.
164      */

165     public static class AvgFromAvg extends BaseAggor {
166         public AvgFromAvg(String JavaDoc factCountExpr) {
167             super("AvgFromAvg", factCountExpr);
168         }
169         public String JavaDoc getExpression(String JavaDoc operand) {
170             StringBuilder JavaDoc buf = new StringBuilder JavaDoc(64);
171             buf.append("sum(");
172             buf.append(operand);
173             buf.append(" * ");
174             buf.append(factCountExpr);
175             buf.append(") / sum(");
176             buf.append(factCountExpr);
177             buf.append(')');
178             return buf.toString();
179         }
180     }
181     /**
182      * This is an aggregator used for aggregate tables implementing the
183      * sum aggregator. It uses the aggregate table fact_count column
184      * and an average measure to create the query used to generate a sum:
185      * <pre>
186      * sum == sum(column_avg * factcount)
187      * </pre>
188      * If the fact table has both a sum and average over the same column and
189      * the aggregate table only has an average and fact count column, then the
190      * sum aggregator can be generated using this aggregator.
191      */

192     public static class SumFromAvg extends BaseAggor {
193         public SumFromAvg(String JavaDoc factCountExpr) {
194             super("SumFromAvg", factCountExpr);
195         }
196         public String JavaDoc getExpression(String JavaDoc operand) {
197             StringBuilder JavaDoc buf = new StringBuilder JavaDoc(64);
198             buf.append("sum(");
199             buf.append(operand);
200             buf.append(" * ");
201             buf.append(factCountExpr);
202             buf.append(')');
203             return buf.toString();
204         }
205     }
206
207
208
209
210     private final boolean distinct;
211
212     public RolapAggregator(String JavaDoc name, int ordinal, boolean distinct) {
213         super(name, ordinal, null);
214         this.distinct = distinct;
215     }
216
217     public boolean isDistinct() {
218         return distinct;
219     }
220
221     /**
222      * Returns the expression to apply this aggregator to an operand.
223      * For example, <code>getExpression("emp.sal")</code> returns
224      * <code>"sum(emp.sal)"</code>.
225      */

226     public String JavaDoc getExpression(String JavaDoc operand) {
227         StringBuilder JavaDoc buf = new StringBuilder JavaDoc(64);
228         buf.append(name);
229         buf.append('(');
230         if (distinct) {
231             buf.append("distinct ");
232         }
233         buf.append(operand);
234         buf.append(')');
235         return buf.toString();
236     }
237
238     /**
239      * If this is a distinct aggregator, returns the corresponding non-distinct
240      * aggregator, otherwise throws an error.
241      */

242     public RolapAggregator getNonDistinctAggregator() {
243         throw new UnsupportedOperationException JavaDoc();
244     }
245
246     /**
247      * Returns the aggregator used to roll up. By default, aggregators roll up
248      * themselves.
249      */

250     public Aggregator getRollup() {
251         return this;
252     }
253 }
254
255 // End RolapAggregator.java
256
Popular Tags