1 10 package mondrian.olap.fun; 11 12 import mondrian.calc.Calc; 13 import mondrian.calc.ExpCompiler; 14 import mondrian.calc.ExpCompiler.ResultStyle; 15 import mondrian.calc.IterCalc; 16 import mondrian.calc.ListCalc; 17 import mondrian.calc.BooleanCalc; 18 import mondrian.calc.impl.AbstractListCalc; 19 import mondrian.calc.impl.AbstractIterCalc; 20 import mondrian.mdx.ResolvedFunCall; 21 import mondrian.olap.type.SetType; 22 import mondrian.olap.type.MemberType; 23 import mondrian.olap.*; 24 25 import java.util.List ; 26 import java.util.ArrayList ; 27 import java.util.Iterator ; 28 29 36 class FilterFunDef extends FunDefBase { 37 static final FilterFunDef instance = new FilterFunDef(); 38 39 private FilterFunDef() { 40 super( 41 "Filter", 42 "Filter(<Set>, <Search Condition>)", 43 "Returns the set resulting from filtering a set based on a search condition.", 44 "fxxb"); 45 } 46 47 public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) { 48 ResultStyle[] rs = compiler.getAcceptableResultStyles(); 49 for (int i = 0; i < rs.length; i++) { 51 switch (rs[i]) { 52 case ITERABLE : 53 case ANY : 54 return compileCallIterable(call, compiler); 56 case MUTABLE_LIST: 57 case LIST : 58 return compileCallList(call, compiler); 60 } 61 } 62 throw ResultStyleException.generate( 63 new ResultStyle[] { 64 ResultStyle.ITERABLE, 65 ResultStyle.LIST, 66 ResultStyle.MUTABLE_LIST, 67 ResultStyle.ANY 68 }, 69 rs 70 ); 71 } 72 73 74 85 protected Calc compileCallIterable(final ResolvedFunCall call, 86 ExpCompiler compiler) { 87 Calc imlcalc = compiler.compile(call.getArg(0), 89 ExpCompiler.ITERABLE_LIST_MUTABLE_LIST_RESULT_STYLE_ARRAY); 90 BooleanCalc bcalc = compiler.compileBoolean(call.getArg(1)); 91 Calc[] calcs = new Calc[] {imlcalc, bcalc}; 92 93 checkIterListResultStyles(imlcalc); 95 96 if (((SetType) imlcalc.getType()).getElementType() instanceof MemberType) { 97 if (imlcalc.getResultStyle() == ResultStyle.ITERABLE) { 98 return new IterMemberIterCalc(call, calcs); 99 } else if (imlcalc.getResultStyle() == ResultStyle.LIST) { 100 return new ImMutableMemberIterCalc(call, calcs); 101 } else { 102 return new MutableMemberIterCalc(call, calcs); 103 } 104 105 } else { 106 107 if (imlcalc.getResultStyle() == ResultStyle.ITERABLE) { 108 return new IterMemberArrayIterCalc(call, calcs); 109 } else if (imlcalc.getResultStyle() == ResultStyle.LIST) { 110 return new ImMutableMemberArrayIterCalc(call, calcs); 111 } else { 112 return new MutableMemberArrayIterCalc(call, calcs); 113 } 114 } 115 } 116 117 private static abstract class BaseIterCalc extends AbstractIterCalc { 118 protected BaseIterCalc(ResolvedFunCall call, Calc[] calcs) { 119 super(call, calcs); 120 } 121 public Iterable evaluateIterable(Evaluator evaluator) { 122 ResolvedFunCall call = (ResolvedFunCall) exp; 123 SchemaReader schemaReader = evaluator.getSchemaReader(); 126 NativeEvaluator nativeEvaluator = 127 schemaReader.getNativeSetEvaluator( 128 call.getFunDef(), call.getArgs(), evaluator, this); 129 if (nativeEvaluator != null) { 130 return (Iterable ) nativeEvaluator.execute( 131 ResultStyle.ITERABLE); 132 } else { 133 return makeIterable(evaluator); 134 } 135 } 136 protected abstract Iterable makeIterable(Evaluator evaluator); 137 138 public boolean dependsOn(Dimension dimension) { 139 return anyDependsButFirst(getCalcs(), dimension); 140 } 141 } 142 private static class MutableMemberIterCalc extends BaseIterCalc { 146 MutableMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 147 super(call, calcs); 148 } 149 protected Iterable makeIterable(Evaluator evaluator) { 150 Calc[] calcs = getCalcs(); 151 ListCalc lcalc = (ListCalc) calcs[0]; 152 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 153 154 final Evaluator evaluator2 = evaluator.push(); 155 List members = lcalc.evaluateList(evaluator); 156 157 Iterator it = members.iterator(); 158 while (it.hasNext()) { 159 Member member = (Member) it.next(); 160 evaluator2.setContext(member); 161 if (! bcalc.evaluateBoolean(evaluator2)) { 162 it.remove(); 163 } 164 } 165 return members; 166 } 167 } 168 private static class ImMutableMemberIterCalc extends BaseIterCalc { 169 ImMutableMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 170 super(call, calcs); 171 } 172 protected Iterable makeIterable(Evaluator evaluator) { 173 Calc[] calcs = getCalcs(); 174 ListCalc lcalc = (ListCalc) calcs[0]; 175 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 176 177 final Evaluator evaluator2 = evaluator.push(); 178 List members = lcalc.evaluateList(evaluator); 179 180 List result = new ArrayList (); 182 for (int i = 0, count = members.size(); i < count; i++) { 183 Member member = (Member) members.get(i); 184 evaluator2.setContext(member); 185 if (bcalc.evaluateBoolean(evaluator2)) { 186 result.add(member); 187 } 188 } 189 return result; 190 } 191 } 192 private static class IterMemberIterCalc extends BaseIterCalc { 193 IterMemberIterCalc(ResolvedFunCall call, Calc[] calcs) { 194 super(call, calcs); 195 } 196 protected Iterable makeIterable(Evaluator evaluator) { 197 Calc[] calcs = getCalcs(); 198 IterCalc icalc = (IterCalc) calcs[0]; 199 final BooleanCalc bcalc = (BooleanCalc) calcs[1]; 200 201 final Evaluator evaluator2 = evaluator.push(); 202 final Iterable <Member> iter = (Iterable <Member>) 205 icalc.evaluateIterable(evaluator); 206 207 Iterable result = new Iterable <Member>() { 208 public Iterator <Member> iterator() { 209 return new Iterator <Member>() { 210 Iterator <Member> it = iter.iterator(); 211 Member m = null; 212 public boolean hasNext() { 213 if (m != null) { 214 return true; 215 } 216 if (! it.hasNext()) { 217 return false; 218 } 219 this.m = it.next(); 220 evaluator2.setContext(this.m); 221 while (! bcalc.evaluateBoolean(evaluator2)) { 222 if (! it.hasNext()) { 223 return false; 224 } 225 this.m = it.next(); 226 evaluator2.setContext(this.m); 227 } 228 return true; 229 } 230 public Member next() { 231 try { 232 return this.m; 233 } finally { 234 this.m = null; 235 } 236 } 237 public void remove() { 238 throw new UnsupportedOperationException ("remove"); 239 } 240 }; 241 } 242 }; 243 return result; 244 } 245 } 246 247 private static class MutableMemberArrayIterCalc extends BaseIterCalc { 251 MutableMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 252 super(call, calcs); 253 } 254 protected Iterable makeIterable(Evaluator evaluator) { 255 Calc[] calcs = getCalcs(); 256 ListCalc lcalc = (ListCalc) calcs[0]; 257 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 258 259 final Evaluator evaluator2 = evaluator.push(); 260 List members = lcalc.evaluateList(evaluator); 261 262 Iterator it = members.iterator(); 263 while (it.hasNext()) { 264 Member[] member = (Member[]) it.next(); 265 evaluator2.setContext(member); 266 if (! bcalc.evaluateBoolean(evaluator2)) { 267 it.remove(); 268 } 269 } 270 return members; 271 } 272 } 273 private static class ImMutableMemberArrayIterCalc extends BaseIterCalc { 274 ImMutableMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 275 super(call, calcs); 276 } 277 protected Iterable makeIterable(Evaluator evaluator) { 278 Calc[] calcs = getCalcs(); 279 ListCalc lcalc = (ListCalc) calcs[0]; 280 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 281 282 final Evaluator evaluator2 = evaluator.push(); 283 List members = lcalc.evaluateList(evaluator); 284 285 List result = new ArrayList (); 287 for (int i = 0, count = members.size(); i < count; i++) { 288 Member[] member = (Member[]) members.get(i); 289 evaluator2.setContext(member); 290 if (bcalc.evaluateBoolean(evaluator2)) { 291 result.add(member); 292 } 293 } 294 return result; 295 } 296 } 297 private static class IterMemberArrayIterCalc extends BaseIterCalc { 298 IterMemberArrayIterCalc(ResolvedFunCall call, Calc[] calcs) { 299 super(call, calcs); 300 } 301 protected Iterable makeIterable(Evaluator evaluator) { 302 Calc[] calcs = getCalcs(); 303 IterCalc icalc = (IterCalc) calcs[0]; 304 final BooleanCalc bcalc = (BooleanCalc) calcs[1]; 305 306 final Evaluator evaluator2 = evaluator.push(); 307 308 final Iterable <Member[]> iter = (Iterable <Member[]>) 311 icalc.evaluateIterable(evaluator); 312 Iterable result = new Iterable <Member[]>() { 313 public Iterator <Member[]> iterator() { 314 return new Iterator <Member[]>() { 315 Iterator <Member[]> it = iter.iterator(); 316 Member[] m = null; 317 public boolean hasNext() { 318 if (m != null) { 319 return true; 320 } 321 if (! it.hasNext()) { 322 return false; 323 } 324 this.m = it.next(); 325 evaluator2.setContext(this.m); 326 while (! bcalc.evaluateBoolean(evaluator2)) { 327 if (! it.hasNext()) { 328 return false; 329 } 330 this.m = it.next(); 331 evaluator2.setContext(this.m); 332 } 333 return true; 334 } 335 public Member[] next() { 336 try { 337 return this.m; 338 } finally { 339 this.m = null; 340 } 341 } 342 public void remove() { 343 throw new UnsupportedOperationException ("remove"); 344 } 345 }; 346 } 347 }; 348 return result; 349 } 350 } 351 352 353 360 protected Calc compileCallList(final ResolvedFunCall call, 361 ExpCompiler compiler) { 362 Calc ilcalc = compiler.compile(call.getArg(0), 363 ExpCompiler.MUTABLE_LIST_LIST_RESULT_STYLE_ARRAY 364 ); 365 BooleanCalc bcalc = compiler.compileBoolean(call.getArg(1)); 366 Calc[] calcs = new Calc[] {ilcalc, bcalc}; 367 368 if (((SetType) ilcalc.getType()).getElementType() instanceof MemberType) { 370 switch (ilcalc.getResultStyle()) { 371 case LIST : 372 return new ImMutableMemberListCalc(call, calcs); 373 case MUTABLE_LIST : 374 return new MutableMemberListCalc(call, calcs); 375 } 376 throw ResultStyleException.generateBadType( 377 new ResultStyle[] { 378 ResultStyle.LIST, 379 ResultStyle.MUTABLE_LIST 380 }, 381 ilcalc.getResultStyle()); 382 383 } else { 384 385 switch (ilcalc.getResultStyle()) { 386 case LIST : 387 return new ImMutableMemberArrayListCalc(call, calcs); 388 case MUTABLE_LIST : 389 return new MutableMemberArrayListCalc(call, calcs); 390 } 391 throw ResultStyleException.generateBadType( 392 new ResultStyle[] { 393 ResultStyle.LIST, 394 ResultStyle.MUTABLE_LIST 395 }, 396 ilcalc.getResultStyle()); 397 } 398 } 399 private static abstract class BaseListCalc extends AbstractListCalc { 400 protected BaseListCalc(ResolvedFunCall call, Calc[] calcs) { 401 super(call, calcs); 402 } 403 public List evaluateList(Evaluator evaluator) { 404 ResolvedFunCall call = (ResolvedFunCall) exp; 405 SchemaReader schemaReader = evaluator.getSchemaReader(); 408 NativeEvaluator nativeEvaluator = 409 schemaReader.getNativeSetEvaluator( 410 call.getFunDef(), call.getArgs(), evaluator, this); 411 if (nativeEvaluator != null) { 412 return (List ) nativeEvaluator.execute( 413 ResultStyle.MUTABLE_LIST); 414 } else { 415 return makeList(evaluator); 416 } 417 } 418 protected abstract List makeList(Evaluator evaluator); 419 420 public boolean dependsOn(Dimension dimension) { 421 return anyDependsButFirst(getCalcs(), dimension); 422 } 423 } 424 private static class MutableMemberListCalc extends BaseListCalc { 428 MutableMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 429 super(call, calcs); 430 } 431 protected List makeList(Evaluator evaluator) { 432 Calc[] calcs = getCalcs(); 433 ListCalc lcalc = (ListCalc) calcs[0]; 434 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 435 436 final Evaluator evaluator2 = evaluator.push(); 437 List members = lcalc.evaluateList(evaluator); 438 439 Iterator it = members.iterator(); 440 while (it.hasNext()) { 441 Member member = (Member) it.next(); 442 evaluator2.setContext(member); 443 if (! bcalc.evaluateBoolean(evaluator2)) { 444 it.remove(); 445 } 446 } 447 return members; 448 } 449 } 450 private static class ImMutableMemberListCalc extends BaseListCalc { 451 ImMutableMemberListCalc(ResolvedFunCall call, Calc[] calcs) { 452 super(call, calcs); 453 } 454 protected List makeList(Evaluator evaluator) { 455 Calc[] calcs = getCalcs(); 456 ListCalc lcalc = (ListCalc) calcs[0]; 457 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 458 459 final Evaluator evaluator2 = evaluator.push(); 460 List members = lcalc.evaluateList(evaluator); 461 462 List result = new ArrayList (); 464 for (int i = 0, count = members.size(); i < count; i++) { 465 Member member = (Member) members.get(i); 466 evaluator2.setContext(member); 467 if (bcalc.evaluateBoolean(evaluator2)) { 468 result.add(member); 469 } 470 } 471 return result; 472 } 473 } 474 private static class MutableMemberArrayListCalc extends BaseListCalc { 478 MutableMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 479 super(call, calcs); 480 } 481 protected List makeList(Evaluator evaluator) { 482 Calc[] calcs = getCalcs(); 483 ListCalc lcalc = (ListCalc) calcs[0]; 484 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 485 486 final Evaluator evaluator2 = evaluator.push(); 487 List members = lcalc.evaluateList(evaluator); 488 489 Iterator it = members.iterator(); 490 while (it.hasNext()) { 491 Member[] member = (Member[]) it.next(); 492 evaluator2.setContext(member); 493 if (! bcalc.evaluateBoolean(evaluator2)) { 494 it.remove(); 495 } 496 } 497 return members; 498 } 499 } 500 private static class ImMutableMemberArrayListCalc extends BaseListCalc { 501 ImMutableMemberArrayListCalc(ResolvedFunCall call, Calc[] calcs) { 502 super(call, calcs); 503 } 504 protected List makeList(Evaluator evaluator) { 505 Calc[] calcs = getCalcs(); 506 ListCalc lcalc = (ListCalc) calcs[0]; 507 BooleanCalc bcalc = (BooleanCalc) calcs[1]; 508 509 final Evaluator evaluator2 = evaluator.push(); 510 List members = lcalc.evaluateList(evaluator); 511 512 List result = new ArrayList (); 514 for (int i = 0, count = members.size(); i < count; i++) { 515 Member[] member = (Member[]) members.get(i); 516 evaluator2.setContext(member); 517 if (bcalc.evaluateBoolean(evaluator2)) { 518 result.add(member); 519 } 520 } 521 return result; 522 } 523 } 524 525 593 } 594 595 | Popular Tags |