KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > xmla > XMLA_QuaxUti


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
14 package com.tonbeller.jpivot.xmla;
15
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.apache.log4j.Logger;
20
21 import com.tonbeller.jpivot.olap.mdxparse.Exp;
22 import com.tonbeller.jpivot.olap.mdxparse.FunCall;
23 import com.tonbeller.jpivot.olap.model.Dimension;
24 import com.tonbeller.jpivot.olap.model.Hierarchy;
25 import com.tonbeller.jpivot.olap.model.Level;
26 import com.tonbeller.jpivot.olap.model.Member;
27 import com.tonbeller.jpivot.olap.model.OlapException;
28 import com.tonbeller.jpivot.olap.query.Quax;
29 import com.tonbeller.jpivot.olap.query.QuaxUti;
30 import com.tonbeller.jpivot.olap.query.SetExp;
31 import com.tonbeller.jpivot.olap.query.Quax.CannotHandleException;
32
33 /**
34  * Utility Functions for Quax
35  */

36 public class XMLA_QuaxUti implements QuaxUti {
37
38   static Logger logger = Logger.getLogger(XMLA_QuaxUti.class);
39
40   /**
41    *
42    * @param f
43    * @param m
44    * @return true if FunCall matches member
45    */

46   public boolean isMemberInFunCall(Object JavaDoc oExp, Member m) throws Quax.CannotHandleException {
47     FunCall f = (FunCall) oExp;
48     XMLA_Member xm = (XMLA_Member) m;
49     try {
50       if (f.isCallTo("Children")) {
51         return isMemberInChildren(f, xm);
52       } else if (f.isCallTo("Descendants")) {
53         return isMemberInDescendants(f, xm);
54       } else if (f.isCallTo("Members")) {
55         return isMemberInLevel(f, xm);
56       } else if (f.isCallTo("Union")) {
57         return isMemberInUnion(f, xm);
58       } else if (f.isCallTo("{}")) { return isMemberInSet(f, xm); }
59     } catch (OlapException e) {
60       logger.error("?", e);
61       return false;
62     }
63     throw new Quax.CannotHandleException(f.getFunction());
64   }
65
66   /**
67    * @param f Children FunCall
68    * @param mSearch member to search for
69    * @return true if member mSearch is in set of children function
70    */

71   private boolean isMemberInChildren(FunCall f, XMLA_Member mSearch) {
72     // calculated members are not really child
73
if (mSearch.isCalculated())
74       return false;
75
76     XMLA_Member parent = (XMLA_Member) f.getArgs()[0];
77     if (checkParent(parent, mSearch))
78       return true;
79     return false;
80   }
81
82   /**
83    * @param f Descendants FunCall
84    * @param mSearch member to search for
85    * @return true if member mSearch is in set of Descendants function
86    */

87   private boolean isMemberInDescendants(FunCall f, XMLA_Member mSearch) throws OlapException {
88     // calculated members are not really child
89
if (mSearch.isCalculated())
90       return false;
91
92     XMLA_Member ancestor = (XMLA_Member) f.getArgs()[0];
93     XMLA_Level level = (XMLA_Level) f.getArgs()[1];
94     XMLA_Level mLevel = (XMLA_Level) mSearch.getLevel();
95     if (!mLevel.equals(level))
96       return false;
97     if (mSearch.equals(ancestor))
98       return false;
99
100     int ancestorLevelNumber = ((XMLA_Level) ancestor.getLevel()).getDepth();
101     XMLA_Member mm = mSearch;
102     while (ancestorLevelNumber < ((XMLA_Level) mm.getLevel()).getDepth()) {
103       mm = (XMLA_Member) mm.getParent();
104     }
105
106     if (mm.equals(ancestor))
107       return true;
108     else
109       return false;
110
111   }
112
113   /**
114    * @param f Members FunCall
115    * @param mSearch member to search for
116    * @return true if member mSearch is in set of Members function
117    */

118   private boolean isMemberInLevel(FunCall f, XMLA_Member mSearch) {
119     XMLA_Level level = (XMLA_Level) f.getArgs()[0];
120     if (level.equals(mSearch.getLevel()))
121       return true;
122     return false;
123   }
124
125   /**
126    * @param f Set FunCall
127    * @param mSearch member to search for
128    * @return true if member mSearch is in set function
129    */

130   private boolean isMemberInSet(FunCall f, XMLA_Member mSearch) {
131     // set of members expected
132
for (int i = 0; i < f.getArgs().length; i++) {
133       XMLA_Member m = (XMLA_Member) f.getArgs()[i];
134       if (m.equals(mSearch))
135         return true;
136     }
137     return false;
138   }
139
140   /**
141    * @param f Union FunCall
142    * @param mSearch member to search for
143    * @return true if member mSearch is in set function
144    */

145   private boolean isMemberInUnion(FunCall f, XMLA_Member mSearch) throws CannotHandleException {
146     // Unions may be nested
147
for (int i = 0; i < 2; i++) {
148       FunCall fChild = (FunCall) f.getArgs()[i];
149       if (isMemberInFunCall(fChild, mSearch))
150         return true;
151     }
152     return false;
153   }
154
155   /**
156    * @param f TopBottom FunCall
157    * @param mSearch member to search for
158    * @return true if member mSearch is in set of Top/Bottom function
159    */

160   /*
161    private boolean isMemberInTopBottom(FunCall f, XMLA_Member mSearch) throws OlapException {
162    if (!(f.getArgs()[0] instanceof FunCall)) {
163    logger.error("unexpected Exp in TopBottom function: " + f.getArgs()[0].getClass());
164    return false; // should not occur
165    }
166    FunCall set = (FunCall) f.getArgs()[0];
167    if (set.isCallTo("Children")) {
168    return isMemberInChildren(set, mSearch);
169
170    } else if (set.isCallTo("Descendants")) {
171    return isMemberInDescendants(set, mSearch);
172    } else if (set.isCallTo("Members")) {
173    return isMemberInLevel(set, mSearch);
174    }
175    return false;
176    }
177    */

178
179   /**
180    *
181    * @param f
182    * @param m
183    * @return true if FunCall contains child of member
184    */

185   public boolean isChildOfMemberInFunCall(Object JavaDoc oFun, Member m) throws CannotHandleException {
186     // calculated members do not have children
187
if (((XMLA_Member) m).isCalculated())
188       return false;
189     FunCall f = (FunCall) oFun;
190     try {
191
192       if (f.isCallTo("Children")) {
193         return (((XMLA_Member) f.getArgs()[0]).equals(m));
194       } else if (f.isCallTo("Descendants")) {
195         // true, if f = descendants(m2, level) contains any child of m
196
// so level must be parent-level of m
197
XMLA_Member ancestor = (XMLA_Member) f.getArgs()[0];
198         XMLA_Level lev = (XMLA_Level) f.getArgs()[1];
199         XMLA_Level parentLevel = lev.getParentLevel();
200         if (parentLevel != null && m.getLevel().equals(parentLevel)) {
201           XMLA_Member mm = (XMLA_Member) m;
202           int ancestorLevelNumber = ((XMLA_Level) ancestor.getLevel()).getDepth();
203           while (ancestorLevelNumber < ((XMLA_Level) mm.getLevel()).getDepth()) {
204             mm = (XMLA_Member) mm.getParent();
205           }
206
207           if (mm.equals(ancestor))
208             return true;
209           else
210             return false;
211         } else
212           return false;
213       } else if (f.isCallTo("Members")) {
214         XMLA_Level lev = (XMLA_Level) f.getArgs()[0];
215         XMLA_Level parentLevel = lev.getParentLevel();
216         if (parentLevel != null && m.getLevel().equals(parentLevel))
217           return true;
218         else
219           return false;
220       } else if (f.isCallTo("Union")) {
221         if (isChildOfMemberInFunCall(f.getArgs()[0], m))
222           return true;
223         else
224           return isChildOfMemberInFunCall(f.getArgs()[1], m);
225       } else if (f.isCallTo("{}")) {
226         for (int i = 0; i < f.getArgs().length; i++) {
227           XMLA_Member mm = (XMLA_Member) f.getArgs()[i];
228           XMLA_Member mmp = (XMLA_Member) mm.getParent();
229           if (mmp != null && mmp.equals(m))
230             return true;
231         }
232         return false;
233       }
234     } catch (OlapException e) {
235       // should not occur
236
logger.error("?", e);
237       return false;
238     }
239     throw new Quax.CannotHandleException(f.getFunction());
240   }
241
242   /**
243    *
244    * @param f
245    * @param m
246    * @return true if FunCall contains descendants of member
247    */

248
249   public boolean isDescendantOfMemberInFunCall(Object JavaDoc oExp, Member member)
250       throws CannotHandleException {
251     XMLA_Member m = (XMLA_Member) member;
252     // calculated members do not have children
253
if (m.isCalculated())
254       return false;
255
256     FunCall f = (FunCall) oExp;
257     if (f.isCallTo("Children")) {
258       // true, if m2.children contains descendants of m
259
// <==> m is equal or ancestor of m2
260
XMLA_Member mExp = (XMLA_Member) f.getArgs()[0];
261       return (m.equals(mExp) || XMLA_Util.isDescendant(m, mExp));
262     } else if (f.isCallTo("Descendants")) {
263       // true, if descendants(m2) contain descendants of m
264
// <==> m is equal or ancestor of m2
265
XMLA_Member mExp = (XMLA_Member) f.getArgs()[0];
266       return (m.equals(mExp) || XMLA_Util.isDescendant(m, mExp));
267     } else if (f.isCallTo("Members")) {
268       XMLA_Level levExp = (XMLA_Level) f.getArgs()[0];
269       return (levExp.getDepth() > ((XMLA_Level) m.getLevel()).getDepth());
270     } else if (f.isCallTo("Union")) {
271       if (isDescendantOfMemberInFunCall(f.getArgs()[0], m))
272         return true;
273       else
274         return isDescendantOfMemberInFunCall(f.getArgs()[1], m);
275     } else if (f.isCallTo("{}")) {
276       for (int i = 0; i < f.getArgs().length; i++) {
277         XMLA_Member mExp = (XMLA_Member) f.getArgs()[i];
278         return (!m.equals(mExp) && XMLA_Util.isDescendant(m, mExp));
279       }
280       return false;
281     }
282     throw new Quax.CannotHandleException(f.getFunction());
283   }
284
285   /**
286    * remove children FunCall from Union
287    * should never be called
288    * @param f
289    * @param mPath
290    */

291   static FunCall removeChildrenFromUnion(FunCall f, XMLA_Member monMember) {
292
293     FunCall f1 = (FunCall) f.getArgs()[0];
294     FunCall f2 = (FunCall) f.getArgs()[1];
295     if (f1.isCallTo("Children") && ((XMLA_Member) f1.getArgs()[0]).equals(monMember)) { return f2; }
296     if (f2.isCallTo("Children") && ((XMLA_Member) f1.getArgs()[0]).equals(monMember)) { return f1; }
297     FunCall f1New = f1;
298     if (f1.isCallTo("Union"))
299       f1New = removeChildrenFromUnion(f1, monMember);
300     FunCall f2New = f2;
301     if (f2.isCallTo("Union"))
302       f2New = removeChildrenFromUnion(f2, monMember);
303
304     if (f1 == f1New && f2 == f2New)
305       return f;
306
307     return new FunCall("Union", new Exp[] { f1New, f2New});
308   }
309
310   /**
311    * check level and add a member's uncles to list
312    * @param m
313    */

314   public void addMemberUncles(List JavaDoc list, Member m, int[] maxLevel) {
315     XMLA_Member xm = (XMLA_Member) m;
316
317     int parentLevel = ((XMLA_Level) xm.getLevel()).getDepth() - 1;
318     if (parentLevel < maxLevel[0])
319       return;
320     if (parentLevel > maxLevel[0]) {
321       maxLevel[0] = parentLevel;
322       list.clear();
323     }
324     AddUncels: if (parentLevel > 0) {
325       XMLA_Member parent;
326       XMLA_Member grandPa;
327       try {
328         parent = (XMLA_Member) xm.getParent();
329         grandPa = (XMLA_Member) parent.getParent();
330       } catch (OlapException e) {
331         // should not occur
332
logger.error("?", e);
333         return;
334       }
335
336       // do nothing if already on List
337
for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
338         Exp exp = (Exp) iter.next();
339         if (exp instanceof FunCall) {
340           FunCall f = (FunCall) exp;
341           if (f.isCallTo("Children") && ((XMLA_Member) f.getArgs()[0]).equals(grandPa)) {
342             break AddUncels; // already there
343
}
344         }
345       }
346       FunCall fUncles = new FunCall("Children", new Exp[] { grandPa}, FunCall.TypeProperty);
347       /*
348        // remove all existing children of grandPa from worklist;
349        for (Iterator iter = workList.iterator(); iter.hasNext();) {
350        Exp exp = (Exp) iter.next();
351        if (exp instanceof XMLA_Member
352        && ((XMLA_Member) exp).getParentMember().equals(grandPa))
353        iter.remove();
354        }
355        */

356       list.add(fUncles);
357     } // AddUncels
358
}
359
360   /**
361    * check level and add a member's parents children to list
362    * @param m
363    */

