KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > container > jorm > MedorFactory


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 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  * Initial developer(s):
22  * Contributor(s):
23  *
24  * --------------------------------------------------------------------------
25  * $Id: MedorFactory.java,v 1.34 2005/04/28 16:52:59 benoitf Exp $
26  * --------------------------------------------------------------------------
27  */

28
29 package org.objectweb.jonas_ejb.container.jorm;
30
31 import java.util.ArrayList JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import javax.ejb.EJBException JavaDoc;
36
37 import org.objectweb.jonas_ejb.container.JContainer;
38 import org.objectweb.jonas_ejb.container.TraceEjb;
39 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
40 import org.objectweb.jonas_ejb.deployment.api.EntityCmp2Desc;
41 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
42 import org.objectweb.jonas_ejb.deployment.api.MethodCmp2Desc;
43 import org.objectweb.jonas_ejb.lib.EjbqlLimiterRange;
44 import org.objectweb.jonas_ejb.lib.EjbqlQueryTreeHolder;
45 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
46 import org.objectweb.jorm.metainfo.api.Manager;
47 import org.objectweb.medor.api.EvaluationException;
48 import org.objectweb.medor.api.MedorException;
49 import org.objectweb.medor.eval.api.ConnectionResources;
50 import org.objectweb.medor.eval.api.QueryEvaluator;
51 import org.objectweb.medor.eval.lib.BasicEvaluationMetaData;
52 import org.objectweb.medor.eval.prefetch.api.PrefetchBuffer;
53 import org.objectweb.medor.eval.prefetch.lib.PrefetchBufferFactoryImpl;
54 import org.objectweb.medor.expression.api.ParameterOperand;
55 import org.objectweb.medor.expression.api.TypingException;
56 import org.objectweb.medor.lib.Log;
57 import org.objectweb.medor.optim.api.ExecPlanGenerator;
58 import org.objectweb.medor.optim.api.QueryTransformer;
59 import org.objectweb.medor.optim.jorm.Jorm2Rdb;
60 import org.objectweb.medor.optim.lib.BasicQueryRewriter;
61 import org.objectweb.medor.optim.lib.FlattenQueryTreeRule;
62 import org.objectweb.medor.optim.lib.IndexesGenerator;
63 import org.objectweb.medor.query.api.QueryLeaf;
64 import org.objectweb.medor.query.api.QueryTree;
65 import org.objectweb.medor.tuple.api.TupleCollection;
66 import org.objectweb.util.monolog.api.BasicLevel;
67
68 /**
69  * This class does the initialisation of Medor and permits to access to the
70  * query. The optimisation of the query tree is done during the first time that
71  * it is used.
72  * @author S.Chassande-Barrioz
73  */

