Localize export form

Change-Id: Id1ca535bf5c246a51efabfc62b56e4a2f738ad00
diff --git a/plugin/pom.xml b/plugin/pom.xml
index c93342b..6404e09 100644
--- a/plugin/pom.xml
+++ b/plugin/pom.xml
@@ -4,7 +4,7 @@
   <groupId>de.ids_mannheim.korap</groupId>
   <artifactId>KalamarExportPlugin</artifactId>
   <packaging>jar</packaging>
-  <version>0.2.1</version>
+  <version>0.2.2</version>
   <name>KalamarExportPlugin</name>
   <url>http://maven.apache.org</url>
   
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/ExWSConf.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/ExWSConf.java
index 333ed60..7fe4233 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/ExWSConf.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/ExWSConf.java
@@ -18,7 +18,7 @@
     // Version of Export Plugin
     public static final int VERSION_MAJOR = 0;
     public static final int VERSION_MINOR = 2;
-    public static final int VERSION_PATCHLEVEL = 1;
+    public static final int VERSION_PATCHLEVEL = 2;
 
     private static Properties prop;
 
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Service.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Service.java
index 972fb12..d8f3a0e 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Service.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/Service.java
@@ -10,12 +10,12 @@
 import java.net.URLEncoder;
 import java.net.ConnectException;
 import java.util.HashMap;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.Properties;
 import java.util.Base64;
+import java.util.ResourceBundle;
+import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -48,6 +48,7 @@
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import org.glassfish.jersey.server.ContainerRequest;
 
 import static de.ids_mannheim.korap.plkexport.Util.*;
 
@@ -67,6 +68,7 @@
  * - Improve Readme.
  * - 100 matches as default for export form.
  * - Test ExWsConf.
+ * - Change "count" to "number of results" in RTF.
  *
  * TODO:
  * - Abort processing when eventsource is closed.
@@ -89,6 +91,9 @@
  *   matches per export, while external users
  *   should be limited to 10.000.
  * - Add 1000-separator to numbers.
+ * - Get the list of availables locales based
+ *   on the given ResourceBundle.
+ * - Check for q/ql definition in JS.
  *
  * IDEAS:
  * - Create a template mechanism for RTF export.
@@ -123,7 +128,10 @@
     private final static Base64.Decoder b64Dec = Base64.getDecoder();
 
     @Context
-    private HttpServletRequest req;     
+    private HttpServletRequest servletReq;
+
+    @Context
+    private ContainerRequest req;
 
 
     /*
@@ -208,12 +216,12 @@
         // Get client IP, in case service is behind a proxy
         // Get auth (temporarily) via Session riding
         String xff = "", auth = "";
-        if (req != null) {
-            xff = getClientIP(req.getHeader("X-Forwarded-For"));
+        if (servletReq != null) {
+            xff = getClientIP(servletReq.getHeader("X-Forwarded-For"));
             if (xff == "")
-                xff = req.getRemoteAddr();
+                xff = servletReq.getRemoteAddr();
 
-            auth = authFromCookie(req);
+            auth = authFromCookie(servletReq);
         };
     
         String resp;
@@ -632,7 +640,6 @@
                 };
             };
         };
-
         return "";
     };
 
@@ -678,6 +685,16 @@
             templateData.put("msg", msg);            
         };
 
+        try {
+            templateData.put("dict", this.getDictionary());
+
+        } catch (Exception e) {
+            return Response
+                .ok(new String("Dictionary not found"))
+                .status(Status.INTERNAL_SERVER_ERROR)
+                .build();
+        };
+
         // Generate template
         try {
             Template template = cfg.getTemplate("export.ftl");
@@ -721,4 +738,33 @@
 
         return "";
     };
+
+
+    /*
+     * Load dictionary for a chosen locale as a resource bundle
+     */
+    private ResourceBundle getDictionary () throws IOException {
+
+        // Load prefered dictionary
+        Locale prefered = new Locale("en");
+
+        if (req != null) {
+
+        CHOOSE:
+            for (Locale l : req.getAcceptableLanguages()) {
+                switch (l.getLanguage()) {
+                case "de":
+                    prefered = l;
+                    break CHOOSE;
+                case "en":
+                    prefered = l;
+                    break CHOOSE;
+                };
+            };
+        };
+
+        return ResourceBundle.getBundle(
+            "locales/export", prefered
+            );
+    };
 };
diff --git a/plugin/src/main/resources/assets/templates/export.ftl b/plugin/src/main/resources/assets/templates/export.ftl
index 424a79c..0b23d0e 100644
--- a/plugin/src/main/resources/assets/templates/export.ftl
+++ b/plugin/src/main/resources/assets/templates/export.ftl
@@ -1,5 +1,4 @@
 <!DOCTYPE html>
-<!-- TODO: localization ... -->
 <html>
   <head>
     <meta charset="UTF-8">
@@ -50,11 +49,20 @@
         background-color: #f6a800;
       }
 
+      label > .desc {
+        font-size: 90%;
+        display: block;
+      }
+
+      #export input[type=radio] {
+        vertical-align: top;
+      }
+
     </style>   
   </head>
   <body>
-    <div class="banner" data-note="Experimental"></div>
-    <h1>Export: <code id="export-query"></code></h1>
+    <div class="banner" data-note="${dict.banner}"></div>
+    <h1>${dict.export}: <code id="export-query"></code></h1>
     <section>
       <form id="export" class="form-table" action="export" method="POST">
         <fieldset>
