Source Code Cross Referenced for PlatformOracle9iImpl.java in  » Database-ORM » db-ojb » org » apache » ojb » broker » platforms » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » db ojb » org.apache.ojb.broker.platforms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.ojb.broker.platforms;
002:
003:        /* Copyright 2003-2005 The Apache Software Foundation
004:         *
005:         * Licensed under the Apache License, Version 2.0 (the "License");
006:         * you may not use this file except in compliance with the License.
007:         * You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
019:        import org.apache.ojb.broker.metadata.ConnectionPoolDescriptor;
020:        import org.apache.ojb.broker.util.ClassHelper;
021:        import org.apache.ojb.broker.util.logging.Logger;
022:        import org.apache.ojb.broker.util.logging.LoggerFactory;
023:
024:        import java.io.ByteArrayInputStream;
025:        import java.lang.reflect.Method;
026:        import java.sql.Connection;
027:        import java.sql.PreparedStatement;
028:        import java.sql.SQLException;
029:        import java.sql.Statement;
030:        import java.sql.Types;
031:        import java.util.Collections;
032:        import java.util.Map;
033:        import java.util.WeakHashMap;
034:
035:        /**
036:         * This class is a concrete implementation of <code>Platform</code>. Provides
037:         * an implementation that works around some issues with Oracle in general and
038:         * Oracle 9i's Thin driver in particular.
039:         *
040:         * NOTE: When using BEA WebLogic and BLOB/CLOB datatypes, the physical connection will be
041:         * used causing WebLogic to mark it as "infected" and discard it when
042:         * the logicical connection is closed. You can change this behavior by setting the
043:         * RemoveInfectedConnectionsEnabled attribute on a connection pool.
044:         * see <a href="http://e-docs.bea.com/wls/docs81/jdbc/thirdparty.html#1043646">WebLogic docs</a>.
045:         *
046:         * Optimization: Oracle Batching (not standard JDBC batching)
047:         * see http://technet.oracle.com/products/oracle9i/daily/jun07.html
048:         *
049:         * Optimization: Oracle Prefetching
050:         * see http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html
051:         *
052:         * Optimization: Oracle Statement Caching
053:         * see http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html
054:         *
055:         * TODO: Optimization: use ROWNUM to minimize the effects of not having server side cursors
056:         * see http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:127412348064
057:         *
058:         * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
059:         * @author <a href="mailto:mkalen@apache.org">Martin Kal&eacute;n</a>
060:         * @author Contributions from: Erik Forkalsrud, Danilo Tommasina, Thierry Hanot, Don Lyon
061:         * @version CVS $Id: PlatformOracle9iImpl.java,v 1.13.2.9 2005/04/26 03:41:36 mkalen Exp $
062:         * @see Platform
063:         * @see PlatformDefaultImpl
064:         * @see PlatformOracleImpl
065:         */
066:        public class PlatformOracle9iImpl extends PlatformOracleImpl {
067:            private Logger logger = LoggerFactory
068:                    .getLogger(PlatformOracle9iImpl.class);
069:
070:            /**
071:             * Number of cached statements per connection,
072:             * when using implicit caching with OracleConnections.
073:             * Set in {@link #initializeJdbcConnection}.
074:             * @see <a href="http://www.apache.org/~mkalen/ojb/broker-tests.html">Profiling page</a>
075:             * for a discussion re sizing
076:             */
077:            protected static final int STATEMENT_CACHE_SIZE = 10;
078:            /**
079:             * Number of rows pre-fetched by the JDBC-driver for each executed query,
080:             * when using Oracle row pre-fetching with OracleConnections.
081:             * Set in {@link #initializeJdbcConnection}.
082:             * <p>
083:             * <em>Note</em>: this setting can be overridden by specifying a
084:             * connection-pool attribute with name="jdbc.defaultRowPrefetch".
085:             * Oracle JDBC-driver default value=10.
086:             */
087:            protected static final int ROW_PREFETCH_SIZE = 20;
088:
089:            // From Oracle9i JDBC Developer's Guide and Reference:
090:            // "Batch values between 5 and 30 tend to be the most effective."
091:            protected static final int STATEMENTS_PER_BATCH = 20;
092:            protected static Map m_batchStatementsInProgress = Collections
093:                    .synchronizedMap(new WeakHashMap(STATEMENTS_PER_BATCH));
094:
095:            protected static final Class[] PARAM_TYPE_EMPTY = {};
096:            protected static final Class[] PARAM_TYPE_INTEGER = { Integer.TYPE };
097:            protected static final Class[] PARAM_TYPE_BOOLEAN = { Boolean.TYPE };
098:            protected static final Class[] PARAM_TYPE_STRING = { String.class };
099:
100:            protected static final Object[] PARAM_EMPTY = new Object[] {};
101:            protected static final Object[] PARAM_STATEMENT_CACHE_SIZE = new Object[] { new Integer(
102:                    STATEMENT_CACHE_SIZE) };
103:            protected static final Object[] PARAM_ROW_PREFETCH_SIZE = new Object[] { new Integer(
104:                    ROW_PREFETCH_SIZE) };
105:            protected static final Object[] PARAM_STATEMENT_BATCH_SIZE = new Object[] { new Integer(
106:                    STATEMENTS_PER_BATCH) };
107:            protected static final Object[] PARAM_BOOLEAN_TRUE = new Object[] { Boolean.TRUE };
108:
109:            protected static final String JBOSS_CONN_NAME = "org.jboss.resource.adapter.jdbc.WrappedConnection";
110:            protected static Class JBOSS_CONN_CLASS = null;
111:
112:            protected static Class ORA_CONN_CLASS;
113:            protected static Class ORA_PS_CLASS;
114:            protected static Class ORA_CLOB_CLASS;
115:            protected static Class ORA_BLOB_CLASS;
116:            protected static Class[] PARAM_TYPE_INT_ORACLOB;
117:            protected static Class[] PARAM_TYPE_INT_ORABLOB;
118:            protected static Method METHOD_SET_STATEMENT_CACHE_SIZE;
119:            protected static Method METHOD_SET_IMPLICIT_CACHING_ENABLED;
120:            protected static Method METHOD_SET_ROW_PREFETCH;
121:            protected static Method METHOD_SET_BLOB = null;
122:            protected static Method METHOD_SET_CLOB = null;
123:            protected static boolean ORA_STATEMENT_CACHING_AVAILABLE;
124:            protected static boolean ORA_ROW_PREFETCH_AVAILABLE;
125:            protected static boolean ORA_CLOB_HANDLING_AVAILABLE;
126:            protected static boolean ORA_BLOB_HANDLING_AVAILABLE;
127:
128:            /** Method names used by {@link #unwrapConnection}. */
129:            protected static final String UNWRAP_CONN_METHOD_NAMES[] = {
130:                    "unwrapCompletely" /* Oracle 10g */,
131:                    "getInnermostDelegate" /* Commons DBCP */,
132:                    "getUnderlyingConnection" /* JBoss */,
133:                    "getVendorConnection" /* BEA WebLogic */, "getJDBC" /* P6Spy */
134:            };
135:            /**
136:             * Method parameter signature used by {@link #unwrapConnection} for corresponding
137:             * {@link #UNWRAP_CONN_METHOD_NAMES}-index.
138:             * If signature is not {@link #PARAM_TYPE_EMPTY}, the actual connection object
139:             * will be passed at runtime. (NB: Requires special handling of param type in constructor.)
140:             */
141:            protected static final Class[][] UNWRAP_CONN_PARAM_TYPES = {
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 */, PARAM_TYPE_EMPTY /* P6Spy */
146:            };
147:            /** Method names used by {@link #unwrapStatement}. */
148:            protected static final String UNWRAP_PS_METHOD_NAMES[] = {
149:                    "getInnermostDelegate" /* Commons DBCP */,
150:                    "getUnderlyingStatement" /* JBoss */, "getJDBC" /* P6Spy */
151:            };
152:            /**
153:             * Method parameter signature used by {@link #unwrapStatement} for corresponding
154:             * {@link #UNWRAP_PS_METHOD_NAMES}-index.
155:             * If signature is not {@link #PARAM_TYPE_EMPTY}, the actual Statement object
156:             * will be passed at runtime. (NB: Requires special handling of param type in constructor.)
157:             */
158:            protected static final Class[][] UNWRAP_PS_PARAM_TYPES = {
159:                    PARAM_TYPE_EMPTY /* Commons DBCP */,
160:                    PARAM_TYPE_EMPTY /* JBoss */, PARAM_TYPE_EMPTY /* P6Spy */
161:            };
162:
163:            /**
164:             * Default constructor.
165:             */
166:            public PlatformOracle9iImpl() {
167:                super ();
168:            }
169:
170:            /**
171:             * Enables Oracle statement caching and row prefetching if supported by the JDBC-driver.
172:             * @param jcd the OJB <code>JdbcConnectionDescriptor</code> (metadata) for the connection to be initialized
173:             * @param conn the <code>Connection</code>-object (physical) to be initialized
174:             * @see PlatformDefaultImpl#initializeJdbcConnection
175:             * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/jdbc30/StmtCacheSample/Readme.html">
176:             * Oracle TechNet Statement Caching Sample</a>
177:             * @see <a href="http://otn.oracle.com/sample_code/tech/java/sqlj_jdbc/files/advanced/RowPrefetchSample/Readme.html">
178:             * Oracle TechNet Row Pre-fetch Sample<a>
179:             */
180:            public void initializeJdbcConnection(
181:                    final JdbcConnectionDescriptor jcd, final Connection conn)
182:                    throws PlatformException {
183:                // Do all the generic initialization in PlatformDefaultImpl first
184:                super .initializeJdbcConnection(jcd, conn);
185:
186:                // Check for managed environments known to reject Oracle extension at this level
187:                // (saves us from trying to unwrap just to catch exceptions next)
188:                final Class connClass = conn.getClass();
189:                if (JBOSS_CONN_CLASS != null
190:                        && JBOSS_CONN_CLASS.isAssignableFrom(connClass)) {
191:                    if (logger.isDebugEnabled()) {
192:                        logger
193:                                .debug("JBoss detected, Oracle Connection tuning left to J2EE container.");
194:                    }
195:                    return;
196:                }
197:
198:                // Check if this is a wrapped connection and if so unwrap it
199:                final Connection oraConn = unwrapConnection(conn);
200:                if (oraConn == null) {
201:                    return;
202:                }
203:
204:                // At this point we know that we have an OracleConnection instance and can thus
205:                // try to invoke methods via reflection (if available)
206:                if (ORA_STATEMENT_CACHING_AVAILABLE) {
207:                    try {
208:                        // Set number of cached statements and enable implicit caching
209:                        METHOD_SET_STATEMENT_CACHE_SIZE.invoke(oraConn,
210:                                PARAM_STATEMENT_CACHE_SIZE);
211:                        METHOD_SET_IMPLICIT_CACHING_ENABLED.invoke(oraConn,
212:                                PARAM_BOOLEAN_TRUE);
213:                    } catch (Exception e) {
214:                        if (logger.isDebugEnabled()) {
215:                            logger
216:                                    .debug("PlatformOracle9iImpl could not enable Oracle statement caching."
217:                                            + " Original/unwrapped connection classes="
218:                                            + connClass.getName()
219:                                            + "/"
220:                                            + oraConn.getClass().getName());
221:                        }
222:                    }
223:                }
224:
225:                /*
226:                mkalen: Note from the Oracle documentation:
227:                    Do not mix the JDBC 2.0 fetch size API and the Oracle row prefetching API
228:                    in your application. You can use one or the other, but not both.
229:                 */
230:                final ConnectionPoolDescriptor cpd = jcd
231:                        .getConnectionPoolDescriptor();
232:                final int cpdFetchSizeHint = cpd.getFetchSize();
233:                if (cpdFetchSizeHint == 0 && ORA_ROW_PREFETCH_AVAILABLE) {
234:                    try {
235:                        final String prefetchFromJcd;
236:                        prefetchFromJcd = cpd.getJdbcProperties().getProperty(
237:                                "defaultRowPrefetch");
238:                        if (prefetchFromJcd == null) {
239:                            METHOD_SET_ROW_PREFETCH.invoke(oraConn,
240:                                    PARAM_ROW_PREFETCH_SIZE);
241:                        }
242:                        // Else, number of prefetched rows were set via Properties on Connection
243:                    } catch (Exception e) {
244:                        if (logger.isDebugEnabled()) {
245:                            logger
246:                                    .debug("PlatformOracle9iImpl could not enable Oracle row pre-fetching."
247:                                            + "Original/unwrapped connection classes="
248:                                            + connClass.getName()
249:                                            + "/"
250:                                            + oraConn.getClass().getName());
251:                        }
252:                    }
253:                }
254:            }
255:
256:            /**
257:             * Performs platform-specific operations on each statement.
258:             * @param stmt the statement just created
259:             */
260:            public void afterStatementCreate(Statement stmt) {
261:                // mkalen:  do NOT call super#afterStatementCreate since escape processing for SQL92
262:                //          syntax is enabled by default for Oracle9i and higher, and explicit calls
263:                //          to setEscapeProcessing for PreparedStatements will make Oracle 10g JDBC-
264:                //          driver throw exceptions (and is functionally useless).
265:            }
266:
267:            /**
268:             * Try Oracle update batching and call setExecuteBatch or revert to
269:             * JDBC update batching. See 12-2 Update Batching in the Oracle9i
270:             * JDBC Developer's Guide and Reference.
271:             * @param stmt the prepared statement to be used for batching
272:             * @throws PlatformException upon JDBC failure
273:             */
274:            public void beforeBatch(PreparedStatement stmt)
275:                    throws PlatformException {
276:                // Check for Oracle batching support
277:                final Method methodSetExecuteBatch;
278:                final Method methodSendBatch;
279:                methodSetExecuteBatch = ClassHelper.getMethod(stmt,
280:                        "setExecuteBatch", PARAM_TYPE_INTEGER);
281:                methodSendBatch = ClassHelper
282:                        .getMethod(stmt, "sendBatch", null);
283:
284:                final boolean statementBatchingSupported = methodSetExecuteBatch != null
285:                        && methodSendBatch != null;
286:                if (statementBatchingSupported) {
287:                    try {
288:                        // Set number of statements per batch
289:                        methodSetExecuteBatch.invoke(stmt,
290:                                PARAM_STATEMENT_BATCH_SIZE);
291:                        m_batchStatementsInProgress.put(stmt, methodSendBatch);
292:                    } catch (Exception e) {
293:                        throw new PlatformException(e.getLocalizedMessage(), e);
294:                    }
295:                } else {
296:                    super .beforeBatch(stmt);
297:                }
298:            }
299:
300:            /**
301:             * Try Oracle update batching and call executeUpdate or revert to
302:             * JDBC update batching.
303:             * @param stmt the statement beeing added to the batch
304:             * @throws PlatformException upon JDBC failure
305:             */
306:            public void addBatch(PreparedStatement stmt)
307:                    throws PlatformException {
308:                // Check for Oracle batching support
309:                final boolean statementBatchingSupported = m_batchStatementsInProgress
310:                        .containsKey(stmt);
311:                if (statementBatchingSupported) {
312:                    try {
313:                        stmt.executeUpdate();
314:                    } catch (SQLException e) {
315:                        throw new PlatformException(e.getLocalizedMessage(), e);
316:                    }
317:                } else {
318:                    super .addBatch(stmt);
319:                }
320:            }
321:
322:            /**
323:             * Try Oracle update batching and call sendBatch or revert to
324:             * JDBC update batching.
325:             * @param stmt the batched prepared statement about to be executed
326:             * @return always <code>null</code> if Oracle update batching is used,
327:             * since it is impossible to dissolve total row count into distinct
328:             * statement counts. If JDBC update batching is used, an int array is
329:             * returned containing number of updated rows for each batched statement.
330:             * @throws PlatformException upon JDBC failure
331:             */
332:            public int[] executeBatch(PreparedStatement stmt)
333:                    throws PlatformException {
334:                // Check for Oracle batching support
335:                final Method methodSendBatch = (Method) m_batchStatementsInProgress
336:                        .remove(stmt);
337:                final boolean statementBatchingSupported = methodSendBatch != null;
338:
339:                int[] retval = null;
340:                if (statementBatchingSupported) {
341:                    try {
342:                        // sendBatch() returns total row count as an Integer
343:                        methodSendBatch.invoke(stmt, null);
344:                    } catch (Exception e) {
345:                        throw new PlatformException(e.getLocalizedMessage(), e);
346:                    }
347:                } else {
348:                    retval = super .executeBatch(stmt);
349:                }
350:                return retval;
351:            }
352:
353:            /** @see Platform#setObjectForStatement */
354:            public void setObjectForStatement(PreparedStatement ps, int index,
355:                    Object value, int sqlType) throws SQLException {
356:                // Check for Oracle JDBC-driver LOB-support
357:                final Statement oraStmt;
358:                final Connection oraConn;
359:                final boolean oraLargeLobSupportAvailable;
360:                if (sqlType == Types.CLOB || sqlType == Types.BLOB) {
361:                    oraStmt = unwrapStatement(ps);
362:                    oraConn = unwrapConnection(ps.getConnection());
363:                    oraLargeLobSupportAvailable = oraStmt != null
364:                            && oraConn != null
365:                            && (sqlType == Types.CLOB ? ORA_CLOB_HANDLING_AVAILABLE
366:                                    : ORA_BLOB_HANDLING_AVAILABLE);
367:                } else {
368:                    oraStmt = null;
369:                    oraConn = null;
370:                    oraLargeLobSupportAvailable = false;
371:                }
372:
373:                // Type-specific Oracle conversions
374:                if (((sqlType == Types.VARBINARY) || (sqlType == Types.LONGVARBINARY))
375:                        && (value instanceof  byte[])) {
376:                    byte buf[] = (byte[]) value;
377:                    ByteArrayInputStream inputStream = new ByteArrayInputStream(
378:                            buf);
379:                    super .changePreparedStatementResultSetType(ps);
380:                    ps.setBinaryStream(index, inputStream, buf.length);
381:                } else if (value instanceof  Double) {
382:                    // workaround for the bug in Oracle thin driver
383:                    ps.setDouble(index, ((Double) value).doubleValue());
384:                } else if (sqlType == Types.BIGINT && value instanceof  Integer) {
385:                    // workaround: Oracle thin driver problem when expecting long
386:                    ps.setLong(index, ((Integer) value).intValue());
387:                } else if (sqlType == Types.INTEGER && value instanceof  Long) {
388:                    ps.setLong(index, ((Long) value).longValue());
389:                } else if (sqlType == Types.CLOB && oraLargeLobSupportAvailable
390:                        && value instanceof  String) {
391:                    // TODO: If using Oracle update batching with the thin driver, throw exception on 4k limit
392:                    try {
393:                        Object clob = Oracle9iLobHandler.createCLOBFromString(
394:                                oraConn, (String) value);
395:                        METHOD_SET_CLOB.invoke(oraStmt, new Object[] {
396:                                new Integer(index), clob });
397:                    } catch (Exception e) {
398:                        throw new SQLException(e.getLocalizedMessage());
399:                    }
400:                } else if (sqlType == Types.BLOB && oraLargeLobSupportAvailable
401:                        && value instanceof  byte[]) {
402:                    // TODO: If using Oracle update batching with the thin driver, throw exception on 2k limit
403:                    try {
404:                        Object blob = Oracle9iLobHandler
405:                                .createBLOBFromByteArray(oraConn,
406:                                        (byte[]) value);
407:                        METHOD_SET_BLOB.invoke(oraStmt, new Object[] {
408:                                new Integer(index), blob });
409:                    } catch (Exception e) {
410:                        throw new SQLException(e.getLocalizedMessage());
411:                    }
412:                } else {
413:                    // Fall-through to superclass
414:                    super .setObjectForStatement(ps, index, value, sqlType);
415:                }
416:            }
417:
418:            /**
419:             * Get join syntax type for this RDBMS.
420:             *
421:             * @return SQL92_NOPAREN_JOIN_SYNTAX
422:             */
423:            public byte getJoinSyntaxType() {
424:                return SQL92_NOPAREN_JOIN_SYNTAX;
425:            }
426:
427:            /**
428:             * Return an OracleConnection after trying to unwrap from known Connection wrappers.
429:             * @param conn the connection to unwrap (if needed)
430:             * @return OracleConnection or null if not able to unwrap
431:             */
432:            protected Connection unwrapConnection(Connection conn) {
433:                final Object unwrapped;
434:                unwrapped = genericUnwrap(ORA_CONN_CLASS, conn,
435:                        UNWRAP_CONN_METHOD_NAMES, UNWRAP_CONN_PARAM_TYPES);
436:                if (unwrapped == null) {
437:                    // mkalen:  only log this as debug since it will be logged for every connection
438:                    //          (ie only useful during development).
439:                    if (logger.isDebugEnabled()) {
440:                        logger.debug("PlatformOracle9iImpl could not unwrap "
441:                                + conn.getClass().getName()
442:                                + ", Oracle-extensions disabled.");
443:                    }
444:                }
445:                return (Connection) unwrapped;
446:            }
447:
448:            /**
449:             * Return an OraclePreparedStatement after trying to unwrap from known Statement wrappers.
450:             * @param ps the PreparedStatement to unwrap (if needed)
451:             * @return OraclePreparedStatement or null if not able to unwrap
452:             */
453:            protected Statement unwrapStatement(Statement ps) {
454:                final Object unwrapped;
455:                unwrapped = genericUnwrap(ORA_PS_CLASS, ps,
456:                        UNWRAP_PS_METHOD_NAMES, UNWRAP_PS_PARAM_TYPES);
457:                if (unwrapped == null) {
458:                    // mkalen:  only log this as debug since it will be logged for every connection
459:                    //          (ie only useful during development).
460:                    if (logger.isDebugEnabled()) {
461:                        logger.debug("PlatformOracle9iImpl could not unwrap "
462:                                + ps.getClass().getName()
463:                                + ", large CLOB/BLOB support disabled.");
464:                    }
465:                }
466:                return (Statement) unwrapped;
467:            }
468:
469:            protected Object genericUnwrap(Class classToMatch, Object toUnwrap,
470:                    String[] methodNameCandidates,
471:                    Class[][] methodTypeCandidates) {
472:                if (classToMatch == null) {
473:                    return null;
474:                }
475:
476:                Object unwrapped;
477:                final Class psClass = toUnwrap.getClass();
478:                if (classToMatch.isAssignableFrom(psClass)) {
479:                    return toUnwrap;
480:                }
481:                try {
482:                    String methodName;
483:                    Class[] paramTypes;
484:                    Object[] args;
485:                    for (int i = 0; i < methodNameCandidates.length; i++) {
486:                        methodName = methodNameCandidates[i];
487:                        paramTypes = methodTypeCandidates[i];
488:                        final Method method = ClassHelper.getMethod(toUnwrap,
489:                                methodName, paramTypes);
490:                        if (method != null) {
491:                            args = paramTypes == PARAM_TYPE_EMPTY ? PARAM_EMPTY
492:                                    : new Object[] { toUnwrap };
493:                            unwrapped = method.invoke(toUnwrap, args);
494:                            if (unwrapped != null) {
495:                                if (classToMatch.isAssignableFrom(unwrapped
496:                                        .getClass())) {
497:                                    return unwrapped;
498:                                }
499:                                // When using eg both DBCP and P6Spy we have to recursively unwrap
500:                                return genericUnwrap(classToMatch, unwrapped,
501:                                        methodNameCandidates,
502:                                        methodTypeCandidates);
503:                            }
504:                        }
505:                    }
506:                } catch (Exception e) {
507:                    // ignore
508:                    if (logger.isDebugEnabled()) {
509:                        logger.debug("genericUnwrap failed", e);
510:                    }
511:                }
512:                return null;
513:            }
514:
515:            /**
516:             * Initializes static variables needed for Oracle-extensions and large BLOB/CLOB support.
517:             */
518:            protected void initOracleReflectedVars() {
519:                super .initOracleReflectedVars();
520:                try {
521:                    /*
522:                    Check for Oracle-specific classes, OracleConnection-specific
523:                    statement caching/row pre-fetch methods and Oracle BLOB/CLOB access methods.
524:                    We can do this in constructor in spite of possible mixing of instance being
525:                    able vs unable passed at runtime (since withouth these classes and methods
526:                    it's impossible to enable ORA-extensions at all even if instances are capable).
527:                     */
528:                    ORA_CONN_CLASS = ClassHelper.getClass(
529:                            "oracle.jdbc.OracleConnection", false);
530:                    ORA_PS_CLASS = ClassHelper.getClass(
531:                            "oracle.jdbc.OraclePreparedStatement", false);
532:                    ORA_CLOB_CLASS = ClassHelper.getClass("oracle.sql.CLOB",
533:                            false);
534:                    ORA_BLOB_CLASS = ClassHelper.getClass("oracle.sql.BLOB",
535:                            false);
536:                    PARAM_TYPE_INT_ORACLOB = new Class[] { Integer.TYPE,
537:                            ORA_CLOB_CLASS };
538:                    PARAM_TYPE_INT_ORABLOB = new Class[] { Integer.TYPE,
539:                            ORA_BLOB_CLASS };
540:
541:                    // Index 0 reserved for Oracle 10g
542:                    UNWRAP_CONN_PARAM_TYPES[0] = new Class[] { ORA_CONN_CLASS };
543:
544:                    METHOD_SET_STATEMENT_CACHE_SIZE = ClassHelper.getMethod(
545:                            ORA_CONN_CLASS, "setStatementCacheSize",
546:                            PARAM_TYPE_INTEGER);
547:                    METHOD_SET_IMPLICIT_CACHING_ENABLED = ClassHelper
548:                            .getMethod(ORA_CONN_CLASS,
549:                                    "setImplicitCachingEnabled",
550:                                    PARAM_TYPE_BOOLEAN);
551:                    METHOD_SET_ROW_PREFETCH = ClassHelper.getMethod(
552:                            ORA_CONN_CLASS, "setDefaultRowPrefetch",
553:                            PARAM_TYPE_INTEGER);
554:                    METHOD_SET_CLOB = ClassHelper.getMethod(ORA_PS_CLASS,
555:                            "setCLOB", PARAM_TYPE_INT_ORACLOB);
556:                    METHOD_SET_BLOB = ClassHelper.getMethod(ORA_PS_CLASS,
557:                            "setBLOB", PARAM_TYPE_INT_ORABLOB);
558:
559:                    ORA_STATEMENT_CACHING_AVAILABLE = METHOD_SET_STATEMENT_CACHE_SIZE != null
560:                            && METHOD_SET_IMPLICIT_CACHING_ENABLED != null;
561:                    ORA_ROW_PREFETCH_AVAILABLE = METHOD_SET_ROW_PREFETCH != null;
562:                    ORA_CLOB_HANDLING_AVAILABLE = METHOD_SET_CLOB != null;
563:                    ORA_BLOB_HANDLING_AVAILABLE = METHOD_SET_BLOB != null;
564:                } catch (ClassNotFoundException e) {
565:                    // ignore (we tried...)
566:                }
567:                // Isolated checks for other connection classes (OK when not found)
568:                try {
569:                    JBOSS_CONN_CLASS = ClassHelper.getClass(JBOSS_CONN_NAME,
570:                            false);
571:                } catch (ClassNotFoundException e) {
572:                    // ignore (no problem)
573:                }
574:            }
575:
576:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.