KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > olap > fun > DrilldownLevelFunDef


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/DrilldownLevelFunDef.java#2 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 2006-2006 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

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 JavaDoc;
24 import java.util.ArrayList JavaDoc;
25
26 /**
27  * Definition of the <code>DrilldownLevel</code> MDX function.
28  *
29  * @author jhyde
30  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/DrilldownLevelFunDef.java#2 $
31  * @since Mar 23, 2006
32  */

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 JavaDoc[]{"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 JavaDoc evaluateList(Evaluator evaluator) {
54                 List JavaDoc<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 JavaDoc<Member> drill(int searchDepth, List JavaDoc<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 JavaDoc<Member> drilledSet = new ArrayList JavaDoc<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             //
93
// This member is drilled if it's at the correct depth
94
// and if it isn't drilled yet. A member is considered
95
// to be "drilled" if it is immediately followed by
96
// at least one descendant
97
//
98
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 // End DrilldownLevelFunDef.java
111
Popular Tags