KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > lib > EjbqlQueryTreeHolder


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2004 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: EjbqlQueryTreeHolder.java,v 1.24 2005/01/22 01:42:53 rhs Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.jonas_ejb.lib;
26
27 import java.util.Collection JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30
31 import org.objectweb.jonas_ejb.container.TraceEjb;
32 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
33 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
34 import org.objectweb.jonas_ejb.deployment.api.MethodCmp2Desc;
35 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEJBQL;
36 import org.objectweb.jorm.api.PMapper;
37 import org.objectweb.jorm.metainfo.api.Manager;
38 import org.objectweb.medor.api.Field;
39 import org.objectweb.medor.eval.api.QueryEvaluator;
40 import org.objectweb.medor.eval.lib.MedorEvaluator;
41 import org.objectweb.medor.expression.api.Expression;
42 import org.objectweb.medor.optim.api.QueryTransformer;
43 import org.objectweb.medor.query.api.OrderField;
44 import org.objectweb.medor.query.api.QueryTree;
45 import org.objectweb.medor.query.api.QueryTreeField;
46 import org.objectweb.medor.query.jorm.api.JormExtent;
47 import org.objectweb.medor.query.jorm.lib.ClassExtent;
48 import org.objectweb.medor.query.jorm.lib.JormQueryTreeHelper;
49 import org.objectweb.medor.query.jorm.lib.QueryBuilder;
50 import org.objectweb.medor.query.lib.QueryTreePrinter;
51 import org.objectweb.medor.query.lib.SelectProject;
52 import org.objectweb.util.monolog.api.BasicLevel;
53
54
55 /**
56  * Class to hold the query tree of a given EJBQL request. This allows walking the
57  * JormExtents of the tree to set the mappers.
58  * @author Christophe Ney - cney@batisseurs.com : Initial developer
59  * @author Helene Joanin: Take into account the ORDER BY clause.
60  * @author Sebastien Chassande-Barrioz & Helene Joanin: prefetch code
61  * @author Helene Joanin: Take into account the aggregate select expression.
62  * @author Cyrille Blot: Take into account the LIMIT clause
63  */

