[tor-commits] [metrics-web/master] Move all R-specific parts to RObjectGenerator.

karsten at torproject.org karsten at torproject.org
Tue Mar 20 19:18:52 UTC 2012


commit 8409797f95ce21c4d6ec93132aed101115451c1a
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Tue Mar 20 14:00:47 2012 +0100

    Move all R-specific parts to RObjectGenerator.
---
 src/org/torproject/ernie/web/CsvServlet.java       |   11 +--
 src/org/torproject/ernie/web/GraphDataServlet.java |   11 +--
 .../torproject/ernie/web/GraphImageServlet.java    |   43 +--------
 .../ernie/web/GraphsSubpagesServlet.java           |   49 +---------
 src/org/torproject/ernie/web/RObjectGenerator.java |   99 +++++++++++++++++++-
 5 files changed, 110 insertions(+), 103 deletions(-)

diff --git a/src/org/torproject/ernie/web/CsvServlet.java b/src/org/torproject/ernie/web/CsvServlet.java
index 39efc14..4f60eaf 100644
--- a/src/org/torproject/ernie/web/CsvServlet.java
+++ b/src/org/torproject/ernie/web/CsvServlet.java
@@ -94,15 +94,10 @@ public class CsvServlet extends HttpServlet {
     }
     logger.fine("CSV file '" + requestedCsvFile + ".csv' requested.");
 
-    /* Prepare filename and R query string. */
-    String rQuery = "export_" + requestedCsvFile.replaceAll("-", "_")
-        + "(path = '%s')";
-    String csvFilename = requestedCsvFile + ".csv";
-
     /* Request CSV file from R object generator, which asks Rserve to
      * generate it. */
-    String csvFileContent = this.rObjectGenerator.generateCsv(rQuery,
-        csvFilename);
+    String csvFileContent = this.rObjectGenerator.generateCsv(
+        requestedCsvFile);
 
     /* Make sure that we have a graph to return. */
     if (csvFileContent == null) {
@@ -115,7 +110,7 @@ public class CsvServlet extends HttpServlet {
     response.setHeader("Content-Length", String.valueOf(
         csvFileContent.length()));
     response.setHeader("Content-Disposition",
-        "inline; filename=\"" + csvFilename + "\"");
+        "inline; filename=\"" + requestedCsvFile + ".csv\"");
     response.getWriter().print(csvFileContent);
   }
 }
diff --git a/src/org/torproject/ernie/web/GraphDataServlet.java b/src/org/torproject/ernie/web/GraphDataServlet.java
index 6bba9f0..35df73b 100644
--- a/src/org/torproject/ernie/web/GraphDataServlet.java
+++ b/src/org/torproject/ernie/web/GraphDataServlet.java
@@ -109,15 +109,10 @@ public class GraphDataServlet extends HttpServlet {
         requestedJsonFile);
     logger.fine("CSV file '" + requestedCsvFile + ".csv' requested.");
 
-    /* Prepare filename and R query string. */
-    String rQuery = "export_" + requestedCsvFile.replaceAll("-", "_")
-        + "(path = '%s')";
-    String csvFilename = requestedCsvFile + ".csv";
-
-    /* Request CSV file from R object generator, which asks Rserve to
+    /* Request CSV file from R object generator, which may ask Rserve to
      * generate it. */
-    String csvFileContent = this.rObjectGenerator.generateCsv(rQuery,
-        csvFilename);
+    String csvFileContent = this.rObjectGenerator.generateCsv(
+        requestedCsvFile);
 
     /* Make sure that we have a CSV to convert into JSON. */
     if (csvFileContent == null) {
diff --git a/src/org/torproject/ernie/web/GraphImageServlet.java b/src/org/torproject/ernie/web/GraphImageServlet.java
index 4ef53dd..5d46cdd 100644
--- a/src/org/torproject/ernie/web/GraphImageServlet.java
+++ b/src/org/torproject/ernie/web/GraphImageServlet.java
@@ -46,47 +46,10 @@ public class GraphImageServlet extends HttpServlet {
           lastIndexOf("/") + 1);
     }
 
-    /* Check parameters. */
-    Map<String, String[]> checkedParameters = GraphParameterChecker.
-        getInstance().checkParameters(requestedGraph,
-        request.getParameterMap());
-    if (checkedParameters == null) {
-      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
-      return;
-    }
-
-    /* Prepare filename and R query string. */
-    StringBuilder rQueryBuilder = new StringBuilder("plot_"
-        + requestedGraph.replaceAll("-", "_") + "("),
-        imageFilenameBuilder = new StringBuilder(requestedGraph);
-    for (Map.Entry<String, String[]> parameter :
-        checkedParameters.entrySet()) {
-      String parameterName = parameter.getKey();
-      String[] parameterValues = parameter.getValue();
-      for (String param : parameterValues) {
-        imageFilenameBuilder.append("-" + param);
-      }
-      if (parameterValues.length < 2) {
-        rQueryBuilder.append(parameterName + " = '" + parameterValues[0]
-            + "', ");
-      } else {
-        rQueryBuilder.append(parameterName + " = c(");
-        for (int i = 0; i < parameterValues.length - 1; i++) {
-          rQueryBuilder.append("'" + parameterValues[i] + "', ");
-        }
-        rQueryBuilder.append("'" + parameterValues[
-            parameterValues.length - 1] + "'), ");
-      }
-    }
-    imageFilenameBuilder.append(".png");
-    String imageFilename = imageFilenameBuilder.toString();
-    rQueryBuilder.append("path = '%s')");
-    String rQuery = rQueryBuilder.toString();
-
     /* Request graph from R object generator, which either returns it from
      * its cache or asks Rserve to generate it. */
