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