KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/CaseMatchFunDef.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.impl.ConstantCalc;
16 import mondrian.calc.impl.AbstractCalc;
17 import mondrian.mdx.ResolvedFunCall;
18
19 import java.util.List JavaDoc;
20 import java.util.ArrayList JavaDoc;
21
22 /**
23  * Definition of the matched <code>CASE</code> MDX operator.
24  *
25  * Syntax is:
26  * <blockquote><pre><code>Case &lt;Expression&gt;
27  * When &lt;Expression&gt; Then &lt;Expression&gt;
28  * [...]
29  * [Else &lt;Expression&gt;]
30  * End</code></blockquote>.
31  *
32  * @see CaseTestFunDef
33  * @author jhyde
34  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CaseMatchFunDef.java#3 $
35  * @since Mar 23, 2006
36  */

37 class CaseMatchFunDef extends FunDefBase {
38     static final ResolverImpl Resolver = new ResolverImpl();
39
40     private CaseMatchFunDef(FunDef dummyFunDef) {
41         super(dummyFunDef);
42     }
43
44     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
45         final Exp[] args = call.getArgs();
46         final List JavaDoc<Calc> calcList = new ArrayList JavaDoc<Calc>();
47         final Calc valueCalc =
48                 compiler.compileScalar(args[0], true);
49         calcList.add(valueCalc);
50         final int matchCount = (args.length - 1) / 2;
51         final Calc[] matchCalcs = new Calc[matchCount];
52         final Calc[] exprCalcs = new Calc[matchCount];
53         for (int i = 0, j = 1; i < exprCalcs.length; i++) {
54             matchCalcs[i] =
55                     compiler.compileScalar(args[j++], true);
56             calcList.add(matchCalcs[i]);
57             exprCalcs[i] =
58                     compiler.compileScalar(args[j++], true);
59             calcList.add(exprCalcs[i]);
60         }
61         final Calc defaultCalc =
62                 args.length % 2 == 0 ?
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
71                 Object JavaDoc value = valueCalc.evaluate(evaluator);
72                 for (int i = 0; i < matchCalcs.length; i++) {
73                     Object JavaDoc match = matchCalcs[i].evaluate(evaluator);
74                     if (match.equals(value)) {
75                         return exprCalcs[i].evaluate(evaluator);
76                     }
77                 }
78                 return defaultCalc.evaluate(evaluator);
79             }
80
81             public Calc[] getCalcs() {
82                 return calcs;
83             }
84         };
85     }
86
87     private static class ResolverImpl extends ResolverBase {
88         private ResolverImpl() {
89             super(
90                     "_CaseMatch",
91                     "Case <Expression> When <Expression> Then <Expression> [...] [Else <Expression>] End",
92                     "Evaluates various expressions, and returns the corresponding expression for the first which matches a particular value.",
93                     Syntax.Case);
94         }
95
96         public FunDef resolve(
97                 Exp[] args, Validator validator, int[] conversionCount) {
98             if (args.length < 3) {
99                 return null;
100             }
101             int valueType = args[0].getCategory();
102             int returnType = args[2].getCategory();
103             int j = 0;
104             int clauseCount = (args.length - 1) / 2;
105             int mismatchingArgs = 0;
106             if (!validator.canConvert(args[j++], valueType, conversionCount)) {
107                 mismatchingArgs++;
108             }
109             for (int i = 0; i < clauseCount; i++) {
110                 if (!validator.canConvert(args[j++], valueType, conversionCount)) {
111                     mismatchingArgs++;
112                 }
113                 if (!validator.canConvert(args[j++], returnType, conversionCount)) {
114                     mismatchingArgs++;
115                 }
116             }
117             if (j < args.length) {
118                 if (!validator.canConvert(args[j++], returnType, conversionCount)) {
119                     mismatchingArgs++;
120                 }
121             }
122             Util.assertTrue(j == args.length);
123             if (mismatchingArgs != 0) {
124                 return null;
125             }
126
127             FunDef dummy = createDummyFunDef(this, returnType, args);
128             return new CaseMatchFunDef(dummy);
129         }
130
131         public boolean requiresExpression(int k) {
132             return true;
133         }
134     }
135 }
136
137 // End CaseMatchFunDef.java
138
Popular Tags