Repository: olingo-odata4 Updated Branches: refs/head/OLINGO-568_SearchParserPoC [created] 193ebc150
[OLINGO-568] second parser draft Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/193ebc15 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/193ebc15 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/193ebc15 Branch: refs/head/OLINGO-568_SearchParserPoC Commit: 193ebc1506e7a75925cad587653e42fddc0dee85 Parents: a8d63fb Author: Christian Amend <[email protected]> Authored: Thu Nov 12 16:32:43 2015 +0100 Committer: Christian Amend <[email protected]> Committed: Thu Nov 12 16:32:43 2015 +0100 ---------------------------------------------------------------------- .../api/uri/queryoption/search/SearchUnary.java | 6 +- .../uri/parser/search/SearchBinaryImpl.java | 14 +- .../core/uri/parser/search/SearchParser.java | 176 +++++++++++-------- .../parser/search/SearchParserException.java | 31 ++++ .../core/uri/parser/search/SearchTokenizer.java | 5 +- .../parser/search/SearchTokenizerException.java | 7 +- .../core/uri/parser/search/SearchUnaryImpl.java | 18 +- .../search/SearchParserAndTokenizerTest.java | 17 +- .../uri/parser/search/SearchParserTest.java | 114 ++++++------ 9 files changed, 240 insertions(+), 148 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/search/SearchUnary.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/search/SearchUnary.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/search/SearchUnary.java index c266308..b01094d 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/search/SearchUnary.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/search/SearchUnary.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -21,6 +21,6 @@ package org.apache.olingo.server.api.uri.queryoption.search; public interface SearchUnary extends SearchExpression { SearchUnaryOperatorKind getOperator(); - SearchTerm getOperand(); + SearchExpression getOperand(); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchBinaryImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchBinaryImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchBinaryImpl.java index 418d9e7..ed0a697 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchBinaryImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchBinaryImpl.java @@ -25,12 +25,18 @@ import org.apache.olingo.server.api.uri.queryoption.search.SearchExpression; public class SearchBinaryImpl extends SearchExpressionImpl implements SearchBinary { private final SearchBinaryOperatorKind operator; - private final SearchExpression left; - private final SearchExpression right; + private SearchExpression left; + private SearchExpression right; - public SearchBinaryImpl(SearchExpression left, SearchBinaryOperatorKind operator, SearchExpression right) { - this.left = left; + public SearchBinaryImpl(SearchBinaryOperatorKind operator) { this.operator = operator; + } + + public void setLeft(SearchExpression left) { + this.left = left; + } + + public void setRight(SearchExpression right) { this.right = right; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParser.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParser.java index 5e26c35..8321b6c 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParser.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParser.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,109 +18,141 @@ */ package org.apache.olingo.server.core.uri.parser.search; +import java.util.ArrayList; + import org.apache.olingo.server.api.uri.queryoption.SearchOption; import org.apache.olingo.server.api.uri.queryoption.search.SearchBinaryOperatorKind; import org.apache.olingo.server.api.uri.queryoption.search.SearchExpression; import org.apache.olingo.server.api.uri.queryoption.search.SearchTerm; import org.apache.olingo.server.core.uri.queryoption.SearchOptionImpl; -import java.util.Iterator; - public class SearchParser { - protected Iterator<SearchQueryToken> tokens; - protected SearchExpression root; -// private SearchQueryToken currentToken; + protected ArrayList<SearchQueryToken> tokens; + private int size; + private int currentPosition = -1; - public SearchOption parse(String path, String value) { + public SearchOption parse(String path, String value) throws SearchTokenizerException, SearchParserException { SearchTokenizer tokenizer = new SearchTokenizer(); - try { - tokens = tokenizer.tokenize(value).iterator(); -// currentToken = tokens.next(); - root = processTokens(); - } catch (SearchTokenizerException e) { - return null; - } + tokens = tokenizer.tokenize(value); + SearchExpression root = processTokens(); final SearchOptionImpl searchOption = new SearchOptionImpl(); searchOption.setSearchExpression(root); return searchOption; } - protected SearchExpression processTokens() { - SearchQueryToken token = nextToken(); - - - if(token.getToken() == SearchQueryToken.Token.OPEN) { - throw illegalState(); - } else if(token.getToken() == SearchQueryToken.Token.NOT) { - return processNot(); - } else if(token.getToken() == SearchQueryToken.Token.PHRASE || - token.getToken() == SearchQueryToken.Token.WORD) { - return processTerm(token); -// } else if(token.getToken() == SearchQueryToken.Token.AND) { -// return processAnd(); - } else { - throw illegalState(); + protected SearchExpression processTokens() throws SearchParserException { + size = tokens.size(); + SearchExpression root = null; + SearchQueryToken nextToken = next(); + switch (nextToken.getToken()) { + case WORD: + case PHRASE: + root = processWord(null, nextToken.getLiteral()); + break; + case NOT: + root = processNot(); + case OPEN: + // TODO: implement + default: + break; } - } - private SearchExpression processAnd(SearchExpression se) { - SearchQueryToken token = nextToken(); - if(token.getToken() == SearchQueryToken.Token.PHRASE || - token.getToken() == SearchQueryToken.Token.WORD) { -// SearchExpression t = processTerm(token); - return new SearchBinaryImpl(se, SearchBinaryOperatorKind.AND, processTerm(token)); + if (hasNext()) { + throw new SearchParserException(); } - throw illegalState(); + + return root; } - private SearchExpression processOr(SearchExpression se) { - SearchQueryToken token = nextToken(); - if(token.getToken() == SearchQueryToken.Token.PHRASE || - token.getToken() == SearchQueryToken.Token.WORD) { - return new SearchBinaryImpl(se, SearchBinaryOperatorKind.OR, processTerm(token)); + private SearchExpression processNot() throws SearchParserException { + SearchUnaryImpl not = new SearchUnaryImpl(); + SearchQueryToken nextToken = next(); + switch (nextToken.getToken()) { + case WORD: + case PHRASE: + processWord(not, nextToken.getLiteral()); + case OPEN: + default: + break; } - throw illegalState(); + return not; } - private RuntimeException illegalState() { - return new RuntimeException(); + private SearchExpression processWord(SearchUnaryImpl not, String literal) throws SearchParserException { + SearchExpression exp = new SearchTermImpl(literal); + if (not != null) { + not.setOperand(exp); + exp = not; + } + if (hasNext()) { + SearchQueryToken nextToken = next(); + switch (nextToken.getToken()) { + case WORD: + case PHRASE: + exp = processImplicitAnd(exp, nextToken); + break; + case AND: + exp = processAnd(exp); + break; + case OR: + exp = processOr(exp); + break; + default: + break; + } + } + return exp; } - private SearchUnaryImpl processNot() { - SearchQueryToken token = nextToken(); - if(token.getToken() == SearchQueryToken.Token.PHRASE || - token.getToken() == SearchQueryToken.Token.WORD) { - throw illegalState(); -// return new SearchUnaryImpl(processTerm(token)); + private SearchExpression processOr(SearchExpression left) throws SearchParserException { + SearchBinaryImpl or = new SearchBinaryImpl(SearchBinaryOperatorKind.OR); + or.setLeft(left); + SearchQueryToken nextToken = next(); + switch (nextToken.getToken()) { + case WORD: + case PHRASE: + or.setRight(processWord(null, nextToken.getLiteral())); + break; + default: + break; } - throw illegalState(); + return or; } - private SearchQueryToken nextToken() { -// if(tokens.hasNext()) { - return tokens.next(); -// } -// return null; + private SearchExpression processAnd(SearchExpression left) throws SearchParserException { + SearchBinaryImpl and = new SearchBinaryImpl(SearchBinaryOperatorKind.AND); + and.setLeft(left); + SearchQueryToken nextToken = next(); + switch (nextToken.getToken()) { + case WORD: + case PHRASE: + and.setRight(processWord(null, nextToken.getLiteral())); + break; + default: + break; + } + return and; } - private SearchExpression processTerm(SearchQueryToken token) { - SearchTerm searchTerm = new SearchTermImpl(token.getLiteral()); - if(isEof()) { - return searchTerm; - } + private SearchExpression processImplicitAnd(SearchExpression left, SearchQueryToken nextToken) + throws SearchParserException { + SearchBinaryImpl and = new SearchBinaryImpl(SearchBinaryOperatorKind.AND); + and.setLeft(left); + and.setRight(new SearchTermImpl(nextToken.getLiteral())); + return and; + } - SearchQueryToken next = nextToken(); - if(next.getToken() == SearchQueryToken.Token.AND) { - return processAnd(searchTerm); - } else if(next.getToken() == SearchQueryToken.Token.OR) { - return processOr(searchTerm); + private SearchQueryToken next() throws SearchParserException { + currentPosition++; + if (currentPosition < size) { + return tokens.get(currentPosition); + } else { + throw new SearchParserException(); } - - throw illegalState(); } - private boolean isEof() { - return !tokens.hasNext(); + private boolean hasNext() { + return currentPosition + 1 < size; } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParserException.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParserException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParserException.java new file mode 100644 index 0000000..be22620 --- /dev/null +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchParserException.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.olingo.server.core.uri.parser.search; + +import org.apache.olingo.server.core.uri.parser.UriParserSemanticException; + +public class SearchParserException extends UriParserSemanticException { + private static final long serialVersionUID = 5781553037561337795L; + + //TODO: message keys + public SearchParserException() { + super(null, null); + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizer.java index 9288981..78936bd 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizer.java @@ -19,7 +19,6 @@ package org.apache.olingo.server.core.uri.parser.search; import java.util.ArrayList; -import java.util.List; /** * <code> @@ -440,13 +439,13 @@ public class SearchTokenizer { * @throws SearchTokenizerException if something in query is not valid * (based on OData search query ABNF) */ - public List<SearchQueryToken> tokenize(final String searchQuery) + public ArrayList<SearchQueryToken> tokenize(final String searchQuery) throws SearchTokenizerException { char[] chars = searchQuery.trim().toCharArray(); State state = new SearchExpressionState(); - List<SearchQueryToken> states = new ArrayList<SearchQueryToken>(); + ArrayList<SearchQueryToken> states = new ArrayList<SearchQueryToken>(); for (char aChar : chars) { State next = state.nextChar(aChar); if (state.isFinished()) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerException.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerException.java index 451632b..6abf6cc 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerException.java @@ -18,11 +18,14 @@ */ package org.apache.olingo.server.core.uri.parser.search; -public class SearchTokenizerException extends Exception { +import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException; + +public class SearchTokenizerException extends UriParserSyntaxException { private static final long serialVersionUID = -8295456415309640166L; + //TODO: Translation texts public SearchTokenizerException(String message) { - super(message); + super(message, null); } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchUnaryImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchUnaryImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchUnaryImpl.java index 51e3a24..f82d478 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchUnaryImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/search/SearchUnaryImpl.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,24 +18,24 @@ */ package org.apache.olingo.server.core.uri.parser.search; -import org.apache.olingo.server.api.uri.queryoption.search.SearchTerm; +import org.apache.olingo.server.api.uri.queryoption.search.SearchExpression; import org.apache.olingo.server.api.uri.queryoption.search.SearchUnary; import org.apache.olingo.server.api.uri.queryoption.search.SearchUnaryOperatorKind; public class SearchUnaryImpl extends SearchExpressionImpl implements SearchUnary { - private final SearchTerm operand; - - public SearchUnaryImpl(SearchTerm operand) { - this.operand = operand; - } + private SearchExpression operand; @Override public SearchUnaryOperatorKind getOperator() { return SearchUnaryOperatorKind.NOT; } + public void setOperand(SearchExpression operand) { + this.operand = operand; + } + @Override - public SearchTerm getOperand() { + public SearchExpression getOperand() { return operand; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserAndTokenizerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserAndTokenizerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserAndTokenizerTest.java index 43b63c3..af21e7a 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserAndTokenizerTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserAndTokenizerTest.java @@ -33,7 +33,7 @@ import org.junit.Test; public class SearchParserAndTokenizerTest { @Test - public void basicParsing() throws SearchTokenizerException { + public void basicParsing() throws Exception { SearchExpressionValidator.init("a") .validate(with("a")); SearchExpressionValidator.init("a AND b") @@ -91,11 +91,15 @@ public class SearchParserAndTokenizerTest { } private static SearchExpression or(SearchExpression right) { - return new SearchBinaryImpl(null, OR, right); + SearchBinaryImpl impl = new SearchBinaryImpl(OR); + impl.setRight(right); + return impl; } private static SearchExpression and(SearchExpression right) { - return new SearchBinaryImpl(null, AND, right); + SearchBinaryImpl impl = new SearchBinaryImpl(AND); + impl.setRight(right); + return impl; } private static SearchExpression and(String right) { @@ -107,7 +111,9 @@ public class SearchParserAndTokenizerTest { } private static SearchUnary not(String term) { - return new SearchUnaryImpl(new SearchTermImpl(term)); + SearchUnaryImpl unary = new SearchUnaryImpl(); + unary.setOperand(new SearchTermImpl(term)); + return unary; } private static void setLeftField(String left, SearchExpression se) { @@ -155,7 +161,8 @@ public class SearchParserAndTokenizerTest { Assert.fail("Expected exception " + exception.getClass().getSimpleName() + " was not thrown."); } - private void validate(SearchExpression expectedSearchExpression) throws SearchTokenizerException { + private void validate(SearchExpression expectedSearchExpression) throws SearchTokenizerException, + SearchParserException { SearchParser tokenizer = new SearchParser(); SearchOption result = tokenizer.parse(null, searchQuery); Assert.assertNotNull(result); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/193ebc15/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserTest.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserTest.java index 961663c..383c0d1 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchParserTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; -import java.util.List; import org.apache.olingo.server.api.uri.queryoption.search.SearchBinaryOperatorKind; import org.apache.olingo.server.api.uri.queryoption.search.SearchExpression; @@ -33,31 +32,31 @@ import org.apache.olingo.server.core.uri.parser.search.SearchQueryToken.Token; import org.junit.Ignore; import org.junit.Test; -public class SearchParserTest extends SearchParser { +public class SearchParserTest { @Test - public void simple() { + public void simple() throws Exception { SearchExpression se = run(Token.WORD); assertEquals("'word1'", se.toString()); assertTrue(se.isSearchTerm()); assertEquals("word1", se.asSearchTerm().getSearchTerm()); - + se = run(Token.PHRASE); assertEquals("'phrase1'", se.toString()); assertTrue(se.isSearchTerm()); - //TODO: Check if quotation marks should be part of the string we deliver + // TODO: Check if quotation marks should be part of the string we deliver assertEquals("phrase1", se.asSearchTerm().getSearchTerm()); } @Test - public void simpleAnd() { + public void simpleAnd() throws Exception { SearchExpression se = run(Token.WORD, Token.AND, Token.WORD); assertEquals("{'word1' AND 'word2'}", se.toString()); assertTrue(se.isSearchBinary()); assertEquals(SearchBinaryOperatorKind.AND, se.asSearchBinary().getOperator()); assertEquals("word1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("word2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); - + se = run(Token.PHRASE, Token.AND, Token.PHRASE); assertEquals("{'phrase1' AND 'phrase2'}", se.toString()); assertTrue(se.isSearchBinary()); @@ -65,16 +64,16 @@ public class SearchParserTest extends SearchParser { assertEquals("phrase1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); } - + @Test - public void simpleOr() { + public void simpleOr() throws Exception { SearchExpression se = run(Token.WORD, Token.OR, Token.WORD); assertEquals("{'word1' OR 'word2'}", se.toString()); assertTrue(se.isSearchBinary()); assertEquals(SearchBinaryOperatorKind.OR, se.asSearchBinary().getOperator()); assertEquals("word1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("word2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); - + se = run(Token.PHRASE, Token.OR, Token.PHRASE); assertEquals("{'phrase1' OR 'phrase2'}", se.toString()); assertTrue(se.isSearchBinary()); @@ -82,17 +81,16 @@ public class SearchParserTest extends SearchParser { assertEquals("phrase1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); } - - @Ignore + @Test - public void simpleImplicitAnd() { + public void simpleImplicitAnd() throws Exception { SearchExpression se = run(Token.WORD, Token.WORD); assertEquals("{'word1' AND 'word2'}", se.toString()); assertTrue(se.isSearchBinary()); assertEquals(SearchBinaryOperatorKind.AND, se.asSearchBinary().getOperator()); assertEquals("word1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("word2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); - + se = run(Token.PHRASE, Token.PHRASE); assertEquals("{'phrase1' AND 'phrase2'}", se.toString()); assertTrue(se.isSearchBinary()); @@ -100,77 +98,93 @@ public class SearchParserTest extends SearchParser { assertEquals("phrase1", se.asSearchBinary().getLeftOperand().asSearchTerm().getSearchTerm()); assertEquals("phrase2", se.asSearchBinary().getRightOperand().asSearchTerm().getSearchTerm()); } - + @Ignore @Test - public void simpleBrackets() { + public void simpleBrackets() throws Exception { SearchExpression se = run(Token.OPEN, Token.WORD, Token.CLOSE); assertEquals("'word1'", se.toString()); assertTrue(se.isSearchTerm()); assertEquals("word1", se.asSearchTerm().getSearchTerm()); - + se = run(Token.OPEN, Token.PHRASE, Token.CLOSE); assertEquals("'phrase1'", se.toString()); assertTrue(se.isSearchTerm()); assertEquals("phrase1", se.asSearchTerm().getSearchTerm()); } - - @Ignore + @Test - public void simpleNot() { + public void simpleNot() throws Exception { SearchExpression se = run(Token.NOT, Token.WORD); assertEquals("{NOT 'word1'}", se.toString()); assertTrue(se.isSearchUnary()); assertEquals("word1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm()); - - se = run(Token.NOT, Token.WORD); - assertEquals("'phrase1'", se.toString()); + + se = run(Token.NOT, Token.PHRASE); + assertEquals("{NOT 'phrase1'}", se.toString()); assertTrue(se.isSearchUnary()); assertEquals("phrase1", se.asSearchUnary().getOperand().asSearchTerm().getSearchTerm()); } - + @Ignore @Test - public void precedenceLast() { - //word1 AND (word2 AND word3) + public void precedenceLast() throws Exception { + // word1 AND (word2 AND word3) SearchExpression se = run(Token.WORD, Token.AND, Token.OPEN, Token.WORD, Token.AND, Token.WORD, Token.CLOSE); assertEquals("{'word1' AND {'word2' AND 'word3'}}", se.toString()); } - + @Ignore @Test - public void precedenceFirst() { - //(word1 AND word2) AND word3 + public void precedenceFirst() throws Exception { + // (word1 AND word2) AND word3 SearchExpression se = run(Token.OPEN, Token.WORD, Token.AND, Token.WORD, Token.CLOSE, Token.AND, Token.WORD); assertEquals("{{'word1' AND 'word2'} AND 'word3'}", se.toString()); } - - private SearchExpression run(SearchQueryToken.Token... tokenArray) { - List<SearchQueryToken> tokenList = prepareTokens(tokenArray); - tokens = tokenList.iterator(); - SearchExpression se = processTokens(); + @Ignore + @Test + public void baseCases() throws Exception { + // word1 AND (word2 OR word3) + SearchExpression se = run(Token.WORD, Token.AND, Token.OPEN, Token.WORD, Token.OR, Token.WORD, Token.CLOSE); + assertEquals("{'word1' AND {'word2' OR 'word3'}}", se.toString()); + + // word1 AND word2 OR word3 + se = run(Token.WORD, Token.AND, Token.WORD, Token.OR, Token.WORD); + assertEquals("{{'word1' AND 'word2'} OR 'word3'}", se.toString()); + + // word1 OR word2 AND word3 + se = run(Token.WORD, Token.OR, Token.WORD, Token.AND, Token.WORD); + assertEquals("{'word1' OR {'word2' AND 'word3'}}", se.toString()); + } + + private SearchExpression run(SearchQueryToken.Token... tokenArray) throws SearchParserException { + LocalTestParser parser = new LocalTestParser(); + parser.prepareTokens(tokenArray); + SearchExpression se = parser.processTokens(); assertNotNull(se); return se; } - public List<SearchQueryToken> prepareTokens(SearchQueryToken.Token... tokenArray) { - ArrayList<SearchQueryToken> tokenList = new ArrayList<SearchQueryToken>(); - int wordNumber = 1; - int phraseNumber = 1; - for (int i = 0; i < tokenArray.length; i++) { - SearchQueryToken token = mock(SearchQueryToken.class); - when(token.getToken()).thenReturn(tokenArray[i]); - if (tokenArray[i] == Token.WORD) { - when(token.getLiteral()).thenReturn("word" + wordNumber); - wordNumber++; - } else if (tokenArray[i] == Token.PHRASE) { - when(token.getLiteral()).thenReturn("phrase" + phraseNumber); - phraseNumber++; + private class LocalTestParser extends SearchParser { + + public void prepareTokens(SearchQueryToken.Token... tokenArray) { + ArrayList<SearchQueryToken> tokenList = new ArrayList<SearchQueryToken>(); + int wordNumber = 1; + int phraseNumber = 1; + for (int i = 0; i < tokenArray.length; i++) { + SearchQueryToken token = mock(SearchQueryToken.class); + when(token.getToken()).thenReturn(tokenArray[i]); + if (tokenArray[i] == Token.WORD) { + when(token.getLiteral()).thenReturn("word" + wordNumber); + wordNumber++; + } else if (tokenArray[i] == Token.PHRASE) { + when(token.getLiteral()).thenReturn("phrase" + phraseNumber); + phraseNumber++; + } + tokenList.add(token); } - tokenList.add(token); + tokens = tokenList; } - return tokenList; } - } \ No newline at end of file
