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 }