
com.orientechnologies.common.console.ODFACommandStream Maven / Gradle / Ivy
The newest version!
package com.orientechnologies.common.console;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author Artem Orobets
*/
public class ODFACommandStream implements OCommandStream {
public static final int BUFFER_SIZE = 1024;
private final Set separators = new HashSet(Arrays.asList(';', '\n'));
private Reader reader;
private Character nextCharacter;
private State state;
private enum State {
S, A, B, C, D, E, F
}
private enum Symbol {
LATTER, WS, QT, AP, SEP, EOF
}
public ODFACommandStream(String commands) {
reader = new StringReader(commands);
init();
}
public ODFACommandStream(File file) throws FileNotFoundException {
reader = new BufferedReader(new FileReader(file), BUFFER_SIZE);
init();
}
private void init() {
try {
final int next = reader.read();
if (next > -1)
nextCharacter = (char) next;
else
nextCharacter = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Character nextCharacter() throws IOException {
if (nextCharacter == null)
return null;
final Character result = nextCharacter;
final int next = reader.read();
if (next < 0)
nextCharacter = null;
else
nextCharacter = (char) next;
return result;
}
@Override
public boolean hasNext() {
return nextCharacter != null;
}
@Override
public String nextCommand() {
try {
state = State.S;
final StringBuilder result = new StringBuilder();
StringBuilder stateWord = new StringBuilder();
while (state != State.E) {
Character c = nextCharacter();
String sch = null;
Symbol s;
if (c == null)
s = Symbol.EOF;
else if (c.equals('\''))
s = Symbol.AP;
else if (c.equals('"'))
s = Symbol.QT;
else if (separators.contains(c))
s = Symbol.SEP;
else if (Character.isWhitespace(c))
s = Symbol.WS;
else if (c == '\\') {
final Character nextCharacter = nextCharacter();
sch = "" + c + nextCharacter;
s = Symbol.LATTER;
} else
s = Symbol.LATTER;
final State newState = transition(state, s);
if (newState == State.F)
throw new IllegalStateException("Unexpected end of file");
State oldState = state;
state = newState;
if (state != State.E && state != State.S) {
if (state != oldState) {
result.append(stateWord);
stateWord = new StringBuilder();
}
if (sch != null)
stateWord.append(sch);
else
stateWord.append(c);
}
if (state == State.E) {
if (stateWord.length() > 0 && (oldState != State.D))
result.append(stateWord);
}
}
return result.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void close(boolean onDelete) {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public Symbol symbol(Character c) {
if (c.equals('\''))
return Symbol.AP;
if (c.equals('"'))
return Symbol.QT;
if (separators.contains(c))
return Symbol.SEP;
if (Character.isWhitespace(c))
return Symbol.WS;
return Symbol.LATTER;
}
private State transition(State s, Symbol c) {
switch (s) {
case S:
switch (c) {
case LATTER:
return State.A;
case WS:
return State.S;
case AP:
return State.B;
case QT:
return State.C;
case SEP:
return State.S;
case EOF:
return State.E;
}
break;
case A:
case D:
switch (c) {
case LATTER:
return State.A;
case WS:
return State.D;
case AP:
return State.B;
case QT:
return State.C;
case SEP:
return State.E;
case EOF:
return State.E;
}
break;
case B:
switch (c) {
case LATTER:
return State.B;
case WS:
return State.B;
case AP:
return State.A;
case QT:
return State.B;
case SEP:
return State.B;
case EOF:
return State.F;
}
break;
case C:
switch (c) {
case LATTER:
return State.C;
case WS:
return State.C;
case AP:
return State.C;
case QT:
return State.A;
case SEP:
return State.C;
case EOF:
return State.F;
}
break;
case E:
return State.E;
case F:
return State.F;
}
throw new IllegalStateException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy