KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/CastFunDef.java#5 $
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-2007 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.olap.type.Type;
14 import mondrian.resource.MondrianResource;
15 import mondrian.calc.Calc;
16 import mondrian.calc.ExpCompiler;
17 import mondrian.calc.impl.GenericCalc;
18 import mondrian.mdx.ResolvedFunCall;
19 import mondrian.olap.fun.FunUtil;
20
21 /**
22  * Definition of the <code>CAST</code> MDX operator.
23  *
24  * <p><code>CAST</code> is a mondrian-specific extension to MDX, because the MDX
25  * standard does not define how values are to be converted from one
26  * type to another. Microsoft Analysis Services, for Resolver, uses the Visual
27  * Basic functions <code>CStr</code>, <code>CInt</code>, etc.
28  * The syntax for this operator was inspired by the <code>CAST</code> operator
29  * in the SQL standard.
30  *
31  * <p>Examples:<ul>
32  * <li><code>CAST(1 + 2 AS STRING)</code></li>
33  * <li><code>CAST('12.' || '56' AS NUMERIC)</code></li>
34  * <li><code>CAST('tr' || 'ue' AS BOOLEAN)</code></li>
35  * </ul>
36  *
37  * @author jhyde
38  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CastFunDef.java#5 $
39  * @since Sep 3, 2006
40  */

41 public class CastFunDef extends FunDefBase {
42     static final ResolverBase Resolver = new ResolverImpl();
43
44     private CastFunDef(FunDef dummyFunDef) {
45         super(dummyFunDef);
46     }
47
48     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
49         final Type targetType = call.getType();
50         final Exp arg = call.getArg(0);
51         final Calc calc = compiler.compileScalar(arg, false);
52         return new GenericCalc(arg) {
53             public Calc[] getCalcs() {
54                 return new Calc[] {calc};
55             }
56
57             public Object JavaDoc evaluate(Evaluator evaluator) {
58                 return calc.evaluate(evaluator);
59             }
60
61             public String JavaDoc evaluateString(Evaluator evaluator) {
62                 final Object JavaDoc o = evaluate(evaluator);
63                 if (o == null) {
64                     return null;
65                 }
66                 return String.valueOf(o);
67             }
68
69             public int evaluateInteger(Evaluator evaluator) {
70                 final Object JavaDoc o = evaluate(evaluator);
71                 if (o == null) {
72                     return FunUtil.IntegerNull;
73                 }
74                 if (o instanceof String JavaDoc) {
75                     return Integer.parseInt((String JavaDoc) o);
76                 }
77                 if (o instanceof Number JavaDoc) {
78                     return ((Number JavaDoc) o).intValue();
79                 }
80                 throw cannotConvert(o);
81             }
82
83             public double evaluateDouble(Evaluator evaluator) {
84                 final Object JavaDoc o = evaluate(evaluator);
85                 if (o == null) {
86                     return FunUtil.DoubleNull;
87                 }
88                 if (o instanceof String JavaDoc) {
89                     return Double.valueOf((String JavaDoc) o);
90                 }
91                 if (o instanceof Number JavaDoc) {
92                     return ((Number JavaDoc) o).doubleValue();
93                 }
94                 throw cannotConvert(o);
95             }
96
97             public boolean evaluateBoolean(Evaluator evaluator) {
98                 final Object JavaDoc o = evaluate(evaluator);
99                 if (o == null) {
100                     return FunUtil.BooleanNull;
101                 }
102                 if (o instanceof Boolean JavaDoc) {
103                     return (Boolean JavaDoc) o;
104                 }
105                 if (o instanceof String JavaDoc) {
106                     return Boolean.valueOf((String JavaDoc) o);
107                 }
108                 throw cannotConvert(o);
109             }
110
111             private RuntimeException JavaDoc cannotConvert(Object JavaDoc o) {
112                 return Util.newInternal(
113                     "cannot convert value '" + o +
114                     "' to targetType '" + targetType +
115                     "'");
116             }
117         };
118     }
119
120     /**
121      * Resolves calls to the CAST operator.
122      */

123     private static class ResolverImpl extends ResolverBase {
124
125         public ResolverImpl() {
126             super("Cast", "Cast(<Expression> AS <Type>)",
127                 "Converts values to another type.", Syntax.Cast);
128         }
129
130         public FunDef resolve(
131             Exp[] args, Validator validator, int[] conversionCount) {
132             if (args.length != 2) {
133                 return null;
134             }
135             if (!(args[1] instanceof Literal)) {
136                 return null;
137             }
138             Literal literal = (Literal) args[1];
139             String JavaDoc typeName = (String JavaDoc) literal.getValue();
140             int returnCategory;
141             if (typeName.equalsIgnoreCase("String")) {
142                 returnCategory = Category.String;
143             } else if (typeName.equalsIgnoreCase("Numeric")) {
144                 returnCategory = Category.Numeric;
145             } else if (typeName.equalsIgnoreCase("Boolean")) {
146                 returnCategory = Category.Logical;
147             } else if (typeName.equalsIgnoreCase("Integer")) {
148                 returnCategory = Category.Integer;
149             } else {
150                 throw MondrianResource.instance().CastInvalidType.ex(typeName);
151             }
152             final FunDef dummyFunDef =
153                 createDummyFunDef(this, returnCategory, args);
154             return new CastFunDef(dummyFunDef);
155         }
156     }
157 }
158
159 // End CastFunDef.java
160
Popular Tags