KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jca > cci > connection > TransactionAwareConnectionFactoryProxy


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

16
17 package org.springframework.jca.cci.connection;
18
19 import java.lang.reflect.InvocationHandler JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Proxy JavaDoc;
23
24 import javax.resource.ResourceException JavaDoc;
25 import javax.resource.cci.Connection JavaDoc;
26 import javax.resource.cci.ConnectionFactory JavaDoc;
27
28 /**
29  * Proxy for a target CCI {@link javax.resource.cci.ConnectionFactory}, adding
30  * awareness of Spring-managed transactions. Similar to a transactional JNDI
31  * ConnectionFactory as provided by a J2EE server.
32  *
33  * <p>Data access code that should remain unaware of Spring's data access support
34  * can work with this proxy to seamlessly participate in Spring-managed transactions.
35  * Note that the transaction manager, for example the {@link CciLocalTransactionManager},
36  * still needs to work with underlying ConnectionFactory, <i>not</i> with this proxy.
37  *
38  * <p><b>Make sure that TransactionAwareConnectionFactoryProxy is the outermost
39  * ConnectionFactory of a chain of ConnectionFactory proxies/adapters.</b>
40  * TransactionAwareConnectionFactoryProxy can delegate either directly to the
41  * target connection pool or to some intermediate proxy/adapter like
42  * {@link ConnectionSpecConnectionFactoryAdapter}.
43  *
44  * <p>Delegates to {@link ConnectionFactoryUtils} for automatically participating in
45  * thread-bound transactions, for example managed by {@link CciLocalTransactionManager}.
46  * <code>getConnection</code> calls and <code>close</code> calls on returned Connections
47  * will behave properly within a transaction, i.e. always operate on the transactional
48  * Connection. If not within a transaction, normal ConnectionFactory behavior applies.
49  *
50  * <p>This proxy allows data access code to work with the plain JCA CCI API and still
51  * participate in Spring-managed transactions, similar to CCI code in a J2EE/JTA
52  * environment. However, if possible, use Spring's ConnectionFactoryUtils, CciTemplate or
53  * CCI operation objects to get transaction participation even without a proxy for
54  * the target ConnectionFactory, avoiding the need to define such a proxy in the first place.
55  *
56  * <p><b>NOTE:</b> This ConnectionFactory proxy needs to return wrapped Connections
57  * in order to handle close calls properly. Therefore, the returned Connections cannot
58  * be cast to a native CCI Connection type or to a connection pool implementation type.
59  *
60  * @author Juergen Hoeller
61  * @since 1.2
62  * @see javax.resource.cci.ConnectionFactory#getConnection
63  * @see javax.resource.cci.Connection#close
64  * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#doGetConnection
65  * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#doReleaseConnection
66  */

67 public class TransactionAwareConnectionFactoryProxy extends DelegatingConnectionFactory {
68
69     /**
70      * Create a new TransactionAwareConnectionFactoryProxy.
71      * @see #setTargetConnectionFactory
72      */

73     public TransactionAwareConnectionFactoryProxy() {
74     }
75
76     /**
77      * Create a new TransactionAwareConnectionFactoryProxy.
78      * @param targetConnectionFactory the target ConnectionFactory
79      */

80     public TransactionAwareConnectionFactoryProxy(ConnectionFactory JavaDoc targetConnectionFactory) {
81         setTargetConnectionFactory(targetConnectionFactory);
82         afterPropertiesSet();
83     }
84
85
86     /**
87      * Delegate to ConnectionFactoryUtils for automatically participating in Spring-managed
88      * transactions. Throws the original ResourceException, if any.
89      * @return a transactional Connection if any, a new one else
90      * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#doGetConnection
91      */

92     public Connection JavaDoc getConnection() throws ResourceException JavaDoc {
93         Connection JavaDoc con = ConnectionFactoryUtils.doGetConnection(getTargetConnectionFactory());
94         return getTransactionAwareConnectionProxy(con, getTargetConnectionFactory());
95     }
96
97     /**
98      * Wrap the given Connection with a proxy that delegates every method call to it
99      * but delegates <code>close</code> calls to ConnectionFactoryUtils.
100      * @param target the original Connection to wrap
101      * @param cf ConnectionFactory that the Connection came from
102      * @return the wrapped Connection
103      * @see javax.resource.cci.Connection#close()
104      * @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#doReleaseConnection
105      */

106     protected Connection JavaDoc getTransactionAwareConnectionProxy(Connection JavaDoc target, ConnectionFactory JavaDoc cf) {
107         return (Connection JavaDoc) Proxy.newProxyInstance(
108                 Connection JavaDoc.class.getClassLoader(),
109                 new Class JavaDoc[] {Connection JavaDoc.class},
110                 new TransactionAwareInvocationHandler(target, cf));
111     }
112
113
114     /**
115      * Invocation handler that delegates close calls on CCI Connections
116      * to ConnectionFactoryUtils for being aware of thread-bound transactions.
117      */

118     private static class TransactionAwareInvocationHandler implements InvocationHandler JavaDoc {
119
120         private final Connection JavaDoc target;
121
122         private final ConnectionFactory JavaDoc connectionFactory;
123
124         public TransactionAwareInvocationHandler(Connection JavaDoc target, ConnectionFactory JavaDoc cf) {
125             this.target = target;
126             this.connectionFactory = cf;
127         }
128
129         public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
130             // Invocation on Connection interface coming in...
131

132             if (method.getName().equals("equals")) {
133                 // Only consider equal when proxies are identical.
134
return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
135             }
136             else if (method.getName().equals("hashCode")) {
137                 // Use hashCode of Connection proxy.
138
return new Integer JavaDoc(hashCode());
139             }
140             else if (method.getName().equals("getLocalTransaction")) {
141                 if (ConnectionFactoryUtils.isConnectionTransactional(this.target, this.connectionFactory)) {
142                     throw new javax.resource.spi.IllegalStateException JavaDoc(
143                             "Local transaction handling not allowed within a managed transaction");
144                 }
145             }
146             else if (method.getName().equals("close")) {
147                 // Handle close method: only close if not within a transaction.
148
ConnectionFactoryUtils.doReleaseConnection(this.target, this.connectionFactory);
149                 return null;
150             }
151
152             // Invoke method on target Connection.
153
try {
154                 return method.invoke(this.target, args);
155             }
156             catch (InvocationTargetException JavaDoc ex) {
157                 throw ex.getTargetException();
158             }
159         }
160     }
161
162 }
163
Popular Tags