364   public void addMemberSiblings(List JavaDoc list, Member m, int[] maxLevel) {
365     XMLA_Member xm = (XMLA_Member) m;
366     int level = ((XMLA_Level) xm.getLevel()).getDepth();
367     if (level < maxLevel[0])
368       return;
369     if (level > maxLevel[0]) {
370       maxLevel[0] = level;
371       list.clear();
372     }
373     AddSiblings: if (level > 0) {
374       XMLA_Member parent;
375       try {
376         parent = (XMLA_Member) xm.getParent();
377       } catch (OlapException e) {
378         // should not occur
379
logger.error("?", e);
380         return;
381       }
382       // do nothing if already on List
383
for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
384         Exp exp = (Exp) iter.next();
385         if (exp instanceof FunCall) {
386           FunCall f = (FunCall) exp;
387           if (f.isCallTo("Children") && ((XMLA_Member) f.getArgs()[0]).equals(parent)) {
388             break AddSiblings;
389           }
390         }
391       }
392       FunCall fSiblings = new FunCall("Children", new Exp[] { parent}, FunCall.TypeProperty);
393       /*
394        // remove all existing children of parent from worklist;
395        for (Iterator iter = workList.iterator(); iter.hasNext();) {
396        Exp exp = (Exp) iter.next();
397        if (exp instanceof XMLA_Member
398        && ((XMLA_Member) exp).getParentMember().equals(parent))
399        iter.remove();
400        }
401        */

402       list.add(fSiblings);
403     } // AddSiblings
404
}
405
406   /**
407    * check level and add a member to list
408    * @param m
409    */

