Example #1
0
  /**
   * Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long,
   * or String, or the JSONObject.NULL object.
   *
   * @throws JSONException If syntax error.
   * @return An object.
   */
  public Object nextValue() throws JSONException {
    char c = nextClean();
    String s;

    switch (c) {
      case '"':
      case '\'':
        return nextString(c);
      case '{':
        back();
        return new JSONObject(this);
      case '[':
      case '(':
        back();
        return new JSONArray(this);
    }

    /*
     * Handle unquoted text. This could be the values true, false, or null,
     * or it can be a number. An implementation (such as this one) is
     * allowed to also accept non-standard forms.
     *
     * Accumulate characters until we reach the end of the text or a
     * formatting character.
     */

    StringBuffer sb = new StringBuffer();
    while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
      sb.append(c);
      c = next();
    }
    back();

    s = sb.toString().trim();
    if (s.equals("")) {
      throw syntaxError("Missing value");
    }
    return JSONObject.stringToValue(s);
  }
Example #2
0
 /**
  * This method has been deprecated in favor of the {@link JSONObject.stringToValue(String)}
  * method. Use it instead.
  *
  * @deprecated Use {@link JSONObject#stringToValue(String)} instead.
  * @param string
  * @return JSON value of this string or the string
  */
 public static Object stringToValue(String string) {
   return JSONObject.stringToValue(string);
 }
