1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.FunDef; 13 import mondrian.olap.Evaluator; 14 import mondrian.calc.Calc; 15 import mondrian.calc.ExpCompiler; 16 import mondrian.calc.ListCalc; 17 import mondrian.calc.IntegerCalc; 18 import mondrian.calc.impl.AbstractListCalc; 19 import mondrian.mdx.ResolvedFunCall; 20 21 import java.util.List ; 22 import java.util.Collections ; 23 24 31 class SubsetFunDef extends FunDefBase { 32 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 33 "Subset", 34 "Subset(<Set>, <Start>[, <Count>])", 35 "Returns a subset of elements from a set.", 36 new String [] {"fxxn", "fxxnn"}, 37 SubsetFunDef.class); 38 39 public SubsetFunDef(FunDef dummyFunDef) { 40 super(dummyFunDef); 41 } 42 43 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 44 final ListCalc listCalc = 45 compiler.compileList(call.getArg(0)); 46 final IntegerCalc startCalc = 47 compiler.compileInteger(call.getArg(1)); 48 final IntegerCalc countCalc = 49 call.getArgCount() > 2 ? 50 compiler.compileInteger(call.getArg(2)) : 51 null; 52 return new AbstractListCalc(call, new Calc[] {listCalc, startCalc, countCalc}) { 53 public List evaluateList(Evaluator evaluator) { 54 final List list = 55 listCalc.evaluateList(evaluator); 56 final int start = 57 startCalc.evaluateInteger(evaluator); 58 int end; 59 if (countCalc != null) { 60 final int count = 61 countCalc.evaluateInteger(evaluator); 62 end = start + count; 63 } else { 64 end = list.size(); 65 } 66 if (end > list.size()) { 67 end = list.size(); 68 } 69 if (start >= end || start < 0) { 70 return Collections.EMPTY_LIST; 71 } 72 assert 0 <= start; 73 assert start < end; 74 assert end <= list.size(); 75 if (start == 0 && end == list.size()) { 76 return list; 77 } else { 78 return list.subList(start, end); 79 } 80 } 81 }; 82 } 83 } 84 85 | Popular Tags |