410   public void addMemberChildren(List JavaDoc list, Member m, int[] maxLevel) {
411     XMLA_Member xm = (XMLA_Member) m;
412     int childLevel = ((XMLA_Level) xm.getLevel()).getDepth() + 1;
413     if (childLevel < maxLevel[0])
414       return;
415     if (childLevel > maxLevel[0]) {
416       maxLevel[0] = childLevel;
417       list.clear();
418     }
419     AddChildren: if (childLevel > 0) {
420       // do nothing if already on List
421
for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
422         Exp exp = (Exp) iter.next();
423         if (exp instanceof FunCall) {
424           FunCall f = (FunCall) exp;
425           if (f.isCallTo("Children") && ((XMLA_Member) f.getArgs()[0]).equals(xm)) {
426             break AddChildren;
427           }
428         }
429       }
430       FunCall fChildren = new FunCall("Children", new Exp[] { xm}, FunCall.TypeProperty);
431       /*
432        // remove all existing children of m from worklist;
433        for (Iterator iter = workList.iterator(); iter.hasNext();) {
434        Exp exp = (Exp) iter.next();
435        if (exp instanceof XMLA_Member
436        && ((XMLA_Member) exp).getParentMember().equals(m))
437        iter.remove();
438        }
439        */

440       list.add(fChildren);
441     } // AddChildren
442
}
443
444   /**
445    * check level and add a members descendatns to list
446    * @param m
447    */

