KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > platforms > PlatformOracle9iImpl


1 package org.apache.ojb.broker.platforms;
2
3 /* Copyright 2003-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
19 import org.apache.ojb.broker.metadata.ConnectionPoolDescriptor;
20 import org.apache.ojb.broker.util.ClassHelper;
21 import org.apache.ojb.broker.util.logging.Logger;
22 import org.apache.ojb.broker.util.logging.LoggerFactory;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.sql.Connection JavaDoc;
27 import java.sql.PreparedStatement JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.sql.Statement JavaDoc;
30 import java.sql.Types JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.WeakHashMap JavaDoc;
34
35 /**
36  * This class is a concrete implementation of <code>Platform</code>. Provides
37  * an implementation that works around some issues with Oracle in general and
38  * Oracle 9i's Thin driver in particular.
39  *
40  * NOTE: When using BEA WebLogic and BLOB/CLOB datatypes, the physical connection will be
41  * used causing WebLogic to mark it as "infected" and discard it when
42  * the logicical connection is closed. You can change this behavior by setting the
43  * RemoveInfectedConnectionsEnabled attribute on a connection pool.
44  * see <a HREF="http://e-docs.bea.com/wls/docs81/jdbc/thirdparty.html#1043646">WebLogic docs</a>.
45  *
46  * Optimization: Oracle Batching (not standard JDBC batching)
47  * see http://technet.oracle.com/products/oracle9i/daily/jun07.html
48  *
49  * Optimization: Oracle Prefetching
50  * see http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html
51  *
52  * Optimization: Oracle Statement Caching
53  * see http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html
54  *
55  * TODO: Optimization: use ROWNUM to minimize the effects of not having server side cursors
56  * see http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:127412348064
57  *
58  * @author <a HREF="mailto:mattbaird@yahoo.com">Matthew Baird</a>
59  * @author <a HREF="mailto:mkalen@apache.org">Martin Kal&eacute;n</a>
60  * @author Contributions from: Erik Forkalsrud, Danilo Tommasina, Thierry Hanot, Don Lyon
61  * @version CVS $Id: PlatformOracle9iImpl.java,v 1.13.2.9 2005/04/26 03:41:36 mkalen Exp $
62  * @see Platform
63  * @see PlatformDefaultImpl
64  * @see PlatformOracleImpl
65  */

