[tor-commits] [onionoo/master] Use Gson to format JSON clients documents.

karsten at torproject.org karsten at torproject.org
Fri May 9 06:35:54 UTC 2014


commit 54ce50aebec208eae02688e7690ab0aa996a6210
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Sun Apr 20 15:20:21 2014 +0200

    Use Gson to format JSON clients documents.
---
 src/org/torproject/onionoo/ClientsDocument.java    |   12 +++
 .../torproject/onionoo/ClientsDocumentWriter.java  |   94 +++++++++-----------
 .../torproject/onionoo/ClientsGraphHistory.java    |   83 +++++++++++++++++
 src/org/torproject/onionoo/ResponseBuilder.java    |    4 +-
 4 files changed, 138 insertions(+), 55 deletions(-)

diff --git a/src/org/torproject/onionoo/ClientsDocument.java b/src/org/torproject/onionoo/ClientsDocument.java
index c8679fc..300541d 100644
--- a/src/org/torproject/onionoo/ClientsDocument.java
+++ b/src/org/torproject/onionoo/ClientsDocument.java
@@ -2,7 +2,19 @@
  * See LICENSE for licensing information */
 package org.torproject.onionoo;
 
+import java.util.Map;
+
 class ClientsDocument extends Document {
 
+  private String fingerprint;
+  public void setFingerprint(String fingerprint) {
+    this.fingerprint = fingerprint;
+  }
+
+  private Map<String, ClientsGraphHistory> average_clients;
+  public void setAverageClients(
+      Map<String, ClientsGraphHistory> averageClients) {
+    this.average_clients = averageClients;
+  }
 }
 
diff --git a/src/org/torproject/onionoo/ClientsDocumentWriter.java b/src/org/torproject/onionoo/ClientsDocumentWriter.java
index bab78e9..1fced6d 100644
--- a/src/org/torproject/onionoo/ClientsDocumentWriter.java
+++ b/src/org/torproject/onionoo/ClientsDocumentWriter.java
@@ -3,8 +3,8 @@
 package org.torproject.onionoo;
 
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.SortedSet;
@@ -74,9 +74,8 @@ public class ClientsDocumentWriter implements FingerprintListener,
         continue;
       }
       SortedSet<ClientsHistory> history = clientsStatus.getHistory();
-      ClientsDocument clientsDocument = new ClientsDocument();
-      clientsDocument.setDocumentString(this.formatHistoryString(
-          hashedFingerprint, history));
+      ClientsDocument clientsDocument = this.compileClientsDocument(
+          hashedFingerprint, history);
       this.documentStore.store(clientsDocument, hashedFingerprint);
       this.writtenDocuments++;
     }
@@ -104,28 +103,27 @@ public class ClientsDocumentWriter implements FingerprintListener,
       DateTimeHelper.TWO_DAYS,
       DateTimeHelper.TEN_DAYS };
 
