Skip to content

Commit a4fe77b

Browse files
Case insensitive relation check, fixes #17 (#24)
Also, custom relations case-insensitive.
1 parent 3a6427a commit a4fe77b

File tree

5 files changed

+46
-46
lines changed

5 files changed

+46
-46
lines changed

src/main/java/org/z3950/zing/cql/CQLParser.java

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class CQLParser {
2121
private CQLTokenizer lexer;
2222
private final int compat; // When false, implement CQL 1.2
2323
private final Set<String> customRelations = new HashSet<String>();
24-
24+
2525
public static final int V1POINT1 = 12368;
2626
public static final int V1POINT2 = 12369;
2727
public static final int V1POINT1SORT = 12370;
@@ -47,10 +47,10 @@ public CQLParser(int compat) {
4747
this.compat = compat;
4848
this.allowKeywordTerms = true;
4949
}
50-
50+
5151
/**
52-
* Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox'
53-
* to be used unquoted in terms. This constructor allows to create an instance
52+
* Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox'
53+
* to be used unquoted in terms. This constructor allows to create an instance
5454
* of a parser that prohibits this behavior while sacrificing compatibility.
5555
* @param compat CQL version compatibility
5656
* @param allowKeywordTerms when false registered keywords are disallowed in unquoted terms
@@ -59,7 +59,7 @@ public CQLParser(int compat, boolean allowKeywordTerms) {
5959
this.compat = compat;
6060
this.allowKeywordTerms = allowKeywordTerms;
6161
}
62-
62+
6363
/**
6464
* The new parser implements CQL 1.2
6565
*/
@@ -72,24 +72,25 @@ private static void debug(String str) {
7272
if (DEBUG)
7373
System.err.println("PARSEDEBUG: " + str);
7474
}
75-
75+
7676
/**
7777
* Registers custom relation in this parser. Note that when a custom relation
7878
* is registered the parser is no longer strictly compliant with the chosen spec.
79+
* Custom relations are case-insensitive.
7980
* @param relation
8081
* @return true if custom relation has not been registered already
8182
*/
8283
public boolean registerCustomRelation(String relation) {
83-
return customRelations.add(relation);
84+
return customRelations.add(relation.toLowerCase());
8485
}
85-
86+
8687
/**
8788
* Unregisters previously registered custom relation in this instance of the parser.
8889
* @param relation
8990
* @return true is relation has been previously registered
9091
*/
9192
public boolean unregisterCustomRelation(String relation) {
92-
return customRelations.remove(relation);
93+
return customRelations.remove(relation.toLowerCase());
9394
}
9495

9596
/**
@@ -117,7 +118,7 @@ public CQLNode parse(String cql)
117118
CQLNode root = parseTopLevelPrefixes("cql.serverChoice",
118119
new CQLRelation(compat == V1POINT2 ? "=" : "scr"));
119120
if (lexer.what() != CQLTokenizer.TT_EOF)
120-
throw new CQLParseException("junk after end: " + lexer.render(),
121+
throw new CQLParseException("junk after end: " + lexer.render(),
121122
lexer.pos());
122123

123124
return root;
@@ -194,7 +195,7 @@ private ModifierSet gatherModifiers(String base)
194195
match('/');
195196
if (lexer.what() != CQLTokenizer.TT_WORD)
196197
throw new CQLParseException("expected modifier, "
197-
+ "got " + lexer.render(),
198+
+ "got " + lexer.render(),
198199
lexer.pos());
199200
String type = lexer.value().toLowerCase();
200201
match(lexer.what());
@@ -241,7 +242,7 @@ private CQLNode parseTerm(String index, CQLRelation relation)
241242

242243
if (!isRelation())
243244
break; //we're done if no relation
244-
245+
245246
//render relation
246247
String relstr = (lexer.what() == CQLTokenizer.TT_WORD ?
247248
lexer.value() : lexer.render(lexer.what(), false));
@@ -282,40 +283,39 @@ private CQLNode parsePrefix(String index, CQLRelation relation,
282283

283284
return new CQLPrefixNode(name, identifier, node);
284285
}
285-
286+
286287
private boolean isWordOrString() {
287-
return CQLTokenizer.TT_WORD == lexer.what()
288+
return CQLTokenizer.TT_WORD == lexer.what()
288289
|| CQLTokenizer.TT_STRING == lexer.what();
289290
}
290291

291292
private boolean isRelation() {
292-
debug("isRelation: checking what()=" + lexer.what() +
293-
" (" + lexer.render() + ")");
294-
if (lexer.what() == CQLTokenizer.TT_WORD &&
295-
(lexer.value().indexOf('.') >= 0 ||
296-
lexer.value().equals("any") ||
297-
lexer.value().equals("all") ||
298-
lexer.value().equals("within") ||
299-
lexer.value().equals("encloses") ||
300-
(lexer.value().equals("exact") && compat != V1POINT2) ||
301-
(lexer.value().equals("scr") && compat != V1POINT2) ||
302-
(lexer.value().equals("adj") && compat == V1POINT2) ||
303-
customRelations.contains(lexer.value())))
304-
return true;
305-
293+
debug("isRelation: checking what()=" + lexer.what() +
294+
" (" + lexer.render() + ")");
295+
if (lexer.what() == CQLTokenizer.TT_WORD) {
296+
return lexer.value().indexOf('.') >= 0 ||
297+
lexer.value().equalsIgnoreCase("any") ||
298+
lexer.value().equalsIgnoreCase("all") ||
299+
lexer.value().equalsIgnoreCase("within") ||
300+
lexer.value().equalsIgnoreCase("encloses") ||
301+
(lexer.value().equalsIgnoreCase("exact") && compat != V1POINT2) ||
302+
(lexer.value().equalsIgnoreCase("scr") && compat != V1POINT2) ||
303+
(lexer.value().equalsIgnoreCase("adj") && compat == V1POINT2) ||
304+
customRelations.stream().anyMatch(r -> r.equalsIgnoreCase(lexer.value()));
305+
}
306306
return isSymbolicRelation();
307307
}
308308

309309
private boolean isSymbolicRelation() {
310-
debug("isSymbolicRelation: checking what()=" + lexer.what() +
311-
" (" + lexer.render() + ")");
312-
return (lexer.what() == '<' ||
313-
lexer.what() == '>' ||
314-
lexer.what() == '=' ||
315-
lexer.what() == CQLTokenizer.TT_LE ||
316-
lexer.what() == CQLTokenizer.TT_GE ||
317-
lexer.what() == CQLTokenizer.TT_NE ||
318-
lexer.what() == CQLTokenizer.TT_EQEQ);
310+
debug("isSymbolicRelation: checking what()=" + lexer.what() +
311+
" (" + lexer.render() + ")");
312+
return (lexer.what() == '<' ||
313+
lexer.what() == '>' ||
314+
lexer.what() == '=' ||
315+
lexer.what() == CQLTokenizer.TT_LE ||
316+
lexer.what() == CQLTokenizer.TT_GE ||
317+
lexer.what() == CQLTokenizer.TT_NE ||
318+
lexer.what() == CQLTokenizer.TT_EQEQ);
319319
}
320320

321321
private void match(int token)
@@ -324,7 +324,7 @@ private void match(int token)
324324
if (lexer.what() != token)
325325
throw new CQLParseException("expected " +
326326
lexer.render(token, true) +
327-
", " + "got " + lexer.render(),
327+
", " + "got " + lexer.render(),
328328
lexer.pos());
329329
lexer.move();
330330
debug("match() got token=" + lexer.what() + ", value()='" + lexer.value() + "'");
@@ -500,7 +500,7 @@ public static void main (String[] args) {
500500
f.close();
501501
System.out.println(root.toPQF(config));
502502
} catch (IOException ex) {
503-
System.err.println("Can't load PQF properties:" +
503+
System.err.println("Can't load PQF properties:" +
504504
ex.getMessage());
505505
System.exit(5);
506506
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
title any fish
1+
title Any fish
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<searchClause>
22
<index>title</index>
33
<relation>
4-
<value>any</value>
4+
<value>Any</value>
55
</relation>
66
<term>fish</term>
77
</searchClause>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sortby sortby sortby sortby sortby
1+
Sortby Sortby Sortby Sortby Sortby

src/test/resources/regression/09/06.xcql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
<relation>
44
<value>=</value>
55
</relation>
6-
<term>sortby</term>
6+
<term>Sortby</term>
77
<sortKeys>
88
<key>
9-
<index>sortby</index>
9+
<index>Sortby</index>
1010
</key>
1111
<key>
12-
<index>sortby</index>
12+
<index>Sortby</index>
1313
</key>
1414
<key>
15-
<index>sortby</index>
15+
<index>Sortby</index>
1616
</key>
1717
</sortKeys>
1818
</searchClause>

0 commit comments

Comments
 (0)