448   public void addMemberDescendants(List JavaDoc list, Member m, Level lev, int[] maxLevel) {
449     XMLA_Member xm = (XMLA_Member) m;
450     int parentLevel = ((XMLA_Level) xm.getLevel()).getDepth() - 1;
451
452     if (parentLevel < maxLevel[0])
453       return;
454     if (parentLevel > maxLevel[0]) {
455       maxLevel[0] = parentLevel;
456       list.clear();
457     }
458     AddDescendants: if (parentLevel > 0) {
459       // do nothing if already on List
460
for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
461         Exp exp = (Exp) iter.next();
462         if (exp instanceof FunCall) {
463           FunCall f = (FunCall) exp;
464           if (f.isCallTo("Descendants") && ((XMLA_Member) f.getArgs()[0]).equals(m)) {
465             break AddDescendants;
466           }
467         }
468       }
469       FunCall fChildren = new FunCall("Descendants", new Exp[] { xm, (XMLA_Level) lev},
470           FunCall.TypeFunction);
471       /*
472        // remove all existing Descendants of m from worklist
473        for (Iterator iter = workList.iterator(); iter.hasNext();) {
474        Exp exp = (Exp) iter.next();
475        if (exp instanceof XMLA_Member
476        && ((XMLA_Member) exp).isChildOrEqualTo(m))
477        iter.remove();
478        }
479        */

480       list.add(fChildren);
481     } // AddDescendants
482
}
483
484   /**
485    * check level and add a levels members to list
486    * @param m
487    */

