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