summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-05-08 19:00:44 +0200
committerPeter Wu <peter@lekensteyn.nl>2014-05-08 19:00:44 +0200
commit5f892ac1e0fe6a21a00808cfb0afae2a2c2071dc (patch)
tree383da575535e24c3865ea793e9b00f30bc457661
parent4ba04e1a6b2ca94a124f63c6f7a6033b7f17344e (diff)
downloadDatafiller-5f892ac1e0fe6a21a00808cfb0afae2a2c2071dc.tar.gz
Add json containers for Tweet and User objects
-rw-r--r--lib/gson-2.2.4.jarbin0 -> 190418 bytes
-rw-r--r--nbproject/project.properties4
-rw-r--r--src/data/Tweet.java57
-rw-r--r--src/data/User.java18
-rw-r--r--src/data/ValidatingJsonDeserializer.java72
5 files changed, 150 insertions, 1 deletions
diff --git a/lib/gson-2.2.4.jar b/lib/gson-2.2.4.jar
new file mode 100644
index 0000000..9478253
--- /dev/null
+++ b/lib/gson-2.2.4.jar
Binary files differ
diff --git a/nbproject/project.properties b/nbproject/project.properties
index 9d41c56..5ed1af4 100644
--- a/nbproject/project.properties
+++ b/nbproject/project.properties
@@ -29,13 +29,15 @@ dist.jar=${dist.dir}/Datafiller.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
+file.reference.gson-2.2.4.jar=lib/gson-2.2.4.jar
file.reference.json.jar=lib/json.jar
file.reference.postgresql-9.3-1101.jdbc41.jar=lib/postgresql-9.3-1101.jdbc41.jar
includes=**
jar.compress=false
javac.classpath=\
${file.reference.json.jar}:\
- ${file.reference.postgresql-9.3-1101.jdbc41.jar}
+ ${file.reference.postgresql-9.3-1101.jdbc41.jar}:\
+ ${file.reference.gson-2.2.4.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
diff --git a/src/data/Tweet.java b/src/data/Tweet.java
new file mode 100644
index 0000000..0d529d6
--- /dev/null
+++ b/src/data/Tweet.java
@@ -0,0 +1,57 @@
+package data;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Represents the tweet object as returned by the twitter API.
+ */
+public class Tweet {
+
+ public String lang;
+ public long id;
+ public long in_reply_to_user_id;
+ public String created_at;
+ public long favorite_count;
+ public String place;
+ public String coordinates;
+ public String text;
+ @ValidatingJsonDeserializer.Nullable
+ public Tweet retweeted_status;
+ public Entities entities;
+ public long retweet_count;
+ @ValidatingJsonDeserializer.Validator()
+ public User user;
+
+ @Override
+ public String toString() {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ return gson.toJson(this);
+ }
+
+ public class Entities {
+
+ public Hashtag[] hashtags;
+ public Url[] urls;
+ public Mention[] user_mentions;
+ }
+
+ public class Hashtag {
+
+ public String text;
+ }
+
+ public class Url {
+
+ public String expanded_url;
+ //public String display_url;
+ //public String url;
+ }
+
+ public class Mention {
+
+ public long id; // user ID
+ //public String name; // display name
+ //public String screen_name; // Screen name (at-name)
+ }
+}
diff --git a/src/data/User.java b/src/data/User.java
new file mode 100644
index 0000000..054fa54
--- /dev/null
+++ b/src/data/User.java
@@ -0,0 +1,18 @@
+package data;
+
+/**
+ * Represents the user object from the Twitter API as contained in a tweet.
+ */
+public class User {
+
+ public long id;
+ public String name;
+ public String time_zone;
+ public long statuses_count;
+ public long followers_count;
+ public long friends_count;
+ public String location;
+ public String screen_name;
+ public String created_at;
+ public String lang;
+}
diff --git a/src/data/ValidatingJsonDeserializer.java b/src/data/ValidatingJsonDeserializer.java
new file mode 100644
index 0000000..91c1709
--- /dev/null
+++ b/src/data/ValidatingJsonDeserializer.java
@@ -0,0 +1,72 @@
+package data;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+/**
+ * JSON deserializer which validates that all fields are present.
+ *
+ * @author Peter Wu.
+ */
+public class ValidatingJsonDeserializer<T> implements JsonDeserializer<T> {
+
+ @Override
+ public T deserialize(JsonElement je, Type type,
+ JsonDeserializationContext jdc) throws JsonParseException {
+ T obj = new Gson().fromJson(je, type);
+ JsonObject jsonObj = je.getAsJsonObject();
+ for (Field f : obj.getClass().getDeclaredFields()) {
+ if (!jsonObj.has(f.getName())) {
+ if (f.getAnnotation(Nullable.class) != null) {
+ // null allowed, skip
+ continue;
+ }
+ throw new JsonParseException("Missing field: " + f.getName());
+ }
+ // TODO: validate type?
+ }
+ return obj;
+ }
+
+ public static GsonBuilder addValidation(GsonBuilder gson, Type type) {
+ GsonBuilder gb = new GsonBuilder();
+ gson.registerTypeAdapter(type, new ValidatingJsonDeserializer());
+ for (Field f : type.getClass().getDeclaredFields()) {
+ Validator v = f.getAnnotation(Validator.class);
+ if (v != null) {
+ addValidation(gson, v.deserializer());
+ }
+ }
+ return gb;
+ }
+
+ /**
+ * Marks a member as object that should be validated too.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface Validator {
+
+ Class deserializer() default ValidatingJsonDeserializer.class;
+ }
+
+ /**
+ * Marks a member as nullable, that is, it can be missing from the JSON
+ * object.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface Nullable {
+ }
+}