KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/PropertiesFunDef.java#16 $
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) 2005-2006 Julian Hyde and others
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.*;
14 import mondrian.calc.impl.GenericCalc;
15 import mondrian.mdx.ResolvedFunCall;
16
17 /**
18  * Definition of the <code>Properties</code> MDX function.
19  *
20  * @author jhyde
21  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/PropertiesFunDef.java#16 $
22  * @since Mar 23, 2006
23  */

24 class PropertiesFunDef extends FunDefBase {
25     static final ResolverImpl Resolver = new ResolverImpl();
26
27     public PropertiesFunDef(
28             String JavaDoc name,
29             String JavaDoc signature,
30             String JavaDoc 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 JavaDoc 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 JavaDoc properties(Member member, String JavaDoc s) {
54         boolean matchCase = MondrianProperties.instance().CaseSensitive.get();
55         Object JavaDoc 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     /**
67      * Resolves calls to the <code>PROPERTIES</code> MDX function.
68      */

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         /**
94          * Deduces the category of a property. This is possible only if the
95          * name is a string literal, and the member's hierarchy is unambigous.
96          * If the type cannot be deduced, returns {@link Category#Value}.
97          *
98          * @param memberExp Expression for the member
99          * @param propertyNameExp Expression for the name of the property
100          * @return Category of the property
101          */

102         private int deducePropertyCategory(
103             Exp memberExp,
104             Exp propertyNameExp)
105         {
106             if (!(propertyNameExp instanceof Literal)) {
107                 return Category.Value;
108             }
109             String JavaDoc propertyName = (String JavaDoc) ((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                 // we'll likely get a runtime error
119
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 // End PropertiesFunDef.java
141

142
Popular Tags