[OLINGO-568] Improved states

This commit is contained in:
Michael Bolz 2015-11-09 15:39:02 +01:00
parent b3bbfa6fe1
commit 43bc49f963
2 changed files with 40 additions and 41 deletions

View File

@ -82,6 +82,10 @@ public class SearchTokenizer {
return token; return token;
} }
public boolean close() {
return nextChar(EOF).isFinished();
}
static boolean isAllowedChar(final char character) { static boolean isAllowedChar(final char character) {
// TODO mibo: add missing allowed characters // TODO mibo: add missing allowed characters
return CHAR_A <= character && character <= 'Z' // case A..Z return CHAR_A <= character && character <= 'Z' // case A..Z
@ -173,11 +177,9 @@ public class SearchTokenizer {
if (c == CHAR_OPEN) { if (c == CHAR_OPEN) {
return new OpenState(); return new OpenState();
} else if (isWhitespace(c)) { } else if (isWhitespace(c)) {
return new RwsState(); return new RwsImplicitAndState();
} else if(c == CHAR_CLOSE) { } else if(c == CHAR_CLOSE) {
return new CloseState(); return new CloseState();
} else if(isEof(c)) {
return finish();
} else if(isWhitespace(c)) { } else if(isWhitespace(c)) {
return new AndState(c); return new AndState(c);
} else { } else {
@ -185,6 +187,11 @@ public class SearchTokenizer {
} }
} }
@Override
public boolean close() {
return true;
}
@Override @Override
public State init(char c) { public State init(char c) {
return nextChar(c); return nextChar(c);
@ -229,7 +236,7 @@ public class SearchTokenizer {
return new CloseState(); return new CloseState();
} else if (isWhitespace(c)) { } else if (isWhitespace(c)) {
finish(); finish();
return new RwsState(); return new RwsImplicitAndState();
} else if (isEof(c)) { } else if (isEof(c)) {
return finish(); return finish();
} }
@ -253,10 +260,16 @@ public class SearchTokenizer {
return allowed(c); return allowed(c);
} else if (c == QUOTATION_MARK) { } else if (c == QUOTATION_MARK) {
finish(); finish();
return allowed(c); allowed(c);
return new SearchExpressionState();
} else if (isWhitespace(c)) { } else if (isWhitespace(c)) {
if(isFinished()) { if(isFinished()) {
return new RwsState(); return new RwsImplicitAndState();
}
return allowed(c);
} else if (c == CHAR_CLOSE) {
if(isFinished()) {
return new CloseState();
} }
return allowed(c); return allowed(c);
} else if (isEof(c)) { } else if (isEof(c)) {
@ -319,22 +332,6 @@ public class SearchTokenizer {
} }
} }
private class ImplicitAndState extends LiteralState {
private State followingState;
public ImplicitAndState(char c) {
super(Token.AND);
finish();
followingState = new SearchExpressionState().init(c);
}
public State nextState() {
return followingState;
}
@Override
public State nextChar(char c) {
return followingState.nextChar(c);
}
}
private class AndState extends LiteralState { private class AndState extends LiteralState {
public AndState(char c) { public AndState(char c) {
super(Token.AND, c); super(Token.AND, c);
@ -393,9 +390,10 @@ public class SearchTokenizer {
} }
} }
private class RwsState extends State { // implicit and
public RwsState() { private class RwsImplicitAndState extends State {
super(Token.RWS); public RwsImplicitAndState() {
super(Token.AND);
} }
@Override @Override
public State nextChar(char c) { public State nextChar(char c) {
@ -406,7 +404,8 @@ public class SearchTokenizer {
} else if (c == CHAR_A) { } else if (c == CHAR_A) {
return new AndState(c); return new AndState(c);
} else { } else {
return new ImplicitAndState(c); finish();
return new SearchExpressionState().init(c);
} }
} }
} }
@ -417,25 +416,18 @@ public class SearchTokenizer {
State state = new SearchExpressionState(); State state = new SearchExpressionState();
List<SearchQueryToken> states = new ArrayList<SearchQueryToken>(); List<SearchQueryToken> states = new ArrayList<SearchQueryToken>();
State lastAdded = null;
for (char aChar : chars) { for (char aChar : chars) {
State next = state.nextChar(aChar); State next = state.nextChar(aChar);
if (next instanceof ImplicitAndState) { if (state.isFinished()) {
lastAdded = next;
states.add(next);
next = ((ImplicitAndState)next).nextState();
} else if (state.isFinished() && state != lastAdded) {
lastAdded = state;
states.add(state); states.add(state);
} }
state = next; state = next;
} }
final State lastState = state.nextChar(State.EOF); if(state.close()) {
if(lastState.isFinished()) { if(state.isFinished()) {
if(state != lastAdded) { states.add(state);
states.add(state); }
}
} else { } else {
throw new IllegalStateException("State: " + state + " not finished and list is: " + states.toString()); throw new IllegalStateException("State: " + state + " not finished and list is: " + states.toString());
} }

View File

@ -86,6 +86,8 @@ public class SearchTokenizerTest {
SearchTokenizer tokenizer = new SearchTokenizer(); SearchTokenizer tokenizer = new SearchTokenizer();
List<SearchQueryToken> result; List<SearchQueryToken> result;
SearchValidator.init("abc AND \"x-y_z\" AND 123").validate();
// //
result = tokenizer.tokenize("\"abc\""); result = tokenizer.tokenize("\"abc\"");
Assert.assertNotNull(result); Assert.assertNotNull(result);
@ -325,12 +327,17 @@ public class SearchTokenizerTest {
// parenthesis // parenthesis
validate("(abc)"); validate("(abc)");
validate("(abc AND def)"); validate("(abc AND def)");
validate("(abc AND def) OR ghi "); validate("(abc AND def) OR ghi");
validate("(abc AND def) ghi "); validate("(abc AND def) ghi");
validate("abc AND (def OR ghi)"); validate("abc AND (def OR ghi)");
validate("abc AND (def ghi)"); validate("abc AND (def ghi)");
} }
@Test
public void parseInvalid() {
SearchValidator.init("abc AND OR something").validate();
}
public boolean validate(String query) { public boolean validate(String query) {
return new SearchValidator(query).validate(); return new SearchValidator(query).validate();
} }