1 10 package mondrian.calc.impl; 11 12 import mondrian.olap.*; 13 import mondrian.olap.fun.*; 14 import mondrian.olap.type.*; 15 import mondrian.olap.type.DimensionType; 16 import mondrian.olap.type.LevelType; 17 import mondrian.resource.MondrianResource; 18 import mondrian.rolap.RolapMember; 19 import mondrian.calc.*; 20 21 import java.util.HashMap ; 22 import java.util.Map ; 23 24 31 public class AbstractExpCompiler implements ExpCompiler { 32 private final Evaluator evaluator; 33 private final Validator validator; 34 private final Map <Parameter, ParameterSlotImpl> parameterSlots = 35 new HashMap <Parameter, ParameterSlotImpl>(); 36 private ResultStyle[] resultStyles; 37 38 public AbstractExpCompiler(Evaluator evaluator, Validator validator) { 39 this(evaluator, validator, ANY_RESULT_STYLE_ARRAY); 40 } 41 public AbstractExpCompiler(Evaluator evaluator, Validator validator, 42 ResultStyle[] resultStyles) { 43 this.evaluator = evaluator; 44 this.validator = validator; 45 this.resultStyles = (resultStyles == null) 46 ? ANY_RESULT_STYLE_ARRAY : resultStyles; 47 } 48 49 public Evaluator getEvaluator() { 50 return evaluator; 51 } 52 53 public Validator getValidator() { 54 return validator; 55 } 56 57 63 public Calc compile(Exp exp) { 64 return exp.accept(this); 65 } 66 67 74 public Calc compile(Exp exp, ResultStyle[] preferredResultTypes) { 75 assert preferredResultTypes != null; 76 if (Util.PreJdk15) { 77 ResultStyle[] tmp = new ResultStyle[preferredResultTypes.length]; 82 for (int i = 0; i < preferredResultTypes.length; i++) { 83 tmp[i] = (preferredResultTypes[i] == ResultStyle.ITERABLE) 84 ? ResultStyle.LIST : preferredResultTypes[i]; 85 } 86 preferredResultTypes = tmp; 87 } 88 ResultStyle[] save = this.resultStyles; 89 try { 90 this.resultStyles = preferredResultTypes; 91 return compile(exp); 92 } finally { 93 this.resultStyles = save; 94 } 95 } 96 97 public MemberCalc compileMember(Exp exp) { 98 final Type type = exp.getType(); 99 if (type instanceof DimensionType) { 100 final DimensionCalc dimensionCalc = compileDimension(exp); 101 return new DimensionCurrentMemberFunDef.CalcImpl( 102 new DummyExp(TypeUtil.toMemberType(type)), dimensionCalc); 103 } else if (type instanceof HierarchyType) { 104 final HierarchyCalc hierarchyCalc = compileHierarchy(exp); 105 return new HierarchyCurrentMemberFunDef.CalcImpl( 106 new DummyExp(TypeUtil.toMemberType(type)), hierarchyCalc); 107 } else if (type instanceof NullType) { 108 throw MondrianResource.instance().NullNotSupported.ex(); 109 } 110 assert type instanceof MemberType; 111 return (MemberCalc) compile(exp); 112 } 113 114 public LevelCalc compileLevel(Exp exp) { 115 final Type type = exp.getType(); 116 if (type instanceof MemberType) { 117 final MemberCalc memberCalc = compileMember(exp); 119 return new MemberLevelFunDef.CalcImpl( 120 new DummyExp(LevelType.forType(type)), 121 memberCalc); 122 } 123 assert type instanceof LevelType; 124 return (LevelCalc) compile(exp); 125 } 126 127 public DimensionCalc compileDimension(Exp exp) { 128 final Type type = exp.getType(); 129 if (type instanceof HierarchyType) { 130 final HierarchyCalc hierarchyCalc = compileHierarchy(exp); 131 return new HierarchyDimensionFunDef.CalcImpl( 132 exp, hierarchyCalc); 133 } 134 assert type instanceof DimensionType : type; 135 return (DimensionCalc) compile(exp); 136 } 137 138 public HierarchyCalc compileHierarchy(Exp exp) { 139 final Type type = exp.getType(); 140 if (type instanceof DimensionType || 141 type instanceof MemberType) { 142 final MemberCalc memberCalc = compileMember(exp); 144 return new MemberHierarchyFunDef.CalcImpl( 145 new DummyExp(HierarchyType.forType(type)), 146 memberCalc); 147 } 148 if (type instanceof LevelType) { 149 final LevelCalc levelCalc = compileLevel(exp); 151 return new LevelHierarchyFunDef.CalcImpl( 152 new DummyExp(HierarchyType.forType(type)), 153 levelCalc); 154 } 155 assert type instanceof HierarchyType; 156 return (HierarchyCalc) compile(exp); 157 } 158 159 public IntegerCalc compileInteger(Exp exp) { 160 final Calc calc = compileScalar(exp, false); 161 if (calc instanceof IntegerCalc) { 162 return (IntegerCalc) calc; 163 } else if (calc instanceof DoubleCalc) { 164 final DoubleCalc doubleCalc = (DoubleCalc) calc; 165 return new AbstractIntegerCalc(exp, new Calc[] {doubleCalc}) { 166 public int evaluateInteger(Evaluator evaluator) { 167 return (int) doubleCalc.evaluateDouble(evaluator); 168 } 169 }; 170 } else { 171 return (IntegerCalc) calc; 172 } 173 } 174 175 public StringCalc compileString(Exp exp) { 176 return (StringCalc) compile(exp); 177 } 178 179 public ListCalc compileList(Exp exp) { 180 return compileList(exp, false); 181 } 182 183 public ListCalc compileList(Exp exp, boolean mutable) { 184 ListCalc listCalc = (mutable) 185 ? (ListCalc) compile(exp, MUTABLE_LIST_RESULT_STYLE_ARRAY) 186 : (ListCalc) compile(exp, LIST_RESULT_STYLE_ARRAY); 187 return listCalc; 188 } 189 190 public IterCalc compileIter(Exp exp) { 191 return (IterCalc) compile(exp, ITERABLE_RESULT_STYLE_ARRAY); 192 } 193 194 public BooleanCalc compileBoolean(Exp exp) { 195 return (BooleanCalc) compileScalar(exp, false); 196 } 197 198 public DoubleCalc compileDouble(Exp exp) { 199 return (DoubleCalc) compileScalar(exp, false); 200 } 201 202 public TupleCalc compileTuple(Exp exp) { 203 return (TupleCalc) compile(exp); 204 } 205 206 public Calc compileScalar(Exp exp, boolean convert) { 207 final Type type = exp.getType(); 208 if (type instanceof MemberType) { 209 MemberType memberType = (MemberType) type; 210 MemberCalc calc = compileMember(exp); 211 return new MemberValueCalc( 212 new DummyExp(memberType.getValueType()), 213 new MemberCalc[] {calc}); 214 } else if (type instanceof DimensionType) { 215 final DimensionCalc dimensionCalc = compileDimension(exp); 216 MemberType memberType = MemberType.forType(type); 217 final MemberCalc dimensionCurrentMemberCalc = 218 new DimensionCurrentMemberFunDef.CalcImpl( 219 new DummyExp(memberType), 220 dimensionCalc); 221 return new MemberValueCalc( 222 new DummyExp(memberType.getValueType()), 223 new MemberCalc[] {dimensionCurrentMemberCalc}); 224 } else if (type instanceof HierarchyType) { 225 HierarchyType hierarchyType = (HierarchyType) type; 226 MemberType memberType = 227 MemberType.forHierarchy(hierarchyType.getHierarchy()); 228 final HierarchyCalc hierarchyCalc = compileHierarchy(exp); 229 final MemberCalc hierarchyCurrentMemberCalc = 230 new HierarchyCurrentMemberFunDef.CalcImpl( 231 new DummyExp(memberType), hierarchyCalc); 232 return new MemberValueCalc( 233 new DummyExp(memberType.getValueType()), 234 new MemberCalc[] {hierarchyCurrentMemberCalc}); 235 } else if (type instanceof TupleType) { 236 TupleType tupleType = (TupleType) type; 237 TupleCalc tupleCalc = compileTuple(exp); 238 final TupleValueCalc scalarCalc = new TupleValueCalc( 239 new DummyExp(tupleType.getValueType()), tupleCalc); 240 return scalarCalc.optimize(); 241 } else if (type instanceof ScalarType) { 242 if (convert) { 243 if (type instanceof BooleanType) { 244 return compileBoolean(exp); 245 } else if (type instanceof NumericType) { 246 return compileDouble(exp); 247 } else if (type instanceof StringType) { 248 return compileString(exp); 249 } else { 250 return compile(exp); 251 } 252 } else { 253 return compile(exp); 254 } 255 } else { 256 return compile(exp); 257 } 258 } 259 260 public ParameterSlot registerParameter(Parameter parameter) { 261 ParameterSlot slot = parameterSlots.get(parameter); 262 if (slot != null) { 263 return slot; 264 } 265 int index = parameterSlots.size(); 266 ParameterSlotImpl slot2 = new ParameterSlotImpl(parameter, index); 267 parameterSlots.put(parameter, slot2); 268 slot2.value = parameter.getValue(); 269 270 Calc calc = parameter.getDefaultExp().accept(this); 273 slot2.setDefaultValueCalc(calc); 274 return slot2; 275 } 276 277 public ResultStyle[] getAcceptableResultStyles() { 278 return resultStyles; 279 } 280 281 284 private static class ParameterSlotImpl implements ParameterSlot { 285 private final Parameter parameter; 286 private final int index; 287 private Calc defaultValueCalc; 288 private Object value; 289 private Object cachedDefaultValue; 290 291 public ParameterSlotImpl( 292 Parameter parameter, int index) 293 { 294 this.parameter = parameter; 295 this.index = index; 296 } 297 298 public int getIndex() { 299 return index; 300 } 301 302 public Calc getDefaultValueCalc() { 303 return defaultValueCalc; 304 } 305 306 public Parameter getParameter() { 307 return parameter; 308 } 309 310 private void setDefaultValueCalc(Calc calc) { 311 this.defaultValueCalc = calc; 312 } 313 314 public void setParameterValue(Object value) { 315 this.value = value; 316 } 317 318 public Object getParameterValue() { 319 return value; 320 } 321 322 public void setCachedDefaultValue(Object value) { 323 this.cachedDefaultValue = value; 324 } 325 326 public Object getCachedDefaultValue() { 327 return cachedDefaultValue; 328 } 329 } 330 } 331 332 | Popular Tags |