summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-05-09 15:14:23 +0200
committerPeter Wu <peter@lekensteyn.nl>2014-05-09 15:14:23 +0200
commit9be617801a8dabe4bcae017c2f671c5c10b3aebb (patch)
treed674460295a804b5b5d059b01ef711a939c2135f
parent71a405ee7b73f91298b029f4d817cc13731340cc (diff)
downloadDatafiller-9be617801a8dabe4bcae017c2f671c5c10b3aebb.tar.gz
Trace object path for JSON validation errors.
-rw-r--r--lib/commons-lang3-3.3.2.jarbin0 -> 412740 bytes
-rw-r--r--nbproject/project.properties4
-rw-r--r--src/data/ValidatingJsonDeserializer.java21
-rw-r--r--test/data/ValidatingJsonDeserializerTest.java9
4 files changed, 18 insertions, 16 deletions
diff --git a/lib/commons-lang3-3.3.2.jar b/lib/commons-lang3-3.3.2.jar
new file mode 100644
index 0000000..bb06979
--- /dev/null
+++ b/lib/commons-lang3-3.3.2.jar
Binary files differ
diff --git a/nbproject/project.properties b/nbproject/project.properties
index d738523..f6acd32 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.commons-lang3-3.3.2.jar=lib/commons-lang3-3.3.2.jar
file.reference.gson-2.2.4.jar=lib/gson-2.2.4.jar
file.reference.postgresql-9.3-1101.jdbc41.jar=lib/postgresql-9.3-1101.jdbc41.jar
includes=**
jar.compress=false
javac.classpath=\
${file.reference.postgresql-9.3-1101.jdbc41.jar}:\
- ${file.reference.gson-2.2.4.jar}
+ ${file.reference.gson-2.2.4.jar}:\
+ ${file.reference.commons-lang3-3.3.2.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
diff --git a/src/data/ValidatingJsonDeserializer.java b/src/data/ValidatingJsonDeserializer.java
index e38f68f..511264d 100644
--- a/src/data/ValidatingJsonDeserializer.java
+++ b/src/data/ValidatingJsonDeserializer.java
@@ -26,14 +26,11 @@ public class ValidatingJsonDeserializer<T> implements JsonDeserializer<T> {
public T deserialize(JsonElement je, Type type,
JsonDeserializationContext jdc) throws JsonParseException {
T obj = new Gson().fromJson(je, type);
- checkObject(je, obj.getClass());
+ checkObject("", je, obj.getClass());
return obj;
}
- private void checkObject(JsonElement je, Class type) {
- if (!je.isJsonObject()) {
- throw new JsonParseException("Expected object: " + type.getName());
- }
+ private void checkObject(String path, JsonElement je, Class type) {
JsonObject jsonObj = je.getAsJsonObject();
for (Field f : type.getDeclaredFields()) {
if (!jsonObj.has(f.getName())) {
@@ -41,14 +38,14 @@ public class ValidatingJsonDeserializer<T> implements JsonDeserializer<T> {
// null allowed, skip
continue;
}
- throw new JsonParseException("Missing field: " + f.getName());
+ throw new JsonParseException("Missing field: " + path + f.getName());
}
- tryValidateProperty(jsonObj.get(f.getName()), f);
+ tryValidateProperty(path, jsonObj.get(f.getName()), f);
// TODO: validate type?
}
}
- private void tryValidateProperty(JsonElement je, Field f) {
+ private void tryValidateProperty(String path, JsonElement je, Field f) {
// assume that this annotation is only applied to objects
Validator v = f.getAnnotation(Validator.class);
if (v != null) {
@@ -56,17 +53,19 @@ public class ValidatingJsonDeserializer<T> implements JsonDeserializer<T> {
if (type.isArray()) {
// the class expects an array, so the value must have one too.
if (!je.isJsonArray()) {
- throw new JsonParseException("Not an array: " + f.getName());
+ throw new JsonParseException("Not an array: " + path + f.getName());
}
JsonArray ja = je.getAsJsonArray();
type = type.getComponentType();
// for each array element, check if the object is valid.
+ path += f.getName() + "."; // e.g. foo[]
for (JsonElement arr_je : ja) {
- checkObject(arr_je, type);
+ checkObject(path, arr_je, type);
}
} else {
// not an array, assume a verifiable object
- checkObject(je, type);
+ path += f.getName() + "."; // e.g. foo
+ checkObject(path, je, type);
}
}
}
diff --git a/test/data/ValidatingJsonDeserializerTest.java b/test/data/ValidatingJsonDeserializerTest.java
index 19ec2f4..84dde5c 100644
--- a/test/data/ValidatingJsonDeserializerTest.java
+++ b/test/data/ValidatingJsonDeserializerTest.java
@@ -6,6 +6,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
+import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -387,7 +388,7 @@ public class ValidatingJsonDeserializerTest {
private void checkImpairedTweet(String... names) {
JsonObject tweet = buildMinimalTweet(buildMinimalUser());
removeProperty(tweet, names);
- String prop = names[names.length - 1];
+ String prop = StringUtils.join(names, ".");
checkTweetFail(tweet, "Missing field: " + prop);
}
@@ -395,8 +396,8 @@ public class ValidatingJsonDeserializerTest {
JsonObject user = buildMinimalUser();
removeProperty(user, names);
JsonObject tweet = buildMinimalTweet(user);
- String prop = names[names.length - 1];
- checkTweetFail(tweet, "Missing field: " + prop);
+ String prop = StringUtils.join(names, ".");
+ checkTweetFail(tweet, "Missing field: user." + prop);
}
private void checkTweetFail(JsonObject tweet, String exp) {
@@ -486,6 +487,6 @@ public class ValidatingJsonDeserializerTest {
JsonObject retweet = buildMinimalTweet(buildMinimalUser());
removeProperty(retweet, "text");
tweet.add("retweeted_status", retweet);
- checkTweetFail(tweet, "Missing field: text");
+ checkTweetFail(tweet, "Missing field: retweeted_status.text");
}
}