[New] Added a QueryParser to parse String queries to Strolch queries
This commit is contained in:
parent
0246adb4ab
commit
5f71427d33
|
@ -109,7 +109,7 @@
|
||||||
<version>${eitchnet.privilege.version}</version>
|
<version>${eitchnet.privilege.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- main -->
|
<!-- Other -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
@ -120,6 +120,11 @@
|
||||||
<artifactId>commons-cli</artifactId>
|
<artifactId>commons-cli</artifactId>
|
||||||
<version>1.2</version>
|
<version>1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.petitparser</groupId>
|
||||||
|
<artifactId>java-petitparser</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- JSON -->
|
<!-- JSON -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -97,6 +97,11 @@
|
||||||
<artifactId>jersey-media-moxy</artifactId>
|
<artifactId>jersey-media-moxy</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.petitparser</groupId>
|
||||||
|
<artifactId>java-petitparser</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>li.strolch</groupId>
|
<groupId>li.strolch</groupId>
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
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 ch.eitchnet.utils.StringMatchMode;
|
||||||
|
import li.strolch.model.Order;
|
||||||
|
import li.strolch.model.Resource;
|
||||||
|
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.NoStrategyOrderVisitor;
|
||||||
|
import li.strolch.model.visitor.NoStrategyResourceVisitor;
|
||||||
|
|
||||||
|
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) -> {
|
||||||
|
if (this.idSelection == null) {
|
||||||
|
this.idSelection = new IdSelection(s.trim(), StringMatchMode.ci());
|
||||||
|
or().with(this.idSelection);
|
||||||
|
} else {
|
||||||
|
this.idSelection.with(s.trim());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
action("name", (String s) -> {
|
||||||
|
or().with(new NameSelection(s.trim(), StringMatchMode.ci()));
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
action("type", (String s) -> {
|
||||||
|
this.query.setNavigation(new StrolchTypeNavigation(s.trim()));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package li.strolch.model.query.parser;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import li.strolch.model.Resource;
|
||||||
|
import li.strolch.model.query.IdSelection;
|
||||||
|
import li.strolch.model.query.NameSelection;
|
||||||
|
import li.strolch.model.query.OrSelection;
|
||||||
|
import li.strolch.model.query.ResourceQuery;
|
||||||
|
import li.strolch.model.query.Selection;
|
||||||
|
import li.strolch.model.query.StrolchTypeNavigation;
|
||||||
|
|
||||||
|
public class QueryParserTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseEmpty() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("", false);
|
||||||
|
assertFalse(query.hasNavigation());
|
||||||
|
assertFalse(query.hasSelection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseId() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("id:asd", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(1, selections.size());
|
||||||
|
assertEquals(IdSelection.class, selections.get(0).getClass());
|
||||||
|
IdSelection idSelection = (IdSelection) selections.get(0);
|
||||||
|
List<String> ids = idSelection.getIds();
|
||||||
|
assertEquals(1, ids.size());
|
||||||
|
assertEquals("asd", ids.get(0));
|
||||||
|
assertFalse(query.hasNavigation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseIds() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("id:asd id:bbb", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(1, selections.size());
|
||||||
|
assertEquals(IdSelection.class, selections.get(0).getClass());
|
||||||
|
IdSelection idSelection = (IdSelection) selections.get(0);
|
||||||
|
List<String> ids = idSelection.getIds();
|
||||||
|
assertEquals(2, ids.size());
|
||||||
|
assertEquals("asd", ids.get(0));
|
||||||
|
assertEquals("bbb", ids.get(1));
|
||||||
|
assertFalse(query.hasNavigation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseName() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("name:asd", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(1, selections.size());
|
||||||
|
assertEquals(NameSelection.class, selections.get(0).getClass());
|
||||||
|
assertEquals("asd", ((NameSelection) selections.get(0)).getName());
|
||||||
|
assertFalse(query.hasNavigation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseNames() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("name:asd name:bbb", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(2, selections.size());
|
||||||
|
assertEquals(NameSelection.class, selections.get(0).getClass());
|
||||||
|
assertEquals("asd", ((NameSelection) selections.get(0)).getName());
|
||||||
|
|
||||||
|
assertEquals(NameSelection.class, selections.get(1).getClass());
|
||||||
|
assertEquals("bbb", ((NameSelection) selections.get(1)).getName());
|
||||||
|
assertFalse(query.hasNavigation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseType() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("type:asd", false);
|
||||||
|
assertFalse(query.hasSelection());
|
||||||
|
assertTrue(query.hasNavigation());
|
||||||
|
StrolchTypeNavigation navigation = (StrolchTypeNavigation) query.getNavigation();
|
||||||
|
assertEquals("asd", navigation.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseIdNameType() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery("id:foo name:bar type:asd", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(2, selections.size());
|
||||||
|
assertEquals(IdSelection.class, selections.get(0).getClass());
|
||||||
|
assertEquals(NameSelection.class, selections.get(1).getClass());
|
||||||
|
assertTrue(query.hasNavigation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldParseWithWhitespace() {
|
||||||
|
ResourceQuery<Resource> query = QueryParser.parseToResourceQuery(" id:foo name:bar type:asd \t ", false);
|
||||||
|
OrSelection or = (OrSelection) query.getSelection();
|
||||||
|
List<Selection> selections = or.getSelections();
|
||||||
|
assertEquals(2, selections.size());
|
||||||
|
assertEquals(IdSelection.class, selections.get(0).getClass());
|
||||||
|
assertEquals(NameSelection.class, selections.get(1).getClass());
|
||||||
|
assertTrue(query.hasNavigation());
|
||||||
|
}
|
||||||
|
}
|
7
pom.xml
7
pom.xml
|
@ -21,6 +21,13 @@
|
||||||
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
|
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<repository>
|
<repository>
|
||||||
<id>archive.eitchnet.ch</id>
|
<id>archive.eitchnet.ch</id>
|
||||||
|
|
Loading…
Reference in New Issue