KickJava   Java API By Example, From Geeks To Geeks.

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


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

10 package mondrian.olap.fun;
11
12 import mondrian.olap.*;
13 import mondrian.calc.Calc;
14 import mondrian.calc.ExpCompiler;
15 import mondrian.calc.BooleanCalc;
16 import mondrian.calc.impl.ConstantCalc;
17 import mondrian.calc.impl.AbstractCalc;
18 import mondrian.mdx.ResolvedFunCall;
19
20 import java.util.List JavaDoc;
21 import java.util.ArrayList JavaDoc;
22
23 /**
24  * Definition of the tested <code>CASE</code> MDX operator.
25  *
26  * Syntax is:
27  * <blockquote><pre><code>Case
28  * When &lt;Logical Expression&gt; Then &lt;Expression&gt;
29  * [...]
30  * [Else &lt;Expression&gt;]
31  * End</code></blockquote>.
32  *
33  * @see CaseMatchFunDef
34  *
35  * @author jhyde
36  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CaseTestFunDef.java#3 $
37  * @since Mar 23, 2006
38  */

39 class CaseTestFunDef extends FunDefBase {
40     static final ResolverImpl Resolver = new ResolverImpl();
41
42     public CaseTestFunDef(FunDef dummyFunDef) {
43         super(dummyFunDef);
44     }
45
46     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
47         final Exp[] args = call.getArgs();
48         final BooleanCalc[] conditionCalcs =
49                 new BooleanCalc[args.length / 2];
50         final Calc[] exprCalcs =
51                 new Calc[args.length / 2];
52         final List JavaDoc<Calc> calcList = new ArrayList JavaDoc<Calc>();
53         for (int i = 0, j = 0; i < exprCalcs.length; i++) {
54             conditionCalcs[i] =
55                     compiler.compileBoolean(args[j++]);
56             calcList.add(conditionCalcs[i]);
57             exprCalcs[i] =
58                     compiler.compileScalar(args[j++], true);
59             calcList.add(exprCalcs[i]);
60         }
61         final Calc defaultCalc =
62                 args.length % 2 == 1 ?
63                 compiler.compileScalar(args[args.length - 1], true) :
64                 ConstantCalc.constantNull(call.getType());
65         calcList.add(defaultCalc);
66         final Calc[] calcs = calcList.toArray(new Calc[calcList.size()]);
67
68         return new AbstractCalc(call) {
69             public Object JavaDoc evaluate(Evaluator evaluator) {
70                 for (int i = 0; i < conditionCalcs.length; i++) {
71                     if (conditionCalcs[i].evaluateBoolean(evaluator)) {
72                         return exprCalcs[i].evaluate(evaluator);
73                     }
74                 }
75                 return defaultCalc.evaluate(evaluator);
76             }
77
78             public Calc[] getCalcs() {
79                 return calcs;
80             }
81         };
82     }
83
84     private static class ResolverImpl extends ResolverBase {
85         public ResolverImpl() {
86             super(
87                     "_CaseTest",
88                     "Case When <Logical Expression> Then <Expression> [...] [Else <Expression>] End",
89                     "Evaluates various conditions, and returns the corresponding expression for the first which evaluates to true.",
90                     Syntax.Case);
91         }
92
93         public FunDef resolve(
94                 Exp[] args, Validator validator, int[] conversionCount) {
95             if (args.length < 1) {
96                 return null;
97             }
98             int j = 0;
99             int clauseCount = args.length / 2;
100             int mismatchingArgs = 0;
101             int returnType = args[1].getCategory();
102             for (int i = 0; i < clauseCount; i++) {
103                 if (!validator.canConvert(args[j++], Category.Logical, conversionCount)) {
104                     mismatchingArgs++;
105                 }
106                 if (!validator.canConvert(args[j++], returnType, conversionCount)) {
107                     mismatchingArgs++;
108                 }
109             }
110             if (j < args.length) {
111                 if (!validator.canConvert(args[j++], returnType, conversionCount)) {
112                     mismatchingArgs++;
113                 }
114             }
115             Util.assertTrue(j == args.length);
116             if (mismatchingArgs != 0) {
117                 return null;
118             }
119             FunDef dummy = createDummyFunDef(this, returnType, args);
120             return new CaseTestFunDef(dummy);
121         }
122
123         public boolean requiresExpression(int k) {
124             return true;
125         }
126     }
127 }
128
129 // End CaseTestFunDef.java
130
Popular Tags