488   public void addLevelMembers(List JavaDoc list, Level lev, int[] maxLevel) {
489
490     int level = ((XMLA_Level) lev).getDepth();
491     if (level < maxLevel[0])
492       return;
493     if (level > maxLevel[0]) {
494       maxLevel[0] = level;
495       list.clear();
496     }
497     AddMembers: if (level > 0) {
498       // do nothing if already on List
499
for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
500         Exp exp = (Exp) iter.next();
501         if (exp instanceof FunCall) {
502           FunCall f = (FunCall) exp;
503           if (f.isCallTo("Members")) {
504             break AddMembers;
505           }
506         }
507       }
508       FunCall fMembers = new FunCall("Members", new Exp[] { (XMLA_Level) lev}, FunCall.TypeProperty);
509       /*
510        // remove all existing level members from worklist
511        for (Iterator iter = workList.iterator(); iter.hasNext();) {
512        Exp exp = (Exp) iter.next();
513        if (exp instanceof XMLA_Member
514        && ((XMLA_Member) exp).getLevel().equals(lev))
515        iter.remove();
516        }
517        */

518       list.add(fMembers);
519     } // AddDescendants
520
}
521
522   /**
523    * create String representation for FunCall
524    * @param f
525    * @return
526    */

527   public StringBuffer JavaDoc funString(Object JavaDoc oFun) {
528     FunCall f = (FunCall) oFun;
529     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
530     if (f.isCallTo("Children")) {
531       XMLA_Member m = (XMLA_Member) f.getArgs()[0];
532       buf.append(m.getUniqueName());
533       buf.append(".children");
534     } else if (f.isCallTo("Descendants")) {
535       XMLA_Member m = (XMLA_Member) f.getArgs()[0];
536       XMLA_Level lev = (XMLA_Level) f.getArgs()[1];
537       buf.append("Descendants(");
538       buf.append(m.getUniqueName());
539       buf.append(",");
540       buf.append(lev.getUniqueName());
541       buf.append(")");
542     } else if (f.isCallTo("members")) {
543       XMLA_Level lev = (XMLA_Level) f.getArgs()[0];
544       buf.append(lev.getUniqueName());
545       buf.append(".Members");
546     } else if (f.isCallTo("Union")) {
547       buf.append("Union(");
548       FunCall f1 = (FunCall) f.getArgs()[0];
549       buf.append(funString(f1));
550       buf.append(",");
551       FunCall f2 = (FunCall) f.getArgs()[1];
552       buf.append(funString(f2));
553       buf.append(")");
554     } else if (f.isCallTo("{}")) {
555       buf.append("{");
556       for (int i = 0; i < f.getArgs().length; i++) {
557         if (i > 0)
558           buf.append(",");
559         XMLA_Member m = (XMLA_Member) f.getArgs()[i];
560         buf.append(m.getUniqueName());
561       }
562       buf.append("}");
563     } else if (f.isCallTo("TopCount") || f.isCallTo("BottomCount") || f.isCallTo("TopPercent")
564         || f.isCallTo("BottomPercent")) {
565       // just generate Topcount(set)
566
buf.append(f.getFunction());
567       buf.append("(");
568       FunCall f1 = (FunCall) f.getArgs()[0];
569       buf.append(funString(f1));
570       buf.append(")");
571     }
572     return buf;
573   }
574
575   /**
576    * determine hierarchy for Exp
577    * @param exp
578    * @return hierarchy
579    */

580   public Hierarchy hierForExp(Object JavaDoc oExp) throws CannotHandleException {
581     if (oExp instanceof XMLA_Member)
582       return ((XMLA_Member) oExp).getHierarchy();
583     else if (oExp instanceof SetExp) {
584       // set expression generated by CalcSet extension
585
SetExp set = (SetExp) oExp;
586       return set.getHier();
587     }
588
589     // must be FunCall
590
FunCall f = (FunCall) oExp;
591     if (f.isCallTo("Children")) {
592       XMLA_Member m = (XMLA_Member) f.getArgs()[0];
593       return m.getHierarchy();
594     } else if (f.isCallTo("Descendants")) {
595       XMLA_Member m = (XMLA_Member) f.getArgs()[0];
596       return m.getHierarchy();
597     } else if (f.isCallTo("Members")) {
598       XMLA_Level lev = (XMLA_Level) f.getArgs()[0];
599       return lev.getHierarchy();
600     } else if (f.isCallTo("Union")) {
601       // continue with first set
602
return hierForExp(f.getArgs()[0]);
603     } else if (f.isCallTo("{}")) {
604       XMLA_Member m = (XMLA_Member) f.getArgs()[0];
605       return m.getHierarchy();
606     } else if (f.isCallTo("TopCount") || f.isCallTo("BottomCount") || f.isCallTo("TopPercent")
607         || f.isCallTo("BottomPercent") || f.isCallTo("Filter")) {
608       // continue with base set of top bottom function
609
return hierForExp(f.getArgs()[0]);
610     }
611     throw new Quax.CannotHandleException(f.getFunction());
612   }
613
614   /**
615    * @param oExp expression
616    * @return true, if exp is member
617    * @see QuaxUti#isMember(java.lang.Object)
618    */

