From 9aeaaebd53afe129fd9d60f6da9d904f57989948 Mon Sep 17 00:00:00 2001 From: tla Date: Fri, 23 Oct 2015 10:47:12 +0200 Subject: [PATCH] Relationship conflation works now. #12 #13 --- .../net/stemmaweb/model/AlignmentModel.java | 6 ++- .../java/net/stemmaweb/rest/Tradition.java | 29 ++++++++++- .../services/Neo4JToTabularParser.java | 16 ++++-- .../TabularInputOutputTest.java | 50 ++++++++++++++++++- 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/stemmarest/src/main/java/net/stemmaweb/model/AlignmentModel.java b/stemmarest/src/main/java/net/stemmaweb/model/AlignmentModel.java index 54117498..312282da 100644 --- a/stemmarest/src/main/java/net/stemmaweb/model/AlignmentModel.java +++ b/stemmarest/src/main/java/net/stemmaweb/model/AlignmentModel.java @@ -69,12 +69,14 @@ public PathExpander reverse() { .uniqueness(Uniqueness.NODE_GLOBAL).traverse(startNode) .nodes().forEach(x -> { if (!conflatedReadings.containsKey(x)) { + conflatedReadings.put(x, x); // Traverse the readings for the given relationships. - db.traversalDescription().depthFirst() + ResourceIterable equivalent = db.traversalDescription().depthFirst() .expand(relationConflater) .evaluator(Evaluators.all()) .uniqueness(Uniqueness.NODE_GLOBAL).traverse(x) - .nodes().forEach(y -> conflatedReadings.put(x, y)); + .nodes(); + equivalent.forEach(y -> conflatedReadings.put(y, x)); } }); } diff --git a/stemmarest/src/main/java/net/stemmaweb/rest/Tradition.java b/stemmarest/src/main/java/net/stemmaweb/rest/Tradition.java index dd871b25..6afe12cb 100644 --- a/stemmarest/src/main/java/net/stemmaweb/rest/Tradition.java +++ b/stemmarest/src/main/java/net/stemmaweb/rest/Tradition.java @@ -575,12 +575,37 @@ public Response getJson() { } + // TODO rethink this API. + @POST + @Path("/json") + @Produces(MediaType.APPLICATION_JSON) + public Response getJson(ArrayList conflatedRelationships) { + return new Neo4JToTabularParser(db).exportAsJSON(traditionId, conflatedRelationships); + } + @GET @Path("/csv") - @Produces(MediaType.TEXT_XML) - public Response get() { + @Produces(MediaType.TEXT_PLAIN) + public Response getCsv() { return new Neo4JToTabularParser(db).exportAsCSV(traditionId, ','); } + + @GET + @Path("/tsv") + @Produces(MediaType.TEXT_PLAIN) + public Response getTsv() { + return new Neo4JToTabularParser(db).exportAsCSV(traditionId, '\t'); + } + + @POST + @Path("/tsv") + @Produces(MediaType.TEXT_PLAIN) + public Response getTsv(ArrayList conflatedRelationships) { + return new Neo4JToTabularParser(db).exportAsCSV(traditionId, '\t', conflatedRelationships); + } + + + /** * Recalculate ranks starting from 'startNode' * Someone would typically use it after inserting a RELATION or a new Node into the graph, diff --git a/stemmarest/src/main/java/net/stemmaweb/services/Neo4JToTabularParser.java b/stemmarest/src/main/java/net/stemmaweb/services/Neo4JToTabularParser.java index da259598..8e5d4ddf 100644 --- a/stemmarest/src/main/java/net/stemmaweb/services/Neo4JToTabularParser.java +++ b/stemmarest/src/main/java/net/stemmaweb/services/Neo4JToTabularParser.java @@ -22,23 +22,27 @@ public Neo4JToTabularParser(GraphDatabaseService db){ this.db = db; } - public Response exportAsJSON(String tradId) { + public Response exportAsJSON(String tradId, ArrayList conflate) { Node traditionNode = DatabaseService.getTraditionNode(tradId, db); if(traditionNode==null) { return Response.status(Response.Status.NOT_FOUND).build(); } // Get the model. - AlignmentModel asJson = new AlignmentModel(traditionNode); + AlignmentModel asJson = new AlignmentModel(traditionNode, conflate); return Response.ok(asJson, MediaType.APPLICATION_JSON_TYPE).build(); } - public Response exportAsCSV(String tradId, char separator) { + public Response exportAsJSON(String tradId) { + return exportAsJSON(tradId, new ArrayList<>()); + } + + public Response exportAsCSV(String tradId, char separator, ArrayList conflate) { Node traditionNode = DatabaseService.getTraditionNode(tradId, db); if(traditionNode==null) { return Response.status(Response.Status.NOT_FOUND).build(); } // Get the model. - AlignmentModel asJson = new AlignmentModel(traditionNode); + AlignmentModel asJson = new AlignmentModel(traditionNode, conflate); // Write the CSV to a string that we can return. StringWriter sw = new StringWriter(); @@ -66,4 +70,8 @@ public Response exportAsCSV(String tradId, char separator) { return Response.ok(sw.toString(), MediaType.TEXT_PLAIN_TYPE).build(); } + public Response exportAsCSV(String tradId, char separator) { + return exportAsCSV(tradId, separator, new ArrayList<>()); + } + } diff --git a/stemmarest/src/test/java/net/stemmaweb/stemmaserver/integrationtests/TabularInputOutputTest.java b/stemmarest/src/test/java/net/stemmaweb/stemmaserver/integrationtests/TabularInputOutputTest.java index 8caafb07..4ccc773e 100644 --- a/stemmarest/src/test/java/net/stemmaweb/stemmaserver/integrationtests/TabularInputOutputTest.java +++ b/stemmarest/src/test/java/net/stemmaweb/stemmaserver/integrationtests/TabularInputOutputTest.java @@ -22,7 +22,7 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; -import java.util.HashMap; +import java.util.HashSet; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -183,6 +183,54 @@ public void testJSONExport() throws Exception { assertEquals(3, i); } + public void testConflatedJSONExport () throws Exception { + GraphMLToNeo4JParser graphImporter = new GraphMLToNeo4JParser(); + String traditionId = null; + try + { + Response response = graphImporter.parseGraphML("src/TestFiles/globalrel_test.xml", "1", "Tradition"); + traditionId = Util.getValueFromJson(response, "tradId"); + } + catch(FileNotFoundException f) + { + // this error should not occur + assertTrue(false); + } + assertNotNull(traditionId); + // Get it back out + ArrayList toConflate = new ArrayList<>(); + toConflate.add("collated"); + ClientResponse result = jerseyTest + .resource() + .path("/tradition/" + traditionId + "/json") + .type(MediaType.APPLICATION_JSON) + .post(ClientResponse.class, toConflate); + assertEquals(Response.Status.OK.getStatusCode(), result.getStatus()); + // Get the JSON out + JSONObject table = result.getEntity(JSONObject.class); + assertTrue(table.has("alignment")); + assertTrue(table.has("length")); + assertEquals(10, table.getInt("length")); + // Every reading at rank 6 should be identical + JSONArray witnesses = table.getJSONArray("alignment"); + HashSet readingsAt6 = new HashSet<>(); + for (int i = 0; i < witnesses.length(); i++) { + Object r6 = witnesses.getJSONObject(i).getJSONArray("tokens").get(5); + if (!r6.toString().equals("null")) + readingsAt6.add(((JSONObject) r6).getString("t")); + } + assertEquals(1, readingsAt6.size()); + + // Every reading at rank 9 should be identical + HashSet readingsAt9 = new HashSet<>(); + for (int i = 0; i < witnesses.length(); i++) { + Object r9 = witnesses.getJSONObject(i).getJSONArray("tokens").get(8); + if (!r9.toString().equals("null")) + readingsAt9.add(((JSONObject) r9).getString("t")); + } + assertEquals(1, readingsAt9.size()); + } + // testOutputCSV // testOutputExcel