Remove iterator from MatchAggregator

Change-Id: I462816c69ea2ed72a292eca4848604155596e60c
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
index 9720d6d..b566928 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
@@ -2,9 +2,11 @@
 
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.Writer;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringWriter;
+
 import java.util.Collection;
 import java.util.ArrayList;
 
@@ -17,22 +19,50 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
 
-public class MatchAggregator implements Iterable<JsonNode> {
+/**
+ * Base class for collecting matches and header information
+ * for exporters implementing the Exporter interface.
+ */
+
+public class MatchAggregator {
 
     private ObjectMapper mapper = new ObjectMapper();
 
     private LinkedList<JsonNode> matches;
 
-    private BufferedWriter writer;
+    private Writer writer;
 
+    private File file;
+    
     public JsonNode meta, query, collection;
 
+    public void setMeta (JsonNode meta) {
+        this.meta = meta;
+    };
+   
+    public void setQuery (JsonNode query) {
+        this.query = query;
+    };
+
+    public void setCollection (JsonNode collection) {
+        this.collection = collection;
+    };
+
+    public void writeHeader (Writer w) throws IOException { };
+    public void writeFooter (Writer w) throws IOException { };
+    public void addMatch (JsonNode n, Writer w) throws IOException { };
+   
+
     /**
      * Create new match aggregator and parse initial Json
      * file to get header information and initial matches.
      */
-    public MatchAggregator (String resp) throws IOException {
+    public void init (String resp) throws IOException {
+
+        this.file = null;
 
         matches = new LinkedList();
 
@@ -45,11 +75,14 @@
         if (actualObj == null)
             return;
 
-        this.meta       = actualObj.get("meta");
-        this.query      = actualObj.get("query");
-        this.collection = actualObj.get("collection");
+        this.setMeta(actualObj.get("meta"));
+        this.setQuery(actualObj.get("query"));
+        this.setCollection(actualObj.get("collection"));
 
+        writer = new StringWriter();
 
+        this.writeHeader(writer);
+        
         JsonNode mNodes = actualObj.get("matches");
 
         if (mNodes == null)
@@ -58,7 +91,8 @@
         // Iterate over the results of the current file
         Iterator<JsonNode> mNode = mNodes.elements();
         while (mNode.hasNext()) {
-            this.matches.add(mNode.next());
+            this.addMatch(mNode.next(), writer);
+            // this.matches.add(mNode.next());
         };
     };
 
@@ -66,73 +100,67 @@
     /**
      * Append more matches to the result set.
      */
-    public void append (String resp) throws IOException {
+    public void appendMatches (String resp) throws IOException {
 
         // Open a temp file if not already opened
-        if (writer == null) {
+        if (this.file == null) {
 
             // Create temporary file
-            File expTmp = File.createTempFile("idsexppl-", ".tmpJson");
+            this.file = File.createTempFile("idsexppl-", ".tmpJson");
 
             // better delete after it is not needed anymore
-            expTmp.deleteOnExit();
+            this.file.deleteOnExit();
+
+            String s = writer.toString();
 
             // Establish writer
-            writer = new BufferedWriter(new FileWriter(expTmp, true));
+            writer = new BufferedWriter(new FileWriter(this.file, true));
+
+            // Add in memory string
+            writer.write(s);
         };
 
         JsonParser parser = mapper.getFactory().createParser(resp);
         JsonNode actualObj = mapper.readTree(parser);
-        Iterator<JsonNode> mNode = actualObj.get("matches").elements();
 
+        if (actualObj == null)
+            return;
+        
+        JsonNode mNodes = actualObj.get("matches");
+
+        if (mNodes == null)
+            return;
+
+        Iterator<JsonNode> mNode = mNodes.elements();
+        
         MatchExport match;
         while (mNode.hasNext()) {
-            writer.append(mNode.next().toString());
-            writer.newLine();
+            this.addMatch(mNode.next(), writer);
         };
     };
 
 
     /**
-     * Return an iterator for all matches
+     * Serve response entity, either as a string or as a file.
      */
-    public MatchIterator iterator() { 
-        return new MatchIterator(); 
-    };
+    public ResponseBuilder serve () {
+        try {
 
-
-    // Private iterator class
-    public class MatchIterator implements Iterator<JsonNode> {
-        private int listIndex, fileIndex;
-
-        // Constructor
-        public MatchIterator () {
-            this.listIndex = matches.size() > 0 ? 0 : -1;
-
-            // Set to zero, if file exists
-            this.fileIndex = (writer != null) ? 0 : -1;
-        };
-
-        @Override
-        public boolean hasNext () {
-            if (this.listIndex >= 0 || this.fileIndex >= 0) {
-                return true;
+            this.writeFooter(this.writer);
+            this.writer.close();
+            
+            if (this.file == null) {
+                return Response.ok(writer.toString());
             };
-            return false;
+            return Response.ok(this.file);            
+        }
+
+        // Catch error
+        catch (IOException io) {
         };
 
-        @Override
-        public JsonNode next () {
-            if (this.listIndex >= 0) {
-                int i = this.listIndex;
-                if (i >= matches.size() - 1) {
-                    this.listIndex = -1;
-                } else {
-                    this.listIndex++;
-                };
-                return matches.get(i);
-            };
-            return null;
-        };
+        // TODO:
+        //   Return exporter error
+        return Response.status(500).entity("error");
     };
 };
diff --git a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/MatchAggregatorTest.java b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/MatchAggregatorTest.java
index 2859597..80fe776 100644
--- a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/MatchAggregatorTest.java
+++ b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/MatchAggregatorTest.java
@@ -15,17 +15,14 @@
 
     @Test
     public void testEmptyInit () throws IOException {
-        MatchAggregator m = new MatchAggregator("");
+        MatchAggregator m = new MatchAggregator();
+        m.init("");
         assertNull(m.meta);
         assertNull(m.query);
         assertNull(m.collection);
 
-        MatchAggregator.MatchIterator mi = m.iterator();
-
-        assertFalse(mi.hasNext());
-        assertNull(mi.next());
-
-        m = new MatchAggregator(null);
+        m = new MatchAggregator();
+        m.init(null);
         assertNull(m.meta);
         assertNull(m.query);
         assertNull(m.collection);
@@ -33,9 +30,8 @@
 
     @Test
     public void testSampleInit () throws IOException {
-        MatchAggregator m = new MatchAggregator(
-            "{\"meta\":{\"totalResults\":6}}"
-            );
+        MatchAggregator m = new MatchAggregator();
+        m.init("{\"meta\":{\"totalResults\":6}}");
         assertEquals(m.meta.toString(),"{\"totalResults\":6}");
         assertNull(m.query);
         assertNull(m.collection);
@@ -43,19 +39,10 @@
   
     @Test
     public void testMatchesInit () throws IOException {
-        MatchAggregator m = new MatchAggregator(
-            "{\"matches\":[\"first\",\"second\"]}"
-            );
+        MatchAggregator m = new MatchAggregator();
+        m.init("{\"matches\":[\"first\",\"second\"]}");
         assertNull(m.meta);
         assertNull(m.query);
         assertNull(m.collection);
-
-        MatchAggregator.MatchIterator mi = m.iterator();
-
-        assertTrue(mi.hasNext());
-        assertEquals(mi.next().toString(),"\"first\"");
-        assertTrue(mi.hasNext());
-        assertEquals(mi.next().toString(),"\"second\"");
-        assertFalse(mi.hasNext());
     };
 };