KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > olap > query > ExpGenerator


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.olap.query;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import com.tonbeller.jpivot.olap.model.Hierarchy;
20 import com.tonbeller.jpivot.util.TreeNode;
21
22 /**
23  * Generate MDX expresstin for Tree Node
24  */

25 public class ExpGenerator {
26
27   TreeNode rootNode = null;
28    int nDimension;
29   Hierarchy[] hiers;
30
31   QuaxUti uti;
32
33   /**
34    * c'tor
35    */

36   public ExpGenerator(QuaxUti uti) {
37     this.uti = uti;
38   }
39
40   /**
41    * init
42    */

43   public void init(TreeNode rootNode, Hierarchy[] hiers) {
44     this.rootNode = rootNode;
45     this.hiers = hiers;
46     this.nDimension = hiers.length;
47   }
48
49   /**
50    * generate MDX Expression
51    * @param genHierarchize
52    * @return
53    */

54   public Object JavaDoc genExp() {
55
56     Object JavaDoc exp = null;
57     List JavaDoc nodes = rootNode.getChildren();
58
59     // single members (nDimension = 1) are enclosed in set brackets
60
List JavaDoc openSet = new ArrayList JavaDoc(); // collect single members
61
// loop over top level nodes
62
NodeLoop: for (Iterator JavaDoc iter = nodes.iterator(); iter.hasNext();) {
63       TreeNode node = (TreeNode) iter.next();
64       Object JavaDoc expForNode = null;
65       expForNode = genExpForNode(node, nDimension);
66       boolean closeOpenSet = false;
67       if (nDimension == 1) {
68         if (uti.isMember(expForNode)) {
69           openSet.add(expForNode);
70           continue NodeLoop;
71         } else
72           closeOpenSet = true;
73       } else {
74         if (uti.isFunCallTo(expForNode, "()")) {
75           openSet.add(expForNode);
76           continue NodeLoop;
77         } else
78           closeOpenSet = true;
79       }
80
81       if (closeOpenSet && openSet.size() > 0) {
82         // close open set
83
Object JavaDoc[] expArray = openSet.toArray(new Object JavaDoc[0]);
84         Object JavaDoc set = uti.createFunCall("{}", expArray, QuaxUti.FUNTYPE_BRACES);
85         if (exp == null) {
86           exp = set;
87         } else {
88           // generate Union
89
exp = uti.createFunCall("Union", new Object JavaDoc[] { exp, set }, QuaxUti.FUNTYPE_FUNCTION);
90         }
91         openSet.clear();
92       }
93
94       if (exp == null) {
95         exp = expForNode;
96       } else {
97         // generate Union of Exp and expForNode
98
exp = uti
99             .createFunCall("Union", new Object JavaDoc[] { exp, expForNode }, QuaxUti.FUNTYPE_FUNCTION);
100       }
101     }
102     if (openSet.size() > 0) {
103       // close open set
104
Object JavaDoc[] expArray = openSet.toArray(new Object JavaDoc[0]);
105       Object JavaDoc set = uti.createFunCall("{}", expArray, QuaxUti.FUNTYPE_BRACES);
106       if (exp == null) {
107         exp = set;
108       } else {
109         // generate Union
110
exp = uti.createFunCall("Union", new Object JavaDoc[] { exp, set }, QuaxUti.FUNTYPE_FUNCTION);
111       }
112       openSet.clear();
113     }
114
115     return exp;
116   }
117
118   /**
119    * recursively generate Exp for a node
120    *
121    * @param node
122    * @return
123    */

124   private Object JavaDoc genExpForNode(TreeNode node, int untilIndex) {
125
126     Object JavaDoc eNode = node.getReference();
127     if (node.getLevel() == untilIndex)
128       return eNode; // last dimension
129

130     // use tuple representation if possible
131
Object JavaDoc[] tuple = genTuple(node);
132     if (tuple != null) {
133       if (tuple.length == 1)
134         return tuple[0];
135       else
136         return uti.createFunCall("()", tuple, QuaxUti.FUNTYPE_TUPLE);
137     }
138
139     // generate CrossJoin
140
Object JavaDoc exp = null;
141     List JavaDoc childNodes = node.getChildren();
142     for (Iterator JavaDoc iter = childNodes.iterator(); iter.hasNext();) {
143       TreeNode childNode = (TreeNode) iter.next();
144       Object JavaDoc childExp = genExpForNode(childNode, untilIndex);
145       Object JavaDoc childSet = bracesAround(childExp);
146
147       Object JavaDoc eSet;
148       if (!uti.isMember(eNode)) {
149         // FunCall
150
eSet = eNode;
151       } else {
152         // member
153
eSet = uti.createFunCall("{}", new Object JavaDoc[] { eNode }, QuaxUti.FUNTYPE_BRACES);
154       }
155       Object JavaDoc cj = uti.createFunCall("CrossJoin", new Object JavaDoc[] { eSet, childSet },
156           QuaxUti.FUNTYPE_FUNCTION);
157       if (exp == null)
158         exp = cj;
159       else {
160         exp = uti.createFunCall("Union", new Object JavaDoc[] { exp, cj }, QuaxUti.FUNTYPE_FUNCTION);
161       }
162     }
163     return exp;
164   }
165
166   /**
167    * generate Union object
168    *
169    * @param oExps
170    * @return
171    */

172   private Object JavaDoc genUnion(Object JavaDoc[] oExps) {
173     if (oExps.length == 1)
174       return oExps[0];
175     Object JavaDoc oUnion = uti.createFunCall("Union", new Object JavaDoc[] { oExps[0], oExps[1] },
176         QuaxUti.FUNTYPE_FUNCTION);
177     for (int i = 2; i < oExps.length; i++)
178       oUnion = uti.createFunCall("Union", new Object JavaDoc[] { oUnion, oExps[i] },
179           QuaxUti.FUNTYPE_FUNCTION);
180     return oUnion;
181   }
182
183   /**
184    * put braces around single member or single tuple
185    *
186    * @param oExp
187    * @return set exp
188    */

189   private Object JavaDoc bracesAround(Object JavaDoc oExp) {
190     Object JavaDoc oSet;
191     if (uti.isMember(oExp) || uti.isFunCallTo(oExp, "()"))
192       oSet = uti.createFunCall("{}", new Object JavaDoc[] { oExp }, QuaxUti.FUNTYPE_BRACES);
193     else
194       oSet = oExp;
195     return oSet;
196   }
197
198   /**
199    * generate Tuple Exp
200    *
201    * @param node
202    * @return
203    */

204   private Object JavaDoc[] genTuple(TreeNode node) {
205     if (!uti.isMember(node.getReference()))
206       return null;
207     int size = nDimension - node.getLevel() + 1;
208     if (size == 1) {
209       return new Object JavaDoc[] { node.getReference() }; // single member
210
}
211     List JavaDoc childNodes = node.getChildren();
212     if (childNodes.size() != 1)
213       return null;
214     Object JavaDoc[] nextTuple = genTuple((TreeNode) childNodes.get(0));
215     if (nextTuple == null)
216       return null;
217     Object JavaDoc[] tupleMembers = new Object JavaDoc[size];
218     tupleMembers[0] = node.getReference();
219     for (int i = 1; i < tupleMembers.length; i++) {
220       tupleMembers[i] = nextTuple[i - 1];
221     }
222     return tupleMembers;
223   }
224
225 } // ExpGenerator
226
Popular Tags