package li.strolch.model.query.parser;
import static org.petitparser.parser.primitive.CharacterParser.whitespace;
import static org.petitparser.parser.primitive.CharacterParser.word;
import static org.petitparser.parser.primitive.StringParser.ofIgnoringCase;
import org.petitparser.context.Result;
import org.petitparser.parser.Parser;
import org.petitparser.tools.CompositeParser;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.OrSelection;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.query.StrolchElementQuery;
import li.strolch.model.query.StrolchTypeNavigation;
import li.strolch.model.visitor.NoStrategyActivityVisitor;
import li.strolch.model.visitor.NoStrategyOrderVisitor;
import li.strolch.model.visitor.NoStrategyResourceVisitor;
import li.strolch.utils.StringMatchMode;
public class QueryParser extends CompositeParser {
private StrolchElementQuery<?> query;
private OrSelection or;
private IdSelection idSelection;
/**
* Use static helper methods instead of constructors
*
* @param resourceQuery
*/
private QueryParser(StrolchElementQuery<?> query) {
// don't allow public construction
this.query = query;
}
private OrSelection or() {
if (this.or == null)
this.or = query.or();
return or;
}
@Override
protected void initialize() {
// [id:<value>] [name:<value>] [type:<value>] [param:<bagId>:<paramId>] [value]
Parser id = ofIgnoringCase("id:").seq(word().star().flatten()).pick(1);
Parser name = ofIgnoringCase("name:").seq(word().star().flatten()).pick(1);
Parser type = ofIgnoringCase("type:").seq(word().star().flatten()).pick(1);
def("id", id);
def("name", name);
def("type", type);
Parser query = whitespace().optional().seq(ref("type").or(ref("id")).or(ref("name")).or(whitespace())).star();
def("query", query);
def("start", ref("query"));
action("id", (String s) -> {
String trimmed = s.trim();
if (trimmed.isEmpty())
return null;
if (this.idSelection == null) {
this.idSelection = new IdSelection(trimmed, StringMatchMode.ci());
or().with(this.idSelection);
} else {
this.idSelection.with(trimmed);
}
return null;
});
action("name", (String s) -> {
String trimmed = s.trim();
if (!trimmed.isEmpty())
or().with(new NameSelection(trimmed, StringMatchMode.ci()));
return null;
});
action("type", (String s) -> {
String trimmed = s.trim();
if (!trimmed.isEmpty())
this.query.setNavigation(new StrolchTypeNavigation(trimmed));
return null;
});
action("start", o -> this.query);
}
public static ResourceQuery<Resource> parseToResourceQuery(String queryString, boolean withAny) {
QueryParser parser = new QueryParser(new ResourceQuery<>());
Result result = parser.parse(queryString);
ResourceQuery<Resource> query = result.get();
query.setResourceVisitor(new NoStrategyResourceVisitor());
if (!query.hasSelection() && withAny) {
query.withAny();
}
return query;
}
public static OrderQuery<Order> parseToOrderQuery(String queryString, boolean withAny) {
QueryParser parser = new QueryParser(new OrderQuery<>());
Result result = parser.parse(queryString);
OrderQuery<Order> query = result.get();
query.setOrderVisitor(new NoStrategyOrderVisitor());
if (!query.hasSelection() && withAny) {
query.withAny();
}
return query;
}
public static ActivityQuery<Activity> parseToActivityQuery(String queryString, boolean withAny) {
QueryParser parser = new QueryParser(new ActivityQuery<>());
Result result = parser.parse(queryString);
ActivityQuery<Activity> query = result.get();
query.setActivityVisitor(new NoStrategyActivityVisitor());
if (!query.hasSelection() && withAny) {
query.withAny();
}
return query;
}
}