1 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 ; 23 import java.util.List ; 24 25 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 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 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 baseCube = 85 getBaseCubeofMeasure( 86 evaluator, members[measurePosition], baseCube); 87 List <Dimension> vMinusBDimensions = 88 getDimensionsToForceToAllLevel(virtualCube, baseCube, members); 89 final Member[] validMeasureMembers = 91 new Member[vMinusBDimensions.size() + members.length]; 92 System.arraycopy(members, 0, validMeasureMembers, 0, members.length); 93 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 <Dimension> getDimensionsToForceToAllLevel( 127 RolapCube virtualCube, 128 RolapCube baseCube, 129 Member[] memberArray) 130 { 131 List <Dimension> vMinusBDimensions = new ArrayList <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 (virtualCube.getDimensions()[i].getName().equals( 138 baseCube.getDimensions()[j].getName())) { 139 foundDim = true; 140 break; 141 } 142 } 143 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 return butDepends(getCalcs(), dimension); 168 } 169 } 170 } 171 172 | Popular Tags |