619   public boolean isMember(Object JavaDoc oExp) {
620     return (oExp instanceof XMLA_Member);
621   }
622
623   /**
624    * @see com.tonbeller.jpivot.olap.query.QuaxUti#isFunCall
625    */

626   public boolean isFunCall(Object JavaDoc oExp) {
627     return (oExp instanceof FunCall);
628   }
629
630   /**
631    * @param oExp expression
632    * @return true if expression equals member
633    * @see QuaxUti#equalMember(java.lang.Object, com.tonbeller.jpivot.olap.model.Member)
634    */

635   public boolean equalMember(Object JavaDoc oExp, Member member) {
636     return ((XMLA_Member) member).equals(oExp);
637   }
638
639   /**
640    * @see QuaxUti#getParentMember(java.lang.Object)
641    */

642   public Member getParentMember(Object JavaDoc oExp) {
643     try {
644       return ((XMLA_Member) oExp).getParent();
645     } catch (OlapException e) {
646       // should not occur
647
logger.error("?", e);
648       return null;
649     }
650   }
651
652   /**
653    * create Children FunCall
654    * @see QuaxUti#funChildren(com.tonbeller.jpivot.olap.model.Member)
655    */

656   public Object JavaDoc funCallChildren(Member member) {
657     return new FunCall("Children", new Exp[] { (XMLA_Member) member}, FunCall.TypeProperty);
658   }
659
660   /**
661    * @return a members hierarchy
662    * @see QuaxUti#hierForMember(com.tonbeller.jpivot.olap.model.Member)
663    */

664   public Hierarchy hierForMember(Member member) {
665     XMLA_Member xm = (XMLA_Member) member;
666     return xm.getHierarchy();
667   }
668
669   /**
670    * return a members dimension
671    * @see QuaxUti#dimForMember(com.tonbeller.jpivot.olap.model.Member)
672    */

673   public Dimension dimForMember(Member member) {
674     XMLA_Member xm = (XMLA_Member) member;
675     return xm.getHierarchy().getDimension();
676   }
677
678   /**
679    * @return a members unique name
680    * @see QuaxUti#getMemberUniqueName(java.lang.Object)
681    */

682   public String JavaDoc getMemberUniqueName(Object JavaDoc oExp) {
683     XMLA_Member m = (XMLA_Member) oExp;
684     return m.getUniqueName();
685   }
686
687   /**
688    * @return true, if an expression is a FunCall to e specific function
689    * @see QuaxUti#funCallTo(java.lang.Object, java.lang.String)
690    */

691   public boolean isFunCallTo(Object JavaDoc oExp, String JavaDoc function) {
692     return ((FunCall) oExp).isCallTo(function);
693   }
694
695   /**
696    * return a FunCalls argument of given index
697    * @see QuaxUti#funCallArg(java.lang.Object, int)
698    */

699   public Object JavaDoc funCallArg(Object JavaDoc oExp, int index) {
700     return ((FunCall) oExp).getArgs()[index];
701   }
702
703   /**
704    * @return funcall name
705    * @see com.tonbeller.jpivot.olap.query.QuaxUti#funCallName(java.lang.Object)
706    */

707   public String JavaDoc funCallName(Object JavaDoc oFun) {
708     return ((FunCall) oFun).getFunction();
709   }
710
711   /**
712    * @return true if member (2.arg) is child of Member (1.arg)
713    * @see com.tonbeller.jpivot.olap.query.QuaxUti#checkParent
714    */

715   public boolean checkParent(Member pMember, Object JavaDoc cMemObj) {
716     // check by unique name, if possible
717
XMLA_Member pm = (XMLA_Member) pMember;
718     XMLA_Member cm = (XMLA_Member) cMemObj;
719     if (pm.isMicrosoft()) {
720       String JavaDoc pUName = cm.getParentUniqueName();
721       return ((XMLA_Member) pMember).getUniqueName().equals(pUName);
722     } else {
723       // SAP - unique name does not contain parent
724
try {
725         return (pm.equals(cm.getParent()));
726       } catch (OlapException e) {
727         return false; // should not occur
728
}
729     }
730   }
731
732   /**
733    * @return true if member (1.arg) is child of Member (2.arg)
734    * @see com.tonbeller.jpivot.olap.query.QuaxUti#checkParent
735    */

