summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurice Laveaux <m.laveaux@student.tue.nl>2014-05-22 09:02:50 +0200
committerMaurice Laveaux <m.laveaux@student.tue.nl>2014-05-22 09:02:50 +0200
commit0c07b1d1a83ab20b4c753c40ea8048f73b3e5745 (patch)
tree47db3723c190bdb264a144b500fb6f41b2f1559f
parent4e0fcd499a14cfc621b256f4a28f0cafe22bfc8c (diff)
downloadTwitterDataAnalytics-0c07b1d1a83ab20b4c753c40ea8048f73b3e5745.tar.gz
Changed Request response to a new Response class.
* Response contains the JsonElement, tickrate, reset and leftover data. * Removed getJsonRelaxed, because it was not used elsewhere.
-rw-r--r--src/io/AbstractRequester.java56
-rw-r--r--src/io/BearerRequester.java26
-rw-r--r--src/io/OAuthRequester.java7
-rw-r--r--src/io/Requester.java14
-rw-r--r--src/io/Response.java42
-rw-r--r--src/mining/TwitterApi.java5
6 files changed, 86 insertions, 64 deletions
diff --git a/src/io/AbstractRequester.java b/src/io/AbstractRequester.java
index ac74533..239e75d 100644
--- a/src/io/AbstractRequester.java
+++ b/src/io/AbstractRequester.java
@@ -1,5 +1,7 @@
package io;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -7,11 +9,10 @@ import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
* Performs an API Request.
@@ -23,36 +24,29 @@ public abstract class AbstractRequester implements Requester {
private static final String API_URL = "https://api.twitter.com/";
@Override
- public JSONObject getJSON(String resource) throws IOException {
- return getJSON(resource, true);
- }
-
- @Override
- public JSONObject getJSONRelax(String resource) throws IOException {
- return getJSON(resource, false);
- }
-
- private JSONObject getJSON(String resource, boolean checkStatusCode)
- throws IOException {
+ public Response getJSON(String resource) throws IOException {
HttpURLConnection conn = open(buildUrl(resource));
try {
preconnect(conn);
- JSONObject resp = getResponseAsJson(conn);
- /* print response to stderr for debugging */
- if (resp.has("errors")) {
- try {
- String errors = resp.get("errors").toString();
- getLogger().info("Request failed: " + errors);
- } catch (JSONException ex) {
- }
+ JsonElement resp = getResponseAsJson(conn);
+
+ if(resp.isJsonObject() && resp.getAsJsonObject().has("errors")) {
+ /* print response to stderr for debugging */
+ String errors = resp.getAsJsonObject().get("errors").toString();
+ getLogger().log(Level.INFO, "Request failed: {0}", errors);
}
// TODO: what if there is an internal server error? Technically we
// should always treat that as "don't know what the server thinks".
- if (checkStatusCode && conn.getResponseCode() != 200) {
+ if (conn.getResponseCode() != 200) {
// TODO: print more helpful details
throw new IOException("Unexpected response code");
- }
- return resp;
+ }
+
+ int rateLimit = Integer.parseInt(conn.getHeaderField("X-Rate-Limit-Limit"));
+ int rateLimitRemaining = Integer.parseInt(conn.getHeaderField("X-Rate-Limit-Remaining"));
+ int rateLimitReset = Integer.parseInt(conn.getHeaderField("X-Rate-Limit-Reset"));
+
+ return new Response(resp, rateLimit, rateLimitRemaining, rateLimitReset);
} finally {
conn.disconnect();
}
@@ -92,7 +86,7 @@ public abstract class AbstractRequester implements Requester {
* @throws java.io.IOException on failure to open a connection.
*/
protected final HttpURLConnection open(URL url) throws IOException {
- getLogger().fine("Opening: " + url);
+ getLogger().log(Level.FINE, "Opening: {0}", url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// set default param: fail if no response within 5 seconds
conn.setReadTimeout(5000);
@@ -107,7 +101,7 @@ public abstract class AbstractRequester implements Requester {
* @throws java.io.IOException if the response cannot be retrieved or if the
* response does not contain well-formed JSON.
*/
- protected final JSONObject getResponseAsJson(HttpURLConnection conn)
+ protected final JsonElement getResponseAsJson(HttpURLConnection conn)
throws IOException {
StringWriter writer = new StringWriter();
InputStream is;
@@ -122,13 +116,11 @@ public abstract class AbstractRequester implements Requester {
throw new IOException("Failed to fetch response");
}
IOUtils.copy(is, writer, Charsets.UTF_8);
- try {
- return new JSONObject(writer.toString());
- } catch (JSONException ex) {
- // treat JSON errors as if an I/O error occurred
- throw new IOException(ex);
- }
+
+ JsonParser parser = new JsonParser();
+ return parser.parse(writer.toString());
}
+
/**
* Prepare the request before it gets send.
diff --git a/src/io/BearerRequester.java b/src/io/BearerRequester.java
index 442f62a..11776fc 100644
--- a/src/io/BearerRequester.java
+++ b/src/io/BearerRequester.java
@@ -1,5 +1,7 @@
package io;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@@ -57,18 +59,16 @@ public class BearerRequester extends AbstractRequester {
conn.setDoOutput(true);
conn.getOutputStream().write(postData.getBytes(Charsets.UTF_8));
- try {
- JSONObject resp = getResponseAsJson(conn);
- // TODO: parse resp.errors
- if (!resp.getString("token_type").equals("bearer")) {
- throw new IOException("Expected bearer token type");
- }
- access_token = resp.getString("access_token");
- } catch (JSONException ex) {
- // treat JSON errors as if an I/O error occurred
- throw new IOException(ex);
+ JsonObject resp = getResponseAsJson(conn).getAsJsonObject();
+ if (!resp.getAsJsonObject().getAsJsonPrimitive("token_type").getAsString().equals("bearer")) {
+ throw new IOException("Expected bearer token type");
}
- } finally {
+ access_token = resp.getAsJsonPrimitive("access_token").getAsString();
+ }
+ catch (ClassCastException ex) {
+ throw new IOException("Response was not a JsonObject");
+ }
+ finally {
conn.disconnect();
}
}
@@ -90,7 +90,7 @@ public class BearerRequester extends AbstractRequester {
public boolean isValid() throws IOException {
// NOTE: this actually contributes to the ratelimit (12/minute)
// TODO: find alternative that does not hit the ratelimit
- JSONObject obj = getJSONRelax("application/rate_limit_status");
- return !obj.has("errors");
+ Response obj = getJSON("application/rate_limit_status");
+ return !obj.getResp().getAsJsonObject().has("errors");
}
}
diff --git a/src/io/OAuthRequester.java b/src/io/OAuthRequester.java
index c3538ee..3621186 100644
--- a/src/io/OAuthRequester.java
+++ b/src/io/OAuthRequester.java
@@ -134,12 +134,9 @@ public class OAuthRequester extends AbstractRequester {
@Override
public boolean isValid() throws IOException {
- if (consumer.getToken() == null) {
- return false;
- }
// NOTE: this actually contributes to the ratelimit (12/minute)
// TODO: find alternative that does not hit the ratelimit
- JSONObject obj = getJSONRelax("application/rate_limit_status");
- return !obj.has("errors");
+ Response obj = getJSON("application/rate_limit_status");
+ return !obj.getResp().getAsJsonObject().has("errors");
}
}
diff --git a/src/io/Requester.java b/src/io/Requester.java
index 7f09a48..3dd09f3 100644
--- a/src/io/Requester.java
+++ b/src/io/Requester.java
@@ -1,5 +1,6 @@
package io;
+import com.google.gson.JsonElement;
import java.io.IOException;
import org.json.JSONObject;
@@ -20,18 +21,7 @@ public interface Requester {
* @return A JSON object resulting from the request.
* @throws java.io.IOException on error fetching the resource.
*/
- public JSONObject getJSON(String resource) throws IOException;
-
- /**
- * Almost equivalent to {@code getJSON(resource, true)}, except that an
- * IOException is not thrown if the request reports an non-successful status
- * code.
- *
- * @see Requester#getJSON(java.lang.String, boolean)
- * @throws IOException on network errors or if the response could not be
- * parsed into a valid JSONObject.
- */
- public JSONObject getJSONRelax(String resource) throws IOException;
+ public Response getJSON(String resource) throws IOException;
/**
* Tests whether this instance can dispatch requests.
diff --git a/src/io/Response.java b/src/io/Response.java
new file mode 100644
index 0000000..5cc36e1
--- /dev/null
+++ b/src/io/Response.java
@@ -0,0 +1,42 @@
+package io;
+
+import com.google.gson.JsonElement;
+
+/**
+ * A response object with the Jsonelement and rate limit values.
+ *
+ * @author Maurice Laveaux
+ */
+public class Response {
+
+ private final JsonElement element;
+
+ private final int rateLimitReset;
+
+ private final int rateLimitRemaining;
+
+ private final int rateLimit;
+
+ public Response(JsonElement resp, int rateLimit, int rateLimitRemaining, int rateLimitReset) {
+ this.element = resp;
+ this.rateLimit = rateLimit;
+ this.rateLimitRemaining = rateLimitRemaining;
+ this.rateLimitReset = rateLimitReset;
+ }
+
+ public JsonElement getResp() {
+ return element;
+ }
+
+ public int getRateLimit() {
+ return this.rateLimit;
+ }
+
+ public int getRateLimitRemaining() {
+ return this.rateLimitRemaining;
+ }
+
+ public int getRateLimitReset() {
+ return this.rateLimitReset;
+ }
+}
diff --git a/src/mining/TwitterApi.java b/src/mining/TwitterApi.java
index 372aade..8889c2f 100644
--- a/src/mining/TwitterApi.java
+++ b/src/mining/TwitterApi.java
@@ -1,8 +1,9 @@
package mining;
+import io.BearerRequester;
import io.OAuthRequester;
import io.Requester;
-import io.BearerRequester;
+import io.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -173,7 +174,7 @@ public class TwitterApi {
return this.resource + "?" + URLEncodedUtils.format(params, Charsets.UTF_8);
}
- public JSONObject request() throws IOException {
+ public Response request() throws IOException {
return TwitterApi.this.requester.getJSON(toString());
}
}