package com.fasterxml.jackson.databind;
import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class ObjectReaderTest extends BaseMapTest
{
final ObjectMapper MAPPER = new ObjectMapper();
static class POJO {
public Map<String, Object> name;
}
public void testSimpleViaParser() throws Exception
{
final String JSON = "[1]";
JsonParser p = MAPPER.getFactory().createParser(JSON);
Object ob = MAPPER.readerFor(Object.class)
.readValue(p);
p.close();
assertTrue(ob instanceof List<?>);
}
public void testSimpleAltSources() throws Exception
{
final String JSON = "[1]";
final byte[] BYTES = JSON.getBytes("UTF-8");
Object ob = MAPPER.readerFor(Object.class)
.readValue(BYTES);
assertTrue(ob instanceof List<?>);
ob = MAPPER.readerFor(Object.class)
.readValue(BYTES, 0, BYTES.length);
assertTrue(ob instanceof List<?>);
assertEquals(1, ((List<?>) ob).size());
}
public void testParserFeatures() throws Exception
{
final String JSON = "[ /* foo */ 7 ]";
// default won't accept comments, let's change that:
ObjectReader reader = MAPPER.readerFor(int[].class)
.with(JsonParser.Feature.ALLOW_COMMENTS);
int[] value = reader.readValue(JSON);
assertNotNull(value);
assertEquals(1, value.length);
assertEquals(7, value[0]);
// but also can go back
try {
reader.without(JsonParser.Feature.ALLOW_COMMENTS).readValue(JSON);
fail("Should not have passed");
} catch (JsonProcessingException e) {
verifyException(e, "foo");
}
}
public void testNoPointerLoading() throws Exception {
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
JsonNode tree = MAPPER.readTree(source);
JsonNode node = tree.at("/foo/bar/caller");
POJO pojo = MAPPER.treeToValue(node, POJO.class);
assertTrue(pojo.name.containsKey("value"));
assertEquals(1234, pojo.name.get("value"));
}
public void testPointerLoading() throws Exception {
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
POJO pojo = reader.readValue(source);
assertTrue(pojo.name.containsKey("value"));
assertEquals(1234, pojo.name.get("value"));
}
public void testPointerLoadingAsJsonNode() throws Exception {
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
ObjectReader reader = MAPPER.readerFor(POJO.class).at(JsonPointer.compile("/foo/bar/caller"));
JsonNode node = reader.readTree(source);
assertTrue(node.has("name"));
assertEquals("{\"value\":1234}", node.get("name").toString());
}
public void testPointerLoadingMappingIteratorOne() throws Exception {
final String source = "{\"foo\":{\"bar\":{\"caller\":{\"name\":{\"value\":1234}}}}}";
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
MappingIterator<POJO> itr = reader.readValues(source);
POJO pojo = itr.next();
assertTrue(pojo.name.containsKey("value"));
assertEquals(1234, pojo.name.get("value"));
assertFalse(itr.hasNext());
itr.close();
}
public void testPointerLoadingMappingIteratorMany() throws Exception {
final String source = "{\"foo\":{\"bar\":{\"caller\":[{\"name\":{\"value\":1234}}, {\"name\":{\"value\":5678}}]}}}";
ObjectReader reader = MAPPER.readerFor(POJO.class).at("/foo/bar/caller");
MappingIterator<POJO> itr = reader.readValues(source);
POJO pojo = itr.next();
assertTrue(pojo.name.containsKey("value"));
assertEquals(1234, pojo.name.get("value"));
assertTrue(itr.hasNext());
pojo = itr.next();
assertNotNull(pojo.name);
assertTrue(pojo.name.containsKey("value"));
assertEquals(5678, pojo.name.get("value"));
assertFalse(itr.hasNext());
itr.close();
}
public void testNodeHandling() throws Exception
{
JsonNodeFactory nodes = new JsonNodeFactory(true);
ObjectReader r = MAPPER.reader().with(nodes);
// but also no further changes if attempting again
assertSame(r, r.with(nodes));
assertTrue(r.createArrayNode().isArray());
assertTrue(r.createObjectNode().isObject());
}
public void testFeatureSettings() throws Exception
{
ObjectReader r = MAPPER.reader();
assertFalse(r.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES));
assertFalse(r.isEnabled(JsonParser.Feature.ALLOW_COMMENTS));
r = r.withoutFeatures(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
assertFalse(r.isEnabled(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES));
assertFalse(r.isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE));
r = r.withFeatures(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
assertTrue(r.isEnabled(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES));
assertTrue(r.isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE));
// alternative method too... can't recall why two
assertSame(r, r.with(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
DeserializationFeature.FAIL_ON_INVALID_SUBTYPE));
}
public void testMiscSettings() throws Exception
{
ObjectReader r = MAPPER.reader();
assertSame(MAPPER.getFactory(), r.getFactory());
JsonFactory f = new JsonFactory();
r = r.with(f);
assertSame(f, r.getFactory());
assertSame(r, r.with(f));
assertNotNull(r.getTypeFactory());
assertNull(r.getInjectableValues());
r = r.withAttributes(Collections.emptyMap());
ContextAttributes attrs = r.getAttributes();
assertNotNull(attrs);
assertNull(attrs.getAttribute("abc"));
assertSame(r, r.withoutAttribute("foo"));
ObjectReader newR = r.forType(MAPPER.constructType(String.class));
assertNotSame(r, newR);
assertSame(newR, newR.forType(String.class));
DeserializationProblemHandler probH = new DeserializationProblemHandler() {
};
newR = r.withHandler(probH);
assertNotSame(r, newR);
assertSame(newR, newR.withHandler(probH));
r = newR;
}
@SuppressWarnings("deprecation")
public void testDeprecatedSettings() throws Exception
{
ObjectReader r = MAPPER.reader();
// and deprecated variants
ObjectReader newR = r.forType(MAPPER.constructType(String.class));
assertSame(newR, newR.withType(String.class));
assertSame(newR, newR.withType(MAPPER.constructType(String.class)));
newR = newR.withRootName(PropertyName.construct("foo"));
assertNotSame(r, newR);
assertSame(newR, newR.withRootName(PropertyName.construct("foo")));
}
public void testNoPrefetch() throws Exception
{
ObjectReader r = MAPPER.reader()
.without(DeserializationFeature.EAGER_DESERIALIZER_FETCH);
Number n = r.forType(Integer.class).readValue("123 ");
assertEquals(Integer.valueOf(123), n);
}
/*
/**********************************************************
/* Test methods, ObjectCodec
/**********************************************************
*/
public void testTreeToValue() throws Exception
{
ArrayNode n = MAPPER.createArrayNode();
n.add("xyz");
ObjectReader r = MAPPER.readerFor(String.class);
List<?> list = r.treeToValue(n, List.class);
assertEquals(1, list.size());
}
public void testCodecUnsupportedWrites() throws Exception
{
ObjectReader r = MAPPER.readerFor(String.class);
JsonGenerator g = MAPPER.getFactory().createGenerator(new StringWriter());
ObjectNode n = MAPPER.createObjectNode();
try {
r.writeTree(g, n);
fail("Should not pass");
} catch (UnsupportedOperationException e) {
;
}
try {
r.writeValue(g, "Foo");
fail("Should not pass");
} catch (UnsupportedOperationException e) {
;
}
g.close();
g.close();
}
/*
/**********************************************************
/* Test methods, failures, other
/**********************************************************
*/
public void testMissingType() throws Exception
{
ObjectReader r = MAPPER.reader();
try {
r.readValue("1");
fail("Should not pass");
} catch (JsonMappingException e) {
verifyException(e, "No value type configured");
}
}
public void testSchema() throws Exception
{
ObjectReader r = MAPPER.readerFor(String.class);
// Ok to try to set `null` schema, always:
r = r.with((FormatSchema) null);
try {
// but not schema that doesn't match format (no schema exists for json)
r = r.with(new BogusSchema())
.readValue(quote("foo"));
fail("Should not pass");
} catch (IllegalArgumentException e) {
verifyException(e, "Can not use FormatSchema");
}
}
}