-    byte[] graphBytes = rObjectGenerator.generateGraph(rQuery,
-        imageFilename);
+    byte[] graphBytes = rObjectGenerator.generateGraph(requestedGraph,
+        request.getParameterMap());
 
     /* Make sure that we have a graph to return. */
     if (graphBytes == null) {
@@ -100,7 +63,7 @@ public class GraphImageServlet extends HttpServlet {
     response.setHeader("Content-Length",
         String.valueOf(graphBytes.length));
     response.setHeader("Content-Disposition",
-        "inline; filename=\"" + imageFilename + "\"");
+        "inline; filename=\"" + requestedGraph + ".png\"");
     output = new BufferedOutputStream(response.getOutputStream(), 1024);
     output.write(graphBytes, 0, graphBytes.length);
     output.flush();
diff --git a/src/org/torproject/ernie/web/GraphsSubpagesServlet.java b/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
index 3e090eb..5c2743d 100644
--- a/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
+++ b/src/org/torproject/ernie/web/GraphsSubpagesServlet.java
@@ -126,54 +126,15 @@ public class GraphsSubpagesServlet extends HttpServlet {
       }
     }
 
-    /* Trigger generation of table data if the graphs subpage has any
-     * tables, regardless of whether a table update was requested. */
+    /* Generate table data if the graphs subpage has any tables,
+     * regardless of whether a table update was requested, and add the
+     * table data as request attribute. */
     if (this.availableGraphsSubpageTables.containsKey(requestedPage)) {
       for (String tableName :
           this.availableGraphsSubpageTables.get(requestedPage)) {
-
-        Map<String, String[]> checkedParameters = null;
-        if (tableName.equals(requestedTable)) {
-          checkedParameters = TableParameterChecker.
-              getInstance().checkParameters(requestedTable,
-              request.getParameterMap());
-        } else {
-          checkedParameters = TableParameterChecker.
-              getInstance().checkParameters(tableName, null);
-        }
-
-        /* Prepare filename and R query string. */
-        StringBuilder rQueryBuilder = new StringBuilder("write_"
-            + tableName.replaceAll("-", "_") + "("),
-            tableFilenameBuilder = new StringBuilder(tableName);
-
-        for (Map.Entry<String, String[]> parameter :
-            checkedParameters.entrySet()) {
-          String parameterName = parameter.getKey();
-          String[] parameterValues = parameter.getValue();
-          for (String param : parameterValues) {
-            tableFilenameBuilder.append("-" + param);
-          }
-          if (parameterValues.length < 2) {
-            rQueryBuilder.append(parameterName + " = '"
-                + parameterValues[0] + "', ");
-          } else {
-            rQueryBuilder.append(parameterName + " = c(");
-            for (int i = 0; i < parameterValues.length - 1; i++) {
-              rQueryBuilder.append("'" + parameterValues[i] + "', ");
-            }
-            rQueryBuilder.append("'" + parameterValues[
-                parameterValues.length - 1] + "'), ");
-          }
-        }
-        tableFilenameBuilder.append(".tbl");
-        String tableFilename = tableFilenameBuilder.toString();
-        rQueryBuilder.append("path = '%s')");
-        String rQuery = rQueryBuilder.toString();
-
-        /* Generate table data and add it as request attribute. */
         List<Map<String, String>> tableData = rObjectGenerator.
-            generateTable(rQuery, tableFilename);
+            generateTable(tableName, requestedTable,
+            request.getParameterMap());
         request.setAttribute(tableName.replaceAll("-", "_")
               + "_tabledata", tableData);
       }
diff --git a/src/org/torproject/ernie/web/RObjectGenerator.java b/src/org/torproject/ernie/web/RObjectGenerator.java
index 97635a2..2fb4477 100644
--- a/src/org/torproject/ernie/web/RObjectGenerator.java
+++ b/src/org/torproject/ernie/web/RObjectGenerator.java
@@ -18,6 +18,7 @@ import java.util.Map;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpServletResponse;
 
 import org.rosuda.REngine.Rserve.RConnection;
 import org.rosuda.REngine.Rserve.RserveException;
@@ -52,9 +53,46 @@ public class RObjectGenerator implements ServletContextListener {
     /* Nothing to do. */
   }
 
+  public byte[] generateGraph(String requestedGraph, Map parameterMap) {
+    Map<String, String[]> checkedParameters = GraphParameterChecker.
+        getInstance().checkParameters(requestedGraph, parameterMap);
+    if (checkedParameters == null) {
+      /* TODO We're going to take the blame by sending an internal server
+       * error to the client, but really the user is to blame. */
+      return null;
+    }
+    StringBuilder rQueryBuilder = new StringBuilder("plot_"
+        + requestedGraph.replaceAll("-", "_") + "("),
+        imageFilenameBuilder = new StringBuilder(requestedGraph);
+    for (Map.Entry<String, String[]> parameter :
+        checkedParameters.entrySet()) {
+      String parameterName = parameter.getKey();
+      String[] parameterValues = parameter.getValue();
+      for (String param : parameterValues) {
+        imageFilenameBuilder.append("-" + param);
+      }
+      if (parameterValues.length < 2) {
+        rQueryBuilder.append(parameterName + " = '" + parameterValues[0]
+            + "', ");
+      } else {
+        rQueryBuilder.append(parameterName + " = c(");
+        for (int i = 0; i < parameterValues.length - 1; i++) {
+          rQueryBuilder.append("'" + parameterValues[i] + "', ");
+        }
+        rQueryBuilder.append("'" + parameterValues[
+            parameterValues.length - 1] + "'), ");
+      }
+    }
+    imageFilenameBuilder.append(".png");
+    String imageFilename = imageFilenameBuilder.toString();
+    rQueryBuilder.append("path = '%s')");
+    String rQuery = rQueryBuilder.toString();
+    return this.generateGraph(rQuery, imageFilename);
+  }
+
   /* Generate a graph using the given R query that has a placeholder for
    * the absolute path to the image to be created. */
-  public byte[] generateGraph(String rQuery, String imageFilename) {
+  private byte[] generateGraph(String rQuery, String imageFilename) {
 
     /* See if we need to generate this graph. */
     File imageFile = new File(this.cachedGraphsDirectory + "/"
@@ -103,9 +141,17 @@ public class RObjectGenerator implements ServletContextListener {
     return result;
   }
 
+  public String generateCsv(String requestedCsvFile) {
+    /* Prepare filename and R query string. */
+    String rQuery = "export_" + requestedCsvFile.replaceAll("-", "_")
+        + "(path = '%s')";
+    String csvFilename = requestedCsvFile + ".csv";
+    return this.generateCsv(rQuery, csvFilename);
+  }
+
   /* Generate a comma-separated value file using the given R query that
    * has a placeholder for the absolute path to the file to be created. */
-  public String generateCsv(String rQuery, String csvFilename) {
+  private String generateCsv(String rQuery, String csvFilename) {
 
     /* See if we need to generate this .csv file. */
     File csvFile = new File(this.cachedGraphsDirectory + "/"
@@ -152,10 +198,57 @@ public class RObjectGenerator implements ServletContextListener {
     return result;
   }
 
+  public List<Map<String, String>> generateTable(String tableName,
+      String requestedTable, Map parameterMap) {
+
+    Map<String, String[]> checkedParameters = null;
+    if (tableName.equals(requestedTable)) {
+      checkedParameters = TableParameterChecker.
+          getInstance().checkParameters(requestedTable,
+          parameterMap);
+    } else {
+      checkedParameters = TableParameterChecker.
+          getInstance().checkParameters(tableName, null);
+    }
+    if (checkedParameters == null) {
+      /* TODO We're going to take the blame by sending an internal server
+       * error to the client, but really the user is to blame. */
+      return null;
+    }
+    StringBuilder rQueryBuilder = new StringBuilder("write_"
+        + tableName.replaceAll("-", "_") + "("),
+        tableFilenameBuilder = new StringBuilder(tableName);
+
+    for (Map.Entry<String, String[]> parameter :
+        checkedParameters.entrySet()) {
+      String parameterName = parameter.getKey();
+      String[] parameterValues = parameter.getValue();
+      for (String param : parameterValues) {
+        tableFilenameBuilder.append("-" + param);
+      }
+      if (parameterValues.length < 2) {
+        rQueryBuilder.append(parameterName + " = '"
+            + parameterValues[0] + "', ");
+      } else {
+        rQueryBuilder.append(parameterName + " = c(");
+        for (int i = 0; i < parameterValues.length - 1; i++) {
+          rQueryBuilder.append("'" + parameterValues[i] + "', ");
+        }
+        rQueryBuilder.append("'" + parameterValues[
+            parameterValues.length - 1] + "'), ");
+      }
+    }
+    tableFilenameBuilder.append(".tbl");
+    String tableFilename = tableFilenameBuilder.toString();
+    rQueryBuilder.append("path = '%s')");
+    String rQuery = rQueryBuilder.toString();
+    return this.generateTable(rQuery, tableFilename);
+  }
+
   /* Generate table data using the given R query and filename or read
    * previously generated table data from disk if it's not too old and
    * return table data. */
-  public List<Map<String, String>> generateTable(String rQuery,
+  private List<Map<String, String>> generateTable(String rQuery,
       String tableFilename) {
 
     /* See if we need to generate this table. */





More information about the tor-commits mailing list