meta query serialization for virtual collections (filter and extend)
diff --git a/pom.xml b/pom.xml
index 87d5e6f..27a2667 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,13 +6,13 @@
<artifactId>KorAP-core-modules</artifactId>
<version>1.0</version>
</parent>
-
<groupId>KorAP-modules</groupId>
<artifactId>KorAP-querySerialization</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
+
<name>KorAP-querySerialization</name>
<url>http://maven.apache.org</url>
@@ -22,12 +22,6 @@
<dependencies>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.0</version>
@@ -38,17 +32,17 @@
<version>2.2.2</version>
</dependency>
<dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.2.2</version>
- </dependency>
- <dependency>
<groupId>KorAP-modules</groupId>
<artifactId>KorAP-PoliqarpParser</artifactId>
<version>0.05</version>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
-
<build>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<outputDirectory>${basedir}/bin</outputDirectory>
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaCollectionSerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaCollectionSerializer.java
new file mode 100644
index 0000000..f80aa83
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaCollectionSerializer.java
@@ -0,0 +1,142 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 04/12/2013
+ */
+public class MetaCollectionSerializer {
+
+ public String meta1 = "{\n" +
+ " \"@type\": \"korap:meta-filter\",\n" +
+ " \"@id\": \"korap-filter#id-23\",\n" +
+ " \"@value\": {\n" +
+ " \"@type\": \"korap:term\",\n" +
+ " \"@value\": \"wissenschaft\"\n" +
+ " }\n" +
+ " }\n";
+ public String meta2 = "{\n" +
+ " \"@type\": \"korap:meta-filter\",\n" +
+ " \"@id\": \"korap-filter#id-24\",\n" +
+ " \"@value\": {\n" +
+ " \"@type\": \"korap:group\",\n" +
+ " \"relation\": \"and\",\n" +
+ " \"operands\": [\n" +
+ " {\n" +
+ " \"@type\": \"korap:term\",\n" +
+ " \"@field\": \"korap:field#pubPlace\",\n" +
+ " \"@value\": \"Erfurt\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"@type\": \"korap:term\",\n" +
+ " \"@field\": \"korap:field#author\",\n" +
+ " \"@value\": \"Hesse\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " }\n";
+ private MetaTypes types;
+ private ObjectMapper mapper;
+ private String meta3 = "{\n" +
+ " \"@type\": \"korap:meta-extend\",\n" +
+ " \"@id\": \"korap-filter#id-25\",\n" +
+ " \"@value\": {\n" +
+ " \"@type\": \"korap:group\",\n" +
+ " \"relation\": \"and\",\n" +
+ " \"operands\": [\n" +
+ " {\n" +
+ " \"@type\": \"korap:group\",\n" +
+ " \"relation\": \"comment: other values can be 'since','until' in combination with a simple korap:term\",\n" +
+ " \"relation\": \"between\",\n" +
+ " \"@field\": \"korap:field#pubDate\",\n" +
+ " \"operands\": [\n" +
+ " {\n" +
+ " \"@type\": \"korap:date\",\n" +
+ " \"@value\": \"comment: either long value or String representation '2013-04-29'\",\n" +
+ " \"@value\": \"2011\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"@type\": \"korap:date\",\n" +
+ " \"@value\": \"2013\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"@type\": \"korap:term\",\n" +
+ " \"@field\": \"korap:field#textClass\",\n" +
+ " \"@value\": \"freizeit\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " }";
+ private Map<String, Map> tester;
+
+ public MetaCollectionSerializer() {
+ this.types = new MetaTypes();
+ this.mapper = new ObjectMapper();
+ this.tester = tester();
+ }
+
+ //resources must be ordered: 0 without parent, 1 has 0 as parent, etc.
+ // what about extend?! is that also part of the VC meta query?!
+ public String serialize(String resource) throws IOException {
+ Map metas = new HashMap();
+ Map<String, String> pa = getParents(resource);
+ List<Map> parids = new ArrayList<>();
+ for (String key : pa.keySet()) {
+ Map re = types.mapify(pa.get(key));
+ parids.add(re);
+ }
+ metas.put("meta", parids);
+ return mapper.writeValueAsString(metas);
+ }
+
+ private Map<String, String> getParents(String id) {
+ Map<String, String> cursor = getResource(id);
+ Map<String, String> parents = new HashMap<>();
+
+ if (cursor.get("parent") != null && !cursor.get("parent").isEmpty()) {
+ parents.put(id, cursor.get("query"));
+ parents.putAll(getParents(cursor.get("parent")));
+ } else
+ parents.put(id, cursor.get("query"));
+ return parents;
+
+ }
+
+ //todo: connection to database module!
+ public Map<String, String> getResource(String id) {
+ return tester.get(id);
+
+ }
+
+ private Map<String, Map> tester() {
+ Map<String, Map> l = new HashMap<>();
+ Map<String, String> s = new HashMap<>();
+ s.put("id", "23");
+ s.put("parent", "");
+ s.put("query", meta1);
+
+ Map<String, String> s2 = new HashMap<>();
+ s2.put("id", "24");
+ s2.put("parent", "23");
+ s2.put("query", meta2);
+
+ Map<String, String> s3 = new HashMap<>();
+ s3.put("id", "25");
+ s3.put("parent", "24");
+ s3.put("query", meta3);
+ l.put("23", s);
+ l.put("24", s2);
+ l.put("25", s3);
+ return l;
+ }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQuerySerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQuerySerializer.java
new file mode 100644
index 0000000..6db54f4
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaQuerySerializer.java
@@ -0,0 +1,106 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * serializes a map of meta queries to JSON-LD. Currently this only works for simple mode queries (simple AND relation, except for date ranges)
+ * Expert mode requires a full blown parser (since different combinations of OR and AND relations are possible)
+ * also normalizes dates to year-month-day
+ * <p/>
+ * <p/>
+ * User: hanl
+ * Date: 11/14/13
+ * Time: 2:03 PM
+ */
+public class MetaQuerySerializer {
+
+ private ObjectMapper mapper;
+ private MetaTypes types;
+
+ public MetaQuerySerializer() {
+ this.mapper = new ObjectMapper();
+ this.types = new MetaTypes();
+ }
+
+ // construct pubdate range query as "pubDate:'<date>' ~ pubDate:'<date>'"
+ //todo: how to handle regex types?
+ // only handles AND relation between query attributes and values!
+ // value pair : pubdate=<date>, pubPlace=<place>, etc.
+ public List serializeQueries(Map<String, String> queries) {
+ boolean single = true;
+ boolean multypes = queries.keySet().size() > 1;
+ List metavalue;
+ String def_key = null;
+ if (queries.size() > 1)
+ single = false;
+
+ List value = new ArrayList<>();
+ for (String key : queries.keySet()) {
+ if (!multypes)
+ def_key = key;
+ String[] dr;
+ if (queries.get(key).contains("~")) {
+ dr = queries.get(key).split("~");
+ Map fd = types.createTerm(null, null, dr[0].trim(), "korap:date");
+ Map td = types.createTerm(null, null, dr[1].trim(), "korap:date");
+ Map dg = types.createGroup("between", key, Arrays.asList(fd, td));
+ value.add(dg);
+ continue;
+ } else if (queries.get(key).contains(">")) {
+ dr = queries.get(key).split(">");
+ Map fd = types.createTerm(null, null, dr[0].trim(), "korap:date");
+ Map td = types.createTerm(null, null, dr[1].trim(), "korap:date");
+ Map dg = types.createGroup("between", key, Arrays.asList(fd, td));
+ value.add(dg);
+ continue;
+ } else if (queries.get(key).contains("<")) {
+ dr = queries.get(key).split("<");
+ Map fd = types.createTerm(null, null, dr[0].trim(), "korap:date");
+ Map td = types.createTerm(null, null, dr[1].trim(), "korap:date");
+ Map dg = types.createGroup("between", key, Arrays.asList(fd, td));
+ value.add(dg);
+ continue;
+ }
+
+ Map term;
+ if (multypes)
+ term = types.createTerm(key, null, queries.get(key).trim(), null);
+ else
+ term = types.createTerm(null, null, queries.get(key).trim(), null);
+ value.add(term);
+ }
+
+ // todo: missing: - takes only one resource, but resources can be chained!
+ // only filters, no extension
+// metavalue.put("meta", Arrays.asList(types.createMetaFilter(resource, (Map) value.get(0))));
+ if (single)
+ metavalue = Arrays.asList(types.createMetaFilter((Map) value.get(0)));
+ else {
+ Map group;
+ if (!multypes)
+ group = types.createGroup("and", def_key, value);
+ else
+ group = types.createGroup("and", null, value);
+// metavalue.put("meta", Arrays.asList(types.createMetaFilter(resource, group)));
+ metavalue = Arrays.asList(types.createMetaFilter(group));
+ }
+ return metavalue;
+ }
+
+ public String stringify(Map<String, String> queries) throws IOException {
+ Map f = new HashMap();
+ f.put("meta", serializeQueries(queries));
+ return mapper.writeValueAsString(f);
+ }
+
+ public JsonNode jsonify(Map<String, String> queries) {
+ List s = serializeQueries(queries);
+ return mapper.valueToTree(s);
+ }
+
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaSerializer.java b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaSerializer.java
deleted file mode 100644
index 12901f5..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaSerializer.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package de.ids_mannheim.korap.query.serialize;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- *
- * serializes a map of meta queries to JSON-LD. Currently this only works for simple mode queries (simple AND relation, except for date ranges)
- * Expert mode requires a full blown parser (since different combinations of OR and AND relations are possible)
- * also normalizes dates to year-month-day
- *
- *
- * User: hanl
- * Date: 11/14/13
- * Time: 2:03 PM
- */
-public class MetaSerializer {
-
- private ObjectMapper mapper;
-
- public MetaSerializer() {
- this.mapper = new ObjectMapper();
- }
-
- private Map createGroup(String relation, String field, List terms) {
- if (relation == null)
- return null;
-
- Map kgroup = new LinkedHashMap<>();
- kgroup.put("@type", "korap:group");
- if (field != null)
- kgroup.put("field", "korap:field#" + field);
- kgroup.put("relation", relation);
- kgroup.put("operands", terms);
- return kgroup;
- }
-
-
- private Map createTerm(String field, String subtype, String value, String type) {
- Map term = new LinkedHashMap<>();
- if (type == null)
- type = "korap:term";
- term.put("@type", type);
- if (field != null)
- term.put("@field", "korap:field#" + field);
- if (subtype != null)
- term.put("subtype", "korap:value#" + subtype);
- term.put("@value", value);
- return term;
- }
-
- private Map createMeta(String resource, Map value) {
- Map meta = new LinkedHashMap();
- meta.put("@type", "korap:meta-filter");
- meta.put("@id", "korap-filter#" + resource);
- meta.put("@value", value);
- return meta;
- }
-
- private Map createMetaFilter(String resource, Map value) {
- return null;
- }
-
-
- // construct pubdate range query as "pubDate:'<date>' ~ pubDate:'<date>'"
- //todo: how to handle regex types?
- // only handles AND relation between query attributes!
- // value pair : pubdate=<date>, pubPlace=<place>, etc.
- private Map serialize(String resource, Map<String, String> queries) {
- boolean single = true;
- boolean multypes = new HashSet<>(queries.keySet()).size() > 1;
- Map metavalue = new LinkedHashMap<>();
- String def_key = null;
- if (queries.size() > 1)
- single = false;
-
- List value = new ArrayList<>();
- for (String key : queries.keySet()) {
- if (!multypes)
- def_key = key;
- if (queries.get(key).contains("~")) {
- String[] dr = queries.get(key).split("~");
- Map fd = createTerm(null, null, dr[0].trim(), "korap:date");
- Map td = createTerm(null, null, dr[1].trim(), "korap:date");
- Map dg = createGroup("between", key, Arrays.asList(fd, td));
- value.add(dg);
- continue;
- }
-
- Map term;
- if (multypes)
- term = createTerm(key, null, queries.get(key).trim(), null);
- else
- term = createTerm(null, null, queries.get(key).trim(), null);
- value.add(term);
- }
-
- if (single)
- metavalue.put("meta", Arrays.asList(createMeta(resource, (Map) value.get(0))));
- else {
- Map group;
- if (!multypes)
- group = createGroup("and", def_key, value);
- else
- group = createGroup("and", null, value);
- metavalue.put("meta", Arrays.asList(createMeta(resource, group)));
- }
- return metavalue;
- }
-
- private String formatDate(String date) {
- return "";
- }
-
-
- public String stringify(String resource, Map<String, String> queries) throws IOException {
- Map s = serialize(resource, queries);
- return mapper.writeValueAsString(s);
- }
-
-
-
-
-
-}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/MetaTypes.java b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaTypes.java
new file mode 100644
index 0000000..887f176
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/MetaTypes.java
@@ -0,0 +1,95 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 04/12/2013
+ */
+public class MetaTypes {
+
+ private ObjectMapper mapper;
+
+ public MetaTypes() {
+ this.mapper = new ObjectMapper();
+ }
+
+ public Map createGroup(String relation, String field, List terms) {
+ if (relation == null)
+ return null;
+
+ Map kgroup = new LinkedHashMap<>();
+ kgroup.put("@type", "korap:group");
+ if (field != null)
+ kgroup.put("field", "korap:field#" + field);
+ kgroup.put("relation", relation);
+ kgroup.put("operands", terms);
+ return kgroup;
+ }
+
+ public Map createTerm(String field, String subtype, String value, String type) {
+ Map term = new LinkedHashMap<>();
+ if (type == null)
+ type = "korap:term";
+ term.put("@type", type);
+ if (field != null)
+ term.put("@field", "korap:field#" + field);
+ if (subtype != null)
+ term.put("subtype", "korap:value#" + subtype);
+ term.put("@value", value);
+ return term;
+ }
+
+ public Map createResourceFilter(String resource, Map value) {
+ Map meta = new LinkedHashMap();
+ meta.put("@type", "korap:meta-filter");
+ meta.put("@id", "korap-filter#" + resource);
+ meta.put("@value", value);
+ return meta;
+ }
+
+ public Map createResourceFilter(String resource, String value) throws IOException {
+ return createResourceFilter(resource, mapify(value));
+ }
+
+ public Map createResourceExtend(String resource, Map value) {
+ Map meta = new LinkedHashMap();
+ meta.put("@type", "korap:meta-extend");
+ meta.put("@id", "korap-filter#" + resource);
+ meta.put("@value", value);
+ return meta;
+ }
+
+ public Map createMetaFilter(Map value) {
+ Map meta = new LinkedHashMap();
+ meta.put("@type", "korap:meta-filter");
+ meta.put("@value", value);
+ return meta;
+ }
+
+ public Map createMetaExtend(Map value) {
+ Map meta = new LinkedHashMap();
+ meta.put("@type", "korap:meta-extend");
+ meta.put("@value", value);
+ return meta;
+ }
+
+ public String formatDate(String date) {
+ return "";
+ }
+
+ public Map mapify(String s) throws IOException {
+ return mapper.readValue(s, Map.class);
+ }
+
+ public String stringify(Map m) throws JsonProcessingException {
+ return mapper.writeValueAsString(m);
+ }
+
+}
diff --git a/src/test/java/MetaQuerySerializationTest.java b/src/test/java/MetaQuerySerializationTest.java
new file mode 100644
index 0000000..71ca546
--- /dev/null
+++ b/src/test/java/MetaQuerySerializationTest.java
@@ -0,0 +1,51 @@
+import de.ids_mannheim.korap.query.serialize.MetaCollectionSerializer;
+import de.ids_mannheim.korap.query.serialize.MetaQuerySerializer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 04/12/2013
+ */
+
+@RunWith(JUnit4.class)
+public class MetaQuerySerializationTest {
+
+ private MetaQuerySerializer serializer;
+
+ public MetaQuerySerializationTest() {
+ serializer = new MetaQuerySerializer();
+ }
+
+ @Test
+ public void test() throws IOException {
+ Map<String, String> j = new HashMap();
+ j.put("author", "Goethe");
+ j.put("pubPLace", "Erfurt");
+ j.put("textClass", "wissenschaft");
+ String s = serializer.stringify(j);
+// System.out.println("value reference " + s);
+ }
+
+ @Test
+ public void testSingle() throws IOException {
+ Map<String, String> j = new HashMap();
+ j.put("textClass", "wissenschaft");
+ String s = serializer.stringify(j);
+// System.out.println("value reference test single " + s);
+ }
+
+ @Test
+ public void testResourceMeta() throws IOException {
+ MetaCollectionSerializer ser = new MetaCollectionSerializer();
+ String s = ser.serialize("25");
+ System.out.println(" --- RESULT JSON " + s);
+
+
+ }
+}