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
00097 QueryBuilder qb = new QueryBuilder();
00098 Map fields = (new EjbqlVariableVisitor(ejbql, dd, qb)).getFields();
00099
00100
00101 SelectProject sp = new SelectProject("");
00102 if (mDesc.getPrefetch() && (mapper != null)) {
00103
00104
00105
00106
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
00129
00130 JormQueryTreeHelper.addPrefetchFields(ce, qt, sp);
00131 prefetchIdentifierIndex = sp.getTupleStructure().getSize() + 1;
00132 }
00133
00134
00135
00136 EjbqlSelectVisitor selectVisitor = new EjbqlSelectVisitor(ejbql, fields, sp);
00137
00138
00139 Expression qf = new EjbqlQueryFilterVisitor
00140 (mapper, fields, mDesc.getMethod().getParameterTypes(), ejbql, qb).getQueryFilter();
00141 sp.setQueryFilter(qf);
00142
00143
00144 OrderField[] ofs = new EjbqlOrderByVisitor(ejbql, fields).getOrderFields();
00145 if (ofs.length > 0) {
00146 sp.setOrderBy(ofs);
00147 }
00148
00149
00150 limiterRanges = new EjbqlLimitVisitor(ejbql, mDesc.getMethod().getParameterTypes()).getLimiterRanges();
00151
00152 queryTree = selectVisitor.getQueryTree();
00153
00154 setMapper(queryTree, mapper);
00155
00156
00157
00158 resField = queryTree.getTupleStructure().getField(queryTree.getTupleStructure().getSize());
00159
00160
00161 beanName = eDesc.getJormClassName();
00162 methodName = mDesc.getMethod().getName();
00163 }
00164
00165 private void setMapper(QueryTree tree, PMapper mapper) {
00166
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 }