KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > datasource > rdb > lib > JDBCWrapper


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2003 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, S. Chassande-Barrioz, A. Lefebvre
22  */

23
24 package org.objectweb.medor.datasource.rdb.lib;
25
26 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter;
27 import org.objectweb.jorm.mapper.rdb.adapter.BasicRdbAdapter;
28 import org.objectweb.jorm.mapper.rdb.adapter.OracleAdapter;
29 import org.objectweb.jorm.mapper.rdb.lib.RdbConnectionWrapper;
30 import org.objectweb.jorm.api.PException;
31 import org.objectweb.medor.api.EvaluationException;
32 import org.objectweb.medor.api.MedorException;
33 import org.objectweb.medor.datasource.api.Wrapper;
34 import org.objectweb.medor.expression.api.CalculatedParameterOperand;
35 import org.objectweb.medor.expression.api.Operator;
36 import org.objectweb.medor.expression.api.ParameterOperand;
37 import org.objectweb.medor.expression.api.Expression;
38 import org.objectweb.medor.expression.api.Operand;
39 import org.objectweb.medor.expression.api.ExpressionException;
40 import org.objectweb.medor.expression.lib.BasicParameterOperand;
41 import org.objectweb.medor.filter.lib.InCollection;
42 import org.objectweb.medor.lib.Log;
43 import org.objectweb.medor.query.api.FilteredQueryTree;
44 import org.objectweb.medor.query.api.QueryLeaf;
45 import org.objectweb.medor.query.api.QueryTree;
46 import org.objectweb.medor.query.rdb.api.RdbExpQueryLeaf;
47 import org.objectweb.medor.query.rdb.api.RdbQueryLeaf;
48 import org.objectweb.medor.query.rdb.lib.AggregateRdbQueryNode;
49 import org.objectweb.medor.tuple.api.TupleCollection;
50 import org.objectweb.medor.tuple.lib.EmptyTupleCollection;
51 import org.objectweb.medor.type.lib.PTypeSpaceMedor;
52 import org.objectweb.medor.type.lib.QTypeTuple;
53 import org.objectweb.medor.eval.api.EvaluationMetaData;
54 import org.objectweb.util.monolog.api.BasicLevel;
55 import org.objectweb.util.monolog.api.Logger;
56
57 import java.io.Serializable JavaDoc;
58 import java.io.IOException JavaDoc;
59 import java.math.BigDecimal JavaDoc;
60 import java.sql.Connection JavaDoc;
61 import java.sql.PreparedStatement JavaDoc;
62 import java.sql.ResultSet JavaDoc;
63 import java.sql.SQLException JavaDoc;
64 import java.util.ArrayList JavaDoc;
65 import java.util.Date JavaDoc;
66 import java.util.Collection JavaDoc;
67 import java.util.Iterator JavaDoc;
68
69 /**
70  * This class implements the Wrapper interface for the jdbc resources. This
71  * implementation uses Statements to perform the request.
72  *
73  * @author Mourad Alia
74  */

75 public class JDBCWrapper implements Wrapper {
76
77     /**
78      * this field references a Logger which is never null.
79      */

80     static Logger log = null;
81     static Logger TClog = null;
82     boolean debug;
83
84     public JDBCWrapper() {
85         if (log == null) {
86             log = Log.loggerFactory.getLogger(
87                     Log.MEDOR_PREFIX + ".eval.rdb.JDBCWrapper");
88             TClog = Log.loggerFactory.getLogger(
89                     Log.MEDOR_PREFIX + ".eval.rdb.JDBCTC");
90         }
91     }
92
93     public TupleCollection fetchData(QueryLeaf lf,
94                                      ParameterOperand[] parameters,
95                                      Object JavaDoc connection,
96                                      EvaluationMetaData evalMD)
97             throws EvaluationException {
98         debug = log.isLoggable(BasicLevel.DEBUG);
99         if (debug) {
100             log.log(BasicLevel.DEBUG, "Parameters: " + posToString(parameters));
101         }
102         RdbQueryLeaf leaf = (RdbQueryLeaf) lf;
103         ParameterOperand[] usedParameters = null;
104         //Calculate the parameter list of the leaf with the parameter list of the query
105
RdbAdapter rdbAdapt = getRdbAdapter(leaf);
106         Connection JavaDoc conn = getConnection(connection);
107         ResultSet JavaDoc resultSet = null;
108         PreparedStatement JavaDoc ps = null;
109         String JavaDoc sqlRequest;
110         synchronized (leaf) {
111             if (parameters != null
112                     && parameters.length > 0
113                     && leaf instanceof FilteredQueryTree) {
114                 Expression filter = ((FilteredQueryTree) leaf).getQueryFilter();
115                 if (filter != null) {
116                     ArrayList JavaDoc al = getUsedParameters(filter, parameters, null);
117                     //add the range parameters if necessary
118
al = addRangeParameters(al, rdbAdapt, evalMD);
119                     if (al != null && al.size() > 0) {
120                         usedParameters = (ParameterOperand[])
121                                 al.toArray(new ParameterOperand[al.size()]);
122                     }
123                 }
124             }
125             if (debug) {
126                 log.log(BasicLevel.DEBUG, "Used parameters: " + posToString(parameters));
127             }
128             try {
129                 //TODO transformer int int en bool�en dans l'appel
130
sqlRequest = leaf.getSqlRequest(usedParameters,
131                         (evalMD != null && evalMD.getLimitedRangeStartAt() > 0),
132                         (evalMD != null && evalMD.getLimitedRangeSize() < Integer.MAX_VALUE));
133                 if (debug) {
134                     log.log(BasicLevel.DEBUG, "SQL query for leaf " + leaf + ": " + sqlRequest);
135                 }
136                 ps = conn.prepareStatement(
137                         sqlRequest,
138                         ResultSet.TYPE_SCROLL_INSENSITIVE,
139                         ResultSet.CONCUR_READ_ONLY);
140                 if (usedParameters != null) {
141                     assignParameter(ps, usedParameters, rdbAdapt);
142                 }
143             } catch (Exception JavaDoc e) {
144                 throw new EvaluationException(e);
145             }
146         }
147         if (debug) {
148             log.log(BasicLevel.DEBUG, "Evaluate the query: " + sqlRequest);
149         }
150         try {
151             resultSet = ps.executeQuery();
152             if (!resultSet.next()) {
153                 if (debug) log.log(BasicLevel.DEBUG, "No result, closing the ResultSet and the PreparedStatement");
154                 resultSet.close();
155                 ps.close();
156                 return new EmptyTupleCollection(lf.getTupleStructure());
157             } else {
158                 if (debug) log.log(BasicLevel.DEBUG, "There is a result");
159                 return new JDBCTupleCollection(
160                         lf.getTupleStructure(), resultSet, ps, rdbAdapt, TClog);
161             }
162         } catch (EvaluationException ee) {
163             throw ee;
164         } catch (Exception JavaDoc mexp) {
165             throw new EvaluationException(mexp);
166         }
167     }
168
169     private Connection JavaDoc getConnection(Object JavaDoc connection) throws EvaluationException {
170         try {
171             return RdbConnectionWrapper.narrow2SQL(connection);
172         } catch (PException e) {
173             throw new EvaluationException(
174                     "Impossible to evaluate a jdbc leaf:", e);
175         }
176     }
177
178     private RdbAdapter getRdbAdapter(RdbQueryLeaf leaf) {
179         RdbAdapter rdbAdapt = null;
180         if (leaf instanceof RdbExpQueryLeaf) {
181             rdbAdapt = ((RdbExpQueryLeaf) leaf).getRdbAdapter();
182         } else if (leaf instanceof AggregateRdbQueryNode) {
183             QueryTree[] children = ((AggregateRdbQueryNode) leaf).getChildren();
184             int i=0;
185             while(rdbAdapt == null) {
186                 rdbAdapt = getRdbAdapter((RdbQueryLeaf) children[i]);
187                 i++;
188             }
189         }
190         if (rdbAdapt == null) {
191             rdbAdapt = new BasicRdbAdapter();
192         }
193         return rdbAdapt;
194     }
195
196     private void assignParameter(PreparedStatement JavaDoc ps,
197                                  ParameterOperand[] usedParameters,
198                                  RdbAdapter rdbAdapt)
199             throws MedorException, ExpressionException, SQLException JavaDoc, IOException JavaDoc {
200         for (int i = 0; i < usedParameters.length; i++) {
201             ParameterOperand po = usedParameters[i];
202             if (debug) {
203                 log.log(BasicLevel.DEBUG, "Assign parameter (name="
204                         + po.getName() + ", value=" + po + ")");
205             }
206             switch (po.getType().getTypeCode()) {
207             case QTypeTuple.TYPECODE_INT:
208                 rdbAdapt.setInt(ps, i + 1, po.getInt());
209                 break;
210             case QTypeTuple.TYPECODE_OBJINT:
211                 rdbAdapt.setOint(ps, i + 1, (Integer JavaDoc) po.getObject());
212                 break;
213             case QTypeTuple.TYPECODE_SHORT:
214                 rdbAdapt.setShort(ps, i + 1, po.getShort());
215                 break;
216             case QTypeTuple.TYPECODE_OBJSHORT:
217                 rdbAdapt.setOshort(ps, i + 1, (Short JavaDoc) po.getObject());
218                 break;
219             case QTypeTuple.TYPECODE_BYTE:
220                 rdbAdapt.setByte(ps, i + 1, po.getByte());
221                 break;
222             case QTypeTuple.TYPECODE_OBJBYTE:
223                 rdbAdapt.setObyte(ps, i + 1, (Byte JavaDoc) po.getObject());
224                 break;
225             case QTypeTuple.TYPECODE_LONG:
226                 rdbAdapt.setLong(ps, i + 1, po.getLong());
227                 break;
228             case QTypeTuple.TYPECODE_OBJLONG:
229                 rdbAdapt.setOlong(ps, i + 1, (Long JavaDoc) po.getObject());
230                 break;
231             case QTypeTuple.TYPECODE_DOUBLE:
232                 rdbAdapt.setDouble(ps, i + 1, po.getDouble());
233                 break;
234             case QTypeTuple.TYPECODE_OBJDOUBLE:
235                 rdbAdapt.setOdouble(ps, i + 1, (Double JavaDoc) po.getObject());
236                 break;
237             case QTypeTuple.TYPECODE_BOOLEAN:
238                 rdbAdapt.setBoolean(ps, i + 1, po.getBoolean());
239                 break;
240             case QTypeTuple.TYPECODE_OBJBOOLEAN:
241                 rdbAdapt.setOboolean(ps, i + 1, (Boolean JavaDoc) po.getObject());
242                 break;
243             case QTypeTuple.TYPECODE_FLOAT:
244                 rdbAdapt.setFloat(ps, i + 1, po.getFloat());
245                 break;
246             case QTypeTuple.TYPECODE_OBJFLOAT:
247                 rdbAdapt.setOfloat(ps, i + 1, (Float JavaDoc) po.getObject());
248                 break;
249             case QTypeTuple.TYPECODE_BIGDECIMAL:
250             case QTypeTuple.TYPECODE_BIGINTEGER:
251                 rdbAdapt.setBigDecimal(ps, i + 1, (BigDecimal JavaDoc) po.getObject());
252                 break;
253             case QTypeTuple.TYPECODE_STRING:
254                 rdbAdapt.setString(ps, i + 1, (String JavaDoc) po.getObject());
255                 break;
256             case QTypeTuple.TYPECODE_CHAR:
257                 rdbAdapt.setChar(ps, i + 1, po.getChar());
258                 break;
259             case QTypeTuple.TYPECODE_OBJCHAR:
260                 rdbAdapt.setOchar(ps, i + 1, (Character JavaDoc) po.getObject());
261                 break;
262             case QTypeTuple.TYPECODE_SERIALIZED:
263                 rdbAdapt.setSerialized(ps, i + 1, (Serializable JavaDoc) po.getObject());
264                 break;
265             case QTypeTuple.TYPECODE_DATE:
266                 rdbAdapt.setDate(ps, i + 1, (Date JavaDoc) po.getObject(), null);
267                 break;
268             case QTypeTuple.TYPECODE_BYTEARRAY:
269                 rdbAdapt.setByteArray(ps, i + 1, (byte[]) po.getObject());
270                 break;
271             case QTypeTuple.TYPECODE_CHARARRAY:
272                 rdbAdapt.setCharArray(ps, i + 1, (char[]) po.getObject());
273                 break;
274             case QTypeTuple.TYPECODE_COLLECTION:
275                 //Already assign in the sql request building
276
break;
277             default:
278                 throw new EvaluationException("The type "
279                         + po.getType().getJormName()
280                         + " is not supported '"
281                         + po.getType().getTypeCode() + "'"
282                 );
283             }
284         }
285     }
286
287     private ArrayList JavaDoc getUsedParameters(Expression e,
288                                         ParameterOperand[] parameters,
289                                         ArrayList JavaDoc al)
290             throws EvaluationException {
291         //TODO take memberof into account for parameters
292
if ((e instanceof InCollection) &&
293                 !(((Operator) e).getExpression(1) instanceof ParameterOperand)
294         ) {
295             al = getUsedParameters(((Operator) e).getExpression(0),
296                     parameters, al);
297             al = getUsedParametersInCollection(
298                     (Collection) ((Operand) ((Operator) e).getExpression(1)).getObject(),
299                     parameters,
300                     al);
301         } else if (e instanceof Operator) {
302             for (int i = 0; i < ((Operator) e).getOperandNumber(); i++) {
303                 al = getUsedParameters(((Operator) e).getExpression(i),
304                         parameters, al);
305             }
306         } else if (e instanceof CalculatedParameterOperand) {
307             CalculatedParameterOperand cpo = (CalculatedParameterOperand) e;
308             try {
309                 cpo.evaluate(parameters);
310             } catch (ExpressionException e1) {
311                 throw new EvaluationException(e1);
312             }
313             if (al == null)
314                 al = new ArrayList JavaDoc();
315             al.add(cpo);
316         } else if (e instanceof ParameterOperand) {
317             int i = 0;
318             ParameterOperand param = (ParameterOperand) e;
319             while (i < parameters.length
320                     && !parameters[i].getName().equals(param.getName()))
321                 i++;
322             if (i < parameters.length) {
323                 if (parameters[i].getType().getTypeCode() !=
324                         param.getType().getTypeCode()) {
325                     throw new EvaluationException("Bad parameter type: found "
326                             + parameters[i].getType().getJormName()
327                             + " / expected " + param.getType().getJormName());
328                 }
329                 if (al == null)
330                     al = new ArrayList JavaDoc();
331                 al.add(parameters[i]);
332             } else {
333                 StringBuffer JavaDoc msg = new StringBuffer JavaDoc();
334                 msg.append("You must specify the value of parameter ");
335                 msg.append(param.getName());
336                 msg.append(". Found: {");
337                 String JavaDoc sep = "";
338                 for (int j = 0; j < parameters.length; j++) {
339                     msg.append(sep);
340                     msg.append(parameters[j].getName());
341                     sep = ", ";
342                 }
343                 msg.append("}");
344                 throw new EvaluationException(msg.toString());
345             }
346         }
347         return al;
348
349     }
350
351     private ArrayList JavaDoc getUsedParametersInCollection(
352             Collection col,
353             ParameterOperand[] parameters,
354             ArrayList JavaDoc al)
355             throws EvaluationException {
356         Iterator JavaDoc colit = col.iterator();
357         while (colit.hasNext()) {
358             Object JavaDoc e = colit.next();
359             if (e instanceof ParameterOperand) {
360                 int i = 0;
361                 ParameterOperand param = (ParameterOperand) e;
362                 while (i < parameters.length
363                         && !parameters[i].getName().equals(param.getName()))
364                     i++;
365                 if (i < parameters.length) {
366                     if (parameters[i].getType().getTypeCode() !=
367                             param.getType().getTypeCode()) {
368                         throw new EvaluationException("Bad parameter type: found "
369                                 + parameters[i].getType().getJormName()
370                                 + " / expected " + param.getType().getJormName());
371                     }
372                     if (al == null)
373                         al = new ArrayList JavaDoc();
374                     al.add(parameters[i]);
375                 } else {
376                     String JavaDoc msg = "You must specify the value of parameter "
377                             + param.getName() + ". Found: {";
378                     String JavaDoc sep = "";
379                     for (int j = 0; j < parameters.length; j++) {
380                         msg += sep + parameters[j].getName();
381                         sep = ", ";
382                     }
383                     msg += "}";
384                     throw new EvaluationException(msg);
385                 }
386             }
387         }
388         return al;
389     }
390
391     private String JavaDoc posToString(ParameterOperand[] pos) {
392         if (pos == null) {
393             return "null";
394         }
395         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("[");
396         String JavaDoc sep = "";
397         for (int i = 0; i < pos.length; i++) {
398             sb.append(sep);
399             sb.append("(name='");
400             sb.append("'");
401             sb.append(pos[i].getName());
402             sb.append("', value=");
403             sb.append(pos[i]);
404             sb.append(")");
405         }
406         sb.append("]");
407         return sb.toString();
408     }
409     
410     private ArrayList JavaDoc addRangeParameters(ArrayList JavaDoc al,
411             RdbAdapter rdbAdapt,
412             EvaluationMetaData evalMD) {
413         if (evalMD != null) {
414             int rangePosition = rdbAdapt.getRangeParametersAtStart();
415             if (rangePosition != RdbAdapter.RANGEUNSUPPORTED) {
416                 if (al == null) {
417                     al = new ArrayList JavaDoc();
418                 }
419                 int rangeStart = evalMD.getLimitedRangeStartAt();
420                 if (rangeStart > 0) {
421                     BasicParameterOperand rangeStartParam =
422                         new BasicParameterOperand(PTypeSpaceMedor.INT,
423                             "rangeStart",
424                             rangeStart);
425                     //position the parameter at the right place
426
if (rangePosition == RdbAdapter.RANGEATSTART) {
427                         al.add(0, rangeStartParam);
428                     } else {
429                         al.add(rangeStartParam);
430                     }
431                 }
432                 
433                 int rangeSize = evalMD.getLimitedRangeSize();
434                 if (rangeSize < Integer.MAX_VALUE) {
435                     ParameterOperand rangeSizeParam =
436                         new BasicParameterOperand(PTypeSpaceMedor.INT,
437                             "rangeSize",
438                             rangeSize);
439                     if (rangePosition == RdbAdapter.RANGEATSTART) {
440                        if (rangeStart > 0) {
441                            al.add(1, rangeSizeParam);
442                        } else { //case where start = 0, already one param added
443
al.add(0, rangeSizeParam);
444                        }
445                     } else {
446                         al.add(rangeSizeParam);
447                     }
448                     if (rangeStart > 0 && rdbAdapt instanceof OracleAdapter) {
449                         al.add(new BasicParameterOperand(PTypeSpaceMedor.INT,
450                                 "rangeStart",
451                                 rangeStart));
452                     }
453                 }
454             }
455         }
456         return al;
457     }
458 }
459
Popular Tags