74 public abstract class MedorFactory extends JormFactory {
75
76     /**
77      * This field references the query transformer which must be used to
78      * optimize the medor requests.
79      */

80     protected QueryTransformer queryTransformer = null;
81
82     protected Manager miManager = null;
83
84     protected ExecPlanGenerator indexesGenerator;
85
86     protected boolean optimizeAtInit = false;
87
88     /**
89      * This is the prefetch index for the query method CURRENTLY evaluated
90      */

91     private int prefetchIndex;
92
93     /**
94      * Limiter ranges for the query method CURRENTLY evaluated
95      */

96     private EjbqlLimiterRange[] limiterRanges = null;
97
98     public MedorFactory() {
99         super();
100         if (Log.loggerFactory != TraceEjb.loggerFactory) {
101             Log.loggerFactory = TraceEjb.loggerFactory;
102         }
103     }
104
105     /**
106      * It retrieves a medor request which is evaluable and optimized. The method
107      * index is translate into a request index, then the found request is
108      * optimized if it is not already.
109      * @param methodDesc is the MethodCmp2Desc of the finder or select method.
110      * @return the QueryTree optimized which is associated to the method index
111      */

112     public synchronized QueryEvaluator getOptimizedRequest(MethodCmp2Desc methodDesc) throws MedorException {
113         if (TraceEjb.isVerbose()) {
114             TraceEjb.logger.log(BasicLevel.DEBUG, "getOptimizedRequest(method name: " + methodDesc.getMethod().getName()
115                     + ")");
116         }
117         try {
118             EjbqlQueryTreeHolder qth = methodDesc.getQueryTreeHolder(mapper);
119             // set the prefetch index for this method
120
setPrefetchIndex(qth.getPrefetchIndex());
121             // set the optimizer if not set yet
122
if (qth.getQueryOptimizer() == null) {
123                 if (queryTransformer == null) {
124                     ArrayList JavaDoc rules = new ArrayList JavaDoc(2);
125                     rules.add(new FlattenQueryTreeRule());
126                     rules.add(new Jorm2Rdb());
127                     queryTransformer = new BasicQueryRewriter(rules);
128                 }
129                 qth.setQueryOptimizer(new QueryTransformer() {
130
131                     public QueryTree transform(QueryTree qt) throws MedorException {
132                         QueryTree qt1 = queryTransformer.transform(qt);
133                         //TraceEjb.query.log(BasicLevel.DEBUG, "Transformed
134
// QueryTree: ");
135
//QueryTreePrinter.printQueryTree(qt1, TraceEjb.query,
136
// BasicLevel.DEBUG);
137
if (indexesGenerator == null) {
138                             throw new Error JavaDoc("getOptimizedRequest: indexesGenerator == null");
139                         }
140                         return indexesGenerator.transform(qt1);
141                     }
142                 });
143             }
144             limiterRanges = qth.getLimiterRanges();
145             return qth.getOptimizedQueryTree();
146         } catch (Exception JavaDoc e) {
147             throw new MedorException("Impossible to optimize the query " + methodDesc.getQuery(), e);
148         }
149     }
150
151     /**
152      * It optimized all medor requests which are already not.
153      */

154     /*
155      * NO MORE USED ??? public void optimizeAll() throws MedorException { for
156      * (Iterator it = dd.getMethodDescIterator(); it.hasNext();) {
157      * MethodCmp2Desc mcd = (MethodCmp2Desc) it.next(); if
158      * (!mcd.isFindByPrimaryKey() && (mcd.isFinder() || mcd.isEjbSelect())) {
159      * getOptimizedRequest(mcd.getIndex()); } } }
160      */

161
162     /**
163      * It evaluate an optimized medor request according to the specified
164      * parameters To evalute the medor request the query evaluator is used.
165      * @param conn is the connection handle
166      * @param methodIndex is method index which permits to find a medor request.
167      * @param parameters is the parameters (key=parameter name / value=parameter
168      * value)
169      * @return TupleCollection is the result of the request
170      */

171     public TupleCollection evaluate(Object JavaDoc conn, int methodIndex, ParameterOperand[] parameters) throws MedorException {
172
173         MethodCmp2Desc mcd = (MethodCmp2Desc) dd.getMethodDesc(methodIndex);
174         QueryEvaluator evaluator = getOptimizedRequest(mcd);
175
176         // Calculates and gets the required connection resources for this query
177
ConnectionResources cr = evaluator.getRequiredConnectionResources();
178
179         // Gets the QueryLeafs that requierd connections
180
QueryLeaf[] leaves = cr.getRequiredQueryLeafConnection();
181
182         // Setting QueryLeaf's appropriated connection Object
183
// TODO : All jorm classes are not mapped on the same mapper
184
// than the current class - should use connections from different
185
// datasources.
186
if (conn == null) {
187             throw new MedorException("invalid connection handle [null]");
188         }
189         for (int i = 0; (i < leaves.length); i++) {
190             cr.setConnection(leaves[i], conn);
191         }
192         // PrefetchBuffer initialization if prefetch tag setting
193
PrefetchBuffer prefetchBuffer = null;
194         if (mcd.getPrefetch()) {
195             Object JavaDoc tx = null;
196             try {
197                 tx = this.getTransactionManager().getTransaction();
198                 if (tx != null) {
199                     prefetchBuffer = mapper.getPrefetchCache().createPrefetchBuffer(new PrefetchBufferFactoryImpl(),
200                             this, tx, getPrefetchIndex(), true);
201                 }
202             } catch (javax.transaction.SystemException JavaDoc e) {
203                 // TODO : Que fait-on ???
204
TraceEjb.logger.log(BasicLevel.ERROR,
205                         "Cannot get the current transaction to create the Prefetch buffer:", e);
206             }
207         }
208         // Map of EvaluationMetaData initialization needed for LIMIT clause
209
Map JavaDoc evalMDMap = null;
210         if (limiterRanges.length > 0) {
211             try {
212                 // There is a LIMIT clause, init the Map of EvaluationMetaData
213
evalMDMap = new HashMap JavaDoc();
214                 BasicEvaluationMetaData evalMD = new BasicEvaluationMetaData();
215                 EjbqlLimiterRange range = limiterRanges[0];
216                 if (range.getKind() == EjbqlLimiterRange.KIND_PARAMETER) {
217                     evalMD.setLimitedRangeStartAt(parameters[range.getValue()].getInt());
218                 } else {
219                     evalMD.setLimitedRangeStartAt(range.getValue());
220                 }
221                 if (TraceEjb.isDebugQuery()) {
222                     TraceEjb.query.log(BasicLevel.LEVEL_DEBUG, "Query with LIMITer Range Start At = "
223                             + evalMD.getLimitedRangeStartAt() + " for method name " + mcd.getMethod().getName());
224                 }
225                 if (limiterRanges.length > 1) {
226                     range = limiterRanges[1];
227                     if (range.getKind() == EjbqlLimiterRange.KIND_PARAMETER) {
228                         System.out.println("parameters[range.getValue()].getInt() = "
229                                 + parameters[range.getValue()].getInt());
230                         evalMD.setLimitedRangeSize(parameters[range.getValue()].getInt());
231                     } else {
232                         evalMD.setLimitedRangeSize(range.getValue());
233                     }
234                     if (TraceEjb.isDebugQuery()) {
235                         TraceEjb.query.log(BasicLevel.LEVEL_DEBUG, "Query with LIMITer Range Size = "
236                                 + evalMD.getLimitedRangeSize() + " for method name " + mcd.getMethod().getName());
237                     }
238                 }
239                 evalMDMap.put(leaves[0], evalMD);
240             } catch (TypingException te) {
241                 throw new MedorException("Invalid parameter for a LIMIT range", te);
242             }
243         }
244         try {
245             return evaluator.evaluate(parameters, cr, prefetchBuffer, evalMDMap);
246         } catch (EvaluationException e) {
247             throw e;
248         }
249     }
250
251     public void init(EntityDesc ed, JContainer c, String JavaDoc mapperName) {
252         super.init(ed, c, mapperName);
253
254         ecd = (EntityCmp2Desc) ed;
255
256         //------------------- JORM META INFORMATION BUILDING ----------------//
257
if (TraceEjb.isVerbose()) {
258             TraceEjb.logger.log(BasicLevel.DEBUG, "Jorm Meta information building");
259         }
260         DeploymentDescEjb2 dd = ecd.getDeploymentDescEjb2();
261         try {
262             miManager = dd.getJormManager();
263         } catch (DeploymentDescException e) {
264             TraceEjb.logger.log(BasicLevel.ERROR, "impossible to load the jorm meta information into the manager", e);
265             throw new EJBException JavaDoc("impossible to load the jorm meta information into the manager", e);
266         }
267
268         //---------------------- MEDOR INITIALIZATION -----------------------//
269
if (TraceEjb.isVerbose()) {
270             TraceEjb.logger.log(BasicLevel.DEBUG, "Medor initialisation");
271         }
272         indexesGenerator = new IndexesGenerator();
273
274     }
275
276     private void setPrefetchIndex(int i) {
277         prefetchIndex = i;
278     }
279
280     private int getPrefetchIndex() {
281         return prefetchIndex;
282     }
283
284 }
Popular Tags