1 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 ; 28 import java.util.List ; 29 30 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 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 string = stringCalc.evaluateString(evaluator); 68 return parseTuple(evaluator, string, hierarchies); 69 } 70 }; 71 } 72 } 73 74 83 private Member[] parseTuple( 84 Evaluator evaluator, String string, Hierarchy[] hierarchies) 85 { 86 final Member[] members = new Member[hierarchies.length]; 87 int i = StrToSetFunDef.parseTuple( 88 evaluator, string, 0, members, hierarchies); 89 return members; 91 } 92 93 private Member parseMember( 94 Evaluator evaluator, String string, Hierarchy hierarchy) { 95 Member[] members = {null}; 96 int i = StrToSetFunDef.parseMember( 97 evaluator, string, 0, members, new Hierarchy[] {hierarchy}, 0); 98 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 DimensionExpr dimensionExpr = (DimensionExpr) arg; 113 Dimension dimension = dimensionExpr.getDimension(); 114 args[i] = new HierarchyExpr(dimension.getHierarchy()); 115 } else if (arg instanceof Hierarchy) { 116 } 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 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 final List <Type> list = new ArrayList <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 | Popular Tags |