EjbqlQueryTreeHolder.java

00001 
00025 package org.objectweb.jonas_ejb.lib;
00026 
00027 import java.util.Collection;
00028 import java.util.Iterator;
00029 import java.util.Map;
00030 
00031 import org.objectweb.jonas_ejb.container.TraceEjb;
00032 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
00033 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
00034 import org.objectweb.jonas_ejb.deployment.api.MethodCmp2Desc;
00035 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEJBQL;
00036 import org.objectweb.jorm.api.PMapper;
00037 import org.objectweb.jorm.metainfo.api.Manager;
00038 import org.objectweb.medor.api.Field;
00039 import org.objectweb.medor.eval.api.QueryEvaluator;
00040 import org.objectweb.medor.eval.lib.MedorEvaluator;
00041 import org.objectweb.medor.expression.api.Expression;
00042 import org.objectweb.medor.optim.api.QueryTransformer;
00043 import org.objectweb.medor.query.api.OrderField;
00044 import org.objectweb.medor.query.api.QueryTree;
00045 import org.objectweb.medor.query.api.QueryTreeField;
00046 import org.objectweb.medor.query.jorm.api.JormExtent;
00047 import org.objectweb.medor.query.jorm.lib.ClassExtent;
00048 import org.objectweb.medor.query.jorm.lib.JormQueryTreeHelper;
00049 import org.objectweb.medor.query.jorm.lib.QueryBuilder;
00050 import org.objectweb.medor.query.lib.QueryTreePrinter;
00051 import org.objectweb.medor.query.lib.SelectProject;
00052 import org.objectweb.util.monolog.api.BasicLevel;
00053 
00054 
00064 public class EjbqlQueryTreeHolder {
00065 
00066     QueryTree queryTree = null;
00067     QueryTransformer queryOptimizer = null;
00068     QueryEvaluator optimizedQuery = null;
00069     Field resField = null;
00070     EjbqlLimiterRange[] limiterRanges = null;
00071 
00072     private String beanName;
00073     private String methodName;
00074 
00079     private int prefetchIdentifierIndex;
00080 
00081 
00089     public EjbqlQueryTreeHolder(MethodCmp2Desc mDesc, ASTEJBQL ejbql, PMapper mapper)
00090             throws Exception {
00091 
00092         EntityCmp2Desc eDesc = (EntityCmp2Desc) mDesc.getBeanDesc();
00093         DeploymentDescEjb2 dd = (DeploymentDescEjb2) eDesc.getDeploymentDesc();
00094         Manager jormManager = dd.getJormManager();
00095 
00096         // create identifiers Map (visit ALL the query)
00097         QueryBuilder qb = new QueryBuilder();
00098         Map fields = (new EjbqlVariableVisitor(ejbql, dd, qb)).getFields();
00099 
00100         // Begin PREFETCHING CODE (by Seb)
00101         SelectProject sp = new SelectProject("");
00102         if (mDesc.getPrefetch() && (mapper != null)) {
00103             // Find the QueryTree of the ClassExtend of the bean of the current finder method
00104             // WARNING: This only works for finder methods, and not for ejbSelect methods!!!
00105             //          (Indeed the result type of the query must be the bean type in which
00106             //           the method is defined)
00107             ClassExtent ce = null;
00108             QueryTree qt = null;
00109             String jormClassName = ((EntityCmp2Desc) mDesc.getBeanDesc()).getJormClassName();
00110             Iterator itFields = fields.values().iterator();
00111             boolean found = false;
00112             while (itFields.hasNext() && !found) {
00113                 QueryTree cqt = ((QueryTreeField) itFields.next()).getQueryTree();
00114                 Collection extents = JormQueryTreeHelper.getJormExtents(cqt);
00115                 for (Iterator it = extents.iterator(); it.hasNext() && !found;) {
00116                     JormExtent je = (JormExtent) it.next();
00117                     if (jormClassName.equals(je.getJormName())) {
00118                         found = true;
00119                         ce = (ClassExtent) je;
00120                         qt = cqt;
00121                     }
00122                 }
00123             }
00124             if ((ce == null) && (qt == null)) {
00125                 throw new Error("EjbqlQueryTreeHolder: cannot do the prefetch !!!");
00126             }
00127             setMapper(qt, mapper);
00128             // Add fields of the class which the values must be prefetched, at
00129             // the begin of the the TupleCollection
00130             JormQueryTreeHelper.addPrefetchFields(ce, qt, sp);
00131             prefetchIdentifierIndex = sp.getTupleStructure().getSize() + 1;
00132         }
00133         // End PREFETCHING CODE
00134 
00135         // create SelectProject (visit the SELECT clause)
00136         EjbqlSelectVisitor selectVisitor = new EjbqlSelectVisitor(ejbql, fields, sp);
00137 
00138         // create the Filter's expression (visit the WHERE clause)
00139         Expression qf = new EjbqlQueryFilterVisitor
00140             (mapper, fields, mDesc.getMethod().getParameterTypes(), ejbql, qb).getQueryFilter();
00141         sp.setQueryFilter(qf);
00142 
00143         // create the OrderField list (visit the ORDER BY clause)
00144         OrderField[] ofs = new EjbqlOrderByVisitor(ejbql, fields).getOrderFields();
00145         if (ofs.length > 0) {
00146             sp.setOrderBy(ofs);
00147         }
00148 
00149         // create the EjbqlLimiterRange list (visit the LIMIT clause)
00150         limiterRanges = new EjbqlLimitVisitor(ejbql, mDesc.getMethod().getParameterTypes()).getLimiterRanges();
00151 
00152         queryTree = selectVisitor.getQueryTree();
00153 
00154         setMapper(queryTree, mapper);
00155 
00156         // Get the field description of the result of the query
00157         // Nota Bene: TupleStructures of queries non optimized and optimized are differents.
00158         resField = queryTree.getTupleStructure().getField(queryTree.getTupleStructure().getSize());
00159 
00160         // Just needed later for debug trace
00161         beanName = eDesc.getJormClassName();
00162         methodName = mDesc.getMethod().getName();
00163     }
00164 
00165     private void setMapper(QueryTree tree, PMapper mapper) {
00166         // set the mapper of each leaves of the QueryTree
00167         if (mapper != null) {
00168             Collection extents = JormQueryTreeHelper.getJormExtents(tree);
00169             for (Iterator it = extents.iterator(); it.hasNext();) {
00170                 JormExtent je = (JormExtent) it.next();
00171                 je.setPMapper(mapper, RdbMappingBuilder.getProjectName());
00172             }
00173         }
00174     }
00175 
00176     public int getPrefetchIndex() {
00177         return prefetchIdentifierIndex;
00178     }
00179 
00183     public QueryTree getQueryTree() {
00184         return queryTree;
00185     }
00186 
00190     public void setQueryOptimizer(QueryTransformer qtf) {
00191         optimizedQuery = null;
00192         queryOptimizer = qtf;
00193     }
00194 
00198     public QueryTransformer getQueryOptimizer() {
00199         return queryOptimizer;
00200     }
00201 
00205     public Field getResField() {
00206         return resField;
00207     }
00212     public EjbqlLimiterRange[] getLimiterRanges() {
00213         return limiterRanges;
00214     }
00215 
00221     public QueryEvaluator getOptimizedQueryTree() throws Exception {
00222         if (optimizedQuery == null) {
00223             if (TraceEjb.isDebugQuery()) {
00224                 TraceEjb.query.log(BasicLevel.DEBUG,
00225                                    "Initial QueryTree of the method " + methodName
00226                                    + " of the bean " + beanName);
00227                 QueryTreePrinter.printQueryTree(queryTree, TraceEjb.query, BasicLevel.DEBUG);
00228             }
00229             QueryTree qt = queryOptimizer.transform(queryTree);
00230             if (TraceEjb.isDebugQuery()) {
00231                 TraceEjb.query.log(BasicLevel.DEBUG,
00232                                    "Optimized QueryTree of the method " + methodName
00233                                    + " of the bean " + beanName);
00234                 QueryTreePrinter.printQueryTree(qt, TraceEjb.query, BasicLevel.DEBUG);
00235             }
00236             optimizedQuery = new MedorEvaluator(qt, 0);
00237         }
00238         return optimizedQuery;
00239     }
00240 
00241 }

Generated on Tue Feb 15 15:05:49 2005 for JOnAS by  doxygen 1.3.9.1