Example #3
0
  /**
   * Scan the content following the named tag, attaching it to the context.
   *
   * @param x The XMLTokener containing the source string.
   * @param context The JSONObject that will include the new material.
   * @param name The tag name.
   * @return true if the close tag is processed.
   * @throws JSONException
   */
  private static boolean parse(XMLTokener x, JSONObject context, String name) throws JSONException {
    char c;
    int i;
    JSONObject jsonobject = null;
    String string;
    String tagName;
    Object token;

    // Test for and skip past these forms:
    // <!-- ... -->
    // <! ... >
    // <![ ... ]]>
    // <? ... ?>
    // Report errors for these forms:
    // <>
    // <=
    // <<

    token = x.nextToken();

    // <!

    if (token == BANG) {
      c = x.next();
      if (c == '-') {
        if (x.next() == '-') {
          x.skipPast("-->");
          return false;
        }
        x.back();
      } else if (c == '[') {
        token = x.nextToken();
        if ("CDATA".equals(token)) {
          if (x.next() == '[') {
            string = x.nextCDATA();
            if (string.length() > 0) {
              context.accumulate("content", string);
            }
            return false;
          }
        }
        throw x.syntaxError("Expected 'CDATA['");
      }
      i = 1;
      do {
        token = x.nextMeta();
        if (token == null) {
          throw x.syntaxError("Missing '>' after '<!'.");
        } else if (token == LT) {
          i += 1;
        } else if (token == GT) {
          i -= 1;
        }
      } while (i > 0);
      return false;
    } else if (token == QUEST) {

      // <?
      x.skipPast("?>");
      return false;
    } else if (token == SLASH) {

      // Close tag </

      token = x.nextToken();
      if (name == null) {
        throw x.syntaxError("Mismatched close tag " + token);
      }
      if (!token.equals(name)) {
        throw x.syntaxError("Mismatched " + name + " and " + token);
      }
      if (x.nextToken() != GT) {
        throw x.syntaxError("Misshaped close tag");
      }
      return true;

    } else if (token instanceof Character) {
      throw x.syntaxError("Misshaped tag");

      // Open tag <

    } else {
      tagName = (String) token;
      token = null;
      jsonobject = new JSONObject();
      for (; ; ) {
        if (token == null) {
          token = x.nextToken();
        }

        // attribute = value
        if (token instanceof String) {
          string = (String) token;
          token = x.nextToken();
          if (token == EQ) {
            token = x.nextToken();
            if (!(token instanceof String)) {
              throw x.syntaxError("Missing value");
            }
            jsonobject.accumulate(string, JSONObject.stringToValue((String) token));
            token = null;
          } else {
            jsonobject.accumulate(string, "");
          }

        } else if (token == SLASH) {
          // Empty tag <.../>
          if (x.nextToken() != GT) {
            throw x.syntaxError("Misshaped tag");
          }
          if (jsonobject.length() > 0) {
            context.accumulate(tagName, jsonobject);
          } else {
            context.accumulate(tagName, "");
          }
          return false;

        } else if (token == GT) {
          // Content, between <...> and </...>
          for (; ; ) {
            token = x.nextContent();
            if (token == null) {
              if (tagName != null) {
                throw x.syntaxError("Unclosed tag " + tagName);
              }
              return false;
            } else if (token instanceof String) {
              string = (String) token;
              if (string.length() > 0) {
                jsonobject.accumulate("content", JSONObject.stringToValue(string));
              }

            } else if (token == LT) {
              // Nested element
              if (parse(x, jsonobject, tagName)) {
                if (jsonobject.length() == 0) {
                  context.accumulate(tagName, "");
                } else if (jsonobject.length() == 1 && jsonobject.opt("content") != null) {
                  context.accumulate(tagName, jsonobject.opt("content"));
                } else {
                  context.accumulate(tagName, jsonobject);
                }
                return false;
              }
            }
          }
        } else {
          throw x.syntaxError("Misshaped tag");
        }
      }
    }
  }
  /**
   * Gets the JSON-Representation of all open-data-fields for one specific open-test-uuid
   *
   * @param openTestUUID
   * @return the json-string
   *     <p>columns in csv ("open data") 1:open_uuid, 2:open_test_uuid, 3:time, 4:cat_technology,
   *     5:network_type, 6:lat, 7:long, 8:loc_src, 9:zip_code, 10:download_kbit, 11:upload_kbit,
   *     12:ping_ms, 13:signal_strength, 14:server_name, 15:test_duration, 16:num_threads,
   *     17:platform, 18:model, 19:client_version, 20:network_mcc_mnc, 21:network_name,
   *     22:sim_mcc_mnc, 23:connection, 24:asn, 25:ip_anonym, 26:ndt_download_kbit,
   *     27:ndt_upload_kbit, 28:implausible, 29:lte_rsrp
   *     <p>Columns in test table uid (internal) uuid (private) client_id client_version client_name
   *     client_language (private) token (private, obsolete) server_id port use_ssl * time
   *     speed_upload speed_download ping_shortest encryption * client_public_ip (private) plattform
   *     os_version (internal) api_level (internal) device model product phone_type (internal)
   *     data_state (internal) network_country (internal) network_operator network_operator_name
   *     network_sim_country (internal) network_sim_operator network_sim_operator_name wifi_ssid
   *     (private) wifi_bssid (private) wifi_network_id (private) duration num_threads status
   *     timezone (private) bytes_download bytes_upload nsec_download nsec_upload server_ip
   *     client_software_version geo_lat geo_long network_type location signal_strength
   *     software_revision client_test_counter nat_type client_previous_test_status public_ip_asn
   *     speed_upload_log speed_download_log total_bytes_download total_bytes_upload wifi_link_speed
   *     public_ip_rdns public_ip_as_name test_slot provider_id network_is_roaming (internal)
   *     ping_shortest_log run_ndt (internal) num_threads_requested client_public_ip_anonymized
   *     zip_code geo_provider geo_accuracy deleted (internal) comment (internal) open_uuid
   *     client_time (internal) zip_code_geo (internal) mobile_provider_id roaming_type
   *     open_test_uuid country_asn country_location test_if_bytes_download test_if_bytes_upload
   *     implausible testdl_if_bytes_download testdl_if_bytes_upload testul_if_bytes_download
   *     testul_if_bytes_upload country_geoip location_max_distance location_max_distance_gps
   *     network_group_name network_group_type time_dl_ns time_ul_ns num_threads_ul lte_rsrp
   *     lte_rsrq mobile_network_id mobile_sim_id dist_prev speed_prev tag ping_median
   *     ping_median_log client_ip_local_type (private)
   *     <p>private: visible to user only (not public) internal: not visible (neither user nor
   *     public)
   */
  private String getSingleOpenTest(String openTestUUID) {
    final String sql =
        "SELECT t.uid as test_uid, "
            + " ('O' || t.open_test_uuid) open_test_uuid,"
            + // csv  open_test_uuid, UUID prefixed with 'O'
            " to_char(t.time AT TIME ZONE 'UTC', 'YYYY-MM-DD HH24:MI:SS') \"time\","
            + " t.time full_time,"
            + // csv: 3:time server time-stamp of start of measurement
            " t.client_time client_time,"
            + // (internal) client time-stamp of start of measure
            " t.network_group_name cat_technology,"
            + // csv 4:cat_technology
            " t.network_group_type network_type,"
            + // csv 5:network_type
            " t.geo_lat lat,"
            + // csv 6:lat
            " t.geo_long long,"
            + // csv 7:long
            " t.geo_provider loc_src,"
            + // csv 8:loc_src android: 'gps'/'network'; browser/iOS: '' (empty string)
            " t.geo_accuracy loc_accuracy, "
            + // accuracy of geo location in m

            /*
            //csv 6:lat
            " (CASE WHEN (t.geo_accuracy < ?) AND (t.geo_provider != 'manual') AND (t.geo_provider != 'geocoder') THEN" +
            " t.geo_lat" +
            " WHEN (t.geo_accuracy < ?) THEN" +
            " ROUND(t.geo_lat*1111)/1111" + // approx 100m
            " ELSE null" +
            " END) lat," +
            // csv 7:long
            " (CASE WHEN (t.geo_accuracy < ?) AND (t.geo_provider != 'manual') AND (t.geo_provider != 'geocoder') THEN" +
            " t.geo_long" +
            " WHEN (t.geo_accuracy < ?) THEN" +
            " ROUND(t.geo_long*741)/741 " + //approx 100m
            " ELSE null" +
            " END) long," +
            // csv 8:loc_src android: 'gps'/'network'; browser/iOS: '' (empty string)
            " (CASE WHEN ((t.geo_provider = 'manual') OR (t.geo_provider = 'geocoder')) THEN" +
            " 'rastered'" + //make raster transparent
            " ELSE t.geo_provider" +
            " END) loc_src," +
            // accuracy of geo location in m
            " (CASE WHEN (t.geo_accuracy < ?) AND (t.geo_provider != 'manual') AND (t.geo_provider != 'geocoder') " +
            " THEN t.geo_accuracy " +
            " WHEN (t.geo_accuracy < 100) AND ((t.geo_provider = 'manual') OR (t.geo_provider = 'geocoder')) THEN 100" + // limit accuracy to 100m
            " WHEN (t.geo_accuracy < ?) THEN t.geo_accuracy" +
            " ELSE null END) loc_accuracy, " +
            */

            // csv 9:zip-code - defined as integer in data base, only meaningful for measurements in
            // Austria
            " (CASE WHEN (t.zip_code < 1000 OR t.zip_code > 9999) THEN null ELSE t.zip_code END) zip_code,"
            +
            // " zip_code_geo," + //(internal) zip-code, integer derived from geo_location, Austria
            // only
            " t.speed_download download_kbit,"
            + // csv 10:download_kbit
            " t.speed_upload upload_kbit,"
            + // csv 11: upload_kbit
            " t.wifi_link_speed,"
            + // nominal speed of wifi-link in mbit/s , Android-only
            " (t.ping_median::float / 1000000) ping_ms,"
            + // median ping-time in ms (stored in ns in data base)
            " signal_strength,"
            + // csv 13:signal_strength RSSI, mainly GSM/UMTS and Wifi, Android only, in dBm
            " lte_rsrp,"
            + // csv 29: signal_strength RSRP, Android only, in dBm
            " lte_rsrq,"
            + // signal quality RSRQ, Android only, in dB
            " ts.name server_name,"
            + // csv 14:server_name, name of the test server used for download/upload (not
              // applicable for JStest)
            " implausible, "
            + // csv 28:implausible, measurement not shown in map nor used in statistics, normally
              // not visible
            " public_ip_as_name, "
            + // name of AS (not number)
            " duration test_duration,"
            + // csv 15:test_duration, nominal duration of downlink and uplink throughput tests in
              // seconds
            " num_threads_requested,"
            + // number of threads requested by control-server
            " num_threads,"
            + // csv 16:num_threads, number of threads used in downlink throughput test (uplink may
              // differ)
            " num_threads_ul,"
            + // number of threads used in uplink test
            " (CASE WHEN publish_public_data THEN COALESCE(t.plattform, t.client_name) ELSE '' END) platform,"
            + // csv 17:platform; currently used: 'CLI'/'Android'/Applet/iOS/[from client_name:
              // RMBTws, RMBTjs](null); (null) is used for RMBTjs  //AKOS: IC
            " (CASE WHEN publish_public_data THEN COALESCE(adm.fullname, t.model) ELSE '' END)  model,"
            + // csv 18:model, translated t.model (model_native) to human readable form  //AKOS: IC
            " (CASE WHEN publish_public_data THEN t.model ELSE '' END) model_native,"
            + // device used for test; Android API 'model'; iOS:'product'; Browser: Browser-name (zB
              // Firefox)  //AKOS: IC
            " t.product product,"
            + // product used for test; Android APO 'product'; iOS: '' (not used); Browser: same as
              // for model (browser name)
            " t.client_software_version client_version,"
            + // csv 19:client_version, SW-version of client software (not RMBT-client-version), eg.
              // '1.3'
            " t.network_operator network_mcc_mnc,"
            + // csv 20:network_mcc_mnc, mobile country and network code of current network (Android
              // only), string, eg "232-12'
            " network_country,"
            + // (internal) Android-only, country code derived by client from mobile network code
            // " network_is_roaming," + //(internal) roaming-status of mobile network, boolean or
            // (null); Android-only (obsolete)
            " roaming_type,"
            + // roaming-status of mobile network, integer: 0:not
              // roaming,1:national,2:international,(null):unknown (eg. iOS)
            " t.network_operator_name network_name,"
            + // csv 21:network_name, name of current mobile network as displayed on device (eg:
              // '3likeHome')
            " t.network_sim_operator sim_mcc_mnc,"
            + // csv 22:sim_mcc_mnc, home network of SIM (initial 5 digits from IMSI), eg '232-01'
            " t.network_sim_country sim_country,"
            + // (internal) Android-only, country derived by client from SIM (country of home
              // network)
            " COALESCE(mprov.name,msim.shortname,msim.name,prov.name) provider_name,"
            + // pre-defined list of providers (based on provider_id) //TODO replace provider
            " t.nat_type \"connection\","
            + // csv 23:connection, translation-mechanism in NAT, eg. nat_local_to_public_ipv4
            " t.public_ip_asn asn,"
            + // csv 24:asn, AS (autonomous system) number, number of public IP network
            " (CASE WHEN publish_public_data THEN t.client_public_ip_anonymized ELSE '' END) ip_anonym,"
            + // csv 25:ip_anonym, anonymized IP of client (IPv4: 8 bits removed, IPv6: 72 bits
              // removed)
            " (ndt.s2cspd*1000)::int ndt_download_kbit,"
            + // csv 26:ndt_download_kbit, result of NDT downlink throughput test kbit/s
            " (ndt.c2sspd*1000)::int ndt_upload_kbit,"
            + // csv 27 ndt_uoload_kbit, result of NDT uplink throughput test in kbit/s
            " country_geoip,"
            + // country-code derived from public IP-address, eg. 'AT'
            " country_location,"
            + // country-code derived from geo_location, eg. 'DE'
            " country_asn,"
            + // country_code derived from AS, eg. 'EU'
            " data->>'region' region,"
            + // si - region from geo location
            " data->>'municipality' municipality,"
            + // si - municipality from geo location
            " data->>'settlement' settlement,"
            + // si - settlement from geo location
            " data->>'whitespace' whitespot,"
            + // si - whitespace from geo location
            " data->>'cell_id' cell_id,"
            + // si - cell_id
            " data->>'cell_name' cell_name,"
            + // si - cell_name
            " data->>'cell_id_multiple' cell_id_multiple,"
            + // si - cell_id_multiple
            " bytes_download,"
            + // number of bytes downloaded during test (download and upload) (obsolete)
            " bytes_upload,"
            + // number of bytes uploaded during test (download and upload) (obsolete)
            " test_if_bytes_download,"
            + // downloaded bytes on interface during total test (inc. training, ping, without NDT)
              // (obsolete)
            " test_if_bytes_upload,"
            + // uploaded bytes on interface during total test (inc. training, ping, without NDT)
              // (obsolete)
            " testdl_if_bytes_download,"
            + // downloaded bytes on interface during download-test (without training-seq)
            " testdl_if_bytes_upload,"
            + // uploaded bytes on interface during download-test (without training-seq)
            " testul_if_bytes_download,"
            + // downloaded bytes on interface during upload-test (without training-seq)
            " testul_if_bytes_upload,"
            + // downloaded bytes on interface during upload-test (without training-seq)
            " (t.nsec_download::float / 1000000) duration_download_ms,"
            + // duration of download-test in ms
            " (t.nsec_upload::float / 1000000) duration_upload_ms,"
            + // duration of upload-test in ms
            " (t.time_dl_ns::float / 1000000) time_dl_ms,"
            + // relative start time of download-test in ms (ignoring training-phase)
            " (t.time_ul_ns::float / 1000000) time_ul_ms,"
            + // relative start time of download-test in ms (ignoring training-phase)
            // " phone_type" + //(internal) radio type of phone: 0 no mobile radio, 1 GSM (incl.
            // UMTS,LTE) 2 CDMA (obsolete)
            " t.publish_public_data, "
            + " ((EXTRACT (EPOCH FROM (t.timestamp - t.time))) * 1000) speed_test_duration "
            + " FROM test t"
            + " LEFT JOIN device_map adm ON adm.codename=t.model"
            + " LEFT JOIN test_server ts ON ts.uid=t.server_id"
            + " LEFT JOIN test_ndt ndt ON t.uid=ndt.test_id"
            + " LEFT JOIN provider prov ON t.provider_id=prov.uid"
            + " LEFT JOIN provider mprov ON t.mobile_provider_id=mprov.uid"
            + " LEFT JOIN mccmnc2name msim ON t.mobile_sim_id=msim.uid"
            + " WHERE "
            + " t.deleted = false "
            + " AND t.status = 'FINISHED' "
            + " AND t.open_test_uuid = ? ";

    // System.out.println(sql);

    final String[] columns;
    PreparedStatement ps = null;
    ResultSet rs = null;
    final JSONObject response = new JSONObject();
    try {
      ps = conn.prepareStatement(sql);

      // insert filter for accuracy
      /*
      double accuracy = Double.parseDouble(getSetting("rmbt_geo_accuracy_detail_limit"));
      ps.setDouble(1, accuracy);
      ps.setDouble(2, accuracy);
      ps.setDouble(3, accuracy);
      ps.setDouble(4, accuracy);
      ps.setDouble(5, accuracy);
      ps.setDouble(6, accuracy);
      */

      // openTestIDs are starting with "O"
      if (openTestUUID != null && openTestUUID.startsWith("O")) {
        openTestUUID = openTestUUID.substring(1);
      }
      ps.setObject(1, openTestUUID, Types.OTHER);

      if (!ps.execute()) return null;
      rs = ps.getResultSet();

      if (rs.next()) {
        final boolean isPublishPublicData = rs.getBoolean("publish_public_data");
        // fetch data for every field
        for (int i = 0; i < openDataFieldsFull.length; i++) {

          // convert data to correct json response
          final Object obj = rs.getObject(openDataFieldsFull[i]);
          if (openDataBooleanFields.contains(openDataFieldsFull[i])) {
            if (obj == null) {
              response.put(openDataFieldsFull[i], false);
            } else {
              response.put(openDataFieldsFull[i], obj);
            }
          } else if (obj == null) {
            response.put(openDataFieldsFull[i], JSONObject.NULL);
          } else if (openDataNumberFields.contains(openDataFieldsFull[i])) {
            final String tmp = obj.toString().trim();
            if (tmp.isEmpty()) response.put(openDataFieldsFull[i], JSONObject.NULL);
            else response.put(openDataFieldsFull[i], JSONObject.stringToValue(tmp));
          } else {
            final String tmp = obj.toString().trim();
            if (tmp.isEmpty()) response.put(openDataFieldsFull[i], JSONObject.NULL);
            else response.put(openDataFieldsFull[i], tmp);
          }
        }
        /* obsolete (now in database)
        //special threatment for lat/lng: if too low accuracy -> do not send back to client
        double accuracy = rs.getDouble("loc_accuracy");
        if (accuracy > Double.parseDouble(settings.getString("RMBT_GEO_ACCURACY_DETAIL_LIMIT"))) {
        	response.put("loc_accuracy", JSONObject.NULL);
        	response.put("long", JSONObject.NULL);
        	response.put("lat", JSONObject.NULL);
        }

        try {
        // do not output invalid zip-codes, must be 4 digits
        int zip_code = rs.getInt("zip_code");
        if (zip_code <= 999 || zip_code > 9999)
        	response.put("zip_code", JSONObject.NULL);
        }
        catch (final SQLException e) {
        	System.out.println("Error on zip_code: " + e.toString());
        };
        */

        // classify download, upload, ping, signal
        response.put(
            "download_classification",
            Classification.classify(
                classification.THRESHOLD_DOWNLOAD, rs.getLong("download_kbit")));
        response.put(
            "upload_classification",
            Classification.classify(classification.THRESHOLD_UPLOAD, rs.getLong("upload_kbit")));
        response.put(
            "ping_classification",
            Classification.classify(
                classification.THRESHOLD_PING, rs.getLong("ping_ms") * 1000000));
        // classify signal accordingly
        if ((rs.getString("signal_strength") != null || rs.getString("lte_rsrp") != null)
            && rs.getString("network_type") != null) { // signal available
          if (rs.getString("lte_rsrp") == null) { // use RSSI
            if (rs.getString("network_type").equals("WLAN")) { // RSSI for Wifi
              response.put(
                  "signal_classification",
                  Classification.classify(
                      classification.THRESHOLD_SIGNAL_WIFI, rs.getLong("signal_strength")));
            } else { // RSSI for Mobile
              response.put(
                  "signal_classification",
                  Classification.classify(
                      classification.THRESHOLD_SIGNAL_MOBILE, rs.getLong("signal_strength")));
            }
          } else // RSRP for LTE
          response.put(
                "signal_classification",
                Classification.classify(
                    classification.THRESHOLD_SIGNAL_RSRP, rs.getLong("lte_rsrp")));
        } else { // no signal available
          response.put("signal_classification", JSONObject.NULL);
        }

        // also load download/upload-speed-data, signal data and location data if possible
        JSONObject speedCurve = new JSONObject();
        JSONArray downloadSpeeds = new JSONArray();
        JSONArray uploadSpeeds = new JSONArray();
        JSONArray locArray = new JSONArray();
        JSONArray signalArray = new JSONArray();

        // Load speed data from database
        SpeedGraph speedGraph =
            new SpeedGraph(
                rs.getLong("test_uid"),
                Math.max(rs.getInt("num_threads"), rs.getInt("num_threads_ul")),
                conn);
        for (SpeedGraph.SpeedGraphItem item : speedGraph.getUpload()) {
          JSONObject obj = new JSONObject();
          obj.put("time_elapsed", item.getTimeElapsed());
          obj.put("bytes_total", item.getBytesTotal());
          uploadSpeeds.put(obj);
        }
        for (SpeedGraph.SpeedGraphItem item : speedGraph.getDownload()) {
          JSONObject obj = new JSONObject();
          obj.put("time_elapsed", item.getTimeElapsed());
          obj.put("bytes_total", item.getBytesTotal());
          downloadSpeeds.put(obj);
        }

        // Load signal strength from database
        SignalGraph sigGraph =
            new SignalGraph(rs.getLong("test_uid"), rs.getTimestamp("client_time").getTime(), conn);
        for (SignalGraph.SignalGraphItem item : sigGraph.getSignalList()) {
          JSONObject json = new JSONObject();
          json.put("time_elapsed", item.getTimeElapsed());
          json.put("network_type", item.getNetworkType());
          json.put("signal_strength", item.getSignalStrength());
          json.put("lte_rsrp", item.getLteRsrp());
          json.put("lte_rsrq", item.getLteRsrq());
          json.put("cat_technology", item.getCatTechnology());
          signalArray.put(json);
        }

        if (isPublishPublicData) {
          // Load gps coordinates from database
          LocationGraph locGraph =
              new LocationGraph(
                  rs.getLong("test_uid"), rs.getTimestamp("client_time").getTime(), conn);
          double totalDistance = locGraph.getTotalDistance();
          for (LocationGraph.LocationGraphItem item : locGraph.getLocations()) {
            JSONObject json = new JSONObject();
            json.put("time_elapsed", item.getTimeElapsed());
            json.put("lat", item.getLatitude());
            json.put("long", item.getLongitude());
            json.put(
                "loc_accuracy", (item.getAccuracy() > 0) ? item.getAccuracy() : JSONObject.NULL);
            locArray.put(json);
          }

          // add total distance during test - but only if within bounds
          if ((totalDistance > 0)
              && totalDistance <= Double.parseDouble(getSetting("rmbt_geo_distance_detail_limit")))
            response.put("distance", totalDistance);
          else response.put("distance", JSONObject.NULL);
        } else {
          response.put("distance", JSONObject.NULL);
        }

        final TestStatDao testStatDao = new TestStatDao(conn);
        final TestStat ts = testStatDao.getById(rs.getLong("test_uid"));
        if (ts != null) {
          response.put("extended_test_stat", ts.toJsonObject());
        }

        speedCurve.put("upload", uploadSpeeds);
        speedCurve.put("download", downloadSpeeds);
        speedCurve.put("signal", signalArray);
        speedCurve.put("location", locArray);
        response.put("speed_curve", speedCurve);

      } else {
        // invalid open_uuid
        setStatus(Status.CLIENT_ERROR_NOT_FOUND);
        response.put("error", "invalid open-uuid");
      }
    } catch (final JSONException e) {
      Logger.getLogger(OpenTestResource.class.getName()).log(Level.SEVERE, null, e);
    } catch (SQLException ex) {
      try {
        setStatus(Status.CLIENT_ERROR_NOT_FOUND);
        response.put("error", "invalid open-uuid");
      } catch (JSONException ex1) {
        Logger.getLogger(OpenTestResource.class.getName()).log(Level.SEVERE, null, ex1);
      }
      Logger.getLogger(OpenTestResource.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
      try {
        if (rs != null) rs.close();
        if (ps != null) ps.close();
      } catch (final SQLException e) {
        Logger.getLogger(OpenTestResource.class.getName()).log(Level.SEVERE, null, e);
      }
    }

    return response.toString();
  }
Example #5
0
  /**
   * Scan the content following the named tag, attaching it to the context.
   *
   * @param x The XMLTokener containing the source string.
   * @param context The JSONObject that will include the new material.
   * @param name The tag name.
   * @return true if the close tag is processed.
   * @throws JSONException
   */
  private static boolean parse(XMLTokener x, JSONObject context, String name) throws JSONException {
    char c;
    int i;
    String n;
    JSONObject o = null;
    String s;
    Object t;

    // Test for and skip past these forms:
    //      <!-- ... -->
    //      <!   ...   >
    //      <![  ... ]]>
    //      <?   ...  ?>
    // Report errors for these forms:
    //      <>
    //      <=
    //      <<

    t = x.nextToken();

    // <!

    if (t == BANG) {
      c = x.next();
      if (c == '-') {
        if (x.next() == '-') {
          x.skipPast("-->");
          return false;
        }
        x.back();
      } else if (c == '[') {
        t = x.nextToken();
        if (t.equals("CDATA")) {
          if (x.next() == '[') {
            s = x.nextCDATA();
            if (s.length() > 0) {
              context.accumulate("content", s);
            }
            return false;
          }
        }
        throw x.syntaxError("Expected 'CDATA['");
      }
      i = 1;
      do {
        t = x.nextMeta();
        if (t == null) {
          throw x.syntaxError("Missing '>' after '<!'.");
        } else if (t == LT) {
          i += 1;
        } else if (t == GT) {
          i -= 1;
        }
      } while (i > 0);
      return false;
    } else if (t == QUEST) {

      // <?

      x.skipPast("?>");
      return false;
    } else if (t == SLASH) {

      // Close tag </

      t = x.nextToken();
      if (name == null) {
        throw x.syntaxError("Mismatched close tag" + t);
      }
      if (!t.equals(name)) {
        throw x.syntaxError("Mismatched " + name + " and " + t);
      }
      if (x.nextToken() != GT) {
        throw x.syntaxError("Misshaped close tag");
      }
      return true;

    } else if (t instanceof Character) {
      throw x.syntaxError("Misshaped tag");

      // Open tag <

    } else {
      n = (String) t;
      t = null;
      o = new JSONObject();
      for (; ; ) {
        if (t == null) {
          t = x.nextToken();
        }

        // attribute = value

        if (t instanceof String) {
          s = (String) t;
          t = x.nextToken();
          if (t == EQ) {
            t = x.nextToken();
            if (!(t instanceof String)) {
              throw x.syntaxError("Missing value");
            }
            o.accumulate(s, JSONObject.stringToValue((String) t));
            t = null;
          } else {
            o.accumulate(s, "");
          }

          // Empty tag <.../>

        } else if (t == SLASH) {
          if (x.nextToken() != GT) {
            throw x.syntaxError("Misshaped tag");
          }
          if (o.length() > 0) {
            context.accumulate(n, o);
          } else {
            context.accumulate(n, "");
          }
          return false;

          // Content, between <...> and </...>

        } else if (t == GT) {
          for (; ; ) {
            t = x.nextContent();
            if (t == null) {
              if (n != null) {
                throw x.syntaxError("Unclosed tag " + n);
              }
              return false;
            } else if (t instanceof String) {
              s = (String) t;
              if (s.length() > 0) {
                o.accumulate("content", JSONObject.stringToValue(s));
              }

              // Nested element

            } else if (t == LT) {
              if (parse(x, o, n)) {
                if (o.length() == 0) {
                  context.accumulate(n, "");
                } else if (o.length() == 1 && o.opt("content") != null) {
                  context.accumulate(n, o.opt("content"));
                } else {
                  context.accumulate(n, o);
                }
                return false;
              }
            }
          }
        } else {
          throw x.syntaxError("Misshaped tag");
        }
      }
    }
  }