Correctly handle cutted matches

Change-Id: Ic74e6b4222b59633e92f8b37b69f1c4973756162
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 e8b2828..fcb74e2 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
@@ -52,8 +52,6 @@
  *   all pages.
  * - Handle timeout results (with minimum total results).
  * - Use offset instead of page parameter
- * - Test Snippet-Export with multiple classes.
- * - Test Snippet-Export with cutted matches.
  * - Add progress mechanism.
  * - Add CSV export format.
  * - Add table layout to RTF information.
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/RtfExporter.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/RtfExporter.java
index e5122b3..eca346a 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/RtfExporter.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/RtfExporter.java
@@ -77,7 +77,6 @@
 
         addVersion(w);
 
-
         // Add Information table
         if (this.getQueryString() != null) {
             w.append("{\\pard Query: \\f1 ");
@@ -133,6 +132,9 @@
             rtfText(w, s.getLeft());
             w.append("{\\b ");
             rtfText(w, s.getMark());
+            if (s.isCutted()) {
+                w.append(" [!]");
+            };
             w.append("}");
             rtfText(w, s.getRight());
             if (s.hasMoreRight()) {
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Snippet.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Snippet.java
index 06b8ca0..3af898d 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Snippet.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Snippet.java
@@ -6,7 +6,7 @@
 public class Snippet {
 
     private String left, right, mark;
-    private boolean leftMore, rightMore;
+    private boolean leftMore, rightMore, cuttedMark;
 
     private static Pattern snippetP =
         Pattern.compile("^(?i)<span[^>]+class=\"(?:[^\"]* )?context-left(?:[^\"]* )?\">(.*?)</span>" +
@@ -16,6 +16,9 @@
     private static Pattern moreP =
         Pattern.compile("(?i)<span[^>]+class=\"more\"></span>");
 
+    private static Pattern cuttedP =
+        Pattern.compile("(?i)<span[^>]+class=\"cutted\"></span>");
+    
     public Snippet (String snippetstr) {
 
         // Match with precise algorithm
@@ -35,6 +38,12 @@
                 this.setLeft(unescapeHTML(left));
             };
 
+            m = cuttedP.matcher(mark);
+            if (m.find()) {
+                mark = m.replaceAll("");
+                this.cuttedMark = true;
+            };
+            
             this.setMark(unescapeHTML(mark.replaceAll("</?mark[^>]*>", "")));
 
             if (right != null) {
@@ -105,6 +114,9 @@
         return rightMore;
     };
 
+    public boolean isCutted () {
+        return cuttedMark;
+    };
     
     private static String unescapeHTML (String text) {
         if (text == null)
diff --git a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/RtfExportTest.java b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/RtfExportTest.java
index e979cc1..799ff6c 100644
--- a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/RtfExportTest.java
+++ b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/RtfExportTest.java
@@ -63,6 +63,25 @@
     };
 
     @Test
+    public void testSnippets () throws IOException {
+        RtfExporter rtf = new RtfExporter();
+        rtf.init("{\"matches\":["+
+                 "{\"author\":\"Goethe\","+
+                 "\"title\":\"Title1\","+
+                 "\"pubDate\":\"20051103\","+
+                 "\"textSigle\":\"RTF/G59/34284\","+
+                 "\"snippet\":\"<span class=\\\"context-left\\\"></span><span class=\\\"match\\\"><mark>Und dafür musstest Du extra ne neue Socke erstellen? Wieso traust Du Dich nicht, mit Deinem Account aufzutreten? - -- ωωσσI -  talk with me 09:17, 17. Dez. 2011 (CET) Der ist doch gesperrt. -- 09:21, 17. Dez. 2011 (CET) WWSS1, weil ich normalerweise mit IP schreibe und in dem Fall nicht möchte, dass</mark><span class=\\\"cutted\\\"></span></span><span class=\\\"context-right\\\"> meine IP öffentlich angezeigt wird. Über die IP kann man auf den Wohnort, den Provider und bei Aufenthalt am Arbeitsplatz auf den Arbeitgeber schließen, über Konto nicht. -- 09:24, 17. Dez. 2011 (CET) Bist Du denn nicht mehr selber Arbeitgeber? -- 09:31<span class=\\\"more\\\"></span></span>\"}"+
+                 "]}");
+
+        Response resp = rtf.serve().build();
+        String x = (String) resp.getEntity();
+        resp.close();
+        assertTrue(x.contains("\\qj {\\b Und daf\\u252\\'fcr"));
+        assertTrue(x.contains("dass [!]} meine"));
+        assertTrue(x.contains("[...]\\par}"));
+    };
+    
+    @Test
     public void testAttributes () throws IOException {
         RtfExporter rtf = new RtfExporter();
         rtf.setFileName("Beispiel");
diff --git a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/SnippetTest.java b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/SnippetTest.java
index 746d3dc..a7f9268 100644
--- a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/SnippetTest.java
+++ b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/SnippetTest.java
@@ -49,4 +49,16 @@
         assertTrue(s.hasMoreLeft());
         assertTrue(s.hasMoreRight());
     };
+
+    @Test
+    public void testCuttedAndEmptyContext () {
+        Snippet s = new Snippet("<span class=\"context-left\"></span><span class=\"match\"><mark>Und dafür musstest Du extra ne neue Socke erstellen? Wieso traust Du Dich nicht, mit Deinem Account aufzutreten? - -- ωωσσI -  talk with me 09:17, 17. Dez. 2011 (CET) Der ist doch gesperrt. -- 09:21, 17. Dez. 2011 (CET) WWSS1, weil ich normalerweise mit IP schreibe und in dem Fall nicht möchte, dass</mark><span class=\"cutted\"></span></span><span class=\"context-right\"> meine IP öffentlich angezeigt wird. Über die IP kann man auf den Wohnort, den Provider und bei Aufenthalt am Arbeitsplatz auf den Arbeitgeber schließen, über Konto nicht. -- 09:24, 17. Dez. 2011 (CET) Bist Du denn nicht mehr selber Arbeitgeber? -- 09:31<span class=\"more\"></span></span>");
+        assertEquals(s.getLeft(), "");
+        assertEquals(s.getRight()," meine IP öffentlich angezeigt wird. Über die IP kann man auf den Wohnort, den Provider und bei Aufenthalt am Arbeitsplatz auf den Arbeitgeber schließen, über Konto nicht. -- 09:24, 17. Dez. 2011 (CET) Bist Du denn nicht mehr selber Arbeitgeber? -- 09:31");
+        assertEquals(s.getMark(),"Und dafür musstest Du extra ne neue Socke erstellen? Wieso traust Du Dich nicht, mit Deinem Account aufzutreten? - -- ωωσσI -  talk with me 09:17, 17. Dez. 2011 (CET) Der ist doch gesperrt. -- 09:21, 17. Dez. 2011 (CET) WWSS1, weil ich normalerweise mit IP schreibe und in dem Fall nicht möchte, dass");
+        assertTrue(s.isCutted());
+        assertFalse(s.hasMoreLeft());
+        assertTrue(s.hasMoreRight());
+        
+    };
 };