Export more than one page (UNTESTED DRAFT)

Change-Id: I34d2d0020baef11bed93a53f4c5495020afd2a51
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
index 61b2800..f16bed2 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
@@ -1,5 +1,8 @@
 package de.ids_mannheim.korap.plkexport;
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.lang.Thread;
@@ -53,6 +56,25 @@
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 
+/**
+ * TODO
+ * This is only a draft!!!
+ * Has to be integrated in Nils sourcecode
+ * 
+ * Export works only for rtf, JSON has to be integrated
+ * 
+ * Delete the temp file of the export at the end
+ * 
+ * Get variable cutoff from URL
+ * 
+ * Right now, the web service returns one page (cutoff=1) or all
+ * pages.
+ * There is now limitations of hits. ("Beschränken auf xy Treffer")
+ * does not work right now.
+ * 
+ * ------------------------------------------------------------
+ * Works with the export demo
+ */
 
 @Path("/")
 public class IdsExportService {
@@ -127,7 +149,14 @@
                     .build());
         }
 
-        ResponseBuilder builder;
+
+        int totalhits;
+
+        //TODO cutoff to try out, retrieve it  later:
+        boolean cutoff = false;
+        //boolean cutoff = true;
+
+        ResponseBuilder builder = null;
         Client client = ClientBuilder.newClient();
 
         String scheme = properties.getProperty("api.scheme", "https");
@@ -158,7 +187,7 @@
             uri = uri.queryParam("count", ExWSConf.MAX_EXP_LIMIT);
         };
         */
-        uri = uri.queryParam("count", 50);
+        uri = uri.queryParam("count", ExWSConf.PAGE_SIZE);
 
         // Get client IP, in case service is behind a proxy
         String xff = "";
@@ -207,8 +236,9 @@
         };
     
         String resp;
+        WebTarget resource;
         try {
-            WebTarget resource = client.target(uri.build());
+            resource = client.target(uri.build());
             Invocation.Builder reqBuilder = resource.request(MediaType.APPLICATION_JSON);
             if (xff != "") {
                 reqBuilder = reqBuilder.header("X-Forwarded-For", xff);
@@ -227,35 +257,82 @@
             fname = q;
         }
 
-        //format == json
+        // format == json
         if (format.equals("json")) {
             builder = Response.ok(resp);
             builder.type(MediaType.APPLICATION_JSON);
         }
 
-        // format == rtf / else
+        // format == rtf
         else {
             ObjectMapper mapper = new ObjectMapper();
             JsonFactory factory = mapper.getFactory();
             JsonParser parser = factory.createParser(resp);
             JsonNode actualObj = mapper.readTree(parser);
-            JsonNode jsonNode1 = actualObj.get("matches");
-            LinkedList<MatchExport> listMatches = new LinkedList();
-            ObjectMapper objectMapper = new ObjectMapper();
-            MatchExport match;
 
-            for (Iterator<JsonNode> itNode = jsonNode1.elements(); itNode
-                    .hasNext();) {
-                match = objectMapper.readValue(itNode.next().toString(),
-                        MatchExport.class);
-                listMatches.addLast(match);
+            /*
+             * Get total results
+             */
+            totalhits = actualObj.at("/meta").get("totalResults").asInt();
+
+            // If only one page should be exported there is no need for an temporary export file
+            if (cutoff) {
+                String rtfresp = getRtf(resp);
+                builder = Response.ok(rtfresp);
             }
 
-            String rtfresp = writeRTF(listMatches);
-            builder = Response.ok(rtfresp);
+            if (!cutoff) {
+           
+                /*
+                 *  Get number of pages and the number of hits 
+                 *  which should be exported at the last page
+                 */
+                int pg = 1;
+                int dr = totalhits % ExWSConf.PAGE_SIZE;
+                if (dr > 0) {
+                    pg = totalhits / ExWSConf.PAGE_SIZE + 1;
+                }
+                else {
+                    pg = totalhits / ExWSConf.PAGE_SIZE;
+                }
+
+                /*
+                 * Create temporary file
+                 */
+                File expTmp = createTempFile("idsexppl-", format);
+                FileWriter fw = new FileWriter(expTmp, true);
+                BufferedWriter bw = new BufferedWriter(fw);
+                //better delete after it is not needed anymore
+                expTmp.deleteOnExit();
+            
+                // position of pages, 1 = first page, 2 = middle pages, 3 = last page
+                int pos = 0;
+                // String urlorg = url;
+                uri.queryParam("page", "{PAGE}");
+                for (int i = 1; i <= pg; i++) {
+                    // url = urlorg + "&page=" + i;
+                    // resource = client.target(url);
+                    resource = client.target(uri.build(i));
+                    resp = resource.request(MediaType.APPLICATION_JSON)
+                        .get(String.class);
+
+                    if (i < pg) {
+                        pos = 2;
+                    }
+                    if (i == 1) {
+                        pos = 1;
+                    }
+                    if (pg == i) {
+                        pos = 3;
+                    }
+                    getRtf(expTmp, fw, resp, bw, pos, dr);
+                }
+                builder = Response.ok(expTmp);
+            }
+
             builder.type("application/rtf");
             format = "rtf";
-        }
+        };        
 
         builder.header(
             "Content-Disposition",
@@ -332,7 +409,7 @@
         };
 
         return resp.build();
-    }
+    };
 
     
     @GET
