Author: arminw
Date: Fri Mar 10 17:03:47 2006
New Revision: 384976
URL: http://svn.apache.org/viewcvs?rev=384976&view=rev
Log:
initial check in
Added:
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/UnwrapHelper.java
db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/UnwrapHelperTest.java
Added:
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/UnwrapHelper.java
URL:
http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/UnwrapHelper.java?rev=384976&view=auto
==============================================================================
---
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/UnwrapHelper.java
(added)
+++
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/util/UnwrapHelper.java
Fri Mar 10 17:03:47 2006
@@ -0,0 +1,284 @@
+package org.apache.ojb.broker.util;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.ojb.broker.util.logging.Logger;
+import org.apache.ojb.broker.util.logging.LoggerFactory;
+
+/**
+ * This a helper class make available methods to unwrap [EMAIL PROTECTED]
java.sql.Connection} and
+ * [EMAIL PROTECTED] java.sql.PreparedStatement} instances of connection-pool
libraries,
+ * application server and other.
+ *
+ * @version $Id: $
+ */
+public class UnwrapHelper
+{
+ private Logger log = LoggerFactory.getLogger(UnwrapHelper.class);
+
+ private static final int UNWARP_CONNECTION = 1;
+ private static final int UNWARP_STATEMENT = 2;
+ public static final Object[] EMPTY_ARG = new Object[]{};
+ public static final Class[] PARAM_TYPE_EMPTY = new Class[]{};
+ public static final Integer TYPE_METHOD = new Integer(5);
+ public static final Integer TYPE_FIELD = new Integer(6);
+ /**
+ * Represents the information of how to unwrap wrapped [EMAIL PROTECTED]
java.sql.Connection}
+ * and [EMAIL PROTECTED] java.sql.PreparedStatement} instances of popular
connection-pool libraries,
+ * application server and other libraries.
+ * <p/>
+ * The array have to be a [n][5] object array. The following arguments
will be expected:
+ * <ul>
+ * <li>unwrapInfo[i][0] = the vendor, product name as [EMAIL PROTECTED]
String}</li>
+ *
+ * <li>unwrapInfo[i][1] = use [EMAIL PROTECTED] #TYPE_METHOD} if access to
the wrapped connection via method call
+ * is possible, use [EMAIL PROTECTED] #TYPE_FIELD} if access to a field
can be used</li>
+ * <li>unwrapInfo[i][2] = use [EMAIL PROTECTED] #PARAM_TYPE_EMPTY} if a
no-arg method call is needed, otherwise
+ * specify the argument type class array (at runtime)</li>
+ * <li>unwrapInfo[i][3] = the name of the method/field to lookup the
wrapped connection
+ * as [EMAIL PROTECTED] String}</li>
+ *
+ * <li>unwrapInfo[i][4] = use [EMAIL PROTECTED] #TYPE_METHOD} if access to
the wrapped statment via method call
+ * is possible, use [EMAIL PROTECTED] #TYPE_FIELD} if access to a field
can be used</li></li>
+ * <li>unwrapInfo[i][5] = use [EMAIL PROTECTED] #PARAM_TYPE_EMPTY} if a
no-arg method call is needed, otherwise
+ * specify the argument type class array (at runtime)</li>
+ * <li>unwrapInfo[i][6] = the name of the method/field to unwrap the
statement</li>
+ * </ul>
+ * Example:
+ * <pre>
+ * protected static Object[][] unwrapInfo = {
+ * {"common-DBCP", TYPE_METHOD, PARAM_TYPE_EMPTY, "getInnermostDelegate",
TYPE_METHOD, PARAM_TYPE_EMPTY, "getInnermostDelegate"},
+ * {"enhydra.XAPool", TYPE_FIELD, null, "con", TYPE_FIELD, null, "ps"},
+ * ....
+ * </pre>
+ */
+ protected Object[][] unwrapInfo = {
+ {"common-DBCP", TYPE_METHOD, PARAM_TYPE_EMPTY, "getInnermostDelegate",
TYPE_METHOD, PARAM_TYPE_EMPTY, "getInnermostDelegate"},
+ {"JBoss", TYPE_METHOD, PARAM_TYPE_EMPTY, "getUnderlyingConnection",
TYPE_METHOD, PARAM_TYPE_EMPTY, "getUnderlyingStatement"},
+ {"enhydra.XAPool", TYPE_FIELD, null, "con", TYPE_FIELD, null, "ps"},
+ {"BEA Weblogic", TYPE_METHOD, PARAM_TYPE_EMPTY, "getVendorConnection",
null, null, null},
+ {"p6spy", TYPE_METHOD, PARAM_TYPE_EMPTY, "getJDBC", TYPE_METHOD,
PARAM_TYPE_EMPTY, "getJDBC"}
+ };
+
+ /**
+ * Add a new unwrap pattern. The object array of length 7 have to be
+ * the following arguments:
+ * <ul>
+ * <li>pattern[0] = the vendor, product name as [EMAIL PROTECTED]
String}</li>
+ *
+ * <li>pattern[1] = use [EMAIL PROTECTED] #TYPE_METHOD} if access to the
wrapped connection via method call
+ * is possible, use [EMAIL PROTECTED] #TYPE_FIELD} if access to a field
can be used</li>
+ * <li>pattern[2] = use [EMAIL PROTECTED] #PARAM_TYPE_EMPTY} if a no-arg
method call is needed, otherwise
+ * specify the argument type class array (at runtime)</li>
+ * <li>pattern[3] = the name of the method/field to lookup the wrapped
connection
+ * as [EMAIL PROTECTED] String}</li>
+ *
+ * <li>pattern[4] = use [EMAIL PROTECTED] #TYPE_METHOD} if access to the
wrapped statment via method call
+ * is possible, use [EMAIL PROTECTED] #TYPE_FIELD} if access to a field
can be used</li></li>
+ * <li>pattern[5] = use [EMAIL PROTECTED] #PARAM_TYPE_EMPTY} if a no-arg
method call is needed, otherwise
+ * specify the argument type class array (at runtime)</li>
+ * <li>pattern[6] = the name of the method/field to unwrap the statement
as [EMAIL PROTECTED] String}</li>
+ * </ul>
+ * Here is an example how to use this method:
+ * <pre>
+ * Object test = new Object[]{"common-DBCP", TYPE_METHOD,
PARAM_TYPE_EMPTY, "getInnermostDelegate",
+ * TYPE_METHOD, PARAM_TYPE_EMPTY, "getInnermostDelegate"};
+ * unwarpHelper.addUnwrapPattern(test);
+ * </pre>
+ *
+ * @param pattern The unwrap pattern array.
+ */
+ public void addUnwrapPattern(Object[] pattern)
+ {
+ Object[][] tmp = new Object[][]{pattern};
+ unwrapInfo = (Object[][]) ArrayUtils.addAll(unwrapInfo, tmp);
+ }
+
+ /** Return the current unwrap patterns. */
+ public Object[][] getUnwrapPatterns()
+ {
+ return unwrapInfo;
+ }
+
+ protected Object genericUnwrap(final Class classToMatch, final Object
toUnwrap, int type)
+ {
+ if(classToMatch == null)
+ {
+ return null;
+ }
+
+ Object unwrapped = null;
+ if(classToMatch.isAssignableFrom(toUnwrap.getClass()))
+ {
+ return toUnwrap;
+ }
+ int i = 0;
+ try
+ {
+ for(; i < unwrapInfo.length; i++)
+ {
+ Object[] info = unwrapInfo[i];
+ if(type == UNWARP_CONNECTION && info[3] != null)
+ {
+ unwrapped = reflectObject(toUnwrap,
info[1].equals(TYPE_METHOD), (Class[]) info[2], (String) info[3]);
+ }
+ else if(type == UNWARP_STATEMENT && info[6] != null)
+ {
+ unwrapped = reflectObject(toUnwrap,
info[4].equals(TYPE_METHOD), (Class[]) info[5], (String) info[6]);
+ }
+ if(unwrapped != null)
+ {
+ if(classToMatch.isAssignableFrom(unwrapped.getClass()))
+ {
+ // Bingo!
+ }
+ else
+ {
+ // When using e.g. both DBCP and P6Spy we have to
recursively unwrap
+ unwrapped = genericUnwrap(classToMatch, unwrapped,
type);
+ }
+ break;
+ }
+ }
+ }
+ catch(Exception e)
+ {
+ //e.printStackTrace();
+ // ignore
+ if(log.isDebugEnabled())
+ {
+ if(type == UNWARP_CONNECTION)
+ {
+ log.debug("Unwrap of connection failed using unwrap rule
for " + unwrapInfo[i][0] + " connections", e);
+ }
+ else
+ {
+ log.debug("Unwrap of prepared stmt failed using unwrap
rule for " + unwrapInfo[i][0] + " statements", e);
+ }
+ }
+ }
+ return unwrapped;
+ }
+
+ private Object reflectObject(Object source, boolean methodType, Class[]
paramType, String fieldOrMethodName) throws Exception
+ {
+ Object unwrapped = null;
+ if(methodType)
+ {
+ final Method method;
+ method = ClassHelper.getMethod(source, fieldOrMethodName,
paramType);
+ if(method != null)
+ {
+ if(!method.isAccessible())
+ {
+ method.setAccessible(true);
+ }
+ unwrapped = method.invoke(source, EMPTY_ARG);
+ }
+ }
+ else
+ {
+ final Field field;
+ field = ClassHelper.getField(source.getClass(), fieldOrMethodName);
+ if(field != null)
+ {
+ if(!field.isAccessible())
+ {
+ field.setAccessible(true);
+ }
+ unwrapped = field.get(source);
+ }
+ }
+ return unwrapped;
+ }
+
+ /**
+ * Rekursive unwrap specified [EMAIL PROTECTED] java.sql.Connection} till
target
+ * class is matched.
+ *
+ * @param target The target class (subclass of [EMAIL PROTECTED]
java.sql.Connection} is mandatory).
+ * @param source The wrapped connection instance.
+ * @return The unwrapped connection or <em>null</em> if no match is
possible.
+ */
+ public Connection unwrapConnection(Class target, Connection source)
+ {
+ Connection result = (Connection) genericUnwrap(target, source,
UNWARP_CONNECTION);
+ if(result == null && log.isDebugEnabled())
+ {
+ log.debug("Could not unwrap source " + source.getClass().getName()
+ + " to target class " + target.getName());
+ }
+ return result;
+ }
+
+ /**
+ * Rekursive unwrap specified [EMAIL PROTECTED] java.sql.Statement} till
target
+ * class is matched.
+ *
+ * @param target The target class (subclass of [EMAIL PROTECTED]
java.sql.PreparedStatement} is mandatory).
+ * @param source The wrapped statement instance.
+ * @return The unwrapped statement or <em>null</em> if no match is
possible.
+ */
+ public Statement unwrapStatement(Class target, Statement source)
+ {
+ Statement result = (Statement) genericUnwrap(target, source,
UNWARP_STATEMENT);
+ if(result == null && log.isDebugEnabled())
+ {
+ log.debug("Could not unwrap source " + source.getClass().getName()
+ + " to target class " + target.getName());
+ }
+ return result;
+ }
+
+ /**
+ * Rekursive unwrap specified [EMAIL PROTECTED] java.sql.Statement} till
target
+ * class is matched.
+ *
+ * @param target The target class (subclass of [EMAIL PROTECTED]
java.sql.PreparedStatement} is mandatory).
+ * @param source The wrapped statement instance.
+ * @return The unwrapped statement or <em>null</em> if no match is
possible.
+ */
+ public PreparedStatement unwrapStatement(Class target, PreparedStatement
source)
+ {
+ PreparedStatement result = (PreparedStatement) genericUnwrap(target,
source, UNWARP_STATEMENT);
+ if(result == null && log.isDebugEnabled())
+ {
+ log.debug("Could not unwrap source " + source.getClass().getName()
+ + " to target class " + target.getName());
+ }
+ return result;
+ }
+
+ public String toString()
+ {
+ ToStringBuilder buf = new ToStringBuilder(this,
ToStringStyle.MULTI_LINE_STYLE);
+ buf.append("Supported unwrap pattern: ");
+ for(int i = 0; i < unwrapInfo.length; i++)
+ {
+ buf.append(ArrayUtils.toString(unwrapInfo[i]));
+ }
+ return buf.toString();
+ }
+}
Added:
db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/UnwrapHelperTest.java
URL:
http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/UnwrapHelperTest.java?rev=384976&view=auto
==============================================================================
---
db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/UnwrapHelperTest.java
(added)
+++
db/ojb/branches/OJB_1_0_RELEASE/src/test/org/apache/ojb/broker/UnwrapHelperTest.java
Fri Mar 10 17:03:47 2006
@@ -0,0 +1,125 @@
+package org.apache.ojb.broker;
+
+/* Copyright 2002-2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+
+import org.apache.ojb.broker.platforms.Platform;
+import org.apache.ojb.broker.platforms.PlatformHsqldbImpl;
+import org.apache.ojb.broker.util.ClassHelper;
+import org.apache.ojb.broker.util.UnwrapHelper;
+import org.apache.ojb.junit.PBTestCase;
+
+/**
+ * Simple test for unwrap helper class.
+ *
+ * @version $Id: $
+ */
+public class UnwrapHelperTest extends PBTestCase
+{
+ private UnwrapHelper helper;
+ private String statementClassName =
"org.hsqldb.jdbc.jdbcPreparedStatement";
+ private String connectionClassName = "org.hsqldb.jdbc.jdbcConnection";
+ private String selectExample = "select 1 from OJB_HL_SEQ";
+
+ public static void main(String[] args)
+ {
+ String[] arr = {UnwrapHelperTest.class.getName()};
+ junit.textui.TestRunner.main(arr);
+ }
+
+ public UnwrapHelperTest(String name)
+ {
+ super(name);
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ helper = new UnwrapHelper();
+ }
+
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ public void testAddPattern()
+ {
+ int length = helper.getUnwrapPatterns().length;
+ Object[] pattern = helper.getUnwrapPatterns()[0];
+ helper.addUnwrapPattern(pattern);
+ //System.out.println("## " + helper.toString());
+ assertEquals(length + 1, helper.getUnwrapPatterns().length);
+ }
+
+ public void testUnwrapConnection() throws Exception
+ {
+ Platform pf = broker.serviceConnectionManager().getSupportedPlatform();
+ if(!PlatformHsqldbImpl.class.isAssignableFrom(pf.getClass()))
+ {
+ return;
+ }
+ Connection con = broker.serviceConnectionManager().getConnection();
+ Class target = ClassHelper.getClass(connectionClassName);
+ Connection result = helper.unwrapConnection(target, con);
+ assertNotNull(result);
+ assertTrue(target.isAssignableFrom(result.getClass()));
+ }
+
+ public void testUnwrapStatement() throws Exception
+ {
+ Platform pf = broker.serviceConnectionManager().getSupportedPlatform();
+ if(!PlatformHsqldbImpl.class.isAssignableFrom(pf.getClass()))
+ {
+ return;
+ }
+ Connection con = broker.serviceConnectionManager().getConnection();
+ PreparedStatement ps = con.prepareStatement(selectExample);
+ Class target = ClassHelper.getClass(statementClassName);
+ PreparedStatement result = helper.unwrapStatement(target, ps);
+ assertNotNull(result);
+ assertTrue(target.isAssignableFrom(result.getClass()));
+ }
+
+ /**
+ * Test useful for development.
+ */
+ public void XXXtestUnwrapLoop() throws Exception
+ {
+ Platform pf = broker.serviceConnectionManager().getSupportedPlatform();
+ if(!PlatformHsqldbImpl.class.isAssignableFrom(pf.getClass()))
+ {
+ return;
+ }
+ Connection con = broker.serviceConnectionManager().getConnection();
+ PreparedStatement ps = con.prepareStatement(selectExample);
+ Class targetC = ClassHelper.getClass(connectionClassName);
+ Class targetS = ClassHelper.getClass(statementClassName);
+ long t = System.currentTimeMillis();
+ int loops = 5000;
+ for(int i = 0;i<loops;i++)
+ {
+ Connection resultC = helper.unwrapConnection(targetC, con);
+ assertNotNull(resultC);
+ PreparedStatement resultS = helper.unwrapStatement(targetS, ps);
+ assertNotNull(resultS);
+ }
+ t = System.currentTimeMillis() - t;
+ System.out.println("Unwarp " + loops + " con/stmt: " + t + " ms");
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]