blob: 01413b41e64a75753a723d21ac13ecc857e333fa [file] [log] [blame]
package com.fasterxml.jackson.databind.deser.filter;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
// Test(s) to verify [databind#1440]
public class ProblemHandlerLocation1440Test extends BaseMapTest
{
static class DeserializationProblem {
public List<String> unknownProperties = new ArrayList<>();
public DeserializationProblem() { }
public void addUnknownProperty(final String prop) {
unknownProperties.add(prop);
}
public boolean foundProblems() {
return !unknownProperties.isEmpty();
}
@Override
public String toString() {
return "DeserializationProblem{" +"unknownProperties=" + unknownProperties +'}';
}
}
static class DeserializationProblemLogger extends DeserializationProblemHandler {
public DeserializationProblem probs = new DeserializationProblem();
public List<String> problems() {
return probs.unknownProperties;
}
@Override
public boolean handleUnknownProperty(final DeserializationContext ctxt, final JsonParser p,
JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName)
throws IOException
{
final JsonStreamContext parsingContext = p.getParsingContext();
final List<String> pathList = new ArrayList<>();
addParent(parsingContext, pathList);
Collections.reverse(pathList);
final String path = _join(".", pathList) + "#" + propertyName;
probs.addUnknownProperty(path);
p.skipChildren();
return true;
}
static String _join(String sep, Collection<String> parts) {
StringBuilder sb = new StringBuilder();
for (String part : parts) {
if (sb.length() > 0) {
sb.append(sep);
}
sb.append(part);
}
return sb.toString();
}
private void addParent(final JsonStreamContext streamContext, final List<String> pathList) {
if (streamContext != null && streamContext.getCurrentName() != null) {
pathList.add(streamContext.getCurrentName());
addParent(streamContext.getParent(), pathList);
}
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
static class Activity {
public ActivityEntity actor;
public String verb;
public ActivityEntity object;
public ActivityEntity target;
@JsonCreator
public Activity(@JsonProperty("actor") final ActivityEntity actor, @JsonProperty("object") final ActivityEntity object, @JsonProperty("target") final ActivityEntity target, @JsonProperty("verb") final String verb) {
this.actor = actor;
this.verb = verb;
this.object = object;
this.target = target;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
static class ActivityEntity {
public String id;
public String type;
public String status;
public String context;
@JsonCreator
public ActivityEntity(@JsonProperty("id") final String id, @JsonProperty("type") final String type, @JsonProperty("status") final String status, @JsonProperty("context") final String context) {
this.id = id;
this.type = type;
this.status = status;
this.context = context;
}
}
/*
/**********************************************************
/* Test methods
/**********************************************************
*/
public void testIncorrectContext() throws Exception
{
// need invalid to trigger problem:
final String invalidInput = aposToQuotes(
"{'actor': {'id': 'actor_id','type': 'actor_type',"
+"'status': 'actor_status','context':'actor_context','invalid_1': 'actor_invalid_1'},"
+"'verb': 'verb','object': {'id': 'object_id','type': 'object_type',"
+"'invalid_2': 'object_invalid_2','status': 'object_status','context': 'object_context'},"
+"'target': {'id': 'target_id','type': 'target_type','invalid_3': 'target_invalid_3',"
+"'invalid_4': 'target_invalid_4','status': 'target_status','context': 'target_context'}}"
);
ObjectMapper mapper = newJsonMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final DeserializationProblemLogger logger = new DeserializationProblemLogger();
mapper.addHandler(logger);
mapper.readValue(invalidInput, Activity.class);
List<String> probs = logger.problems();
assertEquals(4, probs.size());
assertEquals("actor.invalid_1#invalid_1", probs.get(0));
assertEquals("object.invalid_2#invalid_2", probs.get(1));
assertEquals("target.invalid_3#invalid_3", probs.get(2));
assertEquals("target.invalid_4#invalid_4", probs.get(3));
}
}