1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.olap.type.TupleType; 14 import mondrian.olap.type.SetType; 15 import mondrian.calc.Calc; 16 import mondrian.calc.ExpCompiler; 17 import mondrian.calc.ListCalc; 18 import mondrian.calc.impl.AbstractListCalc; 19 import mondrian.mdx.ResolvedFunCall; 20 import mondrian.resource.MondrianResource; 21 22 import java.util.List ; 23 import java.util.HashSet ; 24 import java.util.ArrayList ; 25 import java.util.Set ; 26 27 34 class ToggleDrillStateFunDef extends FunDefBase { 35 static final String [] ReservedWords = new String [] {"RECURSIVE"}; 36 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 37 "ToggleDrillState", 38 "ToggleDrillState(<Set1>, <Set2>[, RECURSIVE])", 39 "Toggles the drill state of members. This function is a combination of DrillupMember and DrilldownMember.", 40 new String []{"fxxx", "fxxxy"}, 41 ToggleDrillStateFunDef.class, 42 ReservedWords); 43 44 public ToggleDrillStateFunDef(FunDef dummyFunDef) { 45 super(dummyFunDef); 46 } 47 48 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 49 if (call.getArgCount() > 2) { 50 throw MondrianResource.instance().ToggleDrillStateRecursiveNotSupported.ex(); 51 } 52 final ListCalc listCalc0 = 53 compiler.compileList(call.getArg(0)); 54 final ListCalc listCalc1 = 55 compiler.compileList(call.getArg(1)); 56 if (((SetType) call.getType()).getArity() == 1) { 57 return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) { 58 public List evaluateList(Evaluator evaluator) { 59 final List <Member> list0 = listCalc0.evaluateList(evaluator); 60 final List <Member> list1 = listCalc1.evaluateList(evaluator); 61 return toggleDrillStateMembers(evaluator, list0, list1); 62 } 63 }; 64 } else { 65 return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) { 66 public List evaluateList(Evaluator evaluator) { 67 final List <Member[]> list0 = listCalc0.evaluateList(evaluator); 68 final List <Member> list1 = listCalc1.evaluateList(evaluator); 69 return toggleDrillStateTuples(evaluator, list0, list1); 70 } 71 }; 72 } 73 } 74 75 List <Member> toggleDrillStateMembers( 76 Evaluator evaluator, List <Member> v0, List <Member> list1) 77 { 78 if (list1.isEmpty()) { 79 return v0; 80 } 81 if (v0.isEmpty()) { 82 return v0; 83 } 84 Set <Member> set = new HashSet <Member>(); 85 set.addAll(list1); 86 List <Member> result = new ArrayList <Member>(); 87 int i = 0, n = v0.size(); 88 while (i < n) { 89 Member m = v0.get(i++); 90 result.add(m); 91 if (!set.contains(m)) { 92 continue; 93 } 94 boolean isDrilledDown = false; 95 if (i < n) { 96 Member nextMember = v0.get(i); 97 boolean strict = true; 98 if (FunUtil.isAncestorOf(m, nextMember, strict)) { 99 isDrilledDown = true; 100 } 101 } 102 if (isDrilledDown) { 103 do { 105 Member nextMember = v0.get(i); 106 boolean strict = true; 107 if (FunUtil.isAncestorOf(m, nextMember, strict)) { 108 i++; 109 } else { 110 break; 111 } 112 } while (i < n); 113 } else { 114 Member[] children = 115 evaluator.getSchemaReader().getMemberChildren(m); 116 for (Member child : children) { 117 result.add(child); 118 } 119 } 120 } 121 return result; 122 } 123 124 List <Member[]> toggleDrillStateTuples( 125 Evaluator evaluator, List <Member[]> v0, List <Member> list1) 126 { 127 if (list1.isEmpty()) { 128 return v0; 129 } 130 if (v0.isEmpty()) { 131 return v0; 132 } 133 Set <Member> set = new HashSet <Member>(); 134 set.addAll(list1); 135 List <Member[]> result = new ArrayList <Member[]>(); 136 int i = 0, n = v0.size(); 137 while (i < n) { 138 Member[] o = v0.get(i++); 139 result.add(o); 140 Member m = null; 141 int k = -1; 142 for (int j = 0; j < o.length; j++) { 143 Member member = o[j]; 144 if (set.contains(member)) { 145 k = j; 146 m = member; 147 break; 148 } 149 } 150 if (k == -1) { 151 continue; 152 } 153 boolean isDrilledDown = false; 154 if (i < n) { 155 Member[] next = v0.get(i); 156 Member nextMember = next[k]; 157 boolean strict = true; 158 if (FunUtil.isAncestorOf(m, nextMember, strict)) { 159 isDrilledDown = true; 160 } 161 } 162 if (isDrilledDown) { 163 do { 165 Member[] next = v0.get(i); 166 Member nextMember = next[k]; 167 boolean strict = true; 168 if (FunUtil.isAncestorOf(m, nextMember, strict)) { 169 i++; 170 } else { 171 break; 172 } 173 } while (i < n); 174 } else { 175 Member[] children = evaluator.getSchemaReader().getMemberChildren(m); 176 for (Member child : children) { 177 Member[] members = o.clone(); 178 members[k] = child; 179 result.add(members); 180 } 181 } 182 } 183 return result; 184 } 185 } 186 187 | Popular Tags |