1 package org.csc.phynixx.connection;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import org.csc.phynixx.common.exceptions.DelegatedRuntimeException;
25 import org.csc.phynixx.common.generator.IDGenerator;
26 import org.csc.phynixx.common.generator.IDGenerators;
27 import org.csc.phynixx.common.logger.IPhynixxLogger;
28 import org.csc.phynixx.common.logger.PhynixxLogManager;
29
30 import java.lang.annotation.Annotation;
31 import java.lang.reflect.InvocationHandler;
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.lang.reflect.Proxy;
35
36
37
38
39
40
41
42
43
44 class DynaPhynixxManagedConnectionFactory<C extends IPhynixxConnection> extends AbstractDynaProxyFactory {
45
46 private static final IDGenerator<Long> idGenerator = IDGenerators.createLongGenerator(1,true);
47
48 private Class<C> connectionInterface;
49 private CloseStrategy<C> closeStrategy=null;
50
51 DynaPhynixxManagedConnectionFactory(Class<C> connectionInterface, CloseStrategy<C> closeStrategy, boolean synchronize) {
52 super(new Class<?>[]{connectionInterface},
53 new Class[]{IPhynixxConnection.class, IPhynixxManagedConnection.class},
54 new Class[]{IXADataRecorderAware.class, ICloseable.class, IAutoCommitAware.class},
55 synchronize);
56 this.connectionInterface = connectionInterface;
57 this.closeStrategy= closeStrategy;
58
59
60 }
61
62 DynaPhynixxManagedConnectionFactory(Class<C> connectionInterface,CloseStrategy<C> closeStrategy) {
63 this(connectionInterface, closeStrategy, true);
64 }
65
66 IPhynixxManagedConnection<C> getManagedConnection(C coreConnection) {
67
68 Long connectionId = null;
69 synchronized (idGenerator) {
70 connectionId = idGenerator.generate();
71 }
72 ConnectionPhynixxGuard proxy = new ConnectionPhynixxGuard(connectionId, connectionInterface, coreConnection,closeStrategy);
73
74 IPhynixxManagedConnection<C> proxied = (IPhynixxManagedConnection<C>)
75 Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
76 this.getImplementedInterfaces(), proxy);
77 proxy.proxiedObject = proxied;
78 return proxied;
79 }
80
81
82 class ConnectionPhynixxGuard<C extends IPhynixxConnection> extends PhynixxManagedConnectionGuard<C> implements InvocationHandler {
83
84
85
86
87 private final IPhynixxLogger log = PhynixxLogManager.getLogger(ConnectionPhynixxGuard.class);
88
89
90
91
92 private IPhynixxManagedConnection<C> proxiedObject;
93
94 ConnectionPhynixxGuard(long id, Class<C> connectionInterface, C connection, CloseStrategy<C> closeStrategy) {
95 super(id, connectionInterface, connection,closeStrategy);
96 }
97
98
99
100
101
102
103
104 private boolean requiresTransaction(Method method) {
105
106 Annotation[] annotations = method.getDeclaredAnnotations();
107 if (annotations == null || annotations.length == 0) {
108 return false;
109 }
110 for (int i = 0; i < annotations.length; i++) {
111 if (RequiresTransaction.class.isAssignableFrom(annotations[i].annotationType())) {
112 RequiresTransaction requiresTransactionAnnotation = (RequiresTransaction) annotations[i];
113 return requiresTransactionAnnotation.value();
114 }
115 }
116
117 return false;
118
119 }
120
121
122 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
123
124
125
126
127
128
129
130 try {
131 if (DynaPhynixxManagedConnectionFactory.this.declaredBySystemInterface(method)) {
132
133 Object obj = null;
134 if (this.isSynchronized()) {
135 synchronized (this) {
136 obj = method.invoke(this, args);
137 }
138 } else {
139 obj = method.invoke(this, args);
140 }
141 return obj;
142 } else if (DynaPhynixxManagedConnectionFactory.this.declaredBySupportedInterface(method)) {
143
144 Object target = this.getCoreConnection();
145
146
147
148 Object obj = null;
149 boolean requireTransaction = this.requiresTransaction(method);
150 try {
151 if (this.isSynchronized()) {
152 synchronized (this) {
153 if (requireTransaction) {
154 this.fireConnectionRequiresTransaction();
155 }
156 obj = method.invoke(target, args);
157 if (requireTransaction) {
158 fireConnectionRequiresTransactionExecuted();
159 }
160 }
161 } else {
162 if (requireTransaction) {
163 this.fireConnectionRequiresTransaction();
164 }
165 obj = method.invoke(target, args);
166 if (requireTransaction) {
167 fireConnectionRequiresTransactionExecuted();
168 }
169 }
170 return obj;
171 } catch (InvocationTargetException targetException) {
172 if (requireTransaction) {
173 Exception e = null;
174 if (!(targetException.getTargetException() instanceof Exception)) {
175 e = new Exception(targetException.getCause());
176 } else {
177 e = (Exception) (targetException.getTargetException());
178 }
179 fireConnectionRequiresTransactionExecuted(e);
180 }
181
182
183
184 throw targetException;
185
186 }
187 } else {
188 Object obj = null;
189 if (this.isSynchronized()) {
190 synchronized (this) {
191 obj = method.invoke(this, args);
192 }
193 } else {
194 obj = method.invoke(this, args);
195 }
196 return obj;
197 }
198 } catch (InvocationTargetException targetEx) {
199
200 throw new DelegatedRuntimeException("Invoking " + method, targetEx.getTargetException());
201 } catch (Throwable ex) {
202
203 throw new DelegatedRuntimeException("Invoking " + method, ex);
204 }
205 }
206
207 protected IPhynixxManagedConnection<C> getObservableProxy() {
208 return (IPhynixxManagedConnection) proxiedObject;
209 }
210
211 }
212 }