001 package com.mockrunner.jdbc; 002 003 import java.util.ArrayList; 004 import java.util.Collection; 005 import java.util.Iterator; 006 import java.util.List; 007 import java.util.Map; 008 009 import com.mockrunner.util.common.StringUtil; 010 011 /** 012 * Helper class for finding matching SQL statements based on various 013 * search parameters. The search parameters are: 014 * <br> 015 * <code>caseSensitive</code> do a case sensitive match (default is <code>false</code>) 016 * <br> 017 * <code>exactMatch</code> the strings must match exactly, the parameter <code>caseSensitive</code> 018 * is recognized, but <code>useRegularExpression</code> is irrelevant, 019 * if <code>exactMatch</code> is <code>true</code> (default is <code>false</code>) 020 * <br> 021 * <code>useRegularExpression</code> use regular expressions for matching, if this parameter is 022 * <code>false</code>, strings match, if one string starts with the other 023 * (default is <code>false</code>) 024 */ 025 public class SQLStatementMatcher 026 { 027 private boolean caseSensitive = false; 028 private boolean exactMatch = false; 029 private boolean useRegularExpressions = false; 030 031 public SQLStatementMatcher(boolean caseSensitive, boolean exactMatch) 032 { 033 this(caseSensitive, exactMatch, false); 034 } 035 036 public SQLStatementMatcher(boolean caseSensitive, boolean exactMatch, boolean useRegularExpressions) 037 { 038 this.caseSensitive = caseSensitive; 039 this.exactMatch = exactMatch; 040 this.useRegularExpressions = useRegularExpressions; 041 } 042 043 /** 044 * Compares all keys in the specified <code>Map</code> with the 045 * specified query string using the method {@link #doStringsMatch}. 046 * If the strings match, the corresponding object from the <code>Map</code> 047 * is added to the resulting <code>List</code>. 048 * @param dataMap the source <code>Map</code> 049 * @param query the query string that must match the keys in <i>dataMap</i> 050 * @param queryContainsMapData only matters if <i>isExactMatch</i> is <code>false</code>, 051 * specifies if query must be contained in the <code>Map</code> keys (<code>false</code>) 052 * or if query must contain the <code>Map</code> keys (<code>true</code>) 053 * @return the result <code>List</code> 054 */ 055 public List getMatchingObjects(Map dataMap, String query, boolean resolveCollection, boolean queryContainsMapData) 056 { 057 if(null == query) query = ""; 058 Iterator iterator = dataMap.keySet().iterator(); 059 ArrayList resultList = new ArrayList(); 060 while(iterator.hasNext()) 061 { 062 String nextKey = (String)iterator.next(); 063 String source, currentQuery; 064 if(queryContainsMapData) 065 { 066 source = query; 067 currentQuery = nextKey; 068 } 069 else 070 { 071 source = nextKey; 072 currentQuery = query; 073 } 074 if(doStringsMatch(source, currentQuery)) 075 { 076 Object matchingObject = dataMap.get(nextKey); 077 if(resolveCollection && (matchingObject instanceof Collection)) 078 { 079 resultList.addAll((Collection)matchingObject); 080 } 081 else 082 { 083 resultList.add(dataMap.get(nextKey)); 084 } 085 } 086 } 087 return resultList; 088 } 089 090 /** 091 * Compares all elements in the specified <code>Collection</code> with the 092 * specified query string using the method {@link #doStringsMatch}. 093 * @param col the <code>Collections</code> 094 * @param query the query string that must match the keys in <i>col</i> 095 * @param queryContainsData only matters if <i>exactMatch</i> is <code>false</code>, 096 * specifies if query must be contained in the <code>Collection</code> data (<code>false</code>) 097 * or if query must contain the <code>Collection</code> data (<code>true</code>) 098 * @return <code>true</code> if <i>col</i> contains <i>query</i>, false otherwise 099 */ 100 public boolean contains(Collection col, String query, boolean queryContainsData) 101 { 102 Iterator iterator = col.iterator(); 103 while(iterator.hasNext()) 104 { 105 String nextKey = (String)iterator.next(); 106 String source, currentQuery; 107 if(queryContainsData) 108 { 109 source = query; 110 currentQuery = nextKey; 111 } 112 else 113 { 114 source = nextKey; 115 currentQuery = query; 116 } 117 if(doStringsMatch(source, currentQuery)) return true; 118 } 119 return false; 120 } 121 122 /** 123 * Compares two strings and returns if they match. 124 * @param query the query string that must match source 125 * @param source the source string 126 * @return <code>true</code> of the strings match, <code>false</code> otherwise 127 */ 128 public boolean doStringsMatch(String source, String query) 129 { 130 if(null == source) source = ""; 131 if(null == query) query = ""; 132 if(useRegularExpressions && !exactMatch) 133 { 134 return doPerl5Match(source, query); 135 } 136 else 137 { 138 return doSimpleMatch(source, query); 139 } 140 } 141 142 private boolean doSimpleMatch(String source, String query) 143 { 144 if(exactMatch) 145 { 146 return StringUtil.matchesExact(source, query, caseSensitive); 147 } 148 else 149 { 150 return StringUtil.matchesContains(source, query, caseSensitive); 151 } 152 } 153 154 private boolean doPerl5Match(String source, String query) 155 { 156 return StringUtil.matchesPerl5(source, query, caseSensitive); 157 } 158 }