KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > util > batch > PreparedStatementInvocationHandler


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

17
18
19 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
20 import org.apache.ojb.broker.platforms.PlatformFactory;
21 import org.apache.ojb.broker.platforms.PlatformException;
22 import org.apache.ojb.broker.platforms.Platform;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.InvocationTargetException JavaDoc;
26 import java.math.BigDecimal JavaDoc;
27 import java.sql.Connection JavaDoc;
28 import java.sql.PreparedStatement JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.ArrayList JavaDoc;
31
32 //#ifdef JDK13
33
import java.lang.reflect.InvocationHandler JavaDoc;
34 //#else
35
/*
36 import com.develop.java.lang.reflect.InvocationHandler;
37 */

38 //#endif
39

40 /**
41  * The implementation of {@link java.reflect.InvocationHandler} which is used
42  * to create dynamic proxy which will implement {@link java.sql.PreparedStatement} and
43  * {@link BatchPreparedStatement}.
44  *
45  * @author Oleg Nitz (<a HREF="mailto:olegnitz@apache.org">olegnitz@apache.org</a>)
46  */

47 public class PreparedStatementInvocationHandler implements InvocationHandler JavaDoc
48 {
49
50     private final static Integer JavaDoc ONE = new Integer JavaDoc(1);
51
52     private static Method JavaDoc ADD_BATCH;
53
54     private final static Method JavaDoc SET_BIG_DECIMAL;
55
56     static
57     {
58         Method JavaDoc setBigDecimal = null;
59         try
60         {
61             setBigDecimal = PreparedStatement JavaDoc.class.getMethod("setBigDecimal",
62                                                               new Class JavaDoc[] {Integer.TYPE, BigDecimal JavaDoc.class});
63         }
64         catch ( Exception JavaDoc ex )
65         {
66             // ignore it
67
}
68         SET_BIG_DECIMAL = setBigDecimal;
69     }
70
71     private final BatchConnection _batchConn;
72
73     private final String JavaDoc _sql;
74
75     private ArrayList JavaDoc _methods = new ArrayList JavaDoc();
76
77     private ArrayList JavaDoc _params = new ArrayList JavaDoc();
78
79     private Platform m_platform = null;
80
81     public PreparedStatementInvocationHandler(BatchConnection batchConn, String JavaDoc sql, JdbcConnectionDescriptor jcd)
82     {
83         _batchConn = batchConn;
84         _sql = sql;
85         m_platform = PlatformFactory.getPlatformFor(jcd);
86         try
87         {
88             ADD_BATCH = m_platform.getClass().getMethod("addBatch",new Class JavaDoc[]{PreparedStatement JavaDoc.class});
89         }
90         catch ( NoSuchMethodException JavaDoc e )
91         {
92             /**
93              * should never happen
94              */

95             ADD_BATCH = null;
96         }
97         catch ( SecurityException JavaDoc e )
98         {
99             // ignore it
100
}
101     }
102
103     public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args)
104     throws Throwable JavaDoc
105     {
106         String JavaDoc name = method.getName();
107         if ( name.equals("executeUpdate") )
108         {
109             _methods.add(ADD_BATCH);
110             _params.add(null);
111             _batchConn.nextExecuted(_sql);
112             return ONE;
113         }
114         else if ( name.equals("doExecute") )
115         {
116             doExecute((Connection JavaDoc) args[0]);
117         }
118         else if ( name.startsWith("set") )
119         {
120             // workaround for the bug in Sybase jConnect JDBC driver
121
if ( name.equals("setLong") )
122             {
123                 method = SET_BIG_DECIMAL;
124                 args[1] = BigDecimal.valueOf(((Long JavaDoc) args[1]).longValue());
125             }
126             _methods.add(method);
127             _params.add(args);
128         }
129         return null;
130     }
131
132     /**
133      * This method performs database modification at the very and of transaction.
134      */

