[OLINGO-568] Improved states
This commit is contained in:
parent
b3bbfa6fe1
commit
43bc49f963
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue