1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.FunDef; 13 import mondrian.olap.Evaluator; 14 import mondrian.olap.Level; 15 import mondrian.olap.Member; 16 import mondrian.calc.Calc; 17 import mondrian.calc.ExpCompiler; 18 import mondrian.calc.ListCalc; 19 import mondrian.calc.LevelCalc; 20 import mondrian.calc.impl.AbstractListCalc; 21 import mondrian.mdx.ResolvedFunCall; 22 23 import java.util.List ; 24 import java.util.ArrayList ; 25 26 33 class DrilldownLevelFunDef extends FunDefBase { 34 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 35 "DrilldownLevel", 36 "DrilldownLevel(<Set>[, <Level>]) or DrilldownLevel(<Set>, , <Index>)", 37 "Drills down the members of a set, at a specified level, to one level below. Alternatively, drills down on a specified dimension in the set.", 38 new String []{"fxx", "fxxl"}, 39 DrilldownLevelFunDef.class); 40 41 public DrilldownLevelFunDef(FunDef dummyFunDef) { 42 super(dummyFunDef); 43 } 44 45 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 46 final ListCalc listCalc = 47 compiler.compileList(call.getArg(0)); 48 final LevelCalc levelCalc = 49 call.getArgCount() > 1 ? 50 compiler.compileLevel(call.getArg(1)) : 51 null; 52 return new AbstractListCalc(call, new Calc[] {listCalc, levelCalc}) { 53 public List evaluateList(Evaluator evaluator) { 54 List <Member> list = listCalc.evaluateList(evaluator); 55 if (list.size() == 0) { 56 return list; 57 } 58 int searchDepth = -1; 59 if (levelCalc != null) { 60 Level level = levelCalc.evaluateLevel(evaluator); 61 searchDepth = level.getDepth(); 62 } 63 return drill(searchDepth, list, evaluator); 64 } 65 }; 66 } 67 68 List <Member> drill(int searchDepth, List <Member> list, Evaluator evaluator) { 69 if (searchDepth == -1) { 70 searchDepth = list.get(0).getLevel().getDepth(); 71 72 for (int i = 1, m = list.size(); i < m; i++) { 73 Member member = list.get(i); 74 int memberDepth = member.getLevel().getDepth(); 75 76 if (memberDepth > searchDepth) { 77 searchDepth = memberDepth; 78 } 79 } 80 } 81 82 List <Member> drilledSet = new ArrayList <Member>(); 83 84 for (int i = 0, m = list.size(); i < m; i++) { 85 Member member = list.get(i); 86 drilledSet.add(member); 87 88 Member nextMember = i == (m - 1) ? 89 null : 90 list.get(i + 1); 91 92 if (member.getLevel().getDepth() == searchDepth 99 && !FunUtil.isAncestorOf(member, nextMember, true)) { 100 Member[] childMembers = evaluator.getSchemaReader().getMemberChildren(member); 101 for (Member childMember : childMembers) { 102 drilledSet.add(childMember); 103 } 104 } 105 } 106 return drilledSet; 107 } 108 } 109 110 | Popular Tags |