KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/ValidMeasureFunDef.java#3 $
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 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.calc.Calc;
13 import mondrian.calc.ExpCompiler;
14 import mondrian.calc.MemberCalc;
15 import mondrian.calc.TupleCalc;
16 import mondrian.calc.impl.AbstractCalc;
17 import mondrian.mdx.ResolvedFunCall;
18 import mondrian.olap.type.TypeUtil;
19 import mondrian.olap.*;
20 import mondrian.rolap.RolapCube;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24
25 /**
26  * Definition of the <code>ValidMeasure</code> MDX function.
27  *
28  * <p>Returns a valid measure in a virtual cube by forcing inapplicable
29  * dimensions to their top level.
30  *
31  * @author kwalker, mpflug
32  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/ValidMeasureFunDef.java#3 $
33  */

34 public class ValidMeasureFunDef extends FunDefBase
35 {
36     static final ValidMeasureFunDef instance = new ValidMeasureFunDef();
37
38     private ValidMeasureFunDef() {
39         super("ValidMeasure",
40                 "ValidMeasure(<Tuple>)",
41                 "Returns a valid measure in a virtual cube by forcing inapplicable dimensions to their top level.",
42                 "fnt");
43     }
44
45     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
46         final Calc calc;
47         final Exp arg = call.getArg(0);
48         if (TypeUtil.couldBeMember(arg.getType())) {
49             calc = compiler.compileMember(arg);
50         } else {
51             calc = compiler.compileTuple(arg);
52         }
53         return new CalcImpl(call, calc);
54     }
55
56     private static class CalcImpl
57         extends AbstractCalc {
58         private final Calc calc;
59
60         public CalcImpl(ResolvedFunCall call, Calc calc) {
61             super(call);
62             this.calc = calc;
63         }
64
65         public Object JavaDoc evaluate(Evaluator evaluator) {
66             final Member[] members;
67             if (calc instanceof MemberCalc) {
68                 members = new Member[1];
69                 members[0] = ((MemberCalc) calc).evaluateMember(evaluator);
70             } else {
71                 members = ((TupleCalc)calc).evaluateTuple(evaluator);
72             }
73             RolapCube baseCube = null;
74             RolapCube virtualCube = (RolapCube) evaluator.getCube();
75             // find the measure in the tuple
76
int measurePosition = -1;
77             for (int i = 0; i < members.length; i++) {
78                 if (members[i].getDimension().isMeasures()) {
79                     measurePosition = i;
80                     break;
81                 }
82             }
83             // problem: if measure is in two base cubes
84
baseCube =
85                 getBaseCubeofMeasure(
86                     evaluator, members[measurePosition], baseCube);
87             List JavaDoc<Dimension> vMinusBDimensions =
88                 getDimensionsToForceToAllLevel(virtualCube, baseCube, members);
89             // declare members array and fill in with all needed members
90
final Member[] validMeasureMembers =
91                 new Member[vMinusBDimensions.size() + members.length];
92             System.arraycopy(members, 0, validMeasureMembers, 0, members.length);
93             // start adding to validMeasureMembers at right place
94
for (int i = 0; i < vMinusBDimensions.size(); i++) {
95                 validMeasureMembers[members.length + i] =
96                     vMinusBDimensions.get(i).getHierarchy().getDefaultMember();
97             }
98             evaluator.setContext(validMeasureMembers);
99             return evaluator.evaluateCurrent();
100         }
101
102         public Calc[] getCalcs() {
103             return new Calc[] { calc };
104         }
105
106         private RolapCube getBaseCubeofMeasure(
107             Evaluator evaluator, Member member, RolapCube baseCube) {
108             final Cube[] cubes = evaluator.getSchemaReader().getCubes();
109             for (Cube cube1 : cubes) {
110                 RolapCube cube = (RolapCube) cube1;
111                 if (!cube.isVirtual()) {
112                     for (int j = 0; j < cube.getMeasuresMembers().length; j++) {
113                         if (cube.getMeasuresMembers()[j].getName().equals(
114                             member.getName())) {
115                             baseCube = cube;
116                         }
117                     }
118                 }
119                 if (baseCube != null) {
120                     break;
121                 }
122             }
123             return baseCube;
124         }
125
126         private List JavaDoc<Dimension> getDimensionsToForceToAllLevel(
127             RolapCube virtualCube,
128             RolapCube baseCube,
129             Member[] memberArray)
130         {
131             List JavaDoc<Dimension> vMinusBDimensions = new ArrayList JavaDoc<Dimension>();
132             boolean foundDim;
133             for (int i = 0; i < virtualCube.getDimensions().length; i++) {
134                 foundDim = false;
135                 for (int j = 0; j<baseCube.getDimensions().length; j++) {
136                     // if we find a match
137
if (virtualCube.getDimensions()[i].getName().equals(
138                         baseCube.getDimensions()[j].getName())) {
139                         foundDim = true;
140                         break;
141                     }
142                 }
143                 // we didn't find the dim in the base cube so we need to
144
// add the all member to the tuple
145
if (!foundDim &&!isDimInMembersArray(
146                     memberArray, virtualCube.getDimensions()[i])) {
147                     vMinusBDimensions.add(virtualCube.getDimensions()[i]);
148                 }
149             }
150             return vMinusBDimensions;
151         }
152
153         private boolean isDimInMembersArray(
154             Member[] members,
155             Dimension dimension)
156         {
157             for (Member member : members) {
158                 if (member.getName().equalsIgnoreCase(dimension.getName())) {
159                     return true;
160                 }
161             }
162             return false;
163         }
164
165         public boolean dependsOn(Dimension dimension) {
166             // depends on all dimensions
167
return butDepends(getCalcs(), dimension);
168         }
169     }
170 }
171
172 // End ValidMeasureFunDef.java
173
Popular Tags