KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > olap > fun > TopBottomCountFunDef


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/TopBottomCountFunDef.java#7 $
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) 2002-2002 Kana Software, Inc.
7 // Copyright (C) 2002-2007 Julian Hyde and others
8 // All Rights Reserved.
9 // You must accept the terms of that agreement to use this software.
10 */

11 package mondrian.olap.fun;
12
13 import mondrian.calc.Calc;
14 import mondrian.calc.ExpCompiler;
15 import mondrian.calc.IntegerCalc;
16 import mondrian.calc.ListCalc;
17 import mondrian.calc.impl.AbstractListCalc;
18 import mondrian.calc.ExpCompiler.ResultStyle;
19 import mondrian.mdx.ResolvedFunCall;
20 import mondrian.olap.*;
21 import mondrian.olap.type.TupleType;
22
23 import java.util.List JavaDoc;
24
25 /**
26  * Definition of the <code>TopCount</code> and <code>BottomCount</code>
27  * MDX builtin functions.
28  *
29  * @author jhyde
30  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/TopBottomCountFunDef.java#7 $
31  * @since Mar 23, 2006
32  */

33 class TopBottomCountFunDef extends FunDefBase {
34     boolean top;
35
36     static final MultiResolver TopCountResolver = new MultiResolver(
37             "TopCount",
38             "TopCount(<Set>, <Count>[, <Numeric Expression>])",
39             "Returns a specified number of items from the top of a set, optionally ordering the set first.",
40             new String JavaDoc[]{"fxxnn", "fxxn"}) {
41         protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) {
42             return new TopBottomCountFunDef(dummyFunDef, true);
43         }
44     };
45
46     static final MultiResolver BottomCountResolver = new MultiResolver(
47             "BottomCount",
48             "BottomCount(<Set>, <Count>[, <Numeric Expression>])",
49             "Returns a specified number of items from the bottom of a set, optionally ordering the set first.",
50             new String JavaDoc[]{"fxxnn", "fxxn"}) {
51         protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) {
52             return new TopBottomCountFunDef(dummyFunDef, false);
53         }
54     };
55
56     public TopBottomCountFunDef(FunDef dummyFunDef, final boolean top) {
57         super(dummyFunDef);
58         this.top = top;
59     }
60
61     public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) {
62         // Compile the member list expression. Ask for a mutable list, because
63
// we're going to sortMembers it later.
64
final ListCalc listCalc =
65                 compiler.compileList(call.getArg(0), true);
66         final IntegerCalc integerCalc =
67                 compiler.compileInteger(call.getArg(1));
68         final Calc orderCalc =
69                 call.getArgCount() > 2 ?
70                 compiler.compileScalar(call.getArg(2), true) :
71                 null;
72         final int arity = call.getType() instanceof TupleType ?
73             ((TupleType) call.getType()).elementTypes.length :
74             1;
75         return new AbstractListCalc(call, new Calc[] {listCalc, integerCalc, orderCalc}) {
76             public List JavaDoc evaluateList(Evaluator evaluator) {
77                 // Use a native evaluator, if more efficient.
78
// TODO: Figure this out at compile time.
79
SchemaReader schemaReader = evaluator.getSchemaReader();
80                 NativeEvaluator nativeEvaluator =
81                         schemaReader.getNativeSetEvaluator(
82                                 call.getFunDef(), call.getArgs(), evaluator, this);
83                 if (nativeEvaluator != null) {
84                     return (List JavaDoc) nativeEvaluator.execute(ResultStyle.LIST);
85                 }
86
87                 List JavaDoc list = listCalc.evaluateList(evaluator);
88                 int n = integerCalc.evaluateInteger(evaluator);
89 // RME
90
if (n == mondrian.olap.fun.FunUtil.IntegerNull) {
91     return new java.util.ArrayList JavaDoc();
92 }
93                 if (orderCalc != null) {
94                     if (arity == 1) {
95                         sortMembers(
96                             evaluator.push(),
97                             (List JavaDoc<Member>) list,
98                             orderCalc, top, true);
99                     } else {
100                         sortTuples(
101                             evaluator.push(),
102                             (List JavaDoc<mondrian.olap.Member[]>) list,
103                             orderCalc, top, true, arity);
104                     }
105                 }
106                 if (n < list.size()) {
107                     list = list.subList(0, n);
108                 }
109                 return list;
110             }
111
112             public boolean dependsOn(Dimension dimension) {
113                 return anyDependsButFirst(getCalcs(), dimension);
114             }
115         };
116     }
117 }
118
119 // End TopBottomCountFunDef.java
120
Popular Tags