KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/StrToTupleFunDef.java#4 $
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.calc.Calc;
13 import mondrian.calc.ExpCompiler;
14 import mondrian.calc.StringCalc;
15 import mondrian.calc.impl.AbstractMemberCalc;
16 import mondrian.calc.impl.AbstractTupleCalc;
17 import mondrian.mdx.ResolvedFunCall;
18 import mondrian.mdx.DimensionExpr;
19 import mondrian.mdx.HierarchyExpr;
20 import mondrian.olap.*;
21 import mondrian.olap.type.Type;
22 import mondrian.olap.type.TupleType;
23 import mondrian.olap.type.MemberType;
24 import mondrian.olap.type.StringType;
25 import mondrian.resource.MondrianResource;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.List JavaDoc;
29
30 /**
31  * Definition of the <code>StrToTuple</code> MDX function.
32  *
33  * @author jhyde
34  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/StrToTupleFunDef.java#4 $
35  * @since Mar 23, 2006
36  */

37 class StrToTupleFunDef extends FunDefBase {
38     static final ResolverImpl Resolver = new ResolverImpl();
39
40     private StrToTupleFunDef(int[] parameterTypes) {
41         super("StrToTuple",
42             "StrToTuple(<String Expression>)",
43             "Constructs a tuple from a string.",
44             Syntax.Function, Category.Tuple, parameterTypes);
45     }
46
47     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
48         final StringCalc stringCalc = compiler.compileString(call.getArg(0));
49         Type elementType = call.getType();
50         if (elementType instanceof MemberType) {
51             final Hierarchy hierarchy = elementType.getHierarchy();
52             return new AbstractMemberCalc(call, new Calc[] {stringCalc}) {
53                 public Member evaluateMember(Evaluator evaluator) {
54                     String JavaDoc string = stringCalc.evaluateString(evaluator);
55                     return parseMember(evaluator, string, hierarchy);
56                 }
57             };
58         } else {
59             TupleType tupleType = (TupleType) elementType;
60             final Hierarchy[] hierarchies =
61                 new Hierarchy[tupleType.elementTypes.length];
62             for (int i = 0; i < tupleType.elementTypes.length; i++) {
63                 hierarchies[i] = tupleType.elementTypes[i].getHierarchy();
64             }
65             return new AbstractTupleCalc(call, new Calc[] {stringCalc}) {
66                 public Member[] evaluateTuple(Evaluator evaluator) {
67                     String JavaDoc string = stringCalc.evaluateString(evaluator);
68                     return parseTuple(evaluator, string, hierarchies);
69                 }
70             };
71         }
72     }
73
74     /**
75      * Parses a tuple, such as "([Gender].[M], [Marital Status].[S])".
76      *
77      * @param evaluator Evaluator, provides a {@link mondrian.olap.SchemaReader}
78      * and {@link Cube}
79      * @param string String to parse
80      * @param hierarchies Hierarchies of the members
81      * @return Tuple represented as array of members
82      */

83     private Member[] parseTuple(
84         Evaluator evaluator, String JavaDoc string, Hierarchy[] hierarchies)
85     {
86         final Member[] members = new Member[hierarchies.length];
87         int i = StrToSetFunDef.parseTuple(
88             evaluator, string, 0, members, hierarchies);
89         // todo: check for garbage at end of string
90
return members;
91     }
92
93     private Member parseMember(
94         Evaluator evaluator, String JavaDoc string, Hierarchy hierarchy) {
95         Member[] members = {null};
96         int i = StrToSetFunDef.parseMember(
97             evaluator, string, 0, members, new Hierarchy[] {hierarchy}, 0);
98         // todo: check for garbage at end of string
99
return members[0];
100     }
101
102     public Exp createCall(Validator validator, Exp[] args) {
103         final int argCount = args.length;
104         if (argCount <= 1) {
105             throw MondrianResource.instance().MdxFuncArgumentsNum.ex(getName());
106         }
107         for (int i = 1; i < argCount; i++) {
108             final Exp arg = args[i];
109             if (arg instanceof DimensionExpr) {
110                 // if arg is a dimension, switch to dimension's default
111
// hierarchy
112
DimensionExpr dimensionExpr = (DimensionExpr) arg;
113                 Dimension dimension = dimensionExpr.getDimension();
114                 args[i] = new HierarchyExpr(dimension.getHierarchy());
115             } else if (arg instanceof Hierarchy) {
116                 // nothing
117
} else {
118                 throw MondrianResource.instance().MdxFuncNotHier.ex(
119                     i + 1, getName());
120             }
121         }
122         return super.createCall(validator, args);
123     }
124
125     public Type getResultType(Validator validator, Exp[] args) {
126         switch (args.length) {
127         case 1:
128             // This is a call to the standard version of StrToTuple,
129
// which doesn't give us any hints about type.
130
return new TupleType(null);
131
132         case 2:
133             final Type argType = args[1].getType();
134             return new MemberType(
135                 argType.getDimension(),
136                 argType.getHierarchy(),
137                 argType.getLevel(),
138                 null);
139
140         default: {
141             // This is a call to Mondrian's extended version of
142
// StrToTuple, of the form
143
// StrToTuple(s, <Hier1>, ... , <HierN>)
144
//
145
// The result is a tuple
146
// (<Hier1>, ... , <HierN>)
147
final List JavaDoc<Type> list = new ArrayList JavaDoc<Type>();
148             for (int i = 1; i < args.length; i++) {
149                 Exp arg = args[i];
150                 final Type type = arg.getType();
151                 list.add(type);
152             }
153             final Type[] types = list.toArray(new Type[list.size()]);
154             return new TupleType(types);
155         }
156         }
157     }
158
159     private static class ResolverImpl extends ResolverBase {
160         ResolverImpl() {
161             super("StrToTuple",
162                     "StrToTuple(<String Expression>)",
163                     "Constructs a tuple from a string.",
164                     Syntax.Function);
165         }
166
167         public FunDef resolve(
168                 Exp[] args, Validator validator, int[] conversionCount) {
169             if (args.length < 1) {
170                 return null;
171             }
172             Type type = args[0].getType();
173             if (!(type instanceof StringType)) {
174                 return null;
175             }
176             for (int i = 1; i < args.length; i++) {
177                 Exp exp = args[i];
178                 if (!(exp instanceof DimensionExpr)) {
179                     return null;
180                 }
181             }
182             int[] argTypes = new int[args.length];
183             argTypes[0] = Category.String;
184             for (int i = 1; i < argTypes.length; i++) {
185                 argTypes[i] = Category.Hierarchy;
186             }
187             return new StrToTupleFunDef(argTypes);
188         }
189
190         public FunDef getFunDef() {
191             return new StrToTupleFunDef(new int[] {Category.String});
192         }
193     }
194 }
195
196 // End StrToTupleFunDef.java
197
Popular Tags