Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.mockrunner.jdbc;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.mockrunner.mock.jdbc.MockResultSet;
import com.mockrunner.util.common.ArrayUtil;
/**
* Abstract base class for all ResultSet handlers.
* Used to coordinate ResultSet objects for a
* statement. You can use this class to prepare ResultSet
* objects and update count values that are returned by the
* execute method of a statement, if the current
* SQL string matches.
* Furthermore it can be used to create ResultSet objects.
* Please note that the ResultSet objects you create and
* prepare with this handler are cloned when executing statements.
* So you cannot rely on object identity. You have to use the id
* of the ResultSet to identify it.
* The ResultSet objects returned by {@link #getReturnedResultSets}
* are actually the instances the executed statements returned.
*/
public abstract class AbstractResultSetHandler
{
private boolean caseSensitive = false;
private boolean exactMatch = false;
private boolean useRegularExpressions = false;
private boolean continueProcessingOnBatchFailure = false;
private Object globalResultSets;
private Map resultSetsForStatement = new TreeMap();
private Object globalUpdateCounts;
private Map updateCountForStatement = new TreeMap();
private MockResultSet globalGeneratedKeys;
private Map generatedKeysForStatement = new TreeMap();
private Map returnsResultSetMap = new TreeMap();
private Map throwsSQLException = new TreeMap();
private List executedStatements = new ArrayList();
private List returnedResultSets = new ArrayList();
/**
* Creates a new ResultSet with a
* random id.
* @return the new ResultSet
*/
public MockResultSet createResultSet()
{
return new MockResultSet(String.valueOf(Math.random()));
}
/**
* Creates a new ResultSet with the specified id.
* @param id the id
* @return the new ResultSet
*/
public MockResultSet createResultSet(String id)
{
return new MockResultSet(id);
}
/**
* Returns a new ResultSet created by the specified factory.
* Creates a random id.
* @param factory the {@link ResultSetFactory}
* @return the new ResultSet
*/
public MockResultSet createResultSet(ResultSetFactory factory)
{
return factory.create(String.valueOf(Math.random()));
}
/**
* Returns a new ResultSet created by the specified factory.
* @param id the id
* @param factory the {@link ResultSetFactory}
* @return the new ResultSet
*/
public MockResultSet createResultSet(String id, ResultSetFactory factory)
{
return factory.create(id);
}
/**
* Set if specified SQL strings should be handled case sensitive.
* Defaults to to false, i.e. INSERT is the same
* as insert.
* Please note that this method controls SQL statement
* matching for prepared results and update counts, i.e. what
* statements the tested application has to execute to receive
* a specified result. Unlike {@link JDBCTestModule#setCaseSensitive(boolean)}
* it does not control the statement matching of {@link JDBCTestModule}
* methods.
* @param caseSensitive enable or disable case sensitivity
*/
public void setCaseSensitive(boolean caseSensitive)
{
this.caseSensitive = caseSensitive;
}
/**
* Set if specified SQL statements must match exactly.
* Defaults to false, i.e. the SQL string
* does not need to match exactly. If the original statement
* is insert into mytable values(?, ?, ?)
* the string insert into mytable will match this statement.
* Usually false is the best choice, so
* prepared ResultSet objects do not have
* to match exactly the current statements SQL string.
* The current SQL string just has to contain the SQL string
* for the prepared prepared ResultSet.
* Please note that this method controls SQL statement
* matching for prepared results and update counts, i.e. what
* statements the tested application has to execute to receive
* a specified result. Unlike {@link JDBCTestModule#setExactMatch(boolean)}
* it does not control the statement matching of {@link JDBCTestModule}
* methods.
* @param exactMatch enable or disable exact matching
*/
public void setExactMatch(boolean exactMatch)
{
this.exactMatch = exactMatch;
}
/**
* Set if regular expressions should be used when matching
* SQL statements. Irrelevant if exactMatch is
* true. Default is false, i.e. you
* cannot use regular expressions and matching is based
* on string comparison.
* Please note that this method controls SQL statement
* matching for prepared results and update counts, i.e. what
* statements the tested application has to execute to receive
* a specified result. Unlike {@link JDBCTestModule#setUseRegularExpressions(boolean)}
* it does not control the statement matching of {@link JDBCTestModule}
* methods.
* @param useRegularExpressions should regular expressions be used
*/
public void setUseRegularExpressions(boolean useRegularExpressions)
{
this.useRegularExpressions = useRegularExpressions;
}
/**
* Set if batch processing should be continued if one of the commands
* in the batch fails. This behaviour is driver dependend. The default is
* false, i.e. if a command fails with an exception,
* batch processing will not continue and the remaining commands
* will not be executed.
* @param continueProcessingOnBatchFailure should batch processing be continued
*/
public void setContinueProcessingOnBatchFailure(boolean continueProcessingOnBatchFailure)
{
this.continueProcessingOnBatchFailure = continueProcessingOnBatchFailure;
}
/**
* Collects all SQL strings that were executed.
* @param sql the SQL string
*/
public void addExecutedStatement(String sql)
{
executedStatements.add(sql);
}
/**
* Collects all ResultSet objects that were returned by
* a Statement, PreparedStatement or
* CallableStatement.
* @param resultSet the ResultSet
*/
public void addReturnedResultSet(MockResultSet resultSet)
{
if(null == resultSet) return;
returnedResultSets.add(resultSet);
}
/**
* Collects all ResultSet[] objects that were returned by
* a Statement, PreparedStatement or
* CallableStatement. Called if a statement returns
* multiple result sets.
* @param resultSets the ResultSet[]
*/
public void addReturnedResultSets(MockResultSet[] resultSets)
{
if(null == resultSets) return;
returnedResultSets.add(resultSets);
}
/**
* Returns the List of all executed SQL strings.
* @return the List of executed SQL strings
*/
public List getExecutedStatements()
{
return Collections.unmodifiableList(executedStatements);
}
/**
* Returns the List of all returned ResultSet
* or ResultSet[] objects. The List contains
* arrays of result sets, if a query returned multiple result sets.
* If a query returned multiple result sets, the list will always contain
* the full array of ResultSet objects that were prepared, even
* if {@link com.mockrunner.mock.jdbc.MockStatement#getMoreResults()} was
* not called for all the result sets.
* @return the List of returned ResultSet or ResultSet[] objects
*/
public List getReturnedResultSets()
{
return Collections.unmodifiableList(returnedResultSets);
}
/**
* Clears all prepared ResultSet objects.
*/
public void clearResultSets()
{
resultSetsForStatement.clear();
}
/**
* Clears all prepared update counts.
*/
public void clearUpdateCounts()
{
updateCountForStatement.clear();
}
/**
* Clears the definitions if statements return
* ResultSet objects or update counts.
*/
public void clearReturnsResultSet()
{
returnsResultSetMap.clear();
}
/**
* Clears the list of statements that should throw an exception.
*/
public void clearThrowsSQLException()
{
throwsSQLException.clear();
}
/**
* Clears the list of statements that return generated keys.
*/
public void clearGeneratedKeys()
{
generatedKeysForStatement.clear();
}
/**
* Clears the prepared global ResultSet.
*/
public void clearGlobalResultSet()
{
this.globalResultSets = null;
}
/**
* Clears the prepared global generated keys ResultSet.
*/
public void clearGlobalGeneratedKeys()
{
this.globalGeneratedKeys = null;
}
/**
* Clears the prepared global update count.
*/
public void clearGlobalUpdateCount()
{
this.globalUpdateCounts = null;
}
/**
* Returns the Map of all ResultSet
* objects, that were added with {@link #prepareResultSet(String, MockResultSet)}.
* The SQL strings map to the corresponding ResultSet.
* @return the Map of ResultSet objects
*/
public Map getResultSetMap()
{
return Collections.unmodifiableMap(resultSetsForStatement);
}
/**
* Returns the Map of all update counts, that were added
* with {@link #prepareUpdateCount(String, int)}.
* The SQL strings map to the corresponding update count as
* Integer object.
* @return the Map of ResultSet objects
*/
public Map getUpdateCountMap()
{
return Collections.unmodifiableMap(updateCountForStatement);
}
/**
* Returns the Map of all generated keys ResultSet
* objects, that were added with {@link #prepareGeneratedKeys(String, MockResultSet)}.
* The SQL strings map to the corresponding generated keys ResultSet.
* @return the Map of generated keys ResultSet objects
*/
public Map getGeneratedKeysMap()
{
return Collections.unmodifiableMap(generatedKeysForStatement);
}
/**
* Returns the first ResultSet that matches the
* specified SQL string. If the specified SQL string was
* prepared to return multiple result sets, the first one will
* be returned.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the corresponding {@link MockResultSet}
*/
public MockResultSet getResultSet(String sql)
{
Object resultSets = getMatchingResultSets(sql);
if(null == resultSets) return null;
if(resultSets instanceof MockResultSet)
{
return (MockResultSet)resultSets;
}
else if(resultSets instanceof MockResultSet[])
{
MockResultSet[] actualResults = (MockResultSet[])resultSets;
if(actualResults.length > 0)
{
return actualResults[0];
}
}
return null;
}
/**
* Returns the first ResultSet[] that matches the
* specified SQL string. If the specified SQL string was
* prepared to return one single result set, this ResultSet
* will be wrapped in an array with one element.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the corresponding MockResultSet[]
*/
public MockResultSet[] getResultSets(String sql)
{
Object resultSets = getMatchingResultSets(sql);
if(null == resultSets) return null;
if(resultSets instanceof MockResultSet)
{
return new MockResultSet[] {(MockResultSet)resultSets};
}
else if(resultSets instanceof MockResultSet[])
{
return (MockResultSet[])resultSets;
}
return null;
}
/**
* Returns the if the specified SQL string returns multiple result sets.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return true if the query returns multiple result sets,
* false otherwise
*/
public boolean hasMultipleResultSets(String sql)
{
Object resultSets = getMatchingResultSets(sql);
return (resultSets instanceof MockResultSet[]);
}
private Object getMatchingResultSets(String sql)
{
SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
List list = matcher.getMatchingObjects(resultSetsForStatement, sql, true, true);
if(null != list && list.size() > 0)
{
return list.get(0);
}
return null;
}
/**
* Returns the global ResultSet.
* If an array of global result sets was prepared, the first one will
* be returned.
* @return the global {@link MockResultSet}
*/
public MockResultSet getGlobalResultSet()
{
if(null == globalResultSets) return null;
if(globalResultSets instanceof MockResultSet)
{
return (MockResultSet)globalResultSets;
}
MockResultSet[] resultSets = getGlobalResultSets();
if(null != resultSets && resultSets.length > 0)
{
return resultSets[0];
}
return null;
}
/**
* Returns the global ResultSet[].
* If one single ResultSet was prepared, this ResultSet
* will be wrapped in an array with one element.
* @return the global MockResultSet[]
*/
public MockResultSet[] getGlobalResultSets()
{
if(null == globalResultSets) return null;
if(globalResultSets instanceof MockResultSet[])
{
return (MockResultSet[])globalResultSets;
}
return new MockResultSet[] {(MockResultSet)globalResultSets};
}
/**
* Returns if multiple global result sets have been prepared, i.e. if
* an array of global result sets was prepared.
* @return true if an array of global result sets was prepared,
* false otherwise
*/
public boolean hasMultipleGlobalResultSets()
{
return (globalResultSets instanceof MockResultSet[]);
}
/**
* Returns the first update count that matches the
* specified SQL string. If the specified SQL string was
* prepared to return multiple update counts, the first one will
* be returned.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the corresponding update count
*/
public Integer getUpdateCount(String sql)
{
Object updateCounts = getMatchingUpdateCounts(sql);
if(null == updateCounts) return null;
if(updateCounts instanceof Integer)
{
return (Integer)updateCounts;
}
else if(updateCounts instanceof Integer[])
{
Integer[] actualUpdateCounts = (Integer[])updateCounts;
if(actualUpdateCounts.length > 0)
{
return actualUpdateCounts[0];
}
}
return null;
}
/**
* Returns the first update count array that matches the
* specified SQL string. If the specified SQL string was
* prepared to return one update count, this value
* will be wrapped in an array with one element.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the corresponding update count array
*/
public Integer[] getUpdateCounts(String sql)
{
Object updateCounts = getMatchingUpdateCounts(sql);
if(null == updateCounts) return null;
if(updateCounts instanceof Integer)
{
return new Integer[] {(Integer)updateCounts};
}
else if(updateCounts instanceof Integer[])
{
return (Integer[])updateCounts;
}
return null;
}
/**
* Returns the if the specified SQL string returns multiple update counts.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return true if the SQL string returns multiple update counts,
* false otherwise
*/
public boolean hasMultipleUpdateCounts(String sql)
{
Object updateCounts = getMatchingUpdateCounts(sql);
return (updateCounts instanceof Integer[]);
}
private Object getMatchingUpdateCounts(String sql)
{
SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
List list = matcher.getMatchingObjects(updateCountForStatement, sql, true, true);
if(null != list && list.size() > 0)
{
return list.get(0);
}
return null;
}
/**
* Returns the global update count for executeUpdate calls.
* If an array of global update counts was prepared, the first one will
* be returned.
* @return the global update count
*/
public int getGlobalUpdateCount()
{
if(null == globalUpdateCounts) return 0;
if(globalUpdateCounts instanceof Integer)
{
return ((Integer)globalUpdateCounts).intValue();
}
int[] updateCounts = getGlobalUpdateCounts();
if(null != updateCounts && updateCounts.length > 0)
{
return updateCounts[0];
}
return 0;
}
/**
* Returns the array of global update counts.
* If one single update count value was prepared, this value
* will be wrapped in an array with one element.
* @return the array of global update counts
*/
public int[] getGlobalUpdateCounts()
{
if(null == globalUpdateCounts) return null;
if(globalUpdateCounts instanceof int[])
{
return (int[])globalUpdateCounts;
}
return new int[] {((Integer)globalUpdateCounts).intValue()};
}
/**
* Returns if multiple global update counts have been prepared, i.e. if
* an array of global update counts was prepared.
* @return true if an array of global update counts was prepared,
* false otherwise
*/
public boolean hasMultipleGlobalUpdateCounts()
{
return (globalUpdateCounts instanceof int[]);
}
/**
* Returns the first generated keys ResultSet that
* matches the specified SQL string. Please note that you can modify
* the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the corresponding generated keys {@link MockResultSet}
*/
public MockResultSet getGeneratedKeys(String sql)
{
SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
List list = matcher.getMatchingObjects(generatedKeysForStatement, sql, true, true);
if(null != list && list.size() > 0)
{
return (MockResultSet)list.get(0);
}
return null;
}
/**
* Returns the global generated keys ResultSet.
* @return the global generated keys {@link MockResultSet}
*/
public MockResultSet getGlobalGeneratedKeys()
{
return globalGeneratedKeys;
}
/**
* Returns if the specified SQL string is a select that returns
* a ResultSet.
* Usually you do not have to specify this.
* It is assumed that an SQL string returns a ResultSet
* if it contains the string select (case insensitive).
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return true if the SQL string returns a ResultSet
*/
public Boolean getReturnsResultSet(String sql)
{
SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
List list = matcher.getMatchingObjects(returnsResultSetMap, sql, true, true);
if(null != list && list.size() > 0)
{
return (Boolean)list.get(0);
}
return null;
}
/**
* Returns if the specified SQL string should raise an exception.
* This can be used to simulate database exceptions.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return true if the specified SQL string should raise an exception,
* false otherwise
*/
public boolean getThrowsSQLException(String sql)
{
return (getSQLException(sql) != null);
}
/**
* Returns the SQLException the specified SQL string
* should throw. Returns null if the specified SQL string
* should not throw an exception.
* This can be used to simulate database exceptions.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @return the SQLException or null
*/
public SQLException getSQLException(String sql)
{
SQLStatementMatcher matcher = new SQLStatementMatcher(getCaseSensitive(), getExactMatch(), getUseRegularExpressions());
List list = matcher.getMatchingObjects(throwsSQLException, sql, true, true);
if(null == list || list.size() == 0) return null;
return (SQLException)list.get(0);
}
/**
* Prepare a ResultSet for a specified SQL string.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param resultSet the corresponding {@link MockResultSet}
*/
public void prepareResultSet(String sql, MockResultSet resultSet)
{
resultSetsForStatement.put(sql, resultSet);
}
/**
* Prepare an array of ResultSet objects for a specified SQL string.
* This method can be used for queries that return multiple result sets.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param resultSets the corresponding MockResultSet[]
*/
public void prepareResultSets(String sql, MockResultSet[] resultSets)
{
resultSetsForStatement.put(sql, resultSets.clone());
}
/**
* Prepare the global ResultSet.
* @param resultSet the {@link MockResultSet}
*/
public void prepareGlobalResultSet(MockResultSet resultSet)
{
this.globalResultSets = resultSet;
}
/**
* Prepare an array of global ResultSet objects.
* @param resultSets the corresponding MockResultSet[]
*/
public void prepareGlobalResultSets(MockResultSet[] resultSets)
{
this.globalResultSets = (MockResultSet[])resultSets.clone();
}
/**
* Prepare the update count for executeUpdate calls
* for a specified SQL string. Please note that you can modify
* the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param updateCount the update count
*/
public void prepareUpdateCount(String sql, int updateCount)
{
updateCountForStatement.put(sql, new Integer(updateCount));
}
/**
* Prepare an array update count values for executeUpdate calls
* for a specified SQL string. This method can be used if multiple update counts
* are returned.
* Please note that you can modify the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param updateCounts the update count array
*/
public void prepareUpdateCounts(String sql, int[] updateCounts)
{
updateCountForStatement.put(sql, ArrayUtil.convertToObjectArray(updateCounts));
}
/**
* Prepare the global update count for executeUpdate calls.
* @param updateCount the update count
*/
public void prepareGlobalUpdateCount(int updateCount)
{
this.globalUpdateCounts = new Integer(updateCount);
}
/**
* Prepare an array of global update count values for executeUpdate calls.
* @param updateCounts the update count array
*/
public void prepareGlobalUpdateCounts(int[] updateCounts)
{
this.globalUpdateCounts = (int[])updateCounts.clone();
}
/**
* Prepare the generated keys ResultSet
* for a specified SQL string. Please note that you can modify
* the match parameters with {@link #setCaseSensitive},
* {@link #setExactMatch} and {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param generatedKeysResult the generated keys {@link MockResultSet}
*/
public void prepareGeneratedKeys(String sql, MockResultSet generatedKeysResult)
{
generatedKeysForStatement.put(sql, generatedKeysResult);
}
/**
* Prepare the global generated keys ResultSet.
* @param generatedKeysResult the generated keys {@link MockResultSet}
*/
public void prepareGlobalGeneratedKeys(MockResultSet generatedKeysResult)
{
this.globalGeneratedKeys = generatedKeysResult;
}
/**
* Prepare if the specified SQL string is a select that returns
* a ResultSet. Usually you do not have to specify this.
* It is assumed that an SQL string returns a ResultSet
* if it contains the string select (case insensitive).
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param returnsResultSet specify if the SQL string returns a ResultSet
*/
public void prepareReturnsResultSet(String sql, boolean returnsResultSet)
{
returnsResultSetMap.put(sql, new Boolean(returnsResultSet));
}
/**
* Prepare that the specified SQL string should raise an exception.
* This can be used to simulate database exceptions. This method
* creates an SQLException and will throw this exception.
* With {@link #prepareThrowsSQLException(String, SQLException)} you
* can specify the exception.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
*/
public void prepareThrowsSQLException(String sql)
{
throwsSQLException.put(sql, new SQLException("Statement " + sql + " was specified to throw an exception"));
}
/**
* Prepare that the specified SQL string should raise an exception.
* This can be used to simulate database exceptions. This method
* takes an exception object that will be thrown.
* Please note that you can modify the match parameters with
* {@link #setCaseSensitive}, {@link #setExactMatch} and
* {@link #setUseRegularExpressions}.
* @param sql the SQL string
* @param exc the SQLException that should be thrown
*/
public void prepareThrowsSQLException(String sql, SQLException exc)
{
throwsSQLException.put(sql, exc);
}
/**
* Returns if specified SQL strings should be handled case sensitive.
* @return is case sensitivity enabled or disabled
*/
protected boolean getCaseSensitive()
{
return caseSensitive;
}
/**
* Returns if specified SQL statements must match exactly.
* @return is exact matching enabled or disabled
*/
protected boolean getExactMatch()
{
return exactMatch;
}
/**
* Returns if regular expression matching is enabled
* @return if regular expression matching is enabled
*/
protected boolean getUseRegularExpressions()
{
return useRegularExpressions;
}
/**
* Returns if batch processing should be continued if one of
* the commands in the batch fails.
* @return if batch processing should be continued
*/
public boolean getContinueProcessingOnBatchFailure()
{
return continueProcessingOnBatchFailure;
}
}