-  private String formatHistoryString(String hashedFingerprint,
+  private ClientsDocument compileClientsDocument(String hashedFingerprint,
       SortedSet<ClientsHistory> history) {
-    StringBuilder sb = new StringBuilder();
-    sb.append("{\"fingerprint\":\"" + hashedFingerprint + "\"");
-    sb.append(",\n\"average_clients\":{");
-    int graphIntervalsWritten = 0;
+    ClientsDocument clientsDocument = new ClientsDocument();
+    clientsDocument.setFingerprint(hashedFingerprint);
+    Map<String, ClientsGraphHistory> averageClients =
+        new LinkedHashMap<String, ClientsGraphHistory>();
     for (int graphIntervalIndex = 0; graphIntervalIndex <
         this.graphIntervals.length; graphIntervalIndex++) {
-      String timeline = this.formatTimeline(graphIntervalIndex, history);
-      if (timeline != null) {
-        sb.append((graphIntervalsWritten++ > 0 ? "," : "") + "\n"
-            + timeline);
+      String graphName = this.graphNames[graphIntervalIndex];
+      ClientsGraphHistory graphHistory = this.compileClientsHistory(
+          graphIntervalIndex, history);
+      if (graphHistory != null) {
+        averageClients.put(graphName, graphHistory);
       }
     }
-    sb.append("}");
-    sb.append("\n}\n");
-    return sb.toString();
+    clientsDocument.setAverageClients(averageClients);
+    return clientsDocument;
   }
 
-  private String formatTimeline(int graphIntervalIndex,
-      SortedSet<ClientsHistory> history) {
-    String graphName = this.graphNames[graphIntervalIndex];
+  private ClientsGraphHistory compileClientsHistory(
+      int graphIntervalIndex, SortedSet<ClientsHistory> history) {
     long graphInterval = this.graphIntervals[graphIntervalIndex];
     long dataPointInterval =
         this.dataPointIntervals[graphIntervalIndex];
@@ -214,16 +212,16 @@ public class ClientsDocumentWriter implements FingerprintListener,
         + (lastNonNullIndex - firstNonNullIndex) * dataPointInterval;
     double factor = ((double) maxValue) / 999.0;
     int count = lastNonNullIndex - firstNonNullIndex + 1;
-    StringBuilder sb = new StringBuilder();
-    sb.append("\"" + graphName + "\":{"
-        + "\"first\":\"" + DateTimeHelper.format(firstDataPointMillis)
-        + "\",\"last\":\"" + DateTimeHelper.format(lastDataPointMillis)
-        + "\",\"interval\":" + String.valueOf(dataPointInterval
-        / DateTimeHelper.ONE_SECOND)
-        + ",\"factor\":" + String.format(Locale.US, "%.9f", factor)
-        + ",\"count\":" + String.valueOf(count) + ",\"values\":[");
-    int dataPointsWritten = 0, previousNonNullIndex = -2;
+    ClientsGraphHistory graphHistory = new ClientsGraphHistory();
+    graphHistory.setFirst(DateTimeHelper.format(firstDataPointMillis));
+    graphHistory.setLast(DateTimeHelper.format(lastDataPointMillis));
+    graphHistory.setInterval((int) (dataPointInterval
+        / DateTimeHelper.ONE_SECOND));
+    graphHistory.setFactor(factor);
+    graphHistory.setCount(count);
+    int previousNonNullIndex = -2;
     boolean foundTwoAdjacentDataPoints = false;
+    List<Integer> values = new ArrayList<Integer>();
     for (int dataPointIndex = firstNonNullIndex; dataPointIndex <=
         lastNonNullIndex; dataPointIndex++) {
       double dataPoint = dataPoints.get(dataPointIndex);
@@ -233,53 +231,45 @@ public class ClientsDocumentWriter implements FingerprintListener,
         }
         previousNonNullIndex = dataPointIndex;
       }
-      sb.append((dataPointsWritten++ > 0 ? "," : "")
-          + (dataPoint < 0.0 ? "null" :
-          String.valueOf((long) ((dataPoint * 999.0) / maxValue))));
+      values.add(dataPoint < 0.0 ? null :
+          (int) ((dataPoint * 999.0) / maxValue));
     }
-    sb.append("]");
+    graphHistory.setValues(values);
     if (!totalResponsesByCountry.isEmpty()) {
-      sb.append(",\"countries\":{");
-      int written = 0;
+      SortedMap<String, Float> countries = new TreeMap<String, Float>();
       for (Map.Entry<String, Double> e :
           totalResponsesByCountry.entrySet()) {
         if (e.getValue() > totalResponses / 100.0) {
-          sb.append((written++ > 0 ? "," : "") + "\"" + e.getKey()
-              + "\":" + String.format(Locale.US, "%.4f",
-              e.getValue() / totalResponses));
+          countries.put(e.getKey(),
+              (float) (e.getValue() / totalResponses));
         }
       }
-      sb.append("}");
+      graphHistory.setCountries(countries);
     }
     if (!totalResponsesByTransport.isEmpty()) {
-      sb.append(",\"transports\":{");
-      int written = 0;
+      SortedMap<String, Float> transports = new TreeMap<String, Float>();
       for (Map.Entry<String, Double> e :
           totalResponsesByTransport.entrySet()) {
         if (e.getValue() > totalResponses / 100.0) {
-          sb.append((written++ > 0 ? "," : "") + "\"" + e.getKey()
-              + "\":" + String.format(Locale.US, "%.4f",
-              e.getValue() / totalResponses));
+          transports.put(e.getKey(),
+              (float) (e.getValue() / totalResponses));
         }
       }
-      sb.append("}");
+      graphHistory.setTransports(transports);
     }
     if (!totalResponsesByVersion.isEmpty()) {
-      sb.append(",\"versions\":{");
-      int written = 0;
+      SortedMap<String, Float> versions = new TreeMap<String, Float>();
       for (Map.Entry<String, Double> e :
           totalResponsesByVersion.entrySet()) {
         if (e.getValue() > totalResponses / 100.0) {
-          sb.append((written++ > 0 ? "," : "") + "\"" + e.getKey()
-              + "\":" + String.format(Locale.US, "%.4f",
-              e.getValue() / totalResponses));
+          versions.put(e.getKey(),
+              (float) (e.getValue() / totalResponses));
         }
       }
-      sb.append("}");
+      graphHistory.setVersions(versions);
     }
-    sb.append("}");
     if (foundTwoAdjacentDataPoints) {
-      return sb.toString();
+      return graphHistory;
     } else {
       return null;
     }
diff --git a/src/org/torproject/onionoo/ClientsGraphHistory.java b/src/org/torproject/onionoo/ClientsGraphHistory.java
new file mode 100644
index 0000000..b7b312b
--- /dev/null
+++ b/src/org/torproject/onionoo/ClientsGraphHistory.java
@@ -0,0 +1,83 @@
+/* Copyright 2014 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.onionoo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedMap;
+
+public class ClientsGraphHistory {
+
+  private String first;
+  public void setFirst(String first) {
+    this.first = first;
+  }
+  public String getFirst() {
+    return this.first;
+  }
+
+  private String last;
+  public void setLast(String last) {
+    this.last = last;
+  }
+  public String getLast() {
+    return this.last;
+  }
+
+  private Integer interval;
+  public void setInterval(Integer interval) {
+    this.interval = interval;
+  }
+  public Integer getInterval() {
+    return this.interval;
+  }
+
+  private Double factor;
+  public void setFactor(Double factor) {
+    this.factor = factor;
+  }
+  public Double getFactor() {
+    return this.factor;
+  }
+
+  private Integer count;
+  public void setCount(Integer count) {
+    this.count = count;
+  }
+  public Integer getCount() {
+    return this.count;
+  }
+
+  private List<Integer> values = new ArrayList<Integer>();
+  public void setValues(List<Integer> values) {
+    this.values = values;
+  }
+  public List<Integer> getValues() {
+    return this.values;
+  }
+
+  private SortedMap<String, Float> countries;
+  public void setCountries(SortedMap<String, Float> countries) {
+    this.countries = countries;
+  }
+  public SortedMap<String, Float> getCountries() {
+    return this.countries;
+  }
+
+  private SortedMap<String, Float> transports;
+  public void setTransports(SortedMap<String, Float> transports) {
+    this.transports = transports;
+  }
+  public SortedMap<String, Float> getTransports() {
+    return this.transports;
+  }
+
+  private SortedMap<String, Float> versions;
+  public void setVersions(SortedMap<String, Float> versions) {
+    this.versions = versions;
+  }
+  public SortedMap<String, Float> getVersions() {
+    return this.versions;
+  }
+}
+
diff --git a/src/org/torproject/onionoo/ResponseBuilder.java b/src/org/torproject/onionoo/ResponseBuilder.java
index dbd8cc7..f59a81c 100644
--- a/src/org/torproject/onionoo/ResponseBuilder.java
+++ b/src/org/torproject/onionoo/ResponseBuilder.java
@@ -222,9 +222,7 @@ public class ResponseBuilder {
         ClientsDocument.class, false, fingerprint);
     if (clientsDocument != null &&
         clientsDocument.getDocumentString() != null) {
-      String clientsLines = clientsDocument.getDocumentString();
-      clientsLines = clientsLines.substring(0, clientsLines.length() - 1);
-      return clientsLines;
+      return clientsDocument.getDocumentString();
     } else {
       return "{\"fingerprint\":\"" + fingerprint.toUpperCase() + "\"}";
     }





More information about the tor-commits mailing list