@@ -63,44 +71,48 @@
           <input type="hidden" id="cq" name="cq">
 
           <fieldset class="form-line">
-            <legend>Dateiformat</legend>
+            <legend>${dict.file_format}</legend>
 
             <div style="margin-top: 1em">
-              <input type="radio" checked="checked" id="formatrtf" name="format" value="rtf" style="vertical-align: top">
+              <input type="radio"
+                     checked="checked"
+                     id="formatrtf"
+                     name="format"
+                     value="rtf">
               <label for="formatrtf">
-                RTF
-                <br /><span style="font-size:8pt">Rich Text Format (Word etc.)</span>
+                RTF <span class="desc">Rich Text Format (Word etc.)</span>
               </label>
             </div>
 
             <div style="margin-top: 1em">
-              <input type="radio" id="formatcsv" name="format" value="csv" style="vertical-align: top">
+              <input type="radio"
+                     id="formatcsv"
+                     name="format"
+                     value="csv">
               <label for="formatcsv">
-                CSV
-                <br /><span style="font-size:8pt">Comma-separated Values (Excel etc.)</span>
+                CSV <span class="desc">Comma-separated Values (Excel etc.)</span>
               </label>
             </div>
 
             <div style="margin-top: 1em">
-              <input type="radio" id="formatjson" name="format" value="json" style="vertical-align: top">
+              <input type="radio"
+                     id="formatjson"
+                     name="format"
+                     value="json">
               <label for="formatjson">
-                JSON
-                <br /><span style="font-size:8pt">JavaScript Object Notation (JavaScript etc.)</span>
+                JSON <span class="desc">JavaScript Object Notation (JavaScript etc.)</span>
               </label>
             </div>
           </fieldset>
 
-          <!-- <input type="checkbox" name="islimit" checked="checked" value="limited"> -->
-          
           <fieldset class="form-line">
-            <legend>Zu exportierender Treffer</legend>
+            <legend>${dict.hitc}</legend>
             <input name="hitc" id="hitc" type="number" min="1" max="10000" value="20" />
           </fieldset>
 
           <progress id="progress" value="0" max="100" style="display: none;">0%</progress>
           
-          <input type="submit" value="Exportieren">
-
+          <input type="submit" value="${dict.export_button}">
         </fieldset>
       </form>
     </section>
diff --git a/plugin/src/main/resources/locales/export.properties b/plugin/src/main/resources/locales/export.properties
new file mode 100644
index 0000000..221e9ba
--- /dev/null
+++ b/plugin/src/main/resources/locales/export.properties
@@ -0,0 +1,5 @@
+export = Export
+file_format = File format
+hitc = Limit to the first matches:
+export_button = Exportieren
+banner = Experimental
\ No newline at end of file
diff --git a/plugin/src/main/resources/locales/export_de.properties b/plugin/src/main/resources/locales/export_de.properties
new file mode 100644
index 0000000..845042f
--- /dev/null
+++ b/plugin/src/main/resources/locales/export_de.properties
@@ -0,0 +1,8 @@
+# Needs to be converted using
+# $ native2ascii -encoding UTF-8 \
+#   export_utf8.properties export_de.properties
+
+file_format = Dateiformat
+hitc = Einschr\u00e4nken auf die ersten Treffer:
+export_button = Exportieren
+banner = Experimentell
\ No newline at end of file
diff --git a/plugin/src/main/resources/locales/export_en.properties b/plugin/src/main/resources/locales/export_en.properties
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugin/src/main/resources/locales/export_en.properties
diff --git a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/AssetTest.java b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/AssetTest.java
index 444e34b..a3dc27b 100644
--- a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/AssetTest.java
+++ b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/AssetTest.java
@@ -40,6 +40,35 @@
     }
 
     @Test
+    public void testFormHtmlLocalization () {
+
+        // Check german
+        Response responsehtml = target("/export").request()
+            .header("Accept-Language","fr-CH, fr;q=0.9, de;q=0.8, en;q=0.7, *;q=0.5").get();
+        assertEquals("HTTP Code",
+                     Status.OK.getStatusCode(), responsehtml.getStatus());
+        String str = responsehtml.readEntity(String.class);
+        assertTrue("HTTP Body (de)", str.contains("Dateiformat"));
+
+        // Check English
+        responsehtml = target("/export").request()
+            .header("Accept-Language","fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5").get();
+        assertEquals("HTTP Code",
+                     Status.OK.getStatusCode(), responsehtml.getStatus());
+        str = responsehtml.readEntity(String.class);
+        assertTrue("HTTP Body (en)", str.contains("File format"));
+
+        // Check German (2)
+        responsehtml = target("/export").request()
+            .header("Accept-Language","de-DE, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5").get();
+        assertEquals("HTTP Code",
+                     Status.OK.getStatusCode(), responsehtml.getStatus());
+        str = responsehtml.readEntity(String.class);
+        assertTrue("HTTP Body (de)", str.contains("Dateiformat"));
+    };
+
+    
+    @Test
     public void testFormHtmlAssets () {
         Properties properties = ExWSConf.properties(null);
         String hostTemp = properties.getProperty("asset.host");