RESOLVED - issue BATCH-1106: SqlPagingQueryProviderFactoryBean ascending should default to true

Plus change PatternMatcher to match patterns instead of prefixes.
This commit is contained in:
dsyer
2009-02-27 22:41:22 +00:00
parent ab1419df4c
commit 6babb9b262
7 changed files with 88 additions and 64 deletions

View File

@@ -58,9 +58,11 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean {
private String sortKey;
private boolean ascending = true;
private Map<DatabaseType, AbstractSqlPagingQueryProvider> providers = new HashMap<DatabaseType, AbstractSqlPagingQueryProvider>();
private boolean ascending;
{
providers.put(DB2, new Db2PagingQueryProvider());
providers.put(DB2ZOS, new Db2PagingQueryProvider());

View File

@@ -39,7 +39,7 @@ import org.springframework.util.Assert;
* with the most specific, and the first match always succeeds.
*
* @see PrefixMatchingCompositeLineTokenizer
* @see PatternMatcher#matchPrefix(String, Map)
* @see PatternMatcher#match(String, Map)
*
* @author Dan Garrette
* @since 2.0
@@ -56,7 +56,7 @@ public class PrefixMatchingCompositeLineMapper<T> implements LineMapper<T>, Init
* int)
*/
public T mapLine(String line, int lineNumber) throws Exception {
return PatternMatcher.matchPrefix(line, this.fieldSetMappers).mapFieldSet(this.tokenizer.tokenize(line));
return PatternMatcher.match(line, this.fieldSetMappers).mapFieldSet(this.tokenizer.tokenize(line));
}
/*
@@ -75,6 +75,13 @@ public class PrefixMatchingCompositeLineMapper<T> implements LineMapper<T>, Init
}
public void setFieldSetMappers(Map<String, FieldSetMapper<T>> fieldSetMappers) {
this.fieldSetMappers = new LinkedHashMap<String, FieldSetMapper<T>>(fieldSetMappers);
this.fieldSetMappers = new LinkedHashMap<String, FieldSetMapper<T>>();
for (String key : fieldSetMappers.keySet()) {
FieldSetMapper<T> value = fieldSetMappers.get(key);
if (!key.endsWith("*")) {
key = key + "*";
}
this.fieldSetMappers.put(key, value);
}
}
}

View File

@@ -31,10 +31,11 @@ import org.springframework.util.Assert;
* are sorted starting with the most specific, and the first match always
* succeeds.
*
* @see PatternMatcher#matchPrefix(String, Map)
* @see PatternMatcher#match(String, Map)
*
* @author Ben Hale
* @author Dan Garrette
* @author Dave Syer
*/
public class PrefixMatchingCompositeLineTokenizer implements LineTokenizer, InitializingBean {
@@ -46,7 +47,7 @@ public class PrefixMatchingCompositeLineTokenizer implements LineTokenizer, Init
* @see org.springframework.batch.item.file.transform.LineTokenizer#tokenize(java.lang.String)
*/
public FieldSet tokenize(String line) {
return PatternMatcher.matchPrefix(line, this.tokenizers).tokenize(line);
return PatternMatcher.match(line, this.tokenizers).tokenize(line);
}
/*
@@ -60,6 +61,13 @@ public class PrefixMatchingCompositeLineTokenizer implements LineTokenizer, Init
}
public void setTokenizers(Map<String, LineTokenizer> tokenizers) {
this.tokenizers = new LinkedHashMap<String, LineTokenizer>(tokenizers);
this.tokenizers = new LinkedHashMap<String, LineTokenizer>();
for (String key : tokenizers.keySet()) {
LineTokenizer value = tokenizers.get(key);
if (!key.endsWith("*")) {
key = key + "*";
}
this.tokenizers.put(key, value);
}
}
}

View File

@@ -21,21 +21,14 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.springframework.util.Assert;
/**
* @author Dave Syer
* @author Dan Garrette
*/
public class PatternMatcher {
/**
* Used for reverse-sorting strings
*/
private static Comparator<String> STRING_REVERSE_COMPARATOR = new Comparator<String>() {
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
};
/**
* Lifted from AntPathMatcher in Spring Core. Tests whether or not a string
* matches against a pattern. The pattern may contain two special
@@ -43,13 +36,11 @@ public class PatternMatcher {
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern
* pattern to match against. Must not be <code>null</code>.
* @param str
* string which must be matched against the pattern. Must not be
* <code>null</code>.
* @param pattern pattern to match against. Must not be <code>null</code>.
* @param str string which must be matched against the pattern. Must not be
* <code>null</code>.
* @return <code>true</code> if the string matches against the pattern, or
* <code>false</code> otherwise.
* <code>false</code> otherwise.
*/
public static boolean match(String pattern, String str) {
char[] patArr = pattern.toCharArray();
@@ -179,12 +170,12 @@ public class PatternMatcher {
/**
* <p>
* This method takes a String line and a map from String prefixes to values
* of any type. During processing, the method will identify the most
* specific prefix in the map that matches the beginning of the line. Once
* the correct is identified, its value is returned. Note that if the map
* contains the empty string as a prefix, then it will serve as the
* "default" case, matching every non-null line given.
* This method takes a String key and a map from Strings to values of any
* type. During processing, the method will identify the most specific key
* in the map that matches the line. Once the correct is identified, its
* value is returned. Note that if the map contains the wildcard string "*"
* as a key, then it will serve as the "default" case, matching every
* line that does not match anything else.
*
* <p>
* If no matching prefix is found, a {@link IllegalStateException} will be
@@ -193,32 +184,34 @@ public class PatternMatcher {
* <p>
* Null keys are not allowed in the map.
*
* @param line
* An input string
* @param map
* A map with String prefixes as keys.
* @param line An input string
* @param map A map with String prefixes as keys.
* @return the value whose prefix matches the given line
*/
public static <S> S matchPrefix(String line, Map<String, S> map) {
public static <S> S match(String line, Map<String, S> map) {
S value = null;
if (line == null) {
throw new IllegalStateException("Could not handle a null line");
}
Assert.notNull(line, "A non-null key must be provided.");
// Sort keys to start with the most specific
List<String> sorted = new ArrayList<String>(map.keySet());
Collections.sort(sorted, STRING_REVERSE_COMPARATOR);
Collections.sort(sorted, new Comparator<String>() {
public int compare(String o1, String o2) {
String s1 = o1; // .replace('?', '{');
String s2 = o2; // .replace('*', '}');
return s2.compareTo(s1);
}
});
for (String key : sorted) {
if (line.startsWith(key)) {
if (PatternMatcher.match(key, line)) {
value = map.get(key);
break;
}
}
if (value == null) {
throw new IllegalStateException("Could not find a matching prefix for line=[" + line + "]");
throw new IllegalStateException("Could not find a matching pattern for key=[" + line + "]");
}
return value;
}
}