KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc2 > AbstractQueryCommand


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software 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 software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc2;
23
24 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
25 import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2;
26 import org.jboss.ejb.plugins.cmp.jdbc2.schema.Schema;
27 import org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil;
28 import org.jboss.ejb.plugins.cmp.jdbc.QueryParameter;
29 import org.jboss.ejb.plugins.cmp.ejbql.SelectFunction;
30 import org.jboss.ejb.GenericEntityObjectFactory;
31 import org.jboss.logging.Logger;
32
33 import javax.ejb.FinderException JavaDoc;
34 import javax.ejb.ObjectNotFoundException JavaDoc;
35 import java.util.Collection JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.Set JavaDoc;
40 import java.util.HashSet JavaDoc;
41 import java.sql.Connection JavaDoc;
42 import java.sql.PreparedStatement JavaDoc;
43 import java.sql.ResultSet JavaDoc;
44 import java.sql.SQLException JavaDoc;
45
46 /**
47  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
48  * @version <tt>$Revision: 58402 $</tt>
49  */

50 public abstract class AbstractQueryCommand implements QueryCommand
51 {
52    static final CollectionFactory COLLECTION_FACTORY = new CollectionFactory()
53    {
54       public Collection JavaDoc newCollection()
55       {
56          return new ArrayList JavaDoc();
57       }
58    };
59
60    static final CollectionFactory SET_FACTORY = new CollectionFactory()
61    {
62       public Collection JavaDoc newCollection()
63       {
64          return new HashSet JavaDoc();
65       }
66    };
67
68    protected String JavaDoc sql;
69    protected Logger log;
70    protected JDBCEntityBridge2 entity;
71    protected QueryParameter[] params = null;
72    private CollectionFactory collectionFactory;
73    private CollectionStrategy collectionStrategy;
74    private ResultReader resultReader;
75
76    // Protected
77

78    protected void setResultType(Class JavaDoc clazz)
79    {
80       if(Set JavaDoc.class.isAssignableFrom(clazz))
81       {
82          collectionFactory = SET_FACTORY;
83       }
84       else if(Collection JavaDoc.class.isAssignableFrom(clazz))
85       {
86          collectionFactory = COLLECTION_FACTORY;
87       }
88       initCollectionStrategy();
89    }
90
91    protected void setFieldReader(JDBCCMPFieldBridge2 field)
92    {
93       this.resultReader = new FieldReader(field);
94       initCollectionStrategy();
95    }
96
97    protected void setFunctionReader(SelectFunction func)
98    {
99       this.resultReader = new FunctionReader(func);
100       initCollectionStrategy();
101    }
102
103    protected void setEntityReader(JDBCEntityBridge2 entity, boolean searchableOnly)
104    {
105       this.entity = entity;
106       this.resultReader = new EntityReader(entity, searchableOnly);
107       initCollectionStrategy();
108    }
109
110    private void initCollectionStrategy()
111    {
112       if(collectionFactory != null && resultReader != null)
113       {
114          collectionStrategy = new EagerCollectionStrategy(collectionFactory, resultReader, log);
115       }
116    }
117
118    // QueryCommand implementation
119

120    public JDBCStoreManager2 getStoreManager()
121    {
122       return (JDBCStoreManager2) entity.getManager();
123    }
124
125    public Collection JavaDoc fetchCollection(Schema schema, GenericEntityObjectFactory factory, Object JavaDoc[] args)
126       throws FinderException JavaDoc
127    {
128       return fetchCollection(entity, sql, params, collectionStrategy, schema, factory, args, log);
129    }
130
131    public Object JavaDoc fetchOne(Schema schema, GenericEntityObjectFactory factory, Object JavaDoc[] args) throws FinderException JavaDoc
132    {
133       schema.flush();
134       return executeFetchOne(args, factory);
135    }
136
137    // Protected
138

139    protected Object JavaDoc executeFetchOne(Object JavaDoc[] args, GenericEntityObjectFactory factory) throws FinderException JavaDoc
140    {
141       return fetchOne(entity, sql, params, resultReader, args, factory, log);
142    }
143
144    static Collection JavaDoc fetchCollection(JDBCEntityBridge2 entity,
145                                      String JavaDoc sql,
146                                      QueryParameter[] params,
147                                      CollectionStrategy collectionStrategy,
148                                      Schema schema,
149                                      GenericEntityObjectFactory factory,
150                                      Object JavaDoc[] args,
151                                      Logger log)
152       throws FinderException JavaDoc
153    {
154       schema.flush();
155
156       Collection JavaDoc result;
157
158       Connection JavaDoc con = null;
159       PreparedStatement JavaDoc ps = null;
160       ResultSet JavaDoc rs = null;
161       boolean throwRuntimeExceptions = entity.getMetaData().getThrowRuntimeExceptions();
162
163       // if metadata is true, the getconnection is done inside
164
// its own try catch block to throw a runtime exception (EJBException)
165
if (throwRuntimeExceptions)
166       {
167           try
168           {
169               con = entity.getDataSource().getConnection();
170           }
171           catch (SQLException JavaDoc sqle)
172           {
173               javax.ejb.EJBException JavaDoc ejbe = new javax.ejb.EJBException JavaDoc("Could not get a connection; " + sqle);
174               ejbe.initCause(sqle);
175               throw ejbe;
176           }
177       }
178       try
179       {
180          if(log.isDebugEnabled())
181          {
182             log.debug("executing: " + sql);
183          }
184
185          // if metadata is false, the getconnection is done inside this try catch block
186
if ( ! throwRuntimeExceptions)
187          {
188              con = entity.getDataSource().getConnection();
189          }
190          ps = con.prepareStatement(sql);
191
192          if(params != null)
193          {
194             for(int i = 0; i < params.length; i++)
195             {
196                params[i].set(log, ps, i + 1, args);
197             }
198          }
199
200          rs = ps.executeQuery();
201       }
202       catch(Exception JavaDoc e)
203       {
204          JDBCUtil.safeClose(rs);
205          JDBCUtil.safeClose(ps);
206          JDBCUtil.safeClose(con);
207
208          log.error("Finder failed: " + e.getMessage(), e);
209          FinderException JavaDoc fe = new FinderException JavaDoc(e.getMessage());
210          fe.initCause(e);
211          throw fe;
212       }
213
214       result = collectionStrategy.readResultSet(con, ps, rs, factory);
215
216       return result;
217    }
218    
219    static Object JavaDoc fetchOne(JDBCEntityBridge2 entity,
220                           String JavaDoc sql,
221                           QueryParameter[] params,
222                           ResultReader resultReader,
223                           Object JavaDoc[] args,
224                           GenericEntityObjectFactory factory,
225                           Logger log)
226       throws FinderException JavaDoc
227    {
228       Object JavaDoc pk;
229       Connection JavaDoc con = null;
230       PreparedStatement JavaDoc ps = null;
231       ResultSet JavaDoc rs = null;
232       boolean throwRuntimeExceptions = entity.getMetaData().getThrowRuntimeExceptions();
233
234       // if metadata is true, the getconnection is done inside
235
// its own try catch block to throw a runtime exception (EJBException)
236
if (throwRuntimeExceptions)
237       {
238           try
239           {
240               con = entity.getDataSource().getConnection();
241           }
242           catch (SQLException JavaDoc sqle)
243           {
244               javax.ejb.EJBException JavaDoc ejbe = new javax.ejb.EJBException JavaDoc("Could not get a connection; " + sqle);
245               //ejbe.initCause(sqle); only for JBoss 4 and +
246
throw ejbe;
247           }
248       }
249       try
250       {
251          if(log.isDebugEnabled())
252          {
253             log.debug("executing: " + sql);
254          }
255
256          // if metadata is false, the getconnection is done inside this try catch block
257
if ( ! throwRuntimeExceptions)
258          {
259              con = entity.getDataSource().getConnection();
260          }
261          ps = con.prepareStatement(sql);
262
263          if(params != null)
264          {
265             for(int i = 0; i < params.length; i++)
266             {
267                params[i].set(log, ps, i + 1, args);
268             }
269          }
270
271          rs = ps.executeQuery();
272          if(rs.next())
273          {
274             pk = resultReader.readRow(rs, factory);
275             if(rs.next())
276             {
277                List JavaDoc list = new ArrayList JavaDoc();
278                list.add(pk);
279                list.add(resultReader.readRow(rs, factory));
280                while(rs.next())
281                {
282                   list.add(resultReader.readRow(rs, factory));
283                }
284                throw new FinderException JavaDoc("More than one instance matches the single-object finder criteria: " + list);
285             }
286          }
287          else
288          {
289             throw new ObjectNotFoundException JavaDoc();
290          }
291       }
292       catch(FinderException JavaDoc e)
293       {
294          throw e;
295       }
296       catch(Exception JavaDoc e)
297       {
298           FinderException JavaDoc fe = new FinderException JavaDoc(e.getMessage());
299           fe.initCause(e);
300           throw fe;
301       }
302       finally
303       {
304          JDBCUtil.safeClose(rs);
305          JDBCUtil.safeClose(ps);
306          JDBCUtil.safeClose(con);
307       }
308
309       return pk;
310    }
311    
312    protected void setParameters(List JavaDoc p)
313    {
314       if(p.size() > 0)
315       {
316          params = new QueryParameter[p.size()];
317          for(int i = 0; i < p.size(); i++)
318          {
319             Object JavaDoc pi = p.get(i);
320             if(!(pi instanceof QueryParameter))
321             {
322                throw new IllegalArgumentException JavaDoc("Element "
323                   +
324                   i
325                   +
326                   " of list is not an instance of QueryParameter, but " +
327                   p.get(i).getClass().getName());
328             }
329             params[i] = (QueryParameter) pi;
330          }
331       }
332    }
333
334    // Inner
335

336    static interface CollectionFactory
337    {
338       Collection JavaDoc newCollection();
339    }
340
341    static interface ResultReader
342    {
343       Object JavaDoc readRow(ResultSet JavaDoc rs, GenericEntityObjectFactory factory) throws SQLException JavaDoc;
344    }
345
346    static class EntityReader implements ResultReader
347    {
348       private final JDBCEntityBridge2 entity;
349       private final boolean searchableOnly;
350
351       public EntityReader(JDBCEntityBridge2 entity, boolean searchableOnly)
352       {
353          this.entity = entity;
354          this.searchableOnly = searchableOnly;
355       }
356
357       public Object JavaDoc readRow(ResultSet JavaDoc rs, GenericEntityObjectFactory factory)
358       {
359          final Object JavaDoc pk = entity.getTable().loadRow(rs, searchableOnly);
360          return pk == null ? null : factory.getEntityEJBObject(pk);
361       }
362    };
363
364    static class FieldReader implements ResultReader
365    {
366       private final JDBCCMPFieldBridge2 field;
367
368       public FieldReader(JDBCCMPFieldBridge2 field)
369       {
370          this.field = field;
371       }
372
373       public Object JavaDoc readRow(ResultSet JavaDoc rs, GenericEntityObjectFactory factory) throws SQLException JavaDoc
374       {
375          return field.loadArgumentResults(rs, 1);
376       }
377    }
378
379    static class FunctionReader implements ResultReader
380    {
381       private final SelectFunction function;
382
383       public FunctionReader(SelectFunction function)
384       {
385          this.function = function;
386       }
387
388       public Object JavaDoc readRow(ResultSet JavaDoc rs, GenericEntityObjectFactory factory) throws SQLException JavaDoc
389       {
390          return function.readResult(rs);
391       }
392    }
393
394    interface CollectionStrategy
395    {
396       Collection JavaDoc readResultSet(Connection JavaDoc con, PreparedStatement JavaDoc ps, ResultSet JavaDoc rs, GenericEntityObjectFactory factory)
397          throws FinderException JavaDoc;
398    }
399
400    static class EagerCollectionStrategy
401       implements CollectionStrategy
402    {
403       private final CollectionFactory collectionFactory;
404       private final ResultReader resultReader;
405       private final Logger log;
406
407       public EagerCollectionStrategy(CollectionFactory collectionFactory,
408                      ResultReader resultReader, Logger log)
409       {
410          this.collectionFactory = collectionFactory;
411          this.resultReader = resultReader;
412          this.log = log;
413       }
414
415       public Collection JavaDoc readResultSet(Connection JavaDoc con,
416                                       PreparedStatement JavaDoc ps,
417                                       ResultSet JavaDoc rs,
418                                       GenericEntityObjectFactory factory)
419          throws FinderException JavaDoc
420       {
421          Collection JavaDoc result;
422          try
423          {
424             if(rs.next())
425             {
426                result = collectionFactory.newCollection();
427                Object JavaDoc instance = resultReader.readRow(rs, factory);
428                result.add(instance);
429                while(rs.next())
430                {
431                   instance = resultReader.readRow(rs, factory);
432                   result.add(instance);
433                }
434             }
435             else
436             {
437                result = Collections.EMPTY_SET;
438             }
439          }
440          catch(Exception JavaDoc e)
441          {
442             log.error("Finder failed: " + e.getMessage(), e);
443             throw new FinderException JavaDoc(e.getMessage());
444          }
445          finally
446          {
447             JDBCUtil.safeClose(rs);
448             JDBCUtil.safeClose(ps);
449             JDBCUtil.safeClose(con);
450          }
451          return result;
452       }
453    }
454 }
455
Popular Tags