736   public boolean checkChild(Member cMember, Object JavaDoc pMemObj) {
737     return checkParent((XMLA_Member) pMemObj, cMember);
738   }
739
740   /**
741    * @return true if member (2.arg) is descendant of Member (1.arg)
742    * @see QuaxUti.checkDescendant
743    */

744   public boolean checkDescendantM(Member aMember, Member dMember) {
745     return XMLA_Util.isDescendant((XMLA_Member) aMember, (XMLA_Member) dMember);
746   }
747
748   /**
749    * @return true if member object (2.arg) is descendant of Member (1.arg)
750    * @see QuaxUti.checkDescendantO
751    */

752   public boolean checkDescendantO(Member aMember, Object JavaDoc oMember) {
753     return XMLA_Util.isDescendant((XMLA_Member) aMember, (XMLA_Member) oMember);
754   }
755
756   /**
757    * @return exp object for member
758    * @see QuaxUti#objForMember(com.tonbeller.jpivot.olap.model.Member)
759    */

760   public Object JavaDoc objForMember(Member member) {
761     return member;
762   }
763
764   /**
765    * @return exp object for dimension
766    * @see com.tonbeller.jpivot.olap.query.QuaxUti#objForDim(com.tonbeller.jpivot.olap.model.Dimension)
767    */

768   public Object JavaDoc objForDim(Dimension dim) {
769     return dim; //(Exp)((XMLA_Dimension)dim);
770
}
771
772   /**
773    * return member for exp object
774    * @see QuaxUti#memberForObj(java.lang.Object)
775    */

776   public Member memberForObj(Object JavaDoc oExp) {
777     return (Member) oExp;
778   }
779
780   /**
781    * display member array for debugging purposes
782    * @param member
783    * @return
784    */

785   public String JavaDoc memberString(Member[] mPath) {
786     if (mPath == null || mPath.length == 0)
787       return "";
788     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
789     for (int i = 0; i < mPath.length; i++) {
790       if (i > 0)
791         sb.append(" ");
792       sb.append(((XMLA_Member) mPath[i]).getUniqueName());
793     }
794     return sb.toString();
795   }
796
797
798   /**
799    * generate an object for a list of members
800    * @param mList list of members
801    * @return null for empty lis, single member or set function otherwise
802    * @see com.tonbeller.jpivot.olap.query.QuaxUti#createMemberSet
803    */

804   public Object JavaDoc createMemberSet(List JavaDoc mList) {
805     if (mList.size() == 0)
806       return null;
807     else if (mList.size() == 1)
808       return (Exp) mList.get(0);
809     else {
810       Exp[] remExps = (Exp[]) mList.toArray(new Exp[0]);
811       return new FunCall("{}", remExps, FunCall.TypeBraces);
812     }
813   }
814
815   /**
816    * check whether a Funcall does NOT resolve to top level of hierarchy
817    * @param f
818    * @return
819    */

820   public boolean isFunCallNotTopLevel(Object JavaDoc oExp) throws CannotHandleException {
821     FunCall f = (FunCall) oExp;
822     if (f.isCallTo("Children")) {
823       return true; // children *not* top level
824
} else if (f.isCallTo("Descendants")) {
825       return true; // descendants*not* top level
826
} else if (f.isCallTo("Members")) {
827       XMLA_Level lev = (XMLA_Level) f.getArgs()[0];
828       return (lev.getDepth() > 0);
829     } else if (f.isCallTo("Union")) {
830       if (isFunCallNotTopLevel(f.getArgs()[0]))
831         return true;
832       return isFunCallNotTopLevel(f.getArgs()[1]);
833     } else if (f.isCallTo("{}")) {
834       for (int i = 0; i < f.getArgs().length; i++) {
835         if (!isMemberOnToplevel(f.getArgs()[i]))
836           return true;
837       }
838       return false;
839     }
840     throw new Quax.CannotHandleException(f.getFunction());
841   }
842
843   /**
844    * @return true if member is on top level (has no parent)
845    * @see com.tonbeller.jpivot.olap.query.QuaxUti#isMemberOnToplevel
846    */

847   public boolean isMemberOnToplevel(Object JavaDoc oMem) {
848     XMLA_Member m = (XMLA_Member) oMem;
849     if (((XMLA_Level) m.getLevel()).getDepth() > 0)
850       return false;
851     else
852       return true;
853   }
854
855   /**
856    * @return the depth of a member's level
857    * @see QuaxUti#levelDepthForMember(java.lang.Object)
858    */

