KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/ToggleDrillStateFunDef.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.*;
13 import mondrian.olap.type.TupleType;
14 import mondrian.olap.type.SetType;
15 import mondrian.calc.Calc;
16 import mondrian.calc.ExpCompiler;
17 import mondrian.calc.ListCalc;
18 import mondrian.calc.impl.AbstractListCalc;
19 import mondrian.mdx.ResolvedFunCall;
20 import mondrian.resource.MondrianResource;
21
22 import java.util.List JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Set JavaDoc;
26
27 /**
28  * Definition of the <code>ToggleDrillState</code> MDX function.
29  *
30  * @author jhyde
31  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/ToggleDrillStateFunDef.java#2 $
32  * @since Mar 23, 2006
33  */

34 class ToggleDrillStateFunDef extends FunDefBase {
35     static final String JavaDoc[] ReservedWords = new String JavaDoc[] {"RECURSIVE"};
36     static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver(
37             "ToggleDrillState",
38             "ToggleDrillState(<Set1>, <Set2>[, RECURSIVE])",
39             "Toggles the drill state of members. This function is a combination of DrillupMember and DrilldownMember.",
40             new String JavaDoc[]{"fxxx", "fxxxy"},
41             ToggleDrillStateFunDef.class,
42             ReservedWords);
43
44     public ToggleDrillStateFunDef(FunDef dummyFunDef) {
45         super(dummyFunDef);
46     }
47
48     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
49         if (call.getArgCount() > 2) {
50             throw MondrianResource.instance().ToggleDrillStateRecursiveNotSupported.ex();
51         }
52         final ListCalc listCalc0 =
53                 compiler.compileList(call.getArg(0));
54         final ListCalc listCalc1 =
55                 compiler.compileList(call.getArg(1));
56         if (((SetType) call.getType()).getArity() == 1) {
57             return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) {
58                 public List JavaDoc evaluateList(Evaluator evaluator) {
59                     final List JavaDoc<Member> list0 = listCalc0.evaluateList(evaluator);
60                     final List JavaDoc<Member> list1 = listCalc1.evaluateList(evaluator);
61                     return toggleDrillStateMembers(evaluator, list0, list1);
62                 }
63             };
64         } else {
65             return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) {
66                 public List JavaDoc evaluateList(Evaluator evaluator) {
67                     final List JavaDoc<Member[]> list0 = listCalc0.evaluateList(evaluator);
68                     final List JavaDoc<Member> list1 = listCalc1.evaluateList(evaluator);
69                     return toggleDrillStateTuples(evaluator, list0, list1);
70                 }
71             };
72         }
73     }
74
75     List JavaDoc<Member> toggleDrillStateMembers(
76         Evaluator evaluator, List JavaDoc<Member> v0, List JavaDoc<Member> list1)
77     {
78         if (list1.isEmpty()) {
79             return v0;
80         }
81         if (v0.isEmpty()) {
82             return v0;
83         }
84         Set JavaDoc<Member> set = new HashSet JavaDoc<Member>();
85         set.addAll(list1);
86         List JavaDoc<Member> result = new ArrayList JavaDoc<Member>();
87         int i = 0, n = v0.size();
88         while (i < n) {
89             Member m = v0.get(i++);
90             result.add(m);
91             if (!set.contains(m)) {
92                 continue;
93             }
94             boolean isDrilledDown = false;
95             if (i < n) {
96                 Member nextMember = v0.get(i);
97                 boolean strict = true;
98                 if (FunUtil.isAncestorOf(m, nextMember, strict)) {
99                     isDrilledDown = true;
100                 }
101             }
102             if (isDrilledDown) {
103                 // skip descendants of this member
104
do {
105                     Member nextMember = v0.get(i);
106                     boolean strict = true;
107                     if (FunUtil.isAncestorOf(m, nextMember, strict)) {
108                         i++;
109                     } else {
110                         break;
111                     }
112                 } while (i < n);
113             } else {
114                 Member[] children =
115                     evaluator.getSchemaReader().getMemberChildren(m);
116                 for (Member child : children) {
117                     result.add(child);
118                 }
119             }
120         }
121         return result;
122     }
123
124     List JavaDoc<Member[]> toggleDrillStateTuples(
125         Evaluator evaluator, List JavaDoc<Member[]> v0, List JavaDoc<Member> list1)
126     {
127         if (list1.isEmpty()) {
128             return v0;
129         }
130         if (v0.isEmpty()) {
131             return v0;
132         }
133         Set JavaDoc<Member> set = new HashSet JavaDoc<Member>();
134         set.addAll(list1);
135         List JavaDoc<Member[]> result = new ArrayList JavaDoc<Member[]>();
136         int i = 0, n = v0.size();
137         while (i < n) {
138             Member[] o = v0.get(i++);
139             result.add(o);
140             Member m = null;
141             int k = -1;
142             for (int j = 0; j < o.length; j++) {
143                 Member member = o[j];
144                 if (set.contains(member)) {
145                     k = j;
146                     m = member;
147                     break;
148                 }
149             }
150             if (k == -1) {
151                 continue;
152             }
153             boolean isDrilledDown = false;
154             if (i < n) {
155                 Member[] next = v0.get(i);
156                 Member nextMember = next[k];
157                 boolean strict = true;
158                 if (FunUtil.isAncestorOf(m, nextMember, strict)) {
159                     isDrilledDown = true;
160                 }
161             }
162             if (isDrilledDown) {
163                 // skip descendants of this member
164
do {
165                     Member[] next = v0.get(i);
166                     Member nextMember = next[k];
167                     boolean strict = true;
168                     if (FunUtil.isAncestorOf(m, nextMember, strict)) {
169                         i++;
170                     } else {
171                         break;
172                     }
173                 } while (i < n);
174             } else {
175                 Member[] children = evaluator.getSchemaReader().getMemberChildren(m);
176                 for (Member child : children) {
177                     Member[] members = o.clone();
178                     members[k] = child;
179                     result.add(members);
180                 }
181             }
182         }
183         return result;
184     }
185 }
186
187 // End ToggleDrillStateFunDef.java
188
Popular Tags