From 5f892ac1e0fe6a21a00808cfb0afae2a2c2071dc Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 8 May 2014 19:00:44 +0200 Subject: Add json containers for Tweet and User objects --- lib/gson-2.2.4.jar | Bin 0 -> 190418 bytes nbproject/project.properties | 4 +- src/data/Tweet.java | 57 ++++++++++++++++++++++++ src/data/User.java | 18 ++++++++ src/data/ValidatingJsonDeserializer.java | 72 +++++++++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 lib/gson-2.2.4.jar create mode 100644 src/data/Tweet.java create mode 100644 src/data/User.java create mode 100644 src/data/ValidatingJsonDeserializer.java diff --git a/lib/gson-2.2.4.jar b/lib/gson-2.2.4.jar new file mode 100644 index 0000000..9478253 Binary files /dev/null and b/lib/gson-2.2.4.jar 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 implements JsonDeserializer { + + @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 { + } +} -- cgit v1.2.1