KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > mapper > rdb > lib > RdbTupleCollection


1 /**
2  * JORM: an implementation of a generic mapping system for persistent Java
3  * objects. Two mapping are supported: to RDBMS and to binary files.
4  * Copyright (C) 2001-2003 France Telecom R&D - INRIA
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 of the License, or (at your option) 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 USA
19  *
20  * Contact: jorm-team@objectweb.org
21  *
22  */

23
24 package org.objectweb.jorm.mapper.rdb.lib;
25
26 import org.objectweb.medor.api.MedorException;
27 import org.objectweb.medor.api.TupleStructure;
28 import org.objectweb.medor.expression.api.Operand;
29 import org.objectweb.medor.tuple.api.Tuple;
30 import org.objectweb.medor.tuple.api.TupleCollection;
31 import org.objectweb.medor.eval.prefetch.api.IntermediaryPrefetchBuffer;
32 import org.objectweb.medor.eval.prefetch.api.PrefetchBuffer;
33 import org.objectweb.medor.eval.prefetch.api.PrefetchBufferFactory;
34 import org.objectweb.medor.eval.prefetch.api.PrefetchBufferHolder;
35 import org.objectweb.medor.eval.prefetch.lib.IntermediaryPrefetchBufferImpl;
36 import org.objectweb.medor.eval.prefetch.lib.PrefetchBufferFactoryImpl;
37 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter;
38 import org.objectweb.jorm.mapper.rdb.lib.PMapperRdb;
39 import org.objectweb.jorm.mapper.rdb.lib.PClassMappingDecoder;
40 import org.objectweb.jorm.api.PClassMapping;
41 import org.objectweb.jorm.api.PPrefetchTupleCollection;
42 import org.objectweb.util.monolog.api.BasicLevel;
43 import org.objectweb.util.monolog.api.Logger;
44
45 import java.math.BigDecimal JavaDoc;
46 import java.math.BigInteger JavaDoc;
47 import java.sql.ResultSet JavaDoc;
48 import java.sql.PreparedStatement JavaDoc;
49 import java.sql.SQLException JavaDoc;
50 import java.util.Date JavaDoc;
51
52 /**
53  * Is a TupleCollection encaspulating a prefetched buffer.
54  *
55  * @author P. Dechamboux
56  */