66 public class PlatformOracle9iImpl extends PlatformOracleImpl
67 {
68     private Logger logger = LoggerFactory.getLogger(PlatformOracle9iImpl.class);
69
70     /**
71      * Number of cached statements per connection,
72      * when using implicit caching with OracleConnections.
73      * Set in {@link #initializeJdbcConnection}.
74      * @see <a HREF="http://www.apache.org/~mkalen/ojb/broker-tests.html">Profiling page</a>
75      * for a discussion re sizing
76      */

77     protected static final int STATEMENT_CACHE_SIZE = 10;
78     /**
79      * Number of rows pre-fetched by the JDBC-driver for each executed query,
80      * when using Oracle row pre-fetching with OracleConnections.
81      * Set in {@link #initializeJdbcConnection}.
82      * <p>
83      * <em>Note</em>: this setting can be overridden by specifying a
84      * connection-pool attribute with name="jdbc.defaultRowPrefetch".
85      * Oracle JDBC-driver default value=10.
86      */

87     protected static final int ROW_PREFETCH_SIZE = 20;
88
89     // From Oracle9i JDBC Developer's Guide and Reference:
90
// "Batch values between 5 and 30 tend to be the most effective."
91
protected static final int STATEMENTS_PER_BATCH = 20;
92     protected static Map JavaDoc m_batchStatementsInProgress = Collections.synchronizedMap(new WeakHashMap JavaDoc(STATEMENTS_PER_BATCH));
93
94     protected static final Class JavaDoc[] PARAM_TYPE_EMPTY = {};
95     protected static final Class JavaDoc[] PARAM_TYPE_INTEGER = {Integer.TYPE};
96     protected static final Class JavaDoc[] PARAM_TYPE_BOOLEAN = {Boolean.TYPE};
97     protected static final Class JavaDoc[] PARAM_TYPE_STRING = {String JavaDoc.class};
98
99     protected static final Object JavaDoc[] PARAM_EMPTY = new Object JavaDoc[]{};
100     protected static final Object JavaDoc[] PARAM_STATEMENT_CACHE_SIZE = new Object JavaDoc[]{new Integer JavaDoc(STATEMENT_CACHE_SIZE)};
101     protected static final Object JavaDoc[] PARAM_ROW_PREFETCH_SIZE = new Object JavaDoc[]{new Integer JavaDoc(ROW_PREFETCH_SIZE)};
102     protected static final Object JavaDoc[] PARAM_STATEMENT_BATCH_SIZE = new Object JavaDoc[]{new Integer JavaDoc(STATEMENTS_PER_BATCH)};
103     protected static final Object JavaDoc[] PARAM_BOOLEAN_TRUE = new Object JavaDoc[]{Boolean.TRUE};
104
105     protected static final String JavaDoc JBOSS_CONN_NAME =
106             "org.jboss.resource.adapter.jdbc.WrappedConnection";
107     protected static Class JavaDoc JBOSS_CONN_CLASS = null;
108
109     protected static Class JavaDoc ORA_CONN_CLASS;
110     protected static Class JavaDoc ORA_PS_CLASS;
111     protected static Class JavaDoc ORA_CLOB_CLASS;
112     protected static Class JavaDoc ORA_BLOB_CLASS;
113     protected static Class JavaDoc[] PARAM_TYPE_INT_ORACLOB;
114     protected static Class JavaDoc[] PARAM_TYPE_INT_ORABLOB;
115     protected static Method JavaDoc METHOD_SET_STATEMENT_CACHE_SIZE;
116     protected static Method JavaDoc METHOD_SET_IMPLICIT_CACHING_ENABLED;
117     protected static Method JavaDoc METHOD_SET_ROW_PREFETCH;
118     protected static Method JavaDoc METHOD_SET_BLOB = null;
119     protected static Method JavaDoc METHOD_SET_CLOB = null;
120     protected static boolean ORA_STATEMENT_CACHING_AVAILABLE;
121     protected static boolean ORA_ROW_PREFETCH_AVAILABLE;
122     protected static boolean ORA_CLOB_HANDLING_AVAILABLE;
123     protected static boolean ORA_BLOB_HANDLING_AVAILABLE;
124
125     /** Method names used by {@link #unwrapConnection}. */
126     protected static final String JavaDoc UNWRAP_CONN_METHOD_NAMES[] =
127             {
128                 "unwrapCompletely" /* Oracle 10g */,
129                 "getInnermostDelegate" /* Commons DBCP */,
130                 "getUnderlyingConnection" /* JBoss */,
131                 "getVendorConnection" /* BEA WebLogic */,
132                 "getJDBC" /* P6Spy */
133             };
134     /**
135      * Method parameter signature used by {@link #unwrapConnection} for corresponding
136      * {@link #UNWRAP_CONN_METHOD_NAMES}-index.
137      * If signature is not {@link #PARAM_TYPE_EMPTY}, the actual connection object
138      * will be passed at runtime. (NB: Requires special handling of param type in constructor.)
139      */

140     protected static final Class JavaDoc[][] UNWRAP_CONN_PARAM_TYPES =
141             {
142                 null /* Index 0 reserved for Oracle 10g - initialized in constructor */,
143                 PARAM_TYPE_EMPTY /* Commons DBCP */,
144                 PARAM_TYPE_EMPTY /* JBoss */,
145                 PARAM_TYPE_EMPTY /* BEA WebLogic */,
146                 PARAM_TYPE_EMPTY /* P6Spy */
147             };
148     /** Method names used by {@link #unwrapStatement}. */
149     protected static final String JavaDoc UNWRAP_PS_METHOD_NAMES[] =
150             {
151                 "getInnermostDelegate" /* Commons DBCP */,
152                 "getUnderlyingStatement" /* JBoss */,
153                 "getJDBC" /* P6Spy */
154             };
155     /**
156      * Method parameter signature used by {@link #unwrapStatement} for corresponding
157      * {@link #UNWRAP_PS_METHOD_NAMES}-index.
158      * If signature is not {@link #PARAM_TYPE_EMPTY}, the actual Statement object
159      * will be passed at runtime. (NB: Requires special handling of param type in constructor.)
160      */

161     protected static final Class JavaDoc[][] UNWRAP_PS_PARAM_TYPES =
162             {
163                 PARAM_TYPE_EMPTY /* Commons DBCP */,
164                 PARAM_TYPE_EMPTY /* JBoss */,
165                 PARAM_TYPE_EMPTY /* P6Spy */
166             };
167
168
169     /**
170      * Default constructor.
171      */

172     public PlatformOracle9iImpl()
173     {
174         super();
175     }
176
177     /**
178      * Enables Oracle statement caching and row prefetching if supported by the JDBC-driver.
179      * @param jcd the OJB <code>JdbcConnectionDescriptor</code> (metadata) for the connection to be initialized
180      * @param conn the <code>Connection</code>-object (physical) to be initialized
181      * @see PlatformDefaultImpl#initializeJdbcConnection
182      * @see <a HREF="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html">
183      * Oracle TechNet Statement Caching Sample</a>
184      * @see <a HREF="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html">
185      * Oracle TechNet Row Pre-fetch Sample<a>
186      */

187     public void initializeJdbcConnection(final JdbcConnectionDescriptor jcd,
188                                          final Connection JavaDoc conn)
189             throws PlatformException
190     {
191         // Do all the generic initialization in PlatformDefaultImpl first
192
super.initializeJdbcConnection(jcd, conn);
193
194         // Check for managed environments known to reject Oracle extension at this level
195
// (saves us from trying to unwrap just to catch exceptions next)
196
final Class JavaDoc connClass = conn.getClass();
197         if (JBOSS_CONN_CLASS != null && JBOSS_CONN_CLASS.isAssignableFrom(connClass))
198         {
199             if (logger.isDebugEnabled())
200             {
201                 logger.debug("JBoss detected, Oracle Connection tuning left to J2EE container.");
202             }
203             return;
204         }
205
206         // Check if this is a wrapped connection and if so unwrap it
207
final Connection JavaDoc oraConn = unwrapConnection(conn);
208         if (oraConn == null)
209         {
210             return;
211         }
212
213         // At this point we know that we have an OracleConnection instance and can thus
214
// try to invoke methods via reflection (if available)
215
if (ORA_STATEMENT_CACHING_AVAILABLE)
216         {
217             try
218             {
219                 // Set number of cached statements and enable implicit caching
220
METHOD_SET_STATEMENT_CACHE_SIZE.invoke(oraConn, PARAM_STATEMENT_CACHE_SIZE);
221                 METHOD_SET_IMPLICIT_CACHING_ENABLED.invoke(oraConn, PARAM_BOOLEAN_TRUE);
222             }
223             catch (Exception JavaDoc e)
224             {
225                 if (logger.isDebugEnabled())
226                 {
227                     logger.debug("PlatformOracle9iImpl could not enable Oracle statement caching."
228                                  + " Original/unwrapped connection classes="
229                                  + connClass.getName() + "/" + oraConn.getClass().getName());
230                 }
231             }
232         }
233
234         /*
235         mkalen: Note from the Oracle documentation:
236             Do not mix the JDBC 2.0 fetch size API and the Oracle row prefetching API
237             in your application. You can use one or the other, but not both.
238         */

239         final ConnectionPoolDescriptor cpd = jcd.getConnectionPoolDescriptor();
240         final int cpdFetchSizeHint = cpd.getFetchSize();
241         if (cpdFetchSizeHint == 0 && ORA_ROW_PREFETCH_AVAILABLE)
242         {
243             try
244             {
245                 final String JavaDoc prefetchFromJcd;
246                 prefetchFromJcd = cpd.getJdbcProperties().getProperty("defaultRowPrefetch");
247                 if (prefetchFromJcd == null)
248                 {
249                     METHOD_SET_ROW_PREFETCH.invoke(oraConn, PARAM_ROW_PREFETCH_SIZE);
250                 }
251                 // Else, number of prefetched rows were set via Properties on Connection
252
}
253             catch (Exception JavaDoc e)
254             {
255                 if (logger.isDebugEnabled())
256                 {
257                     logger.debug("PlatformOracle9iImpl could not enable Oracle row pre-fetching."
258                                  + "Original/unwrapped connection classes="
259                                  + connClass.getName() + "/" + oraConn.getClass().getName());
260                 }
261             }
262         }
263     }
264
265     /**
266      * Performs platform-specific operations on each statement.
267      * @param stmt the statement just created
268      */

269     public void afterStatementCreate(Statement JavaDoc stmt)
270     {
271         // mkalen: do NOT call super#afterStatementCreate since escape processing for SQL92
272
// syntax is enabled by default for Oracle9i and higher, and explicit calls
273
// to setEscapeProcessing for PreparedStatements will make Oracle 10g JDBC-
274
// driver throw exceptions (and is functionally useless).
275
}
276
277     /**
278      * Try Oracle update batching and call setExecuteBatch or revert to
279      * JDBC update batching. See 12-2 Update Batching in the Oracle9i
280      * JDBC Developer's Guide and Reference.
281      * @param stmt the prepared statement to be used for batching
282      * @throws PlatformException upon JDBC failure
283      */

284     public void beforeBatch(PreparedStatement JavaDoc stmt) throws PlatformException
285     {
286         // Check for Oracle batching support
287
final Method JavaDoc methodSetExecuteBatch;
288         final Method JavaDoc methodSendBatch;
289         methodSetExecuteBatch = ClassHelper.getMethod(stmt, "setExecuteBatch", PARAM_TYPE_INTEGER);
290         methodSendBatch = ClassHelper.getMethod(stmt, "sendBatch", null);
291
292         final boolean statementBatchingSupported = methodSetExecuteBatch != null && methodSendBatch != null;
293         if (statementBatchingSupported)
294         {
295             try
296             {
297                 // Set number of statements per batch
298
methodSetExecuteBatch.invoke(stmt, PARAM_STATEMENT_BATCH_SIZE);
299                 m_batchStatementsInProgress.put(stmt, methodSendBatch);
300             }
301             catch (Exception JavaDoc e)
302             {
303                 throw new PlatformException(e.getLocalizedMessage(), e);
304             }
305         }
306         else
307         {
308             super.beforeBatch(stmt);
309         }
310     }
311
312     /**
313      * Try Oracle update batching and call executeUpdate or revert to
314      * JDBC update batching.
315      * @param stmt the statement beeing added to the batch
316      * @throws PlatformException upon JDBC failure
317      */

318     public void addBatch(PreparedStatement JavaDoc stmt) throws PlatformException
319     {
320         // Check for Oracle batching support
321
final boolean statementBatchingSupported = m_batchStatementsInProgress.containsKey(stmt);
322         if (statementBatchingSupported)
323         {
324             try
325             {
326                 stmt.executeUpdate();
327             }
328             catch (SQLException JavaDoc e)
329             {
330                 throw new PlatformException(e.getLocalizedMessage(), e);
331             }
332         }
333         else
334         {
335             super.addBatch(stmt);
336         }
337     }
338
339     /**
340      * Try Oracle update batching and call sendBatch or revert to
341      * JDBC update batching.
342      * @param stmt the batched prepared statement about to be executed
343      * @return always <code>null</code> if Oracle update batching is used,
344      * since it is impossible to dissolve total row count into distinct
345      * statement counts. If JDBC update batching is used, an int array is
346      * returned containing number of updated rows for each batched statement.
347      * @throws PlatformException upon JDBC failure
348      */

349     public int[] executeBatch(PreparedStatement JavaDoc stmt) throws PlatformException
350     {
351         // Check for Oracle batching support
352
final Method JavaDoc methodSendBatch = (Method JavaDoc) m_batchStatementsInProgress.remove(stmt);
353         final boolean statementBatchingSupported = methodSendBatch != null;
354
355         int[] retval = null;
356         if (statementBatchingSupported)
357         {
358             try
359             {
360                 // sendBatch() returns total row count as an Integer
361
methodSendBatch.invoke(stmt, null);
362             }
363             catch (Exception JavaDoc e)
364             {
365                 throw new PlatformException(e.getLocalizedMessage(), e);
366             }
367         }
368         else
369         {
370             retval = super.executeBatch(stmt);
371         }
372         return retval;
373     }
374
375     /** @see Platform#setObjectForStatement */
376     public void setObjectForStatement(PreparedStatement JavaDoc ps, int index, Object JavaDoc value, int sqlType) throws SQLException JavaDoc
377     {
378         // Check for Oracle JDBC-driver LOB-support
379
final Statement JavaDoc oraStmt;
380         final Connection JavaDoc oraConn;
381         final boolean oraLargeLobSupportAvailable;
382         if (sqlType == Types.CLOB || sqlType == Types.BLOB)
383         {
384             oraStmt = unwrapStatement(ps);
385             oraConn = unwrapConnection(ps.getConnection());
386             oraLargeLobSupportAvailable =
387                     oraStmt != null && oraConn != null &&
388                     (sqlType == Types.CLOB ? ORA_CLOB_HANDLING_AVAILABLE : ORA_BLOB_HANDLING_AVAILABLE);
389         }
390         else
391         {
392             oraStmt = null;
393             oraConn = null;
394             oraLargeLobSupportAvailable = false;
395         }
396
397         // Type-specific Oracle conversions
398
if (((sqlType == Types.VARBINARY) || (sqlType == Types.LONGVARBINARY)) && (value instanceof byte[]))
399         {
400             byte buf[] = (byte[]) value;
401             ByteArrayInputStream JavaDoc inputStream = new ByteArrayInputStream JavaDoc(buf);
402             super.changePreparedStatementResultSetType(ps);
403             ps.setBinaryStream(index, inputStream, buf.length);
404         }
405         else if (value instanceof Double JavaDoc)
406         {
407             // workaround for the bug in Oracle thin driver
408
ps.setDouble(index, ((Double JavaDoc) value).doubleValue());
409         }
410         else if (sqlType == Types.BIGINT && value instanceof Integer JavaDoc)
411         {
412             // workaround: Oracle thin driver problem when expecting long
413
ps.setLong(index, ((Integer JavaDoc) value).intValue());
414         }
415         else if (sqlType == Types.INTEGER && value instanceof Long JavaDoc)
416         {
417             ps.setLong(index, ((Long JavaDoc) value).longValue());
418         }
419         else if (sqlType == Types.CLOB && oraLargeLobSupportAvailable && value instanceof String JavaDoc)
420         {
421             // TODO: If using Oracle update batching with the thin driver, throw exception on 4k limit
422
try
423             {
424                 Object JavaDoc clob = Oracle9iLobHandler.createCLOBFromString(oraConn, (String JavaDoc) value);
425                 METHOD_SET_CLOB.invoke(oraStmt, new Object JavaDoc[]{new Integer JavaDoc(index), clob});
426             }
427             catch (Exception JavaDoc e)
428             {
429                 throw new SQLException JavaDoc(e.getLocalizedMessage());
430             }
431         }
432         else if (sqlType == Types.BLOB && oraLargeLobSupportAvailable && value instanceof byte[])
433         {
434             // TODO: If using Oracle update batching with the thin driver, throw exception on 2k limit
435
try
436             {
437                 Object JavaDoc blob = Oracle9iLobHandler.createBLOBFromByteArray(oraConn, (byte[]) value);
438                 METHOD_SET_BLOB.invoke(oraStmt, new Object JavaDoc[]{new Integer JavaDoc(index), blob});
439             }
440             catch (Exception JavaDoc e)
441             {
442                 throw new SQLException JavaDoc(e.getLocalizedMessage());
443             }
444         }
445         else
446         {
447             // Fall-through to superclass
448
super.setObjectForStatement(ps, index, value, sqlType);
449         }
450     }
451
452     /**
453      * Get join syntax type for this RDBMS.
454      *
455      * @return SQL92_NOPAREN_JOIN_SYNTAX
456      */

457     public byte getJoinSyntaxType()
458     {
459         return SQL92_NOPAREN_JOIN_SYNTAX;
460     }
461
462     /**
463      * Return an OracleConnection after trying to unwrap from known Connection wrappers.
464      * @param conn the connection to unwrap (if needed)
465      * @return OracleConnection or null if not able to unwrap
466      */

467     protected Connection JavaDoc unwrapConnection(Connection JavaDoc conn)
468     {
469         final Object JavaDoc unwrapped;
470         unwrapped = genericUnwrap(ORA_CONN_CLASS, conn, UNWRAP_CONN_METHOD_NAMES, UNWRAP_CONN_PARAM_TYPES);
471         if (unwrapped == null)
472         {
473             // mkalen: only log this as debug since it will be logged for every connection
474
// (ie only useful during development).
475
if (logger.isDebugEnabled())
476             {
477                 logger.debug("PlatformOracle9iImpl could not unwrap " + conn.getClass().getName() +
478                              ", Oracle-extensions disabled.");
479             }
480         }
481         return (Connection JavaDoc) unwrapped;
482     }
483
484     /**
485      * Return an OraclePreparedStatement after trying to unwrap from known Statement wrappers.
486      * @param ps the PreparedStatement to unwrap (if needed)
487      * @return OraclePreparedStatement or null if not able to unwrap
488      */

489     protected Statement JavaDoc unwrapStatement(Statement JavaDoc ps)
490     {
491         final Object JavaDoc unwrapped;
492         unwrapped = genericUnwrap(ORA_PS_CLASS, ps, UNWRAP_PS_METHOD_NAMES, UNWRAP_PS_PARAM_TYPES);
493         if (unwrapped == null)
494         {
495             // mkalen: only log this as debug since it will be logged for every connection
496
// (ie only useful during development).
497
if (logger.isDebugEnabled())
498             {
499                 logger.debug("PlatformOracle9iImpl could not unwrap " + ps.getClass().getName() +
500                              ", large CLOB/BLOB support disabled.");
501             }
502         }
503         return (Statement JavaDoc) unwrapped;
504     }
505     
506     protected Object JavaDoc genericUnwrap(Class JavaDoc classToMatch, Object JavaDoc toUnwrap,
507                                    String JavaDoc[] methodNameCandidates,
508                                    Class JavaDoc[][] methodTypeCandidates)
509     {
510         if (classToMatch == null)
511         {
512             return null;
513         }
514
515         Object JavaDoc unwrapped;
516         final Class JavaDoc psClass = toUnwrap.getClass();
517         if (classToMatch.isAssignableFrom(psClass))
518         {
519             return toUnwrap;
520         }
521         try
522         {
523             String JavaDoc methodName;
524             Class JavaDoc[] paramTypes;
525             Object JavaDoc[] args;
526             for (int i = 0; i < methodNameCandidates.length; i++)
527             {
528                 methodName = methodNameCandidates[i];
529                 paramTypes = methodTypeCandidates[i];
530                 final Method JavaDoc method = ClassHelper.getMethod(toUnwrap, methodName, paramTypes);
531                 if (method != null)
532                 {
533                     args = paramTypes == PARAM_TYPE_EMPTY ? PARAM_EMPTY : new Object JavaDoc[]{ toUnwrap };
534                     unwrapped = method.invoke(toUnwrap, args);
535                     if (unwrapped != null)
536                     {
537                         if (classToMatch.isAssignableFrom(unwrapped.getClass()))
538                         {
539                             return unwrapped;
540                         }
541                         // When using eg both DBCP and P6Spy we have to recursively unwrap
542
return genericUnwrap(classToMatch, unwrapped,
543                                 methodNameCandidates, methodTypeCandidates);
544                     }
545                 }
546             }
547         }
548         catch (Exception JavaDoc e)
549         {
550             // ignore
551
if (logger.isDebugEnabled())
552             {
553                 logger.debug("genericUnwrap failed", e);
554             }
555         }
556         return null;
557     }
558
559     /**
560      * Initializes static variables needed for Oracle-extensions and large BLOB/CLOB support.
561      */

562     protected void initOracleReflectedVars()
563     {
564         super.initOracleReflectedVars();
565         try
566         {
567             /*
568             Check for Oracle-specific classes, OracleConnection-specific
569             statement caching/row pre-fetch methods and Oracle BLOB/CLOB access methods.
570             We can do this in constructor in spite of possible mixing of instance being
571             able vs unable passed at runtime (since withouth these classes and methods
572             it's impossible to enable ORA-extensions at all even if instances are capable).
573             */

574             ORA_CONN_CLASS = ClassHelper.getClass("oracle.jdbc.OracleConnection", false);
575             ORA_PS_CLASS = ClassHelper.getClass("oracle.jdbc.OraclePreparedStatement", false);
576             ORA_CLOB_CLASS = ClassHelper.getClass("oracle.sql.CLOB", false);
577             ORA_BLOB_CLASS = ClassHelper.getClass("oracle.sql.BLOB", false);
578             PARAM_TYPE_INT_ORACLOB = new Class JavaDoc[]{ Integer.TYPE, ORA_CLOB_CLASS };
579             PARAM_TYPE_INT_ORABLOB = new Class JavaDoc[]{ Integer.TYPE, ORA_BLOB_CLASS };
580
581             // Index 0 reserved for Oracle 10g
582
UNWRAP_CONN_PARAM_TYPES[0] = new Class JavaDoc[]{ ORA_CONN_CLASS };
583
584             METHOD_SET_STATEMENT_CACHE_SIZE =
585                     ClassHelper.getMethod(ORA_CONN_CLASS, "setStatementCacheSize", PARAM_TYPE_INTEGER);
586             METHOD_SET_IMPLICIT_CACHING_ENABLED =
587                     ClassHelper.getMethod(ORA_CONN_CLASS, "setImplicitCachingEnabled", PARAM_TYPE_BOOLEAN);
588             METHOD_SET_ROW_PREFETCH = ClassHelper.getMethod(ORA_CONN_CLASS, "setDefaultRowPrefetch", PARAM_TYPE_INTEGER);
589             METHOD_SET_CLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setCLOB", PARAM_TYPE_INT_ORACLOB);
590             METHOD_SET_BLOB = ClassHelper.getMethod(ORA_PS_CLASS, "setBLOB", PARAM_TYPE_INT_ORABLOB);
591
592             ORA_STATEMENT_CACHING_AVAILABLE =
593                     METHOD_SET_STATEMENT_CACHE_SIZE != null && METHOD_SET_IMPLICIT_CACHING_ENABLED != null;
594             ORA_ROW_PREFETCH_AVAILABLE = METHOD_SET_ROW_PREFETCH != null;
595             ORA_CLOB_HANDLING_AVAILABLE = METHOD_SET_CLOB != null;
596             ORA_BLOB_HANDLING_AVAILABLE = METHOD_SET_BLOB != null;
597         }
598         catch (ClassNotFoundException JavaDoc e)
599         {
600             // ignore (we tried...)
601
}
602         // Isolated checks for other connection classes (OK when not found)
603
try
604         {
605             JBOSS_CONN_CLASS = ClassHelper.getClass(JBOSS_CONN_NAME, false);
606         }
607         catch (ClassNotFoundException JavaDoc e)
608         {
609             // ignore (no problem)
610
}
611     }
612
613 }
614
Popular Tags