@@ -342,9 +419,54 @@
         return Response
             .ok(exportJsStr, "application/javascript")
             .build();
-    };    
+    };
 
-    public String writeRTF (LinkedList list) {
+
+    /*
+     * returns export results of one page as rtf String 
+     */
+    public String getRtf (String resp) throws IOException {
+        LinkedList<MatchExport> listMatches = getListMatches(resp);
+        return writeRTF(listMatches);
+    };
+
+
+    /* 
+     * Writes result of export pages to temporary file
+     */
+    public void getRtf (File file, FileWriter filewriter, String resp,
+            BufferedWriter bw, int pos, int dr) throws IOException {
+        LinkedList<MatchExport> listMatches = getListMatches(resp);
+        writeRTF(listMatches, file, filewriter, bw, pos, dr);
+    };
+    
+    
+    /*
+     * returns LinkedList of Matches
+     */
+    public LinkedList<MatchExport> getListMatches (String resp)
+            throws IOException {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonFactory factory = mapper.getFactory();
+        JsonParser parser = factory.createParser(resp);
+        JsonNode actualObj = mapper.readTree(parser);
+        JsonNode jsonNode1 = actualObj.get("matches");
+        LinkedList<MatchExport> listMatches = new LinkedList();
+        ObjectMapper objectMapper = new ObjectMapper();
+        MatchExport match;
+
+        for (Iterator<JsonNode> itNode = jsonNode1.elements(); itNode
+                .hasNext();) {
+            match = objectMapper.readValue(itNode.next().toString(),
+                    MatchExport.class);
+            listMatches.addLast(match);
+        };
+        return listMatches;
+    };
+    
+  
+
+    public String getRtfSection (LinkedList list, int pos, int dr) {
         LinkedList matchlist = list;
         RtfTextPara par = p((" "));
         RtfTextPara[] pararray;
@@ -354,14 +476,18 @@
         String reference;
         String textSigle;
         int j = matchlist.size();
-
+        if (dr != 0 && pos == 3) {
+            j = dr;
+        }
+        
         //TODO Add export plugin version to JSON output?
-        /*
-         * TODO 
-         * The output rtf file lacks style, 
-         * but I'm thinking about changing the jRTF library to OpenRTF https://github.com/LibrePDF/OpenRTF, 
-         * because jRTF is very rudimentary, so I only list the information in a section right now.
-         */
+        //
+         // TODO 
+         // The output rtf file lacks style, 
+         // but I'm thinking about changing the jRTF library to OpenRTF https://github.com/LibrePDF/OpenRTF, 
+         // because jRTF is very rudimentary, so I only list the information in a section right now.
+         //
+
         RtfTextPara pv = getVersion();
         listp.add(pv);
 
@@ -378,11 +504,61 @@
             listp.add(par);
         }
 
+
         String rtfresp = rtf().section(listp).toString();
         return rtfresp;
+
     }
 
+    
+    public String writeRTF (LinkedList list) throws IOException {
+        String rtfresp =  getRtfSection(list, 0, 0);
+        return rtfresp;
+    }
+    
+    public void writeRTF (LinkedList list, File file, FileWriter filewriter,
+            BufferedWriter bw, int pos, int dr) throws IOException {
+   
+        String rtfresp = getRtfSection(list, pos,dr);
+        
+        switch (pos) {
 
+            case 1: {
+                rtfresp = rtfresp.substring(0, rtfresp.length() - 1);
+                bw.append(rtfresp);
+                bw.flush();
+                break;
+            }
+
+            case 2: {
+                rtfresp = rtfresp.substring(143, rtfresp.length() - 1);
+                bw.append(rtfresp);
+                bw.flush();
+                break;
+            }
+
+            case 3: {
+                rtfresp = rtfresp.substring(143);
+                bw.append(rtfresp);
+                bw.flush();
+                bw.close();
+                break;
+            }
+
+            default: {
+                //TODO Error Handling
+                System.out.println("Invalid pos Parameter");
+                break;
+            }
+        }
+
+        return;
+
+    }
+
+    /**
+     *  Get version for RTF document 
+     *  */
     public RtfTextPara getVersion () {
         Version version = new Version(ExWSConf.VERSION_MAJOR,
                 ExWSConf.VERSION_MINOR, ExWSConf.VERSION_PATCHLEVEL, null, null,
@@ -412,4 +588,20 @@
 
         return "";
     }
+
+    /**
+     * Creates file to hold the result temporarily
+     *
+     */
+    public static File createTempFile (String name, String suffix) {
+        try {
+            File temp = File.createTempFile(name, "." + suffix);
+            return temp;
+
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }