[OLINGO-568] Added missing SearchParser parse paths

This commit is contained in:
mibo 2015-11-13 08:16:15 +01:00
parent 40962a9a18
commit cef72e45ab
3 changed files with 85 additions and 42 deletions

View File

@ -29,20 +29,20 @@ import java.util.List;
public class SearchParser { public class SearchParser {
private Iterator<SearchQueryToken> tokens; private Iterator<SearchQueryToken> tokens;
private SearchExpression root;
private SearchQueryToken token; private SearchQueryToken token;
public SearchOption parse(String path, String value) { public SearchOption parse(String path, String value) {
SearchTokenizer tokenizer = new SearchTokenizer(); SearchTokenizer tokenizer = new SearchTokenizer();
SearchExpression searchExpression;
try { try {
tokens = tokenizer.tokenize(value).iterator(); tokens = tokenizer.tokenize(value).iterator();
nextToken(); nextToken();
root = processSearchExpression(null); searchExpression = processSearchExpression(null);
} catch (SearchTokenizerException e) { } catch (SearchTokenizerException e) {
return null; return null;
} }
final SearchOptionImpl searchOption = new SearchOptionImpl(); final SearchOptionImpl searchOption = new SearchOptionImpl();
searchOption.setSearchExpression(root); searchOption.setSearchExpression(searchExpression);
return searchOption; return searchOption;
} }
@ -57,26 +57,47 @@ public class SearchParser {
return left; return left;
} }
if(token.getToken() == SearchQueryToken.Token.OPEN) { SearchExpression expression = left;
if(isToken(SearchQueryToken.Token.OPEN)) {
processOpen(); processOpen();
throw illegalState(); expression = processSearchExpression(left);
} else if(token.getToken() == SearchQueryToken.Token.CLOSE) { validateToken(SearchQueryToken.Token.CLOSE);
processClose(); processClose();
throw illegalState(); } else if(isTerm()) {
} else if(token.getToken() == SearchQueryToken.Token.NOT) { expression = processTerm();
processNot(); }
} else if(token.getToken() == SearchQueryToken.Token.PHRASE ||
token.getToken() == SearchQueryToken.Token.WORD) { if(isToken(SearchQueryToken.Token.AND) || isTerm()) {
return processSearchExpression(processTerm()); expression = processAnd(expression);
} else if(token.getToken() == SearchQueryToken.Token.AND) { } else if(isToken(SearchQueryToken.Token.OR)) {
SearchExpression se = processAnd(left); expression = processOr(expression);
return processSearchExpression(se); } else if(isEof()) {
} else if(token.getToken() == SearchQueryToken.Token.OR) { return expression;
return processOr(left); }
} else { return expression;
}
private boolean isTerm() {
return isToken(SearchQueryToken.Token.NOT)
|| isToken(SearchQueryToken.Token.PHRASE)
|| isToken(SearchQueryToken.Token.WORD);
}
private boolean isEof() {
return token == null;
}
private boolean isToken(SearchQueryToken.Token toCheckToken) {
if(token == null) {
return false;
}
return token.getToken() == toCheckToken;
}
private void validateToken(SearchQueryToken.Token toValidateToken) {
if(!isToken(toValidateToken)) {
throw illegalState(); throw illegalState();
} }
throw illegalState();
} }
private void processClose() { private void processClose() {
@ -88,13 +109,24 @@ public class SearchParser {
} }
private SearchExpression processAnd(SearchExpression left) { private SearchExpression processAnd(SearchExpression left) {
nextToken(); if(isToken(SearchQueryToken.Token.AND)) {
SearchExpression se = processTerm(); nextToken();
return new SearchBinaryImpl(left, SearchBinaryOperatorKind.AND, se); }
SearchExpression se = left;
if(isTerm()) {
se = processTerm();
se = new SearchBinaryImpl(left, SearchBinaryOperatorKind.AND, se);
return processSearchExpression(se);
} else {
se = processSearchExpression(se);
return new SearchBinaryImpl(left, SearchBinaryOperatorKind.AND, se);
}
} }
public SearchExpression processOr(SearchExpression left) { public SearchExpression processOr(SearchExpression left) {
nextToken(); if(isToken(SearchQueryToken.Token.OR)) {
nextToken();
}
SearchExpression se = processSearchExpression(left); SearchExpression se = processSearchExpression(left);
return new SearchBinaryImpl(left, SearchBinaryOperatorKind.OR, se); return new SearchBinaryImpl(left, SearchBinaryOperatorKind.OR, se);
} }
@ -103,8 +135,13 @@ public class SearchParser {
return new RuntimeException(); return new RuntimeException();
} }
private void processNot() { private SearchExpression processNot() {
nextToken(); nextToken();
SearchExpression searchExpression = processTerm();
if(searchExpression.isSearchTerm()) {
return new SearchUnaryImpl(searchExpression.asSearchTerm());
}
throw illegalState();
} }
private void nextToken() { private void nextToken() {
@ -113,20 +150,18 @@ public class SearchParser {
} else { } else {
token = null; token = null;
} }
// return null;
} }
private SearchExpression processTerm() { private SearchExpression processTerm() {
if(token.getToken() == SearchQueryToken.Token.NOT) { if(isToken(SearchQueryToken.Token.NOT)) {
return new SearchUnaryImpl(processPhrase()); return processNot();
} }
if(token.getToken() == SearchQueryToken.Token.PHRASE) { if(isToken(SearchQueryToken.Token.PHRASE)) {
return processPhrase(); return processPhrase();
} } else if(isToken(SearchQueryToken.Token.WORD)) {
if(token.getToken() == SearchQueryToken.Token.WORD) {
return processWord(); return processWord();
} }
return null; throw illegalState();
} }
private SearchTermImpl processWord() { private SearchTermImpl processWord() {

View File

@ -34,9 +34,6 @@ public class SearchParserAndTokenizerTest {
@Test @Test
public void basicParsing() throws SearchTokenizerException { public void basicParsing() throws SearchTokenizerException {
// SearchExpressionValidator.init("a AND b OR c").enableLogging()
// .validate(with("a"));
SearchExpressionValidator.init("a") SearchExpressionValidator.init("a")
.validate(with("a")); .validate(with("a"));
SearchExpressionValidator.init("a AND b") SearchExpressionValidator.init("a AND b")
@ -57,6 +54,22 @@ public class SearchParserAndTokenizerTest {
.validate("{'a' OR {'b' AND 'c'}}"); .validate("{'a' OR {'b' AND 'c'}}");
} }
@Test
public void notParsing() throws Exception {
SearchExpressionValidator.init("NOT a AND b OR c")
.validate("{{{NOT 'a'} AND 'b'} OR 'c'}");
SearchExpressionValidator.init("a OR b AND NOT c")
.validate("{'a' OR {'b' AND {NOT 'c'}}}");
}
@Test
public void parenthesesParsing() throws Exception {
SearchExpressionValidator.init("a AND (b OR c)")
.validate("{'a' AND {'b' OR 'c'}}");
SearchExpressionValidator.init("(a OR b) AND NOT c")
.validate("{{'a' OR 'b'} AND {NOT 'c'}}");
}
@Ignore @Ignore
@Test @Test
public void sebuilder() { public void sebuilder() {

View File

@ -83,7 +83,6 @@ public class SearchParserTest extends SearchParser {
assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm());
} }
@Ignore
@Test @Test
public void simpleImplicitAnd() { public void simpleImplicitAnd() {
SearchExpression se = run(Token.WORD, Token.WORD); SearchExpression se = run(Token.WORD, Token.WORD);
@ -101,7 +100,6 @@ public class SearchParserTest extends SearchParser {
assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm());
} }
@Ignore
@Test @Test
public void simpleBrackets() { public void simpleBrackets() {
SearchExpression se = run(Token.OPEN, Token.WORD, Token.CLOSE); SearchExpression se = run(Token.OPEN, Token.WORD, Token.CLOSE);
@ -115,7 +113,6 @@ public class SearchParserTest extends SearchParser {
assertEquals("phrase1", se.asSearchTerm().getSearchTerm()); assertEquals("phrase1", se.asSearchTerm().getSearchTerm());
} }
@Ignore
@Test @Test
public void simpleNot() { public void simpleNot() {
SearchExpression se = run(Token.NOT, Token.WORD); SearchExpression se = run(Token.NOT, Token.WORD);
@ -123,13 +120,12 @@ public class SearchParserTest extends SearchParser {
assertTrue(se.isSearchUnary()); assertTrue(se.isSearchUnary());
assertEquals("word1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm()); assertEquals("word1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm());
se = run(Token.NOT, Token.WORD); se = run(Token.NOT, Token.PHRASE);
assertEquals("'phrase1'", se.toString()); assertEquals("{NOT 'phrase1'}", se.toString());
assertTrue(se.isSearchUnary()); assertTrue(se.isSearchUnary());
assertEquals("phrase1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm());
} }
@Ignore
@Test @Test
public void precedenceLast() { public void precedenceLast() {
//word1 AND (word2 AND word3) //word1 AND (word2 AND word3)
@ -137,7 +133,6 @@ public class SearchParserTest extends SearchParser {
assertEquals("{'word1' AND {'word2' AND 'word3'}}", se.toString()); assertEquals("{'word1' AND {'word2' AND 'word3'}}", se.toString());
} }
@Ignore
@Test @Test
public void precedenceFirst() { public void precedenceFirst() {
//(word1 AND word2) AND word3 //(word1 AND word2) AND word3