KickJava   Java API By Example, From Geeks To Geeks.

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


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 mondrian.olap.Exp;
16 import mondrian.olap.Literal;
17 import mondrian.olap.Syntax;
18 import mondrian.mdx.MemberExpr;
19 import mondrian.mdx.UnresolvedFunCall;
20
21 import org.apache.log4j.Logger;
22
23 import com.tonbeller.jpivot.olap.navi.SortRank;
24 import com.tonbeller.jpivot.olap.query.QuaxChangeListener;
25 import com.tonbeller.jpivot.olap.query.SortRankBase;
26
27 /**
28  * @author hh
29  *
30  * Implementation of the Sort Extension for Mondrian Data Source.
31  */

32 public class MondrianSortRank extends SortRankBase implements SortRank, QuaxChangeListener {
33
34   static Logger logger = Logger.getLogger(MondrianSortRank.class);
35
36   public MondrianSortRank() {
37     super.setId(SortRank.ID);
38   }
39
40   /**
41    * apply sort to mondrian query
42    */

43   public void addSortToQuery() {
44     if (sorting && sortPosMembers != null) {
45       MondrianModel model = (MondrianModel) getModel();
46       mondrian.olap.Query monQuery = ((MondrianQueryAdapter)model.getQueryAdapter()).getMonQuery();
47
48       switch (sortMode) {
49         case com.tonbeller.jpivot.olap.navi.SortRank.ASC :
50         case com.tonbeller.jpivot.olap.navi.SortRank.DESC :
51         case com.tonbeller.jpivot.olap.navi.SortRank.BASC :
52         case com.tonbeller.jpivot.olap.navi.SortRank.BDESC :
53           // call sort
54
orderAxis(monQuery, sortMode);
55           break;
56         case com.tonbeller.jpivot.olap.navi.SortRank.TOPCOUNT :
57           topBottomAxis(monQuery, "TopCount");
58           break;
59         case com.tonbeller.jpivot.olap.navi.SortRank.BOTTOMCOUNT :
60           topBottomAxis(monQuery, "BottomCount");
61           break;
62         default :
63           return; // do nothing
64
}
65     }
66   }
67
68   /**
69   * Convert sort mode ordinal to sort mode name
70   * @param sortMode mode
71   * @return name of sort mode
72   */

73   static private String JavaDoc sortModeName(int sortMode) {
74     switch (sortMode) {
75       case com.tonbeller.jpivot.olap.navi.SortRank.ASC :
76         return "ASC";
77       case com.tonbeller.jpivot.olap.navi.SortRank.DESC :
78         return "DESC";
79       case com.tonbeller.jpivot.olap.navi.SortRank.BASC :
80         return "BASC";
81       case com.tonbeller.jpivot.olap.navi.SortRank.BDESC :
82         return "BDESC";
83       default :
84         return null;
85     }
86   }
87
88   /**
89    * add Order Funcall to QueryAxis
90    * @param monQuery
91    * @param sortMode
92    */

93   private void orderAxis(mondrian.olap.Query monQuery, int sortMode) {
94     // Order(TopCount) is allowed, Order(Order) is not permitted
95
//removeTopLevelSort(monQuery, new String[] { "Order" });
96
mondrian.olap.QueryAxis monAx = monQuery.getAxes()[quaxToSort.getOrdinal()];
97     Exp setForAx = monAx.getSet();
98     Exp memToSort;
99     if (sortPosMembers.length == 1) {
100       memToSort = new MemberExpr(((MondrianMember) sortPosMembers[0]).getMonMember());
101     } else {
102       MemberExpr[] memberExprs = new MemberExpr[sortPosMembers.length];
103       for (int i = 0; i < memberExprs.length; i++) {
104         memberExprs[i] = new MemberExpr(((MondrianMember) sortPosMembers[i]).getMonMember());
105       }
106       memToSort = new UnresolvedFunCall("()", Syntax.Parentheses, memberExprs);
107     }
108     String JavaDoc sDirection = sortModeName(sortMode);
109     UnresolvedFunCall funOrder =
110       new UnresolvedFunCall("Order", new Exp[] { setForAx, memToSort, Literal.createSymbol(sDirection)});
111     monAx.setSet(funOrder);
112   }
113
114   /**
115    * add Top/BottomCount Funcall to QueryAxis
116    */

117   private void topBottomAxis(mondrian.olap.Query monQuery, String JavaDoc function) {
118     // TopCount(TopCount) and TopCount(Order) is not permitted
119
//removeTopLevelSort(monQuery, new String[] { "TopCount", "BottomCount", "Order" });
120
mondrian.olap.QueryAxis monAx = monQuery.getAxes()[quaxToSort.getOrdinal()];
121     Exp setForAx = monAx.getSet();
122     Exp memToSort;
123     if (sortPosMembers.length > 1) {
124       MemberExpr[] memberExprs = new MemberExpr[sortPosMembers.length];
125       for (int i = 0; i < memberExprs.length; i++) {
126         memberExprs[i] = new MemberExpr(((MondrianMember) sortPosMembers[i]).getMonMember());
127       }
128       memToSort = new UnresolvedFunCall("()", Syntax.Parentheses, memberExprs);
129     } else {
130       memToSort = new MemberExpr(((MondrianMember) sortPosMembers[0]).getMonMember());
131     }
132     UnresolvedFunCall funOrder =
133       new UnresolvedFunCall(
134         function,
135         new Exp[] { setForAx, Literal.create(new Integer JavaDoc(topBottomCount)), memToSort });
136     monAx.setSet(funOrder);
137   }
138
139   /**
140    * remove top level sort functions from query axis
141    * @param monAx
142    * @param functions
143    */

144   /* not neeeded as of MDX generation version 3
145    private void removeTopLevelSort(mondrian.olap.Query monQuery, String[] functions) {
146      // if the original MDX starts with a sort function, remove it from current query
147      Exp originalSet = quaxToSort.getOriginalSet();
148      if (!(originalSet instanceof FunCall))
149        return;
150      FunCall topF = (FunCall) originalSet;
151      String fuName = topF.getFunName();
152      boolean found = false;
153      for (int i = 0; i < functions.length; i++) {
154        if (functions[i].equalsIgnoreCase(fuName)) {
155          found = true;
156          break;
157        }
158      }
159      if (!found)
160        return;
161
162      // remove sort function from current set
163      mondrian.olap.QueryAxis monAx = monQuery.axes[quaxToSort.getOrdinal()];
164      Exp setForAx = monAx.set;
165      Exp exp = setForAx;
166      FunCall parent = null;
167      while (exp instanceof FunCall) {
168        // we skip over Hierarchize and Union, which was added by navigation
169        FunCall f = (FunCall) exp;
170        String currentName = f.getFunName();
171        if (currentName.equalsIgnoreCase("Hierarchize") || currentName.equalsIgnoreCase("Union")) {
172          // skip over
173          parent = f;
174          exp = f.args[0]; // first arg leads to original set
175        } else if (currentName.equalsIgnoreCase(fuName)) {
176          // remove it
177          if (parent == null)
178            monAx.set = f.args[0];
179          else
180            parent.args[0] = f.args[0];
181          return;
182        } else
183          return; // should never get here
184      }
185    }
186   */

187
188 } // End MondrianSortRank
189
Popular Tags