1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.orm.hibernate4;
18
19 import java.lang.reflect.InvocationHandler;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Proxy;
23 import javax.transaction.Status;
24 import javax.transaction.Synchronization;
25 import javax.transaction.SystemException;
26 import javax.transaction.Transaction;
27 import javax.transaction.TransactionManager;
28 import javax.transaction.TransactionSynchronizationRegistry;
29 import javax.transaction.UserTransaction;
30
31 import org.hibernate.TransactionException;
32 import org.hibernate.service.Service;
33
34 import org.springframework.transaction.jta.UserTransactionAdapter;
35 import org.springframework.util.Assert;
36 import org.springframework.util.ClassUtils;
37
38
39
40
41
42
43
44
45
46 @SuppressWarnings({"serial", "unchecked"})
47 class ConfigurableJtaPlatform implements InvocationHandler {
48
49 static final Class<? extends Service> jtaPlatformClass;
50
51 static {
52 Class<?> jpClass;
53 try {
54
55 jpClass = ClassUtils.forName("org.hibernate.service.jta.platform.spi.JtaPlatform",
56 ConfigurableJtaPlatform.class.getClassLoader());
57 }
58 catch (ClassNotFoundException ex) {
59 try {
60
61 jpClass = ClassUtils.forName("org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform",
62 ConfigurableJtaPlatform.class.getClassLoader());
63 }
64 catch (ClassNotFoundException ex2) {
65 throw new IllegalStateException("Neither Hibernate 4.0-4.2 nor 4.3 variant of JtaPlatform found");
66 }
67 }
68 jtaPlatformClass = (Class<? extends Service>) jpClass;
69 }
70
71 static String getJtaPlatformBasePackage() {
72 String className = jtaPlatformClass.getName();
73 return className.substring(0, className.length() - "spi.JtaPlatform".length());
74 }
75
76
77 private final TransactionManager transactionManager;
78
79 private final UserTransaction userTransaction;
80
81 private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
82
83
84
85
86
87
88
89
90
91 public ConfigurableJtaPlatform(TransactionManager tm, UserTransaction ut, TransactionSynchronizationRegistry tsr) {
92 Assert.notNull(tm, "TransactionManager reference must not be null");
93 this.transactionManager = tm;
94 this.userTransaction = (ut != null ? ut : new UserTransactionAdapter(tm));
95 this.transactionSynchronizationRegistry = tsr;
96 }
97
98
99 public TransactionManager retrieveTransactionManager() {
100 return this.transactionManager;
101 }
102
103 public UserTransaction retrieveUserTransaction() {
104 return this.userTransaction;
105 }
106
107 public Object getTransactionIdentifier(Transaction transaction) {
108 return transaction;
109 }
110
111 public boolean canRegisterSynchronization() {
112 try {
113 return (this.transactionManager.getStatus() == Status.STATUS_ACTIVE);
114 }
115 catch (SystemException ex) {
116 throw new TransactionException("Could not determine JTA transaction status", ex);
117 }
118 }
119
120 public void registerSynchronization(Synchronization synchronization) {
121 if (this.transactionSynchronizationRegistry != null) {
122 this.transactionSynchronizationRegistry.registerInterposedSynchronization(synchronization);
123 }
124 else {
125 try {
126 this.transactionManager.getTransaction().registerSynchronization(synchronization);
127 }
128 catch (Exception ex) {
129 throw new TransactionException("Could not access JTA Transaction to register synchronization", ex);
130 }
131 }
132 }
133
134 public int getCurrentStatus() throws SystemException {
135 return this.transactionManager.getStatus();
136 }
137
138
139 @Override
140 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
141 try {
142 return getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(this, args);
143 }
144 catch (InvocationTargetException ex) {
145 throw ex.getTargetException();
146 }
147 catch (Throwable ex) {
148 throw new IllegalStateException("Failed to delegate to corresponding implementation method", ex);
149 }
150 }
151
152
153
154
155
156
157 public Object getJtaPlatformProxy() {
158 return Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] {jtaPlatformClass}, this);
159 }
160
161 }