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 --- src/data/Tweet.java | 57 +++++++++++++++++++++++++ src/data/User.java | 18 ++++++++ src/data/ValidatingJsonDeserializer.java | 72 ++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/data/Tweet.java create mode 100644 src/data/User.java create mode 100644 src/data/ValidatingJsonDeserializer.java (limited to 'src/data') 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