1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.calc.*; 14 import mondrian.calc.impl.GenericCalc; 15 import mondrian.mdx.ResolvedFunCall; 16 17 24 class PropertiesFunDef extends FunDefBase { 25 static final ResolverImpl Resolver = new ResolverImpl(); 26 27 public PropertiesFunDef( 28 String name, 29 String signature, 30 String description, 31 Syntax syntax, 32 int returnType, 33 int[] parameterTypes) { 34 super(name, signature, description, syntax, returnType, parameterTypes); 35 } 36 37 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 38 final MemberCalc memberCalc = compiler.compileMember(call.getArg(0)); 39 final StringCalc stringCalc = compiler.compileString(call.getArg(1)); 40 return new GenericCalc(call) { 41 public Object evaluate(Evaluator evaluator) { 42 return properties( 43 memberCalc.evaluateMember(evaluator), 44 stringCalc.evaluateString(evaluator)); 45 } 46 47 public Calc[] getCalcs() { 48 return new Calc[] {memberCalc, stringCalc}; 49 } 50 }; 51 } 52 53 static Object properties(Member member, String s) { 54 boolean matchCase = MondrianProperties.instance().CaseSensitive.get(); 55 Object o = member.getPropertyValue(s, matchCase); 56 if (o == null) { 57 if (!Util.isValidProperty(member, s)) { 58 throw new MondrianEvaluationException( 59 "Property '" + s + 60 "' is not valid for member '" + member + "'"); 61 } 62 } 63 return o; 64 } 65 66 69 private static class ResolverImpl extends ResolverBase { 70 private ResolverImpl() { 71 super("Properties", 72 "<Member>.Properties(<String Expression>)", 73 "Returns the value of a member property.", 74 Syntax.Method); 75 } 76 77 public FunDef resolve( 78 Exp[] args, Validator validator, int[] conversionCount) { 79 final int[] argTypes = new int[]{Category.Member, Category.String}; 80 final Exp propertyNameExp = args[1]; 81 final Exp memberExp = args[0]; 82 if ((args.length != 2) || 83 (memberExp.getCategory() != Category.Member) || 84 (propertyNameExp.getCategory() != Category.String)) { 85 return null; 86 } 87 int returnType = deducePropertyCategory(memberExp, propertyNameExp); 88 return new PropertiesFunDef( 89 getName(), getSignature(), getDescription(),getSyntax(), 90 returnType, argTypes); 91 } 92 93 102 private int deducePropertyCategory( 103 Exp memberExp, 104 Exp propertyNameExp) 105 { 106 if (!(propertyNameExp instanceof Literal)) { 107 return Category.Value; 108 } 109 String propertyName = (String ) ((Literal) propertyNameExp).getValue(); 110 Hierarchy hierarchy = memberExp.getType().getHierarchy(); 111 if (hierarchy == null) { 112 return Category.Value; 113 } 114 Level[] levels = hierarchy.getLevels(); 115 Property property = lookupProperty( 116 levels[levels.length - 1], propertyName); 117 if (property == null) { 118 return Category.Value; 120 } else { 121 switch (property.getType()) { 122 case TYPE_BOOLEAN: 123 return Category.Logical; 124 case TYPE_NUMERIC: 125 return Category.Numeric; 126 case TYPE_STRING: 127 return Category.String; 128 default: 129 throw Util.badValue(property.getType()); 130 } 131 } 132 } 133 134 public boolean requiresExpression(int k) { 135 return true; 136 } 137 } 138 } 139 140 142 | Popular Tags |