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

commit 8409797f95ce21c4d6ec93132aed101115451c1a Author: Karsten Loesing <karsten.loesing@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. */
participants (1)
-
karsten@torproject.org