Added KrillStats class
Change-Id: Ib574021ce1358ff7b6ed3dba81447f2d50911b5e
diff --git a/Changes b/Changes
index 4f91121..672c91e 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.55.6 2016-06-23
+0.55.6 2016-06-25
- [bugfix] distance with key "t" uses default foundry (diewald)
- [cleanup] Renamed fromJson() to fromKoral() (diewald)
- [cleanup] Removed deprecated methods in Krill:
@@ -11,6 +11,7 @@
- [feature] Added getDoc() method to KrillIndex (diewald)
- [bugfix] Fixed UID handling (diewald)
- [feature] Added document method to Web-API (diewald)
+ - [feature] Added experimental KrillStats class (diewald)
0.55.5 2016-05-02
- [performance] Changed to a dynamic window for sorting in FocusSpans (margaretha)
diff --git a/misc/errorcodes.md b/misc/errorcodes.md
index 27da151..b01ac08 100644
--- a/misc/errorcodes.md
+++ b/misc/errorcodes.md
@@ -10,6 +10,7 @@
610: "Missing request parameters"
620: "Unable to generate JSON"
621: "Unable to parse JSON"
+630: "Document not found"
651: "Unable to extend context"
680: "Server is up and running!"
681: "Document was added successfully", document id
diff --git a/src/main/java/de/ids_mannheim/korap/KrillIndex.java b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
index 43b7928..97576cf 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillIndex.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
@@ -836,7 +836,7 @@
log.warn(e.getLocalizedMessage());
};
- text.addError(830, "Filter was empty");
+ text.addError(630, "Document not found");
return text;
};
diff --git a/src/main/java/de/ids_mannheim/korap/KrillStats.java b/src/main/java/de/ids_mannheim/korap/KrillStats.java
new file mode 100644
index 0000000..898058b
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/KrillStats.java
@@ -0,0 +1,78 @@
+package de.ids_mannheim.korap;
+
+import java.util.*;
+import java.io.IOException;
+
+import com.fasterxml.jackson.annotation.*;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import de.ids_mannheim.korap.response.Notifications;
+
+import java.nio.ByteBuffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Create a Statistics object.
+ *
+ * This is early work and highliy experimental!
+ *
+ * <blockquote><pre>
+ * KrillStats ks = new KrillStats(json);
+ * </pre></blockquote>
+ *
+ * Should serialize to something like
+ *
+ * "stats" : {
+ * "@type" : "koral:stats",
+ * "collection" : [
+ * {
+ * "@type" : "stats:collection",
+ * "foundry" : "base",
+ * "layer" : "s",
+ * "key" : "s",
+ * "value" : 450
+ * },
+ * {
+ * "@type" : "stats:collection",
+ * "key" : "texts",
+ * "value" : 2
+ * }
+ * ]
+ * }
+ *
+ *
+ * @author diewald
+ */
+/*
+ * TODO: THIS IS CURRENTLY HIGHLY EXPERIMENTAL
+ */
+public final class KrillStats extends Notifications {
+
+ // Logger
+ private final static Logger log = LoggerFactory
+ .getLogger(KrillStats.class);
+
+ // This advices the java compiler to ignore all loggings
+ public static final boolean DEBUG = false;
+
+
+ /**
+ * Construct a new KrillStats.
+ *
+ */
+ public KrillStats () {};
+
+ @Override
+ public JsonNode toJsonNode () {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode json = mapper.createObjectNode();
+
+ json.put("@type", "koral:stats");
+
+ return (JsonNode) json;
+ }
+};
diff --git a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
index 4589bb4..f90945f 100644
--- a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
@@ -33,7 +33,7 @@
*
* @author diewald
*/
-@JsonInclude(Include.NON_NULL)
+@JsonInclude(Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class AbstractDocument extends Response {
ObjectMapper mapper = new ObjectMapper();
@@ -428,8 +428,9 @@
* @throws NumberFormatException
*/
public void setUID (String UID) throws NumberFormatException {
- if (UID != null)
+ if (UID != null) {
this.UID = Integer.parseInt(UID);
+ };
};
@@ -1216,6 +1217,10 @@
public JsonNode toJsonNode () {
ObjectNode json = (ObjectNode) super.toJsonNode();
json.putAll((ObjectNode) mapper.valueToTree(this));
+
+ if (this.getUID() == 0)
+ json.remove("UID");
+
return json;
};
};
diff --git a/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java b/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
index baed325..73a7ecf 100644
--- a/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
@@ -35,7 +35,6 @@
* @author diewald
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-// @JsonDeserialize(using = FieldDocumentDeserializer.class)
public class FieldDocument extends AbstractDocument {
ObjectMapper mapper = new ObjectMapper();
@@ -309,8 +308,10 @@
@Override
@JsonIgnore
public void setUID (int ID) {
- super.setUID(ID);
- this.addString("UID", new Integer(ID).toString());
+ if (ID != 0) {
+ super.setUID(ID);
+ this.addString("UID", new Integer(ID).toString());
+ }
};
@Override
diff --git a/src/main/java/de/ids_mannheim/korap/response/Response.java b/src/main/java/de/ids_mannheim/korap/response/Response.java
index 4ac95f9..ccb3056 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Response.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Response.java
@@ -12,6 +12,7 @@
import de.ids_mannheim.korap.KrillCollection;
import de.ids_mannheim.korap.KrillMeta;
import de.ids_mannheim.korap.KrillQuery;
+import de.ids_mannheim.korap.KrillStats;
import de.ids_mannheim.korap.response.Notifications;
/**
@@ -41,6 +42,7 @@
private KrillMeta meta;
private KrillCollection collection;
private KrillQuery query;
+ private KrillStats stats;
private String version, name, node, listener;
@@ -444,6 +446,37 @@
};
+ /**
+ * Get the associated statistics object.
+ * In case no statistics information was defined yet,
+ * a new {@link KrillStats} object will be created.
+ *
+ * @return The attached {@link KrillStats} object.
+ */
+ @JsonIgnore
+ public KrillStats getStats () {
+ if (this.stats == null)
+ this.stats = new KrillStats();
+ return this.stats;
+ };
+
+
+ /**
+ * Set a new {@link KrillStats} object.
+ *
+ * @param stats
+ * A {@link KrillStats} object.
+ * @return The {@link Response} object for chaining
+ */
+ @JsonIgnore
+ public Response setStats (KrillStats stats) {
+ this.stats = stats;
+
+ // Move messages from the stats
+ return (Response) this.moveNotificationsFrom(stats);
+ };
+
+
public void addJsonNode (String key, ObjectNode value) {
if (this.jsonFields == null)
this.jsonFields = new HashMap<String, ObjectNode>(4);
diff --git a/src/main/java/de/ids_mannheim/korap/response/Result.java b/src/main/java/de/ids_mannheim/korap/response/Result.java
index 01102a1..83d08f4 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Result.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Result.java
@@ -270,6 +270,7 @@
*/
public JsonNode toJsonNode () {
ObjectNode json = (ObjectNode) mapper.valueToTree(super.toJsonNode());
+
this._addMeta(json);
// Add matches
diff --git a/src/main/java/de/ids_mannheim/korap/server/Resource.java b/src/main/java/de/ids_mannheim/korap/server/Resource.java
index a439480..08f5399 100644
--- a/src/main/java/de/ids_mannheim/korap/server/Resource.java
+++ b/src/main/java/de/ids_mannheim/korap/server/Resource.java
@@ -43,6 +43,7 @@
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -192,6 +193,40 @@
};
+ // Return corpus info
+ @GET
+ @Path("/corpus")
+ @Produces(MediaType.APPLICATION_JSON)
+ public String getCorpus (@Context UriInfo uri) {
+ ObjectMapper mapper = new ObjectMapper();
+
+ // TODO: Accept fields!!!!
+
+ final Response kresp = _initResponse();
+ if (kresp.hasErrors())
+ return kresp.toJsonString();
+
+ // TODO: Statistics should be node fields - not annotations!
+ // TODO: This is just temporary
+ KrillIndex ki = Node.getIndex();
+
+ ObjectNode obj = mapper.createObjectNode();
+ obj.put("tokens", ki.numberOf("tokens"));
+ obj.put("base/texts", ki.numberOf("base/texts"));
+ obj.put("base/sentences", ki.numberOf("base/sentences"));
+ obj.put("base/paragraphs", ki.numberOf("base/paragraphs"));
+
+ // <legacy>
+ obj.put("sentences", ki.numberOf("sentences"));
+ obj.put("paragraphs", ki.numberOf("paragraphs"));
+ // </legacy>
+
+ kresp.addJsonNode("stats", obj);
+ return kresp.toJsonString();
+ };
+
+ // PUT: Return corpus info for virtual corpus
+
/**
* Find matches in the lucene index based on UIDs and return one
diff --git a/src/test/java/de/ids_mannheim/korap/server/TestResource.java b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
index d390de5..11f27d7 100644
--- a/src/test/java/de/ids_mannheim/korap/server/TestResource.java
+++ b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
@@ -183,17 +183,64 @@
assertEquals("WPD", res.at("/corpusID").asText());
assertEquals(5, res.at("/UID").asInt());
assertEquals("WPD_AAA.00005", res.at("/ID").asText());
+
+ // Get document by UID
+ resp = target.path("/index/17").request().get(String.class);
+ res = mapper.readTree(resp);
+
+ assertEquals(630, res.at("/errors/0/0").asInt());
+ assertTrue(res.at("/UID").isMissingNode());
+
+ // Get corpus statistics
+ resp = target.path("/corpus").request().get(String.class);
+ res = mapper.readTree(resp);
+
+ assertEquals(281, res.at("/stats/sentences").asInt());
+ assertEquals(174, res.at("/stats/paragraphs").asInt());
+ assertEquals(2661, res.at("/stats/tokens").asInt());
+
+ assertEquals(7, res.at("/stats/base~1texts").asInt());
};
/*
@Test
public void testRemoving () throws IOException {
- resp = target.path("/index/" + i).request("application/json")
- .put(jsonE, String.class);
+ String resp;
+ JsonNode res;
+
+ String json = StringfromFile(getClass().getResource("/wiki/02439.json")
+ .getFile());
+ Entity jsonE = Entity.json(json);
+
+ try {
+ // Put new documents to the index
+ resp = target.path("/index/02439").request("application/json")
+ .put(jsonE, String.class);
+
+ res = mapper.readTree(resp);
+
+ // Check mirroring
+ assertEquals(2439, res.at("/text/UID").asInt());
+ assertEquals("milena", res.at("/meta/node").asText());
+ assertEquals(681, res.at("/messages/0/0").asInt());
+ }
+ catch (Exception e) {
+ fail("Server response failed " + e.getMessage() + " (Known issue)");
+ };
+
+ // Commit!
+ resp = target.path("/index").request("application/json")
+ .post(Entity.text(""), String.class);
+ res = mapper.readTree(resp);
+ assertEquals("milena", res.at("/meta/node").asText());
+
+ // Staged data committed
+ assertEquals(683, res.at("/messages/0/0").asInt());
};
*/
+
@Test
public void testCollection () throws IOException {