64 public class EjbqlQueryTreeHolder {
65
66     QueryTree queryTree = null;
67     QueryTransformer queryOptimizer = null;
68     QueryEvaluator optimizedQuery = null;
69     Field resField = null;
70     EjbqlLimiterRange[] limiterRanges = null;
71
72     private String JavaDoc beanName;
73     private String JavaDoc methodName;
74
75     /**
76      * Indicates the index of the identifier (PName) in the TupleCollection of
77      * the SelectProject node (root of of the tree).
78      */

79     private int prefetchIdentifierIndex;
80
81
82     /**
83      * constructor of a holder for a specific query.
84      * @param mDesc JOnAS meta-information for the corresponding finder/select method
85      * @param ejbql root of the lexical tree of the query
86      * @param mapper mapper to associate at each leaves of the QueryTree.
87      * The mapper may be null in case of the QueryTree is build in the GenIC phase.
88      */

89     public EjbqlQueryTreeHolder(MethodCmp2Desc mDesc, ASTEJBQL ejbql, PMapper mapper)
90             throws Exception JavaDoc {
91
92         EntityCmp2Desc eDesc = (EntityCmp2Desc) mDesc.getBeanDesc();
93         DeploymentDescEjb2 dd = (DeploymentDescEjb2) eDesc.getDeploymentDesc();
94         Manager jormManager = dd.getJormManager();
95
96         // create identifiers Map (visit ALL the query)
97
QueryBuilder qb = new QueryBuilder();
98         Map JavaDoc fields = (new EjbqlVariableVisitor(ejbql, dd, qb)).getFields();
99
100         // Begin PREFETCHING CODE (by Seb)
101
SelectProject sp = new SelectProject("");
102         if (mDesc.getPrefetch() && (mapper != null)) {
103             // Find the QueryTree of the ClassExtend of the bean of the current finder method
104
// WARNING: This only works for finder methods, and not for ejbSelect methods!!!
105
// (Indeed the result type of the query must be the bean type in which
106
// the method is defined)
107
ClassExtent ce = null;
108             QueryTree qt = null;
109             String JavaDoc jormClassName = ((EntityCmp2Desc) mDesc.getBeanDesc()).getJormClassName();
110             Iterator JavaDoc itFields = fields.values().iterator();
111             boolean found = false;
112             while (itFields.hasNext() && !found) {
113                 QueryTree cqt = ((QueryTreeField) itFields.next()).getQueryTree();
114                 Collection JavaDoc extents = JormQueryTreeHelper.getJormExtents(cqt);
115                 for (Iterator JavaDoc it = extents.iterator(); it.hasNext() && !found;) {
116                     JormExtent je = (JormExtent) it.next();
117                     if (jormClassName.equals(je.getJormName())) {
118                         found = true;
119                         ce = (ClassExtent) je;
120                         qt = cqt;
121                     }
122                 }
123             }
124             if ((ce == null) && (qt == null)) {
125                 throw new Error JavaDoc("EjbqlQueryTreeHolder: cannot do the prefetch !!!");
126             }
127             setMapper(qt, mapper);
128             // Add fields of the class which the values must be prefetched, at
129
// the begin of the the TupleCollection
130
JormQueryTreeHelper.addPrefetchFields(ce, qt, sp);
131             prefetchIdentifierIndex = sp.getTupleStructure().getSize() + 1;
132         }
133         // End PREFETCHING CODE
134

135         // create SelectProject (visit the SELECT clause)
136
EjbqlSelectVisitor selectVisitor = new EjbqlSelectVisitor(ejbql, fields, sp);
137
138         // create the Filter's expression (visit the WHERE clause)
139
Expression qf = new EjbqlQueryFilterVisitor
140             (mapper, fields, mDesc.getMethod().getParameterTypes(), ejbql, qb).getQueryFilter();
141         sp.setQueryFilter(qf);
142
143         // create the OrderField list (visit the ORDER BY clause)
144
OrderField[] ofs = new EjbqlOrderByVisitor(ejbql, fields).getOrderFields();
145         if (ofs.length > 0) {
146             sp.setOrderBy(ofs);
147         }
148
149         // create the EjbqlLimiterRange list (visit the LIMIT clause)
150
limiterRanges = new EjbqlLimitVisitor(ejbql, mDesc.getMethod().getParameterTypes()).getLimiterRanges();
151
152         queryTree = selectVisitor.getQueryTree();
153
154         setMapper(queryTree, mapper);
155
156         // Get the field description of the result of the query
157
// Nota Bene: TupleStructures of queries non optimized and optimized are differents.
158
resField = queryTree.getTupleStructure().getField(queryTree.getTupleStructure().getSize());
159
160         // Just needed later for debug trace
161
beanName = eDesc.getJormClassName();
162         methodName = mDesc.getMethod().getName();
163     }
164
165     private void setMapper(QueryTree tree, PMapper mapper) {
166         // set the mapper of each leaves of the QueryTree
167
if (mapper != null) {
168             Collection JavaDoc extents = JormQueryTreeHelper.getJormExtents(tree);
169             for (Iterator JavaDoc it = extents.iterator(); it.hasNext();) {
170                 JormExtent je = (JormExtent) it.next();
171                 je.setPMapper(mapper, RdbMappingBuilder.getProjectName());
172             }
173         }
174     }
175
176     public int getPrefetchIndex() {
177         return prefetchIdentifierIndex;
178     }
179
180     /**
181      * get the query tree that was built from visiting the lexical tree
182      */

183     public QueryTree getQueryTree() {
184         return queryTree;
185     }
186
187     /**
188      * Set the optimizer to be used when optimizing the query tree
189      */

190     public void setQueryOptimizer(QueryTransformer qtf) {
191         optimizedQuery = null;
192         queryOptimizer = qtf;
193     }
194
195     /**
196      * get the current query tree optimizer
197      */

198     public QueryTransformer getQueryOptimizer() {
199         return queryOptimizer;
200     }
201
202     /**
203      * get the Medor result Field of the query (useful for the ejbSelect method)
204      */

205     public Field getResField() {
206         return resField;
207     }
208     /**
209      * @return returns the limiter ranges of the LIMIT clause.
210      * May be 0 element if no LIMIT clause, 1 or 2 elements otherwise.
211      */

212     public EjbqlLimiterRange[] getLimiterRanges() {
213         return limiterRanges;
214     }
215
216     /**
217      * Get the query evaluator of the optimized query. The query is optimized on first call.
218      * All mappers of the query should have been already set with the help of the iterator
219      * returned by the <code>getJormExtentIterator</code> method.
220      */

221     public QueryEvaluator getOptimizedQueryTree() throws Exception JavaDoc {
222         if (optimizedQuery == null) {
223             if (TraceEjb.isDebugQuery()) {
224                 TraceEjb.query.log(BasicLevel.DEBUG,
225                                    "Initial QueryTree of the method " + methodName
226                                    + " of the bean " + beanName);
227                 QueryTreePrinter.printQueryTree(queryTree, TraceEjb.query, BasicLevel.DEBUG);
228             }
229             QueryTree qt = queryOptimizer.transform(queryTree);
230             if (TraceEjb.isDebugQuery()) {
231                 TraceEjb.query.log(BasicLevel.DEBUG,
232                                    "Optimized QueryTree of the method " + methodName
233                                    + " of the bean " + beanName);
234                 QueryTreePrinter.printQueryTree(qt, TraceEjb.query, BasicLevel.DEBUG);
235             }
236             optimizedQuery = new MedorEvaluator(qt, 0);
237         }
238         return optimizedQuery;
239     }
240
241 }
242
Popular Tags