MedorFactory.java

00001 
00029 package org.objectweb.jonas_ejb.container.jorm;
00030 
00031 import java.util.ArrayList;
00032 import java.util.HashMap;
00033 import java.util.Map;
00034 
00035 import javax.ejb.EJBException;
00036 
00037 import org.objectweb.jonas_ejb.container.JContainer;
00038 import org.objectweb.jonas_ejb.container.TraceEjb;
00039 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
00040 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
00041 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00042 import org.objectweb.jonas_ejb.deployment.api.MethodCmp2Desc;
00043 import org.objectweb.jonas_ejb.lib.EjbqlLimiterRange;
00044 import org.objectweb.jonas_ejb.lib.EjbqlQueryTreeHolder;
00045 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
00046 import org.objectweb.jorm.metainfo.api.Manager;
00047 import org.objectweb.medor.api.EvaluationException;
00048 import org.objectweb.medor.api.MedorException;
00049 import org.objectweb.medor.eval.api.ConnectionResources;
00050 import org.objectweb.medor.eval.api.QueryEvaluator;
00051 import org.objectweb.medor.eval.lib.BasicEvaluationMetaData;
00052 import org.objectweb.medor.eval.prefetch.api.PrefetchBuffer;
00053 import org.objectweb.medor.eval.prefetch.lib.PrefetchBufferFactoryImpl;
00054 import org.objectweb.medor.expression.api.ParameterOperand;
00055 import org.objectweb.medor.expression.api.TypingException;
00056 import org.objectweb.medor.lib.Log;
00057 import org.objectweb.medor.optim.api.ExecPlanGenerator;
00058 import org.objectweb.medor.optim.api.QueryTransformer;
00059 import org.objectweb.medor.optim.jorm.Jorm2Rdb;
00060 import org.objectweb.medor.optim.lib.BasicQueryRewriter;
00061 import org.objectweb.medor.optim.lib.FlattenQueryTreeRule;
00062 import org.objectweb.medor.optim.lib.IndexesGenerator;
00063 import org.objectweb.medor.query.api.QueryLeaf;
00064 import org.objectweb.medor.query.api.QueryTree;
00065 import org.objectweb.medor.tuple.api.TupleCollection;
00066 import org.objectweb.util.monolog.api.BasicLevel;
00067 
00074 public abstract class MedorFactory extends JormFactory {
00075 
00080     protected QueryTransformer queryTransformer = null;
00081 
00082     protected Manager miManager = null;
00083 
00084     protected ExecPlanGenerator indexesGenerator;
00085 
00086     protected boolean optimizeAtInit = false;
00087 
00091     private int prefetchIndex;
00092 
00096     private EjbqlLimiterRange[] limiterRanges = null;
00097 
00098     public MedorFactory() {
00099         super();
00100         if (Log.loggerFactory != TraceEjb.loggerFactory) {
00101             Log.loggerFactory = TraceEjb.loggerFactory;
00102         }
00103     }
00104 
00112     public synchronized QueryEvaluator getOptimizedRequest(MethodCmp2Desc methodDesc) throws MedorException {
00113         TraceEjb.logger.log(BasicLevel.DEBUG, "getOptimizedRequest(method name: " + methodDesc.getMethod().getName()
00114                 + ")");
00115         try {
00116             EjbqlQueryTreeHolder qth = methodDesc.getQueryTreeHolder(mapper);
00117             // set the prefetch index for this method
00118             setPrefetchIndex(qth.getPrefetchIndex());
00119             // set the optimizer if not set yet
00120             if (qth.getQueryOptimizer() == null) {
00121                 if (queryTransformer == null) {
00122                     ArrayList rules = new ArrayList(2);
00123                     rules.add(new FlattenQueryTreeRule());
00124                     rules.add(new Jorm2Rdb());
00125                     queryTransformer = new BasicQueryRewriter(rules);
00126                 }
00127                 qth.setQueryOptimizer(new QueryTransformer() {
00128 
00129                     public QueryTree transform(QueryTree qt) throws MedorException {
00130                         QueryTree qt1 = queryTransformer.transform(qt);
00131                         //TraceEjb.query.log(BasicLevel.DEBUG, "Transformed
00132                         // QueryTree: ");
00133                         //QueryTreePrinter.printQueryTree(qt1, TraceEjb.query,
00134                         // BasicLevel.DEBUG);
00135                         if (indexesGenerator == null) {
00136                             throw new Error("getOptimizedRequest: indexesGenerator == null");
00137                         }
00138                         return indexesGenerator.transform(qt1);
00139                     }
00140                 });
00141             }
00142             limiterRanges = qth.getLimiterRanges();
00143             return qth.getOptimizedQueryTree();
00144         } catch (Exception e) {
00145             throw new MedorException("Impossible to optimize the query " + methodDesc.getQuery(), e);
00146         }
00147     }
00148 
00152     /*
00153      * NO MORE USED ??? public void optimizeAll() throws MedorException { for
00154      * (Iterator it = dd.getMethodDescIterator(); it.hasNext();) {
00155      * MethodCmp2Desc mcd = (MethodCmp2Desc) it.next(); if
00156      * (!mcd.isFindByPrimaryKey() && (mcd.isFinder() || mcd.isEjbSelect())) {
00157      * getOptimizedRequest(mcd.getIndex()); } } }
00158      */
00159 
00169     public TupleCollection evaluate(Object conn, int methodIndex, ParameterOperand[] parameters) throws MedorException {
00170 
00171         MethodCmp2Desc mcd = (MethodCmp2Desc) dd.getMethodDesc(methodIndex);
00172         QueryEvaluator evaluator = getOptimizedRequest(mcd);
00173 
00174         // Calculates and gets the required connection resources for this query
00175         ConnectionResources cr = evaluator.getRequiredConnectionResources();
00176 
00177         // Gets the QueryLeafs that requierd connections
00178         QueryLeaf[] leaves = cr.getRequiredQueryLeafConnection();
00179 
00180         // Setting QueryLeaf's appropriated connection Object
00181         // TODO : All jorm classes are not mapped on the same mapper
00182         // than the current class - should use connections from different
00183         // datasources.
00184         if (conn == null) {
00185             throw new MedorException("invalid connection handle [null]");
00186         }
00187         for (int i = 0; (i < leaves.length); i++) {
00188             cr.setConnection(leaves[i], conn);
00189         }
00190         // PrefetchBuffer initialization if prefetch tag setting
00191         PrefetchBuffer prefetchBuffer = null;
00192         if (mcd.getPrefetch()) {
00193             Object tx = null;
00194             try {
00195                 tx = this.getTransactionManager().getTransaction();
00196                 if (tx != null) {
00197                     prefetchBuffer = mapper.getPrefetchCache().createPrefetchBuffer(new PrefetchBufferFactoryImpl(),
00198                             this, tx, getPrefetchIndex());
00199                 }
00200             } catch (javax.transaction.SystemException e) {
00201                 // TODO : Que fait-on ???
00202                 TraceEjb.logger.log(BasicLevel.ERROR,
00203                         "Cannot get the current transaction to create the Prefetch buffer:", e);
00204             }
00205         }
00206         // Map of EvaluationMetaData initialization needed for LIMIT clause
00207         Map evalMDMap = null;
00208         if (limiterRanges.length > 0) {
00209             try {
00210                 // There is a LIMIT clause, init the Map of EvaluationMetaData
00211                 evalMDMap = new HashMap();
00212                 BasicEvaluationMetaData evalMD = new BasicEvaluationMetaData();
00213                 EjbqlLimiterRange range = limiterRanges[0];
00214                 if (range.getKind() == EjbqlLimiterRange.KIND_PARAMETER) {
00215                     evalMD.setLimitedRangeStartAt(parameters[range.getValue()].getInt());
00216                 } else {
00217                     evalMD.setLimitedRangeStartAt(range.getValue());
00218                 }
00219                 if (TraceEjb.isDebugQuery()) {
00220                     TraceEjb.query.log(BasicLevel.LEVEL_DEBUG, "Query with LIMITer Range Start At = "
00221                             + evalMD.getLimitedRangeStartAt() + " for method name " + mcd.getMethod().getName());
00222                 }
00223                 if (limiterRanges.length > 1) {
00224                     range = limiterRanges[1];
00225                     if (range.getKind() == EjbqlLimiterRange.KIND_PARAMETER) {
00226                         System.out.println("parameters[range.getValue()].getInt() = "
00227                                 + parameters[range.getValue()].getInt());
00228                         evalMD.setLimitedRangeSize(parameters[range.getValue()].getInt());
00229                     } else {
00230                         evalMD.setLimitedRangeSize(range.getValue());
00231                     }
00232                     if (TraceEjb.isDebugQuery()) {
00233                         TraceEjb.query.log(BasicLevel.LEVEL_DEBUG, "Query with LIMITer Range Size = "
00234                                 + evalMD.getLimitedRangeSize() + " for method name " + mcd.getMethod().getName());
00235                     }
00236                 }
00237                 evalMDMap.put(leaves[0], evalMD);
00238             } catch (TypingException te) {
00239                 throw new MedorException("Invalid parameter for a LIMIT range", te);
00240             }
00241         }
00242         try {
00243             return evaluator.evaluate(parameters, cr, prefetchBuffer, evalMDMap);
00244         } catch (EvaluationException e) {
00245             throw e;
00246         }
00247     }
00248 
00249     public void init(EntityDesc ed, JContainer c, String mapperName) {
00250         super.init(ed, c, mapperName);
00251 
00252         ecd = (EntityCmp2Desc) ed;
00253 
00254         //------------------- JORM META INFORMATION BUILDING ----------------//
00255         TraceEjb.logger.log(BasicLevel.DEBUG, "Jorm Meta information building");
00256         DeploymentDescEjb2 dd = ecd.getDeploymentDescEjb2();
00257         try {
00258             miManager = dd.getJormManager();
00259         } catch (DeploymentDescException e) {
00260             TraceEjb.logger.log(BasicLevel.ERROR, "impossible to load the jorm meta information into the manager", e);
00261             throw new EJBException("impossible to load the jorm meta information into the manager", e);
00262         }
00263 
00264         //---------------------- MEDOR INITIALIZATION -----------------------//
00265         TraceEjb.logger.log(BasicLevel.DEBUG, "Medor initialisation");
00266         indexesGenerator = new IndexesGenerator();
00267 
00268     }
00269 
00270     private void setPrefetchIndex(int i) {
00271         prefetchIndex = i;
00272     }
00273 
00274     private int getPrefetchIndex() {
00275         return prefetchIndex;
00276     }
00277 
00278 }

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