135     private void doExecute(Connection JavaDoc conn) throws SQLException JavaDoc
136     {
137         PreparedStatement JavaDoc stmt;
138         int size;
139
140         size = _methods.size();
141         if ( size == 0 )
142         {
143             return;
144         }
145         stmt = conn.prepareStatement(_sql);
146         try
147         {
148             m_platform.afterStatementCreate(stmt);
149         }
150         catch ( PlatformException e )
151         {
152             if ( e.getCause() instanceof SQLException JavaDoc )
153             {
154                 throw (SQLException JavaDoc)e.getCause();
155             }
156             else
157             {
158                 throw new SQLException JavaDoc(e.getMessage());
159             }
160         }
161         try
162         {
163             m_platform.beforeBatch(stmt);
164         }
165         catch ( PlatformException e )
166         {
167             if ( e.getCause() instanceof SQLException JavaDoc )
168             {
169                 throw (SQLException JavaDoc)e.getCause();
170             }
171             else
172             {
173                 throw new SQLException JavaDoc(e.getMessage());
174             }
175         }
176         try
177         {
178             for ( int i = 0; i < size; i++ )
179             {
180                 Method JavaDoc method = (Method JavaDoc) _methods.get(i);
181                 try
182                 {
183                     if ( method.equals(ADD_BATCH) )
184                     {
185                         /**
186                          * we invoke on the platform and pass the stmt as an arg.
187                          */

188                         m_platform.addBatch(stmt);
189                     }
190                     else
191                     {
192                         method.invoke(stmt, (Object JavaDoc[]) _params.get(i));
193                     }
194                 }
195                 catch (IllegalArgumentException JavaDoc ex)
196                 {
197                     StringBuffer JavaDoc buffer = generateExceptionMessage(i, stmt, ex);
198                     throw new SQLException JavaDoc(buffer.toString());
199                 }
200                 catch ( IllegalAccessException JavaDoc ex )
201                 {
202                     StringBuffer JavaDoc buffer = generateExceptionMessage(i, stmt, ex);
203                     throw new SQLException JavaDoc(buffer.toString());
204                 }
205                 catch ( InvocationTargetException JavaDoc ex )
206                 {
207                     Throwable JavaDoc th = ex.getTargetException();
208
209                     if ( th == null )
210                     {
211                         th = ex;
212                     }
213                     if ( th instanceof SQLException JavaDoc )
214                     {
215                         throw ((SQLException JavaDoc) th);
216                     }
217                     else
218                     {
219                         throw new SQLException JavaDoc(th.toString());
220                     }
221                 }
222                 catch (PlatformException e)
223                 {
224                     throw new SQLException JavaDoc(e.toString());
225                 }
226             }
227             try
228             {
229                 /**
230                  * this will call the platform specific call
231                  */

232                 m_platform.executeBatch(stmt);
233             }
234             catch ( PlatformException e )
235             {
236                 if ( e.getCause() instanceof SQLException JavaDoc )
237                 {
238                     throw (SQLException JavaDoc)e.getCause();
239                 }
240                 else
241                 {
242                     throw new SQLException JavaDoc(e.getMessage());
243                 }
244             }
245
246         }
247         finally
248         {
249             stmt.close();
250             _methods.clear();
251             _params.clear();
252         }
253     }
254     
255     private StringBuffer JavaDoc generateExceptionMessage(int i, PreparedStatement JavaDoc stmt, Exception JavaDoc ex)
256     {
257         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
258         buffer.append("Method of type: ");
259         buffer.append(_methods.get(i));
260         buffer.append(" invoking on instance: ");
261         if (( _methods.get(i)).equals(ADD_BATCH))
262             buffer.append(m_platform);
263         else
264             buffer.append(stmt);
265         buffer.append(" with parameters: ");
266         if ((_methods.get(i)).equals(ADD_BATCH))
267             buffer.append(stmt);
268         else
269             buffer.append(_params.get(i));
270         buffer.append(" with root: ");
271         buffer.append(ex.toString());
272         return buffer;
273     }
274 }
275
276
Popular Tags