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 }