package nl.knaw.huygens.alexandria.endpoint.command;
/*
* #%L
* alexandria-main
* =======
* Copyright (C) 2015 - 2017 Huygens ING (KNAW)
* =======
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import com.google.common.base.Joiner;
import nl.knaw.huygens.alexandria.antlr.AQL2Lexer;
import nl.knaw.huygens.alexandria.antlr.AQL2Parser;
import nl.knaw.huygens.alexandria.antlr.QueryErrorListener;
import nl.knaw.huygens.alexandria.api.model.CommandStatus;
public class AQL2Task implements Runnable {
private CommandStatus status;
private UUID uuid;
private String aql2Command;
public AQL2Task(String aql2Command) {
this.aql2Command = aql2Command;
this.uuid = UUID.randomUUID();
this.status = new CommandStatus();
}
public CommandStatus getStatus() {
return status;
}
@Override
public void run() {
status.setStarted();
try {
Object result = process();
status.setResult(result);
status.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
status.setSuccess(false);
status.setErrorMessage(e.getMessage());
}
status.setDone();
}
private Object process() {
QueryVisitor visitor = new QueryVisitor();
List<String> parseErrors = parse(visitor);
if (!parseErrors.isEmpty()) {
throw new RuntimeException("parse error(s): " + Joiner.on("\n").join(parseErrors));
}
String function = visitor.getFunction();
List<Object> parameters = visitor.getParameters();
Object result;
switch (function) {
case "hello":
result = parameters.stream().map(this::hello).collect(joining("\n"));
break;
case "bye":
result = parameters.stream().map(this::bye).collect(joining("\n"));
break;
default:
throw new RuntimeException("unknown command: " + aql2Command);
}
return result;
}
private List<String> parse(QueryVisitor visitor) {
List<String> parseErrors = new ArrayList<>();
QueryErrorListener errorListener = new QueryErrorListener();
CharStream stream = new ANTLRInputStream(aql2Command);
AQL2Lexer lex = new AQL2Lexer(stream);
lex.removeErrorListeners();
CommonTokenStream tokenStream = new CommonTokenStream(lex);
AQL2Parser parser = new AQL2Parser(tokenStream);
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
parser.setBuildParseTree(true);
ParseTree tree = parser.root();
// Log.info("tree={}", tree.toStringTree(parser));
if (errorListener.heardErrors()) {
parseErrors.addAll(errorListener.getParseErrors().stream()//
// .map(AlexandriaQueryParser::clarifyParseError)//
.collect(toList()));
// result = "error";
}
visitor.visit(tree);
parseErrors.addAll(errorListener.getParseErrors());
return parseErrors;
}
public UUID getUUID() {
return uuid;
}
public String hello(Object parameter) {
return "Hello and welcome, " + parameter + "!";
}
public String bye(Object parameter) {
return "Goodbye " + parameter + "!";
}
}