57 public class RdbTupleCollection
58         implements PPrefetchTupleCollection, Tuple, PrefetchBufferHolder {
59
60     /**
61      * The inner SQL resultset containg the PName and the other field values
62      */

63     private ResultSet JavaDoc resultSet;
64
65     /**
66      * the PreparedStatement to close when the collection will be no more used
67      */

68     private PreparedStatement JavaDoc preparedStatement;
69
70     /**
71      * The index of the PName in the current TupleCollection;
72      */

73     private int pnameIndex;
74
75     /**
76      * The RdbAdapter to access the resultset.
77      */

78     private RdbAdapter rdbAdapter;
79
80     /**
81      * The inner prefetch buffer to fill when the TupleCollection is read
82      */

83     private PrefetchBuffer prefetchBuffer;
84
85     /**
86      * The PClassMapping of the persistent class which is prefetched.
87      */

88     private PClassMapping pclassMapping;
89
90     /**
91      * The PNameGetter able to build the PName of the persistent class which is
92      * prefetched.
93      */

94     private Object JavaDoc pnameGetter;
95
96     /**
97      * A factory of prefetched buffer
98      */

99     private static PrefetchBufferFactory pbf = new PrefetchBufferFactoryImpl();
100
101     /**
102      * The row index in the ResultSet / TupleCollection
103      */

104     private int pos = 0;
105
106     private Logger logger;
107
108     public RdbTupleCollection(Object JavaDoc txctx,
109                               ResultSet JavaDoc rs,
110                               PreparedStatement JavaDoc ps,
111                               int pi,
112                               Logger l,
113                               PClassMapping pcm,
114                               boolean withSubType,
115                               Object JavaDoc png)
116             throws MedorException, SQLException JavaDoc {
117         logger = l;
118         logger.log(BasicLevel.DEBUG, "TupleCollection creation");
119         resultSet = rs;
120         preparedStatement = ps;
121         pnameIndex = pi;
122         rdbAdapter = ((PMapperRdb) pcm.getPMapper()).getRdbAdapter();
123         pclassMapping = pcm;
124         pnameGetter = png;
125         boolean isPolymorphic = (pcm instanceof RdbPPolymorphicClass) && withSubType;
126         prefetchBuffer = pcm.getPMapper().getPrefetchCache().createPrefetchBuffer(
127                 pbf, pcm, txctx, pi, !isPolymorphic);
128         prefetchBuffer.setTupleCollection(this);
129         //if the class is polymorphic, create intermediary prefetch buffer
130
if (isPolymorphic) {
131             IntermediaryPrefetchBuffer ipb = new IntermediaryPrefetchBufferImpl(
132                                         prefetchBuffer,
133                                         pcm.getIndexesTable(pcm));
134             if (!pcm.getPMapper().getPrefetchCache().registerPrefetchBuffer(
135                     ipb, pcm, txctx)) {
136                 throw new MedorException("No prefetch buffer registered for the pcm " + pcm.getClassName() + ".");
137             }
138             try{
139                 //get the list of all the sub pclassmappings
140
PClassMapping[] subPCMs = pcm.getSubPCMs();
141                 if(subPCMs != null){
142                     for (int i = 0; i < subPCMs.length; i++) {
143                         //create an intermediary prefetchBuffer that has the prefetchBuffer
144
//of the superclass as delegate prefetch buffer
145
//and the association table for the pcm of the superclass
146
IntermediaryPrefetchBuffer intermediaryPb = new IntermediaryPrefetchBufferImpl(
147                                                                 prefetchBuffer,
148                                                                 subPCMs[i].getIndexesTable(pcm));
149                         if (!subPCMs[i].getPMapper().getPrefetchCache().registerPrefetchBuffer(
150                                 intermediaryPb, subPCMs[i], txctx)) {
151                             throw new MedorException("No prefetch buffer registered for the pcm " + subPCMs[i].getClassName() + ".");
152                         }
153                     }
154                 }
155             }
156             catch(Exception JavaDoc e){
157                 throw new MedorException("Error while trying to register the prefetchBuffer with the subclasses. ", e);
158             }
159         }
160     }
161
162     public PrefetchBuffer getPrefetchBuffer() {
163         return prefetchBuffer;
164     }
165
166     public int getPNameIndex() {
167         return pnameIndex;
168     }
169
170     public TupleStructure getMetaData() throws MedorException {
171         return null;
172     }
173
174     public boolean isLast() throws MedorException {
175         if (resultSet == null) {
176             throw new MedorException("Impossible to use a closed TupleCollection");
177         }
178         logger.log(BasicLevel.DEBUG, "");
179         try {
180             return resultSet.isLast();
181         } catch (SQLException JavaDoc sqlex) {
182             throw new MedorException(sqlex);
183         }
184     }
185
186     public void close() throws MedorException {
187         if (resultSet != null) {
188             try {
189                 resultSet.close();
190                 preparedStatement.close();
191             } catch (SQLException JavaDoc e) {
192                 throw new MedorException("Impossible to close the result set: ", e);
193             } finally {
194                 resultSet = null;
195                 preparedStatement = null;
196             }
197         }
198     }
199
200     /**
201      * Moves the cursor down one row from its
202      * current position to the next tuple
203      */

204     public boolean next() throws MedorException {
205         if (resultSet == null) {
206             throw new MedorException("Impossible to use a closed TupleCollection");
207         }
208         logger.log(BasicLevel.DEBUG, "");
209         try {
210             if (resultSet.next()) {
211                 pos++;
212                 logger.log(BasicLevel.DEBUG, "resultset.next()=true");
213                 return true;
214             } else {
215                 logger.log(BasicLevel.DEBUG, "resultset.next()=false");
216                 return false;
217             }
218         } catch (SQLException JavaDoc sqlex) {
219             throw new MedorException(sqlex);
220         }
221     }
222
223     /**
224      * Moves the cursor to the first Tuple of this TupleCollection
225      */

226     public void first() throws MedorException {
227         if (resultSet == null) {
228             throw new MedorException("Impossible to use a closed TupleCollection");
229         }
230         logger.log(BasicLevel.DEBUG, "");
231         try {
232             if (resultSet.first()) {
233                 pos = 1;
234                 logger.log(BasicLevel.DEBUG, "resultset.previous()=true");
235             } else
236                 throw new MedorException("can't move the cursor to the first row");
237         } catch (SQLException JavaDoc ex) {
238             throw new MedorException(ex);
239         }
240     }
241
242     /**
243      * Retrieves the current row Number of this TupleCollection
244      */

245     public int getRow() throws MedorException {
246         return pos;
247     }
248
249     public Tuple getTuple() throws MedorException {
250         if (resultSet == null) {
251             throw new MedorException("Impossible to use a closed TupleCollection");
252         }
253         logger.log(BasicLevel.DEBUG, "");
254         return this;
255     }
256
257     public Tuple getTuple(int row) throws MedorException {
258         if (resultSet == null) {
259             throw new MedorException("Impossible to use a closed TupleCollection");
260         }
261         row(row);
262         return this;
263     }
264
265     public boolean isEmpty() throws MedorException {
266         throw new MedorException("No need to support it here!!");
267     }
268
269     public boolean row(int i) throws MedorException {
270         if (resultSet == null) {
271             throw new MedorException("Impossible to use a closed TupleCollection");
272         }
273         try {
274             logger.log(BasicLevel.DEBUG, "resultSet.absolute(" + i + ")");
275             if (pos == i) {
276                 return true;
277             }
278             if (i == 1) {
279                 first();
280                 return true;
281             }
282             if (pos == (i - 1)) {
283                 return next();
284             }
285             if (resultSet.absolute(i)) {
286                 pos = i;
287                 return true;
288             } else
289                 return false;
290         } catch (SQLException JavaDoc sqlex) {
291             throw new MedorException(sqlex);
292         }
293     }
294
295     // IMPLEMENTATION OF METHODS OF THE Tuple INTERFACE
296

297     /**
298      * Give the number of the attribute in this Tuple object.
299      * @return an int
300      */

301     public int getSize() {
302         try {
303             return resultSet.getMetaData().getColumnCount() + 1;
304         } catch (SQLException JavaDoc e) {
305             return -1;
306         }
307     }
308
309     /**
310      * Give the array of Operand object representation of the Tuple.
311      * @return an array of Operand type.
312      */

313     public Operand[] toOperandArray() {
314         return null;
315     }
316
317     /**
318      * Returns the value of the designated column
319      * in the current row of this Tuple
320      * as a Boolean of java programming language
321      */

322     public boolean getBoolean(int i) throws MedorException {
323         if (resultSet == null) {
324             throw new MedorException("Impossible to use a closed TupleCollection");
325         }
326         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
327         try {
328             return rdbAdapter.getBoolean(resultSet, (i >= pnameIndex) ? i - 1 : i, false);
329         } catch (SQLException JavaDoc e) {
330             throw new MedorException(e);
331         }
332     }
333
334     /**
335      * Returns the value of the designated column
336      * in the current row of this Tuple as a Java byte
337      */

338     public byte getByte(int i) throws MedorException {
339         if (resultSet == null) {
340             throw new MedorException("Impossible to use a closed TupleCollection");
341         }
342         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
343         try {
344             return rdbAdapter.getByte(resultSet, (i >= pnameIndex) ? i - 1 : i, (byte) 0);
345         } catch (SQLException JavaDoc e) {
346             throw new MedorException(e);
347         }
348     }
349
350     /**
351      * Returns the value of the designated column
352      * in the current row of this Tuple as a Java byte
353      */

354     public byte[] getByteArray(int i) throws MedorException {
355         if (resultSet == null) {
356             throw new MedorException("Impossible to use a closed TupleCollection");
357         }
358         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
359         try {
360             return rdbAdapter.getByteArray(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
361         } catch (SQLException JavaDoc e) {
362             throw new MedorException(e);
363         }
364     }
365
366     /**
367      * Returns the value of the designated column
368      * in the current row of this Tuple as a Java char
369      */

370     public char getChar(int i) throws MedorException {
371         if (resultSet == null) {
372             throw new MedorException("Impossible to use a closed TupleCollection");
373         }
374         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
375         try {
376             return rdbAdapter.getChar(resultSet, (i >= pnameIndex) ? i - 1 : i, (char) 0);
377         } catch (SQLException JavaDoc e) {
378             throw new MedorException(e);
379         }
380     }
381
382     /**
383      * Returns the value of the designated column
384      * in the current row of this Tuple as a Java char[]
385      */

386     public char[] getCharArray(int i) throws MedorException {
387         if (resultSet == null) {
388             throw new MedorException("Impossible to use a closed TupleCollection");
389         }
390         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
391         try {
392             return rdbAdapter.getCharArray(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
393         } catch (SQLException JavaDoc e) {
394             throw new MedorException(e);
395         }
396     }
397
398     /**
399      * Returns the value of the designated column
400      * in the current row of this Tuple as a java.sql.Data
401      */

402     public Date JavaDoc getDate(int i) throws MedorException {
403         if (resultSet == null) {
404             throw new MedorException("Impossible to use a closed TupleCollection");
405         }
406         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
407         try {
408             return rdbAdapter.getDate(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
409         } catch (SQLException JavaDoc e) {
410             throw new MedorException(e);
411         }
412     }
413
414     /**
415      * Returns the value of the designated column
416      * in the current row of this Tuple as a Java double
417      */

418     public double getDouble(int i) throws MedorException {
419         if (resultSet == null) {
420             throw new MedorException("Impossible to use a closed TupleCollection");
421         }
422         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
423         try {
424             return rdbAdapter.getDouble(resultSet, (i >= pnameIndex) ? i - 1 : i, ((double) 0.0));
425         } catch (SQLException JavaDoc e) {
426             throw new MedorException(e);
427         }
428     }
429
430     /**
431      * Returns the value of the designated column
432      * in the current row of this Tuple as a Java float
433      */

434     public float getFloat(int i) throws MedorException {
435         if (resultSet == null) {
436             throw new MedorException("Impossible to use a closed TupleCollection");
437         }
438         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
439         try {
440             return rdbAdapter.getFloat(resultSet, (i >= pnameIndex) ? i - 1 : i, ((float) 0.0));
441         } catch (SQLException JavaDoc e) {
442             throw new MedorException(e);
443         }
444     }
445
446     /**
447      * Returns the value of the designated column
448      * in the current row of this Tuple as a java int
449      */

450     public int getInt(int i) throws MedorException {
451         if (resultSet == null) {
452             throw new MedorException("Impossible to use a closed TupleCollection");
453         }
454         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
455         try {
456             return rdbAdapter.getInt(resultSet, (i >= pnameIndex) ? i - 1 : i, -1);
457         } catch (SQLException JavaDoc e) {
458             throw new MedorException(e);
459         }
460     }
461
462     /**
463      * Returns the value of the designated column
464      * in the current row of this Tuple
465      * as an org.objectweb.medor.filter.Operand Object
466      */

467     public Operand getLikeOperand(int i) throws MedorException {
468         return null;
469     }
470
471     /**
472      * Returns the value of the designated column
473      * in the current row of this Tuple as a Java long
474      */

475     public long getLong(int i) throws MedorException {
476         if (resultSet == null) {
477             throw new MedorException("Impossible to use a closed TupleCollection");
478         }
479         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
480         try {
481             return rdbAdapter.getLong(resultSet, (i >= pnameIndex) ? i - 1 : i, ((long) -1));
482         } catch (SQLException JavaDoc e) {
483             throw new MedorException(e);
484         }
485     }
486
487     /**
488      * Returns the value of the designated column
489      * in the current row of this Tuple
490      * as an Object in the java programming language
491      */

492     public Object JavaDoc getObject(int i) throws MedorException {
493         if (resultSet == null) {
494             throw new MedorException("Impossible to use a closed TupleCollection");
495         }
496         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
497         try {
498             if (i == pnameIndex) {
499                 // should return the PName
500
return ((PClassMappingDecoder) pclassMapping).decode(resultSet, pnameIndex, pnameGetter);
501             } else {
502                 Object JavaDoc o = resultSet.getObject((i >= pnameIndex) ? i - 1 : i);
503                 return (resultSet.wasNull() ? null : o);
504             }
505         } catch (SQLException JavaDoc sqlex) {
506             throw new MedorException(sqlex);
507         } catch (Exception JavaDoc e) {
508             throw new MedorException("Invalid field index " + i, e);
509         }
510     }
511
512     /**
513      * Returns the value of the designated column
514      * in the current row of this Tuple
515      * as a Short in the java programming language
516      */

517     public short getShort(int i) throws MedorException {
518         if (resultSet == null) {
519             throw new MedorException("Impossible to use a closed TupleCollection");
520         }
521         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
522         try {
523             return rdbAdapter.getShort(resultSet, (i >= pnameIndex) ? i - 1 : i, (short) -1);
524         } catch (SQLException JavaDoc e) {
525             throw new MedorException(e);
526         }
527     }
528
529     /**
530      * Returns the value of the designated column
531      * in the current row of this Tuple
532      * as a BigDecimal in the java programming language
533      */

534     public BigDecimal JavaDoc getBigDecimal(int i) throws MedorException {
535         if (resultSet == null) {
536             throw new MedorException("Impossible to use a closed TupleCollection");
537         }
538         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
539         try {
540             return rdbAdapter.getBigDecimal(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
541         } catch (SQLException JavaDoc e) {
542             throw new MedorException(e);
543         }
544     }
545
546     /**
547      * Returns the value of the designated column
548      * in the current row of this Tuple
549      * as a BigDecimal in the java programming language
550      */

551     public BigInteger JavaDoc getBigInteger(int i) throws MedorException {
552         if (resultSet == null) {
553             throw new MedorException("Impossible to use a closed TupleCollection");
554         }
555         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
556         try {
557             BigDecimal JavaDoc bd = rdbAdapter.getBigDecimal(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
558             return (bd == null) ? null : bd.toBigInteger();
559         } catch (SQLException JavaDoc e) {
560             throw new MedorException(e);
561         }
562     }
563
564     /**
565      * Returns the value of the designated column
566      * in the current row of this Tuple
567      * as a String in java programming language
568      */

569     public String JavaDoc getString(int i) throws MedorException {
570         if (resultSet == null) {
571             throw new MedorException("Impossible to use a closed TupleCollection");
572         }
573         logger.log(BasicLevel.DEBUG, "numColumn=" + i);
574         try {
575             return rdbAdapter.getString(resultSet, (i >= pnameIndex) ? i - 1 : i, null);
576         } catch (SQLException JavaDoc e) {
577             throw new MedorException(e);
578         }
579     }
580
581     /**
582      * Returns the value of the designated column
583      * in the current row of this Tuple
584      * as a org.objectweb.medor object
585      */

586     public TupleCollection getTupleCollection(int i) throws MedorException {
587         return this;
588     }
589
590     public boolean isDefined(int i) {
591         try {
592             return !resultSet.wasNull();
593         } catch (SQLException JavaDoc e) {
594             return false;
595         }
596     }
597
598     // IMPLEMENTATION OF METHODS OF THE PrefetchBufferHolder INTERFACE
599

600     public void invalidatePrefetchBuffer() throws MedorException {
601         logger.log(BasicLevel.DEBUG, "Invalidating PrefetchBuffer " + prefetchBuffer + " for " + this);
602         prefetchBuffer = null;
603         if (prefetchBuffer != null) {
604             this.close();
605             prefetchBuffer = null;
606         } else {
607             logger.log(BasicLevel.DEBUG, "The tupleCollection was closed earlier: closing it for real");
608         }
609     }
610 }
611
Popular Tags