| 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.ConstantCalc; 19 import mondrian.calc.impl.AbstractListCalc; 20 import mondrian.mdx.ResolvedFunCall; 21 22 import java.util.List ; 23 import java.util.Collections ; 24 25 33 class HeadTailFunDef extends FunDefBase { 34 static final Resolver TailResolver = new ReflectiveMultiResolver( 35 "Tail", 36 "Tail(<Set>[, <Count>])", 37 "Returns a subset from the end of a set.", 38 new String [] {"fxx", "fxxn"}, 39 HeadTailFunDef.class); 40 41 static final Resolver HeadResolver = new ReflectiveMultiResolver( 42 "Head", 43 "Head(<Set>[, < Numeric Expression >])", 44 "Returns the first specified number of elements in a set.", 45 new String [] {"fxx", "fxxn"}, 46 HeadTailFunDef.class); 47 48 private final boolean head; 49 50 public HeadTailFunDef(FunDef dummyFunDef) { 51 super(dummyFunDef); 52 head = dummyFunDef.getName().equals("Head"); 53 } 54 55 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 56 final ListCalc listCalc = 57 compiler.compileList(call.getArg(0)); 58 final IntegerCalc integerCalc = 59 call.getArgCount() > 1 ? 60 compiler.compileInteger(call.getArg(1)) : 61 ConstantCalc.constantInteger(1); 62 if (head) { 63 return new AbstractListCalc(call, new Calc[] {listCalc, integerCalc}) { 64 public List evaluateList(Evaluator evaluator) { 65 List list = listCalc.evaluateList(evaluator); 66 int count = integerCalc.evaluateInteger(evaluator); 67 return head(count, list); 68 } 69 }; 70 } else { 71 return new AbstractListCalc(call, new Calc[] {listCalc, integerCalc}) { 72 73 public List evaluateList(Evaluator evaluator) { 74 List list = listCalc.evaluateList(evaluator); 75 int count = integerCalc.evaluateInteger(evaluator); 76 return tail(count, list); 77 } 78 }; 79 } 80 } 81 82 static List tail(final int count, List members) { 83 assert members != null; 84 final int memberCount = members.size(); 85 if (count >= memberCount) { 86 return members; 87 } 88 if (count <= 0) { 89 return Collections.EMPTY_LIST; 90 } 91 return members.subList(memberCount - count, memberCount); 92 } 93 94 static List head(final int count, List members) { 95 assert members != null; 96 if (count >= members.size()) { 97 return members; 98 } 99 if (count <= 0) { 100 return Collections.EMPTY_LIST; 101 } 102 return members.subList(0, count); 103 } 104 } 105 106 | Popular Tags |