001 package com.mockrunner.jdbc;
002
003 import java.util.ArrayList;
004 import java.util.Arrays;
005 import java.util.HashMap;
006 import java.util.List;
007 import java.util.Map;
008
009 /**
010 * Abstract base class for all statement types
011 * that support out parameters, i.e. <code>CallableStatement</code>.
012 */
013 public abstract class AbstractOutParameterResultSetHandler extends AbstractParameterResultSetHandler
014 {
015 private boolean mustRegisterOutParameters = false;
016 private Map globalOutParameter = null;
017 private Map outParameterForStatement = new HashMap();
018 private Map outParameterForStatementParameters = new HashMap();
019
020 /**
021 * Set if out parameters must be registered to be returned.
022 * The default is <code>false</code>, i.e. if there are matching
023 * out parameters prepared, they are returned even if the
024 * <code>registerOutParameter</code> methods of <code>CallableStatement</code>
025 * have not been called. If set to <code>true</code>, <code>registerOutParameter</code>
026 * must be called.
027 * @param mustOutParameterBeRegistered must out parameter be registered
028 */
029 public void setMustRegisterOutParameters(boolean mustOutParameterBeRegistered)
030 {
031 this.mustRegisterOutParameters = mustOutParameterBeRegistered;
032 }
033
034 /**
035 * Get if out parameter must be registered to be returned.
036 * @return must out parameter be registered
037 */
038 public boolean getMustRegisterOutParameters()
039 {
040 return mustRegisterOutParameters;
041 }
042
043 /**
044 * Returns the first out parameter <code>Map</code> that matches
045 * the specified SQL string.
046 * Please note that you can modify the match parameters with
047 * {@link #setCaseSensitive}, {@link #setExactMatch} and
048 * {@link #setUseRegularExpressions}.
049 * @param sql the SQL string
050 * @return the corresponding out parameter <code>Map</code>
051 */
052 public Map getOutParameter(String sql)
053 {
054 SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
055 List list = matcher.getMatchingObjects(outParameterForStatement, sql, true, true);
056 if(null != list && list.size() > 0)
057 {
058 return (Map)list.get(0);
059 }
060 return null;
061 }
062
063 /**
064 * Returns the first out parameter <code>Map</code> that matches
065 * the specified SQL string and the specified parameters.
066 * Please note that you can modify the match parameters with
067 * {@link #setCaseSensitive}, {@link #setExactMatch} and
068 * {@link #setUseRegularExpressions} and the match parameters for the
069 * specified parameter list with {@link #setExactMatchParameter}.
070 * @param sql the SQL string
071 * @param parameters the parameters
072 * @return the corresponding out parameter <code>Map</code>
073 */
074 public Map getOutParameter(String sql, Map parameters)
075 {
076 MockOutParameterWrapper wrapper = (MockOutParameterWrapper)getMatchingParameterWrapper(sql, parameters, outParameterForStatementParameters);
077 if(null != wrapper)
078 {
079 return wrapper.getOutParameter();
080 }
081 return null;
082 }
083
084 /**
085 * Clears the out parameters.
086 */
087 public void clearOutParameter()
088 {
089 outParameterForStatement.clear();
090 outParameterForStatementParameters.clear();
091 }
092
093 /**
094 * Returns the global out parameter <code>Map</code>.
095 * @return the global out parameter <code>Map</code>
096 */
097 public Map getGlobalOutParameter()
098 {
099 return globalOutParameter;
100 }
101
102 /**
103 * Prepares the global out parameter <code>Map</code>.
104 * @param outParameters the global out parameter <code>Map</code>
105 */
106 public void prepareGlobalOutParameter(Map outParameters)
107 {
108 globalOutParameter = new HashMap(outParameters);
109 }
110
111 /**
112 * Prepare an out parameter <code>Map</code> for a specified
113 * SQL string.
114 * Please note that you can modify the match parameters with
115 * {@link #setCaseSensitive}, {@link #setExactMatch} and
116 * {@link #setUseRegularExpressions}.
117 * @param sql the SQL string
118 * @param outParameters the out parameter <code>Map</code>
119 */
120 public void prepareOutParameter(String sql, Map outParameters)
121 {
122 outParameterForStatement.put(sql, new HashMap(outParameters));
123 }
124
125 /**
126 * Prepare an out parameter <code>Map</code> for a specified SQL string and
127 * the specified parameters. The specified parameters array
128 * must contain the parameters in the correct order starting with index 0 for
129 * the first parameter. Please keep in mind that parameters in
130 * <code>CallableStatement</code> objects start with 1 as the first
131 * parameter. So <code>parameters[0]</code> maps to the
132 * parameter with index 1.
133 * Please note that you can modify the match parameters with
134 * {@link #setCaseSensitive}, {@link #setExactMatch} and
135 * {@link #setUseRegularExpressions} and the match parameters for the
136 * specified parameter list with {@link #setExactMatchParameter}.
137 * @param sql the SQL string
138 * @param outParameters the corresponding out parameter <code>Map</code>
139 * @param parameters the parameters
140 */
141 public void prepareOutParameter(String sql, Map outParameters, Object[] parameters)
142 {
143 prepareOutParameter(sql, outParameters, Arrays.asList(parameters));
144 }
145
146 /**
147 * Prepare an out parameter <code>Map</code> for a specified SQL string and
148 * the specified parameters. The specified parameters array
149 * must contain the parameters in the correct order starting with index 0 for
150 * the first parameter. Please keep in mind that parameters in
151 * <code>CallableStatement</code> objects start with 1 as the first
152 * parameter. So <code>parameters.get(0)</code> maps to the
153 * parameter with index 1.
154 * Please note that you can modify the match parameters with
155 * {@link #setCaseSensitive}, {@link #setExactMatch} and
156 * {@link #setUseRegularExpressions} and the match parameters for the
157 * specified parameter list with {@link #setExactMatchParameter}.
158 * @param sql the SQL string
159 * @param outParameters the corresponding out parameter <code>Map</code>
160 * @param parameters the parameters
161 */
162 public void prepareOutParameter(String sql, Map outParameters, List parameters)
163 {
164 Map params = new HashMap();
165 for(int ii = 0; ii < parameters.size(); ii++)
166 {
167 params.put(new Integer(ii + 1), parameters.get(ii));
168 }
169 prepareOutParameter(sql, outParameters, params);
170 }
171
172 /**
173 * Prepare an out parameter <code>Map</code> for a specified SQL string
174 * and the specified parameters. The specified parameters <code>Map</code>
175 * must contain the parameters by mapping <code>Integer</code> or
176 * <code>String</code> objects to the corresponding parameter.
177 * An <code>Integer</code> object is the index of the parameter.
178 * A <code>String</code> is the name of the parameter.
179 * Please note that you can modify the match parameters with
180 * {@link #setCaseSensitive}, {@link #setExactMatch} and
181 * {@link #setUseRegularExpressions} and the match parameters for the
182 * specified parameter list with {@link #setExactMatchParameter}.
183 * @param sql the SQL string
184 * @param outParameters the corresponding out parameter <code>Map</code>
185 * @param parameters the parameters
186 */
187 public void prepareOutParameter(String sql, Map outParameters, Map parameters)
188 {
189 List list = (List)outParameterForStatementParameters.get(sql);
190 if(null == list)
191 {
192 list = new ArrayList();
193 outParameterForStatementParameters.put(sql, list);
194 }
195 list.add(new MockOutParameterWrapper(new HashMap(outParameters), new HashMap(parameters)));
196 }
197
198 private class MockOutParameterWrapper extends ParameterWrapper
199 {
200 private Map outParameter;
201
202 public MockOutParameterWrapper(Map outParameter, Map parameters)
203 {
204 super(parameters);
205 this.outParameter = outParameter;
206 }
207
208 public Map getOutParameter()
209 {
210 return outParameter;
211 }
212 }
213 }