859   public int levelDepthForMember(Object JavaDoc oExp) {
860     XMLA_Member m = (XMLA_Member) oExp;
861     XMLA_Level level = (XMLA_Level) m.getLevel();
862     return level.getDepth();
863   }
864
865   /**
866    * @return an Expression Object for the top level members of an hierarchy
867    * @see QuaxUti#topLevelMembers(com.tonbeller.jpivot.olap.model.Hierarchy)
868    */

869   public Object JavaDoc topLevelMembers(Hierarchy hier, boolean expandAllMember) {
870     return XMLA_Util.topLevelMembers(hier, expandAllMember);
871   }
872
873   /**
874    * @return count of a FunCall's arguments
875    * @see QuaxUti#funCallArgCount(java.lang.Object)
876    */

877   public int funCallArgCount(Object JavaDoc oFun) {
878     FunCall f = (FunCall) oFun;
879     return f.getArgs().length;
880   }
881
882   /**
883    * @param oLevel expression object representing level
884    * @return Level for given Expression Object
885    * @see QuaxUti#LevelForObj(java.lang.Object)
886    */

887   public Level LevelForObj(Object JavaDoc oLevel) {
888     return (Level) oLevel;
889   }
890
891   /**
892    * @return the parent level of a given level
893    * @see QuaxUti#getParentLevel(com.tonbeller.jpivot.olap.model.Level)
894    */

895   public Level getParentLevel(Level level) {
896     return ((XMLA_Level) level).getParentLevel();
897   }
898
899   public mondrian.olap.Exp toExp(Object JavaDoc o) {
900     return (mondrian.olap.Exp) o;
901   }
902
903     /**
904    * create FunCall
905    * @see QuaxUti#createFunCall(java.lang.String, java.lang.Object[], int)
906    */

907   public Object JavaDoc createFunCall(String JavaDoc function, Object JavaDoc[] args, int funType) {
908     Exp[] expArgs = new Exp[args.length];
909     for (int i = 0; i < expArgs.length; i++) {
910       expArgs[i] = (Exp) args[i];
911     }
912     int type;
913     switch (funType) {
914     case QuaxUti.FUNTYPE_BRACES:
915       type = FunCall.TypeBraces;
916       break;
917     case QuaxUti.FUNTYPE_PROPERTY:
918       type = FunCall.TypeProperty;
919       break;
920     case QuaxUti.FUNTYPE_TUPLE:
921       type = FunCall.TypeParentheses;
922       break;
923     case QuaxUti.FUNTYPE_INFIX:
924       type = FunCall.TypeInfix;
925       break;
926     default:
927       type = FunCall.TypeFunction;
928     }
929     return new FunCall(function, expArgs, type);
930   }
931
932   /**
933    * check an expression whether we can handle it (expand, collapse)
934    * currently we can basically handle following FunCalls
935    * member.children, member.descendants, level.members
936    * @see com.tonbeller.jpivot.olap.query.QuaxUti#canHandle(java.lang.Object)
937    */

938   public boolean canHandle(Object JavaDoc oExp) {
939
940     if (oExp instanceof Member)
941       return true;
942     FunCall f = (FunCall) oExp;
943     if (f.isCallTo("children"))
944       return true;
945     if (f.isCallTo("descendants"))
946       return true;
947     if (f.isCallTo("members"))
948       return true;
949     if (f.isCallTo("{}"))
950       return true;
951     if (f.isCallTo("union")) {
952       for (int i = 0; i < f.getArgs().length; i++) {
953         if (!canHandle(f.getArgs()[i]))
954           return false;
955       }
956       return true;
957     }
958
959     return false;
960   }
961
962
963   /**
964    * @return member children
965    * @see com.tonbeller.jpivot.olap.query.QuaxUti#getChildren(java.lang.Object)
966    */

967   public Object JavaDoc[] getChildren(Object JavaDoc oMember) {
968     XMLA_Member[] mChildren;
969     try {
970       mChildren = ((XMLA_Member) oMember).getChildren();
971     } catch (OlapException e) {
972       // should not occur
973
logger.fatal("unexpected exception", e);
974       return null;
975     }
976     return mChildren;
977   }
978
979   /**
980    * get the members of a level
981    */

982   public Object JavaDoc[] getLevelMembers(Level level) {
983      XMLA_Member[] members;
984     try {
985       members = ((XMLA_Level)level).getMembers();
986     } catch (OlapException e) {
987       logger.fatal("unexpected failure level members", e);
988       return null;
989     }
990      return members;
991   }
992
993 } //XMLA_QuaxUti
994
Popular Tags