KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > mondrian > MondrianMemberTree


1 /*
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) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.jpivot.mondrian;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Arrays JavaDoc;
17 import java.util.Comparator JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20
21 import mondrian.olap.ResultLimitExceededException;
22 import mondrian.olap.SchemaReader;
23
24 import org.apache.log4j.Logger;
25
26 import com.tonbeller.jpivot.core.ExtensionSupport;
27 import com.tonbeller.jpivot.olap.model.Axis;
28 import com.tonbeller.jpivot.olap.model.Hierarchy;
29 import com.tonbeller.jpivot.olap.model.Member;
30 import com.tonbeller.jpivot.olap.model.Position;
31 import com.tonbeller.jpivot.olap.model.Result;
32 import com.tonbeller.jpivot.olap.navi.MemberTree;
33 import com.tonbeller.jpivot.olap.query.Quax;
34
35 /**
36  * Implementation of the DrillExpand Extension for Mondrian Data Source.
37  */

38 public class MondrianMemberTree extends ExtensionSupport implements MemberTree {
39
40   static Logger logger = Logger.getLogger(MondrianMemberTree.class);
41
42   /**
43    * Constructor sets ID
44    */

45   public MondrianMemberTree() {
46     super.setId(MemberTree.ID);
47   }
48
49   /**
50    * @return the root members of a hierarchy. This is for example the "All"
51    * member or the list of measures.
52    */

53   public Member[] getRootMembers(Hierarchy hier) {
54     try {
55       return internalGetRootMembers(hier);
56     } catch (ResultLimitExceededException e) {
57       logger.error(null, e);
58       throw new TooManyMembersException(e);
59     }
60   }
61
62   private Member[] internalGetRootMembers(Hierarchy hier) {
63     MondrianModel model = (MondrianModel) getModel();
64     mondrian.olap.Hierarchy monHier = ((MondrianHierarchy) hier).getMonHierarchy();
65     mondrian.olap.Query q = ((MondrianQueryAdapter) model.getQueryAdapter()).getMonQuery();
66     // Use the schema reader from the query, because it contains calculated
67
// members defined in both the cube and the query.
68
//SchemaReader scr = model.getMonConnection().getSchemaReader();
69
SchemaReader scr = q.getSchemaReader(true);
70     mondrian.olap.Member[] monMembers = scr.getHierarchyRootMembers(monHier);
71     ArrayList JavaDoc aMem = new ArrayList JavaDoc();
72     final List JavaDoc visibleRootMembers = new ArrayList JavaDoc();
73     int k = monMembers.length;
74     for (int i = 0; i < k; i++) {
75       mondrian.olap.Member monMember = monMembers[i];
76       if (isVisible(monMember)) {
77         aMem.add(model.addMember(monMembers[i]));
78       }
79     }
80
81     // find the calculated members for this hierarchy
82
// show them together with root level members
83
mondrian.olap.Formula[] formulas = q.getFormulas();
84     for (int i = 0; i < formulas.length; i++) {
85       mondrian.olap.Formula f = formulas[i];
86       mondrian.olap.Member monMem = f.getMdxMember();
87       if (monMem != null) {
88         // is the member for this hierarchy,
89
// and is it visible?
90
// if yes add it
91
if (monMem.getHierarchy().equals(monHier)) {
92           if (!isVisible(monMem))
93             continue;
94           Member m = model.addMember(monMem);
95           if (!aMem.contains(m))
96             aMem.add(m);
97         }
98       }
99     }
100
101     // order members according to occurrence in query result
102
// if there is no result available, do not sort
103
Result res = model.currentResult();
104     if (res != null) {
105         // locate the appropriate result axis
106
// find the Quax for this hier
107
MondrianQueryAdapter adapter = (MondrianQueryAdapter) model.getQueryAdapter();
108         Quax quax = adapter.findQuax(hier.getDimension());
109         if (quax != null) {
110             int iDim = quax.dimIdx(hier.getDimension());
111             int iAx = quax.getOrdinal();
112             if (adapter.isSwapAxes())
113               iAx = (iAx + 1) % 2;
114             Axis axis = res.getAxes()[iAx];
115             List JavaDoc positions = axis.getPositions();
116
117             for (Iterator JavaDoc iter = positions.iterator(); iter.hasNext();) {
118               Position pos = (Position) iter.next();
119               Member[] posMembers = pos.getMembers();
120               MondrianMember mem = (MondrianMember) posMembers[iDim];
121               if (!(mem.getMonMember().getParentMember() == null))
122                 continue; // ignore, not root
123
if (!visibleRootMembers.contains(mem))
124                 visibleRootMembers.add(mem);
125
126               // Check if the result axis contains invisible members
127
if (!aMem.contains(mem)) {
128                   aMem.add(mem);
129               }
130             }
131         }
132     }
133
134     Member[] members = (Member[]) aMem.toArray(new Member[0]);
135
136     // If there is no query result, do not sort
137
if (visibleRootMembers.size() != 0) {
138         Arrays.sort(members, new Comparator JavaDoc() {
139           public int compare(Object JavaDoc arg0, Object JavaDoc arg1) {
140             Member m1 = (Member) arg0;
141             Member m2 = (Member) arg1;
142             int index1 = visibleRootMembers.indexOf(m1);
143             int index2 = visibleRootMembers.indexOf(m2);
144             if (index2 == -1)
145               return -1; // m2 is higher, unvisible to the end
146
if (index1 == -1)
147               return 1; // m1 is higher, unvisible to the end
148
return index1 - index2;
149           }
150         });
151     }
152
153     return members;
154   }
155
156   private boolean isVisible(mondrian.olap.Member monMember) {
157     // Name convention: if member starts with "." its hidden
158
if (monMember.getName().startsWith("."))
159       return false;
160
161     // from schema: if visible-Property is not-null and equals false,
162
// then its hidden
163
Object JavaDoc visible = monMember.getPropertyValue(mondrian.olap.Property.VISIBLE.name);
164     return !Boolean.FALSE.equals(visible);
165   }
166
167   /**
168    * @return true if the member has children
169    */

170   public boolean hasChildren(Member member) {
171     mondrian.olap.Member monMember = ((MondrianMember) member).getMonMember();
172     if (monMember.isCalculatedInQuery())
173       return false;
174     if (monMember.getLevel().getChildLevel() != null)
175       return true;
176     // here for a leaf-level, but also for a level in a parent-child hierarchy:
177
MondrianModel model = (MondrianModel) getModel();
178     SchemaReader scr = model.getMonConnection().getSchemaReader();
179     return scr.isDrillable(monMember);
180   }
181
182   /**
183    * @return the children of the member
184    */

185   public Member[] getChildren(Member member) {
186     try {
187       return internalGetChildren(member);
188     } catch (ResultLimitExceededException e) {
189       logger.error(null, e);
190       throw new TooManyMembersException(e);
191     }
192   }
193
194   private Member[] internalGetChildren(Member member) {
195
196     mondrian.olap.Member monMember = ((MondrianMember) member).getMonMember();
197     // unreliable: always null in a parent-child hierarch
198
// if (monMember.getLevel().getChildLevel() == null)
199
// return null;
200

201     MondrianModel model = (MondrianModel) getModel();
202
203     SchemaReader scr = model.getMonConnection().getSchemaReader();
204     mondrian.olap.Member[] monChildren = scr.getMemberChildren(monMember);
205     Member[] children = new Member[monChildren.length];
206     for (int i = 0; i < children.length; i++) {
207       children[i] = model.addMember(monChildren[i]);
208     }
209     return children;
210   }
211
212   /**
213    * @return the parent of member or null, if this is a root member
214    */

215   public Member getParent(Member member) {
216     mondrian.olap.Member monMember = ((MondrianMember) member).getMonMember();
217
218     MondrianModel model = (MondrianModel) getModel();
219
220     SchemaReader scr = model.getMonConnection().getSchemaReader();
221     mondrian.olap.Member monParent = scr.getMemberParent(monMember);
222     if (monParent == null)
223       return null; // already top level
224
Member parent = model.addMember(monParent);
225
226     return parent;
227   }
228
229 } // End MondrianMemberTree
230
Popular Tags