1
2
3
4
5
6
7
8
9
10
11 package it.imolinfo.jbi4cics.connection.jdbc.util;
12
13 import java.lang.reflect.InvocationHandler;
14 import java.lang.reflect.InvocationTargetException;
15 import java.lang.reflect.Method;
16 import java.sql.Connection;
17 import java.sql.ResultSet;
18 import java.sql.SQLException;
19 import java.sql.Statement;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import javax.sql.rowset.CachedRowSet;
26 import com.sun.rowset.CachedRowSetImpl;
27 import it.imolinfo.jbi4cics.jbi.Messages;
28 import it.imolinfo.jbi4cics.Logger;
29 import it.imolinfo.jbi4cics.LoggerFactory;
30
31
32
33
34
35
36
37
38
39
40
41 class StatementInvocationHandler implements InvocationHandler {
42
43
44
45
46 private static final Logger LOG
47 = LoggerFactory.getLogger(StatementInvocationHandler.class);
48
49
50
51
52 private static final Messages MESSAGES
53 = Messages.getMessages(StatementInvocationHandler.class);
54
55 private Connection connection;
56 private Statement underlyingStatement;
57 private boolean connected;
58
59 private List<Command> commands=new ArrayList<Command>();
60
61
62 protected int resultSetType=ResultSet.TYPE_FORWARD_ONLY;
63 protected int resultSetConcurrency=ResultSet.CONCUR_READ_ONLY;
64 protected int resultSetHoldability=ResultSet.CLOSE_CURSORS_AT_COMMIT;
65
66
67
68
69 public StatementInvocationHandler() {
70 super();
71 }
72
73
74
75
76
77 public StatementInvocationHandler(int resultSetType, int resultSetConcurrency) {
78 super();
79 this.resultSetType=resultSetType;
80 this.resultSetConcurrency=resultSetConcurrency;
81 }
82
83
84
85
86
87
88 public StatementInvocationHandler(int resultSetType, int resultSetConcurrency, int resultSetHoldability) {
89 super();
90 this.resultSetType=resultSetType;
91 this.resultSetConcurrency=resultSetConcurrency;
92 this.resultSetHoldability=resultSetHoldability;
93 }
94
95
96
97
98 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
99
100
101 if (method.getName().startsWith("get")){
102 if ("getUnderlyingStatement".equals( method )){
103 return getUnderlyingStatement();
104 }
105 if (method.equals("getConnection")){
106 return getConnection();
107 }
108 return handleGet(proxy,method,args);
109 }
110
111 if (method.getName().startsWith("set")){
112 if (method.getName().equals("setConnection")){
113 setConnection((Connection)args[0]);
114 return null;
115 }
116 if (method.getName().equals("setConnected")){
117 setConnected(((Boolean)args[0]).booleanValue());
118 return null;
119 }
120 return handleSet(proxy,method,args);
121
122 }
123
124
125 if (method.getName().startsWith("execute")){
126 return handleExecute(proxy,method,args);
127 }
128
129 if ("toString".equals(method.getName())){
130 return toString();
131 }
132
133
134 return handleOtherMethods(proxy,method,args);
135
136 }
137
138 public Object handleGet(Object proxy, Method method, Object[] args) throws SQLException{
139 if (isConnected()){
140 return invokeMethod(method, args);
141 }
142 else {
143 throw new SQLException("trying to invoke an execute method on a disconnected statement");
144 }
145 }
146
147 public Object handleSet(Object proxy, Method method, Object[] args) throws SQLException{
148 if (isConnected()){
149 return invokeMethod(method, args);
150 }
151 else {
152 commands.add(new Command(method,args));
153 return null;
154 }
155 }
156
157 public Object handleExecute(Object proxy, Method method, Object[] args) throws SQLException{
158 if (isConnected()){
159 return invokeMethod(method, args);
160 }
161 else {
162 throw new SQLException(MESSAGES.getString("CIC000703_Error_invoking_execute_method"));
163 }
164 }
165
166 public Object handleOtherMethods(Object proxy, Method method, Object[] args) throws SQLException{
167 if (isConnected()){
168 return invokeMethod(method, args);
169 }
170 else {
171 commands.add(new Command(method,args));
172 return null;
173 }
174 }
175
176
177
178
179 public Connection getConnection() {
180 return connection;
181 }
182
183
184
185
186 public void setConnection(Connection conn) {
187 this.connection = conn;
188 }
189
190
191
192
193 public boolean isConnected() {
194 return connected;
195 }
196
197
198
199
200
201 public void setConnected(boolean connected) throws SQLException {
202 if (connected){
203 if (connection!=null){
204 if (underlyingStatement==null){
205
206 underlyingStatement=createStatement();
207 }
208 }
209 else {
210 throw new SQLException(MESSAGES.getString("CIC000704_Error_setting_connected_state"));
211 }
212
213 for (Iterator<Command> i=commands.iterator();i.hasNext();){
214 Command command=i.next();
215 Method method=command.getMethod();
216 Object[] args=command.getArgs();
217 invokeMethod(method, args);
218 }
219 }
220 else {
221
222 underlyingStatement=null;
223 connection=null;
224 }
225 this.connected = connected;
226 }
227
228
229
230
231
232 protected Statement createStatement() throws SQLException {
233 return connection.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);
234 }
235
236
237
238
239
240
241
242 protected Object invokeMethod(Method method, Object[] args) throws SQLException {
243 try{
244 Object result=method.invoke(underlyingStatement,args);
245 if (result!=null && result instanceof ResultSet){
246 CachedRowSet cachedRowSet=new CachedRowSetImpl();
247 cachedRowSet.populate((ResultSet)result);
248 return cachedRowSet;
249 }
250 else {
251 return result;
252 }
253 }
254 catch(IllegalAccessException e){
255 LOG.error("CIC000705_Illegal_access", new Object[]{method.toGenericString(), Arrays.toString(args), underlyingStatement}, e);
256 throw new SQLException(MESSAGES.getString("CIC000705_Illegal_access", new Object[]{method.toGenericString(), Arrays.toString(args), underlyingStatement}));
257 }
258 catch(InvocationTargetException e){
259 LOG.error("CIC000706_Target_exception", new Object[] {e.getTargetException()});
260 Throwable targetException=e.getTargetException();
261 if (targetException instanceof SQLException){
262 throw (SQLException)e.getTargetException();
263 }
264 else {
265 throw new SQLException(MESSAGES.getString("CIC000706_Target_exception", new Object[] {targetException.getMessage()}));
266 }
267 }
268 }
269
270
271
272
273 public String toString(){
274 return "connected: "+connected+ ", "+
275 (connected?"connection: "+connection+", ":"")+
276 (connected?"underlyingStatement: "+underlyingStatement+", ":"")+
277 (!connected?"stacked commands: "+Arrays.toString(commands.toArray()):"");
278 }
279
280
281
282
283 public Statement getUnderlyingStatement() {
284 return underlyingStatement;
285 }
286
287
288
289
290
291 private static class Command {
292 private Method method;
293 private Object[] args;
294 public Command(Method method, Object[] args) {
295 super();
296
297 this.method = method;
298 this.args = args;
299 }
300
301
302
303
304 public Object[] getArgs() {
305 return args;
306 }
307
308
309
310
311 public void setArgs(Object[] args) {
312 this.args = args;
313 }
314
315
316
317 public Method getMethod() {
318 return method;
319 }
320
321
322
323 public void setMethod(Method method) {
324 this.method = method;
325 }
326
327 public String toString(){
328 return "method: "+method.toGenericString()+" ,"+
329 "args: "+Arrays.toString(args);
330 }
331 }
332
333 }