| 1 10 package mondrian.calc.impl; 11 12 import mondrian.olap.*; 13 import mondrian.olap.type.Type; 14 import mondrian.calc.Calc; 15 import mondrian.calc.CalcWriter; 16 import mondrian.calc.ExpCompiler; 17 import mondrian.mdx.ResolvedFunCall; 18 19 import java.io.PrintWriter ; 20 import java.util.List ; 21 import java.util.Collections ; 22 23 30 public abstract class AbstractCalc implements Calc { 31 protected final Type type; 32 protected final Exp exp; 33 34 protected AbstractCalc(Exp exp) { 35 assert exp != null; 36 this.exp = exp; 37 this.type = exp.getType(); 38 } 39 40 public Type getType() { 41 return type; 42 } 43 44 public void accept(CalcWriter calcWriter) { 45 final PrintWriter pw = calcWriter.getWriter(); 46 String name = getName(); 47 pw.print(name); 48 final Calc[] calcs = getCalcs(); 49 final List <Object > argumentList = getArguments(); 50 if (calcs.length > 0 || !argumentList.isEmpty()) { 51 pw.print("("); 52 int k = 0; 53 for (Calc calc : calcs) { 54 if (k++ > 0) { 55 pw.print(", "); 56 } 57 calc.accept(calcWriter); 58 } 59 for (Object o : argumentList) { 60 if (k++ > 0) { 61 pw.print(", "); 62 } 63 pw.print(o); 64 } 65 pw.print(")"); 66 } 67 } 68 69 76 protected String getName() { 77 String name; 78 if (exp instanceof ResolvedFunCall) { 79 ResolvedFunCall funCall = (ResolvedFunCall) exp; 80 name = funCall.getFunDef().getName(); 81 } else { 82 name = getClass().getName(); 83 int dot = name.lastIndexOf('.'); 84 int dollar = name.lastIndexOf('$'); 85 int dotDollar = Math.max(dot, dollar); 86 if (dotDollar >= 0) { 87 name = name.substring(dotDollar + 1); 88 } 89 } 90 return name; 91 } 92 93 96 public abstract Calc[] getCalcs(); 97 98 public boolean dependsOn(Dimension dimension) { 99 return anyDepends(getCalcs(), dimension); 100 } 101 102 105 public static boolean anyDepends(Calc[] calcs, Dimension dimension) { 106 for (Calc calc : calcs) { 107 if (calc != null && calc.dependsOn(dimension)) { 108 return true; 109 } 110 } 111 return false; 112 } 113 114 123 public static boolean anyDependsButFirst( 124 Calc[] calcs, Dimension dimension) { 125 if (calcs.length == 0) { 126 return false; 127 } 128 if (calcs[0].dependsOn(dimension)) { 129 return true; 130 } 131 if (calcs[0].getType().usesDimension(dimension, true)) { 132 return false; 133 } 134 for (int i = 1; i < calcs.length; i++) { 135 Calc calc = calcs[i]; 136 if (calc != null && calc.dependsOn(dimension)) { 137 return true; 138 } 139 } 140 return false; 141 } 142 143 148 public static boolean butDepends( 149 Calc[] calcs, Dimension dimension) { 150 boolean result = true; 151 for (Calc calc : calcs) { 152 if (calc != null) { 153 if (calc.dependsOn(dimension)) { 154 return true; 155 } 156 if (calc.getType().usesDimension(dimension, true)) { 157 result = false; 158 } 159 } 160 } 161 return result; 162 } 163 164 168 public List <Object > getArguments() { 169 return Collections.emptyList(); 170 } 171 172 183 public static Evaluator simplifyEvaluator(Calc calc, Evaluator evaluator) { 184 if (evaluator.isNonEmpty()) { 185 return evaluator; 190 } 191 int changeCount = 0; 192 Evaluator ev = evaluator; 193 final Dimension[] dimensions = evaluator.getCube().getDimensions(); 194 for (Dimension dimension : dimensions) { 195 final Member member = ev.getContext(dimension); 196 if (member.isAll()) { 197 continue; 198 } 199 if (calc.dependsOn(dimension)) { 200 continue; 201 } 202 final Member unconstrainedMember = 203 member.getHierarchy().getDefaultMember(); 204 if (member == unconstrainedMember) { 205 continue; 208 } 209 if (changeCount++ == 0) { 210 ev = evaluator.push(unconstrainedMember); 211 } else { 212 ev.setContext(unconstrainedMember); 213 } 214 } 215 return ev; 216 } 217 218 public ExpCompiler.ResultStyle getResultStyle() { 219 return ExpCompiler.ResultStyle.VALUE; 220 } 221 } 222 223 | Popular Tags |