Only in ignore case situations is the string normalized via the method normalize.

Made normalize a protected method so the default behavior can now be modified.

Modified tests accordingly.
This commit is contained in:
Vesa Martilla 2011-01-25 14:32:17 +00:00
parent a75ce7c3c9
commit 8e4ecbb01b
2 changed files with 79 additions and 66 deletions

View File

@ -87,20 +87,28 @@ public class LuceneSerializer {
return bq;
} else if (op == Ops.LIKE) {
return like(operation, metadata);
} else if (op == Ops.EQ_OBJECT || op == Ops.EQ_PRIMITIVE || op == Ops.EQ_IGNORE_CASE) {
return eq(operation, metadata);
} else if (op == Ops.EQ_OBJECT || op == Ops.EQ_PRIMITIVE) {
return eq(operation, metadata, false);
} else if (op == Ops.EQ_IGNORE_CASE) {
return eq(operation, metadata, true);
} else if (op == Ops.NE_OBJECT || op == Ops.NE_PRIMITIVE) {
return ne(operation, metadata);
} else if (op == Ops.STARTS_WITH || op == Ops.STARTS_WITH_IC) {
return startsWith(metadata, operation);
} else if (op == Ops.ENDS_WITH || op == Ops.ENDS_WITH_IC) {
return endsWith(operation, metadata);
} else if (op == Ops.STRING_CONTAINS || op == Ops.STRING_CONTAINS_IC) {
return stringContains(operation, metadata);
return ne(operation, metadata, false);
} else if (op == Ops.STARTS_WITH) {
return startsWith(metadata, operation, false);
} else if (op == Ops.STARTS_WITH_IC) {
return startsWith(metadata, operation, true);
} else if (op == Ops.ENDS_WITH) {
return endsWith(operation, metadata, false);
} else if (op == Ops.ENDS_WITH_IC) {
return endsWith(operation, metadata, true);
} else if (op == Ops.STRING_CONTAINS) {
return stringContains(operation, metadata, false);
} else if (op == Ops.STRING_CONTAINS_IC) {
return stringContains(operation, metadata, true);
} else if (op == Ops.BETWEEN) {
return between(operation, metadata);
} else if (op == Ops.IN) {
return in(operation, metadata);
return in(operation, metadata, false);
} else if (op == Ops.LT || op == Ops.BEFORE) {
return lt(operation, metadata);
} else if (op == Ops.GT || op == Ops.AFTER) {
@ -143,7 +151,7 @@ public class LuceneSerializer {
verifyArguments(operation);
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
String[] terms = createTerms(operation.getArg(1), tokenized, metadata);
if (terms.length > 1) {
BooleanQuery bq = new BooleanQuery();
@ -156,16 +164,16 @@ public class LuceneSerializer {
}
@SuppressWarnings("unchecked")
protected Query eq(Operation<?> operation, QueryMetadata metadata) {
protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
verifyArguments(operation);
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
if (Number.class.isAssignableFrom(operation.getArg(1).getType())) {
return new TermQuery(new Term(field, convertNumber(((Constant<Number>) operation
.getArg(1)).getConstant())));
}
return eq(field, createTerms(operation.getArg(1), tokenized, metadata), metadata);
return eq(field, createTerms(operation.getArg(1), tokenized, metadata), ignoreCase);
}
@ -192,7 +200,7 @@ public class LuceneSerializer {
}
}
protected Query eq(String field, String[] terms, QueryMetadata metadata) {
protected Query eq(String field, String[] terms, boolean ignoreCase) {
if (terms.length > 1) {
PhraseQuery pq = new PhraseQuery();
for (String s : terms) {
@ -200,11 +208,11 @@ public class LuceneSerializer {
}
return pq;
}
return new TermQuery(new Term(field, normalize(terms[0])));
return new TermQuery(new Term(field, (ignoreCase ? normalize(terms[0]) : terms[0])));
}
@SuppressWarnings("unchecked")
protected Query in(Operation<?> operation, QueryMetadata metadata) {
protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
Collection values = (Collection) ((Constant) operation.getArg(1)).getConstant();
@ -212,18 +220,18 @@ public class LuceneSerializer {
for (Object value : values) {
// FIXME : use proper splitting
String str = convert(value);
bq.add(eq(field, tokenized ? StringUtils.split(str) : new String[] {str }, metadata), Occur.SHOULD);
bq.add(eq(field, tokenized ? StringUtils.split(str) : new String[] { str }, ignoreCase), Occur.SHOULD);
}
return bq;
}
protected Query ne(Operation<?> operation, QueryMetadata metadata) {
protected Query ne(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
BooleanQuery bq = new BooleanQuery();
bq.add(new BooleanClause(eq(operation, metadata), Occur.MUST_NOT));
bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), Occur.MUST_NOT));
return bq;
}
protected Query startsWith(QueryMetadata metadata, Operation<?> operation) {
protected Query startsWith(QueryMetadata metadata, Operation<?> operation, boolean ignoreCase) {
verifyArguments(operation);
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
@ -232,14 +240,14 @@ public class LuceneSerializer {
BooleanQuery bq = new BooleanQuery();
for (int i = 0; i < terms.length; ++i) {
String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*";
bq.add(new WildcardQuery(new Term(field, normalize(s))), Occur.MUST);
bq.add(new WildcardQuery(new Term(field, (ignoreCase ? normalize(s) : s))), Occur.MUST);
}
return bq;
}
return new PrefixQuery(new Term(field, normalize(terms[0])));
}
protected Query stringContains(Operation<?> operation, QueryMetadata metadata) {
protected Query stringContains(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
verifyArguments(operation);
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
@ -247,14 +255,14 @@ public class LuceneSerializer {
if (terms.length > 1) {
BooleanQuery bq = new BooleanQuery();
for (String s : terms) {
bq.add(new WildcardQuery(new Term(field, "*" + normalize(s) + "*")), Occur.MUST);
bq.add(new WildcardQuery(new Term(field, "*" + (ignoreCase ? normalize(s) : s) + "*")), Occur.MUST);
}
return bq;
}
return new WildcardQuery(new Term(field, "*" + normalize(terms[0]) + "*"));
}
protected Query endsWith(Operation<?> operation, QueryMetadata metadata) {
protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) {
verifyArguments(operation);
String field = toField(operation.getArg(0));
boolean tokenized = isTokenized(operation.getArg(0));
@ -263,7 +271,7 @@ public class LuceneSerializer {
BooleanQuery bq = new BooleanQuery();
for (int i = 0; i < terms.length; ++i) {
String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*";
bq.add(new WildcardQuery(new Term(field, normalize(s))), Occur.MUST);
bq.add(new WildcardQuery(new Term(field, (ignoreCase ? normalize(s) : s))), Occur.MUST);
}
return bq;
}
@ -351,7 +359,7 @@ public class LuceneSerializer {
/**
* template method, override to customize
*
*
* @param path
* @return
*/
@ -365,8 +373,8 @@ public class LuceneSerializer {
}
return rv;
}
protected boolean isTokenized(Expression<?> expr) {
private boolean isTokenized(Expression<?> expr) {
if (expr instanceof Path<?>) {
return isTokenized((Path<?>) expr);
} else if (expr instanceof Operation<?>) {
@ -374,13 +382,13 @@ public class LuceneSerializer {
if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) {
return isTokenized(operation.getArg(0));
}
}
return splitTerms;
}
return splitTerms;
}
/**
* template method, override to customize
*
* Template method, override to customize.
*
* @param arg
* @return
*/
@ -412,10 +420,10 @@ public class LuceneSerializer {
return split(expr, tokenized, convert(expr));
}
}
/**
* template method, override to customize
*
* Template method, override to customize.
*
* @param object
* @return
*/
@ -451,7 +459,12 @@ public class LuceneSerializer {
}
}
private String normalize(String s) {
/**
* Template method, override to customize.
* @param s
* @return
*/
protected String normalize(String s) {
return lowerCase ? s.toLowerCase(Locale.ENGLISH) : s;
}

View File

@ -185,13 +185,13 @@ public class LuceneSerializerTest {
@Test
public void eq() throws Exception {
testQuery(rating.eq("Good"), "rating:good", 1);
testQuery(rating.eq("good"), "rating:good", 1);
}
@Test
public void eq_with_deep_path() throws Exception{
StringPath deepPath = entityPath.get("property1", Object.class).getString("property2");
testQuery(deepPath.eq("Good"), "property1.property2:good", 0);
testQuery(deepPath.eq("good"), "property1.property2:good", 0);
}
@Test
@ -228,13 +228,13 @@ public class LuceneSerializerTest {
}
@Test
public void eq_Should_Not_Find_Results_But_Lucene_Semantics_Differs_From_Querydsls() throws Exception {
testQuery(title.eq("Jurassic"), "title:jurassic", 1);
public void Equals_Finds_Nothing_When_Case_Does_Not_Match() throws Exception {
testQuery(title.eq("Jurassic"), "title:Jurassic", 0);
}
@Test
public void eq_or_eq() throws Exception {
testQuery(title.eq("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1);
public void Title_Equals_Ignore_Case_Or_Year_Equals() throws Exception {
testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1);
}
@Test
@ -248,13 +248,13 @@ public class LuceneSerializerTest {
}
@Test
public void eq_and_eq_or_eq() throws Exception {
testQuery(title.eq("Jurassic Park").and(rating.eq("Bad")).or(author.eq("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1);
public void Equals_Ignore_Case_And_Or() throws Exception {
testQuery(title.equalsIgnoreCase("Jurassic Park").and(rating.equalsIgnoreCase("Bad")).or(author.equalsIgnoreCase("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1);
}
@Test
public void eq_or_eq_and_eq_Does_Not_Find_Results() throws Exception {
testQuery(title.eq("Jeeves").or(rating.eq("Superb")).and(author.eq("Michael Crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0);
testQuery(title.eq("jeeves").or(rating.eq("superb")).and(author.eq("michael crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0);
}
@Test
@ -284,8 +284,8 @@ public class LuceneSerializerTest {
}
@Test
public void eq_not_or_eq() throws Exception {
testQuery(title.eq("House").not().or(rating.eq("Good")), "-title:house rating:good", 1);
public void Title_Equals_Ignore_Case_Negation_Or_Rating_Equals_Ignore_Case() throws Exception {
testQuery(title.equalsIgnoreCase("House").not().or(rating.equalsIgnoreCase("Good")), "-title:house rating:good", 1);
}
@Test
@ -295,12 +295,12 @@ public class LuceneSerializerTest {
@Test
public void eq_and_eq_not_Does_Not_Find_Results_Because_Second_Expression_Finds_Nothing() throws Exception {
testQuery(rating.eq("Superb").and(title.eq("House").not()), "+rating:superb -title:house", 0);
testQuery(rating.eq("superb").and(title.eq("house").not()), "+rating:superb -title:house", 0);
}
@Test
public void ne_Does_Not_Find_Results() throws Exception {
testQuery(title.ne("House"), "-title:house", 0);
testQuery(title.ne("house"), "-title:house", 0);
}
@Test
@ -310,12 +310,12 @@ public class LuceneSerializerTest {
@Test
public void ne_or_eq() throws Exception {
testQuery(title.ne("Jurassic Park").or(rating.eq("Lousy")), "-title:\"jurassic park\" rating:lousy", 0);
testQuery(title.ne("jurassic park").or(rating.eq("lousy")), "-title:\"jurassic park\" rating:lousy", 0);
}
@Test
public void ne_and_eq() throws Exception {
testQuery(title.ne("House").and(rating.eq("Good")), "-title:house +rating:good", 1);
testQuery(title.ne("house").and(rating.eq("good")), "-title:house +rating:good", 1);
}
@Test
@ -325,12 +325,12 @@ public class LuceneSerializerTest {
@Test
public void startsWith_Phrase() throws Exception {
testQuery(title.startsWith("Jurassic Par"), "+title:jurassic* +title:*par*", 1);
testQuery(title.startsWith("jurassic par"), "+title:jurassic* +title:*par*", 1);
}
@Test
public void startsWith_Phrase_Does_Not_Find_Results() throws Exception {
testQuery(title.startsWith("urassic Par"), "+title:urassic* +title:*par*", 0);
public void Starts_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception {
testQuery(title.startsWithIgnoreCase("urassic Par"), "+title:urassic* +title:*par*", 0);
}
@Test
@ -339,13 +339,13 @@ public class LuceneSerializerTest {
}
@Test
public void endsWith_Phrase() throws Exception {
testQuery(title.endsWith("sic Park"), "+title:*sic* +title:*park", 1);
public void Ends_With_Ignore_Case_Phrase() throws Exception {
testQuery(title.endsWithIgnoreCase("sic Park"), "+title:*sic* +title:*park", 1);
}
@Test
public void endsWith_Phrase_Does_Not_Find_Results() throws Exception {
testQuery(title.endsWith("sic Par"), "+title:*sic* +title:*par", 0);
public void Ends_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception {
testQuery(title.endsWithIgnoreCase("sic Par"), "+title:*sic* +title:*par", 0);
}
@Test
@ -354,8 +354,8 @@ public class LuceneSerializerTest {
}
@Test
public void contains_Phrase() throws Exception {
testQuery(title.contains("rassi Pa"), "+title:*rassi* +title:*pa*", 1);
public void Contains_Ignore_Case_Phrase() throws Exception {
testQuery(title.containsIgnoreCase("rassi Pa"), "+title:*rassi* +title:*pa*", 1);
}
@Test
@ -414,9 +414,9 @@ public class LuceneSerializerTest {
@Test
public void in() throws Exception {
testQuery(title.in(Arrays.asList("Jurassic","Park")), "title:jurassic title:park", 1);
testQuery(title.in("Jurassic","Park"), "title:jurassic title:park", 1);
testQuery(title.eq("Jurassic").or(title.eq("Park")), "title:jurassic title:park", 1);
testQuery(title.in(Arrays.asList("jurassic", "park")), "title:jurassic title:park", 1);
testQuery(title.in("jurassic","park"), "title:jurassic title:park", 1);
testQuery(title.eq("jurassic").or(title.eq("park")), "title:jurassic title:park", 1);
}
@Test
@ -630,12 +630,12 @@ public class LuceneSerializerTest {
@Test
public void various() throws Exception{
MatchingFilters filters = new MatchingFilters(Module.LUCENE, Target.LUCENE);
for (BooleanExpression filter : filters.string(title, StringConstant.create("Jurassic"))){
for (BooleanExpression filter : filters.string(title, StringConstant.create("jurassic park"))){
System.out.println(filter);
testQuery(filter, 1);
}
for (BooleanExpression filter : filters.string(author, StringConstant.create("Michael Crichton"))){
for (BooleanExpression filter : filters.string(author, StringConstant.create("michael crichton"))){
System.out.println(filter);
testQuery(filter, 1);
}