KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jdbc > core > CallableStatementCreatorFactory


1 /*
2  * Copyright 2002-2006 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.jdbc.core;
18
19 import java.sql.CallableStatement JavaDoc;
20 import java.sql.Connection JavaDoc;
21 import java.sql.ResultSet JavaDoc;
22 import java.sql.SQLException JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.LinkedList JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.springframework.dao.InvalidDataAccessApiUsageException;
29 import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
30
31 /**
32  * Helper class that can efficiently create multiple CallableStatementCreator
33  * objects with different parameters based on a SQL statement and a single
34  * set of parameter declarations.
35  *
36  * @author Rod Johnson
37  * @author Thomas Risberg
38  * @author Juergen Hoeller
39  */

40 public class CallableStatementCreatorFactory {
41
42     /** The SQL call string, which won't change when the parameters change. */
43     private final String JavaDoc callString;
44
45     /** List of SqlParameter objects. May not be <code>null</code>. */
46     private final List JavaDoc declaredParameters;
47
48     private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
49
50     private boolean updatableResults = false;
51
52     private NativeJdbcExtractor nativeJdbcExtractor;
53
54
55     /**
56      * Create a new factory. Will need to add parameters
57      * via the addParameter() method or have no parameters.
58      */

59     public CallableStatementCreatorFactory(String JavaDoc callString) {
60         this.callString = callString;
61         this.declaredParameters = new LinkedList JavaDoc();
62     }
63
64     /**
65      * Create a new factory with sql and the given parameters.
66      * @param callString the SQL call string
67      * @param declaredParameters list of SqlParameter objects
68      */

69     public CallableStatementCreatorFactory(String JavaDoc callString, List JavaDoc declaredParameters) {
70         this.callString = callString;
71         this.declaredParameters = declaredParameters;
72     }
73
74     /**
75      * Add a new declared parameter.
76      * Order of parameter addition is significant.
77      */

78     public void addParameter(SqlParameter param) {
79         this.declaredParameters.add(param);
80     }
81         
82     /**
83      * Set whether to use prepared statements that return a
84      * specific type of ResultSet.
85      * @param resultSetType the ResultSet type
86      * @see java.sql.ResultSet#TYPE_FORWARD_ONLY
87      * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE
88      * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE
89      */

90     public void setResultSetType(int resultSetType) {
91         this.resultSetType = resultSetType;
92     }
93
94     /**
95      * Set whether to use prepared statements capable of returning
96      * updatable ResultSets.
97      */

98     public void setUpdatableResults(boolean updatableResults) {
99         this.updatableResults = updatableResults;
100     }
101
102     /**
103      * Specify the NativeJdbcExtractor to use for unwrapping
104      * CallableStatements, if any.
105      */

106     public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
107         this.nativeJdbcExtractor = nativeJdbcExtractor;
108     }
109
110
111     /**
112      * Return a new CallableStatementCreator instance given this parameters.
113      * @param inParams List of parameters. May be <code>null</code>.
114      */

115     public CallableStatementCreator newCallableStatementCreator(Map JavaDoc inParams) {
116         return new CallableStatementCreatorImpl(inParams != null ? inParams : new HashMap JavaDoc());
117     }
118
119     /**
120      * Return a new CallableStatementCreator instance given this parameter mapper.
121      * @param inParamMapper ParameterMapper implementation that will return a Map of parameters. May not be <code>null</code>.
122      */

123     public CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) {
124         return new CallableStatementCreatorImpl(inParamMapper);
125     }
126
127
128     /**
129      * CallableStatementCreator implementation returned by this class.
130      */

131     private class CallableStatementCreatorImpl
132             implements CallableStatementCreator, SqlProvider, ParameterDisposer {
133
134         private ParameterMapper inParameterMapper;
135
136         private Map JavaDoc inParameters;
137
138         /**
139          * Create a new CallableStatementCreatorImpl.
140          * @param inParamMapper ParameterMapper implementation for mapping input parameters.
141          * May not be <code>null</code>.
142          */

143         public CallableStatementCreatorImpl(ParameterMapper inParamMapper) {
144             this.inParameterMapper = inParamMapper;
145         }
146
147         /**
148          * Create a new CallableStatementCreatorImpl.
149          * @param inParams list of SqlParameter objects. May not be <code>null</code>.
150          */

151         public CallableStatementCreatorImpl(Map JavaDoc inParams) {
152             this.inParameters = inParams;
153         }
154
155         public CallableStatement JavaDoc createCallableStatement(Connection JavaDoc con) throws SQLException JavaDoc {
156             // If we were given a ParameterMapper - we must let the mapper do its thing to create the Map.
157
if (this.inParameterMapper != null) {
158                 this.inParameters = this.inParameterMapper.createMap(con);
159             }
160             else {
161                 if (this.inParameters == null) {
162                     throw new InvalidDataAccessApiUsageException(
163                             "A ParameterMapper or a Map of parameters must be provided");
164                 }
165             }
166
167             CallableStatement JavaDoc cs = null;
168             if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
169                 cs = con.prepareCall(callString);
170             }
171             else {
172                 cs = con.prepareCall(callString, resultSetType,
173                         updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY);
174             }
175
176             // Determine CallabeStatement to pass to custom types.
177
CallableStatement JavaDoc csToUse = cs;
178             if (nativeJdbcExtractor != null) {
179                 csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs);
180             }
181
182             int sqlColIndx = 1;
183             for (int i = 0; i < declaredParameters.size(); i++) {
184                 SqlParameter declaredParameter = (SqlParameter) declaredParameters.get(i);
185                 if (!this.inParameters.containsKey(declaredParameter.getName()) &&
186                         !(declaredParameter instanceof ResultSetSupportingSqlParameter)) {
187                     throw new InvalidDataAccessApiUsageException(
188                             "Required input parameter '" + declaredParameter.getName() + "' is missing");
189                 }
190                 // The value may still be null.
191
Object JavaDoc inValue = this.inParameters.get(declaredParameter.getName());
192                 if (!(declaredParameter instanceof ResultSetSupportingSqlParameter)) {
193                     StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParameter, inValue);
194                 }
195                 else {
196                     // It's an output parameter: Skip SqlReturnResultSet parameters.
197
// It need not (but may be) supplied by the caller.
198
if (declaredParameter instanceof SqlOutParameter) {
199                         if (declaredParameter.getTypeName() != null) {
200                             cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType(), declaredParameter.getTypeName());
201                         }
202                         else {
203                             cs.registerOutParameter(sqlColIndx, declaredParameter.getSqlType());
204                         }
205                         if (((SqlOutParameter) declaredParameter).isInputValueProvided() || inValue != null) {
206                             StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParameter, inValue);
207                         }
208                     }
209                 }
210                 if (!(declaredParameter instanceof SqlReturnResultSet)) {
211                     sqlColIndx++;
212                 }
213             }
214
215             return cs;
216         }
217
218         public String JavaDoc getSql() {
219             return callString;
220         }
221
222         public void cleanupParameters() {
223             if (this.inParameters != null) {
224                 StatementCreatorUtils.cleanupParameters(this.inParameters.values());
225             }
226         }
227
228         public String JavaDoc toString() {
229             StringBuffer JavaDoc buf = new StringBuffer JavaDoc("CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=[");
230             buf.append(callString).append("]; parameters=").append(this.inParameters);
231             return buf.toString();
232         }
233     }
234
235 }
236
Popular Tags