| package com.fasterxml.jackson.databind.seq; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| import com.fasterxml.jackson.core.*; |
| import com.fasterxml.jackson.core.type.TypeReference; |
| |
| import com.fasterxml.jackson.databind.BaseMapTest; |
| import com.fasterxml.jackson.databind.MappingIterator; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.ObjectReader; |
| |
| @SuppressWarnings("resource") |
| public class ReadValuesTest extends BaseMapTest |
| { |
| static class Bean { |
| public int a; |
| |
| @Override |
| public boolean equals(Object o) { |
| if (o == null || o.getClass() != getClass()) return false; |
| Bean other = (Bean) o; |
| return other.a == this.a; |
| } |
| @Override public int hashCode() { return a; } |
| } |
| |
| /* |
| /********************************************************** |
| /* Unit tests; root-level value sequences via Mapper |
| /********************************************************** |
| */ |
| |
| private enum Source { |
| STRING, |
| INPUT_STREAM, |
| READER, |
| BYTE_ARRAY, |
| BYTE_ARRAY_OFFSET |
| ; |
| } |
| |
| private final ObjectMapper MAPPER = new ObjectMapper(); |
| |
| public void testRootBeans() throws Exception |
| { |
| for (Source src : Source.values()) { |
| _testRootBeans(src); |
| } |
| } |
| |
| private <T> MappingIterator<T> _iterator(ObjectReader r, |
| String json, |
| Source srcType) throws IOException |
| { |
| switch (srcType) { |
| case BYTE_ARRAY: |
| return r.readValues(json.getBytes("UTF-8")); |
| case BYTE_ARRAY_OFFSET: |
| { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| out.write(0); |
| out.write(0); |
| out.write(0); |
| out.write(json.getBytes("UTF-8")); |
| out.write(0); |
| out.write(0); |
| out.write(0); |
| byte[] b = out.toByteArray(); |
| return r.readValues(b, 3, b.length-6); |
| } |
| case INPUT_STREAM: |
| return r.readValues(new ByteArrayInputStream(json.getBytes("UTF-8"))); |
| case READER: |
| return r.readValues(new StringReader(json)); |
| case STRING: |
| default: |
| return r.readValues(json); |
| } |
| } |
| |
| private void _testRootBeans(Source srcType) throws Exception |
| { |
| final String JSON = "{\"a\":3}{\"a\":27} "; |
| |
| MappingIterator<Bean> it = _iterator(MAPPER.readerFor(Bean.class), |
| JSON, srcType); |
| assertNotNull(it.getCurrentLocation()); |
| assertTrue(it.hasNext()); |
| Bean b = it.next(); |
| assertEquals(3, b.a); |
| assertTrue(it.hasNext()); |
| b = it.next(); |
| assertEquals(27, b.a); |
| assertFalse(it.hasNext()); |
| it.close(); |
| |
| // Also, test 'readAll()' |
| it = _iterator(MAPPER.readerFor(Bean.class), JSON, srcType); |
| List<Bean> all = it.readAll(); |
| assertEquals(2, all.size()); |
| it.close(); |
| |
| it = _iterator(MAPPER.readerFor(Bean.class), "{\"a\":3}{\"a\":3}", srcType); |
| Set<Bean> set = it.readAll(new HashSet<Bean>()); |
| assertEquals(HashSet.class, set.getClass()); |
| assertEquals(1, set.size()); |
| assertEquals(3, set.iterator().next().a); |
| it.close(); |
| } |
| |
| public void testRootBeansInArray() throws Exception |
| { |
| final String JSON = "[{\"a\":6}, {\"a\":-7}]"; |
| |
| MappingIterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(JSON); |
| |
| assertNotNull(it.getCurrentLocation()); |
| assertTrue(it.hasNext()); |
| Bean b = it.next(); |
| assertEquals(6, b.a); |
| assertTrue(it.hasNext()); |
| b = it.next(); |
| assertEquals(-7, b.a); |
| assertFalse(it.hasNext()); |
| it.close(); |
| |
| // Also, test 'readAll()' |
| it = MAPPER.readerFor(Bean.class).readValues(JSON); |
| List<Bean> all = it.readAll(); |
| assertEquals(2, all.size()); |
| it.close(); |
| |
| it = MAPPER.readerFor(Bean.class).readValues("[{\"a\":4},{\"a\":4}]"); |
| Set<Bean> set = it.readAll(new HashSet<Bean>()); |
| assertEquals(HashSet.class, set.getClass()); |
| assertEquals(1, set.size()); |
| assertEquals(4, set.iterator().next().a); |
| } |
| |
| public void testRootMaps() throws Exception |
| { |
| final String JSON = "{\"a\":3}{\"a\":27} "; |
| Iterator<Map<?,?>> it = MAPPER.readerFor(Map.class).readValues(JSON); |
| |
| assertNotNull(((MappingIterator<?>) it).getCurrentLocation()); |
| assertTrue(it.hasNext()); |
| Map<?,?> map = it.next(); |
| assertEquals(1, map.size()); |
| assertEquals(Integer.valueOf(3), map.get("a")); |
| assertTrue(it.hasNext()); |
| assertNotNull(((MappingIterator<?>) it).getCurrentLocation()); |
| map = it.next(); |
| assertEquals(1, map.size()); |
| assertEquals(Integer.valueOf(27), map.get("a")); |
| assertFalse(it.hasNext()); |
| } |
| |
| /* |
| /********************************************************** |
| /* Unit tests; root-level value sequences via JsonParser |
| /********************************************************** |
| */ |
| |
| public void testRootBeansWithParser() throws Exception |
| { |
| final String JSON = "{\"a\":3}{\"a\":27} "; |
| JsonParser jp = MAPPER.getFactory().createParser(JSON); |
| |
| Iterator<Bean> it = jp.readValuesAs(Bean.class); |
| |
| assertTrue(it.hasNext()); |
| Bean b = it.next(); |
| assertEquals(3, b.a); |
| assertTrue(it.hasNext()); |
| b = it.next(); |
| assertEquals(27, b.a); |
| assertFalse(it.hasNext()); |
| } |
| |
| public void testRootArraysWithParser() throws Exception |
| { |
| final String JSON = "[1][3]"; |
| JsonParser jp = MAPPER.getFactory().createParser(JSON); |
| |
| // NOTE: We must point JsonParser to the first element; if we tried to |
| // use "managed" accessor, it would try to advance past START_ARRAY. |
| assertToken(JsonToken.START_ARRAY, jp.nextToken()); |
| |
| Iterator<int[]> it = MAPPER.readerFor(int[].class).readValues(jp); |
| assertTrue(it.hasNext()); |
| int[] array = it.next(); |
| assertEquals(1, array.length); |
| assertEquals(1, array[0]); |
| assertTrue(it.hasNext()); |
| array = it.next(); |
| assertEquals(1, array.length); |
| assertEquals(3, array[0]); |
| assertFalse(it.hasNext()); |
| } |
| |
| public void testHasNextWithEndArray() throws Exception { |
| final String JSON = "[1,3]"; |
| JsonParser jp = MAPPER.getFactory().createParser(JSON); |
| |
| // NOTE: We must point JsonParser to the first element; if we tried to |
| // use "managed" accessor, it would try to advance past START_ARRAY. |
| assertToken(JsonToken.START_ARRAY, jp.nextToken()); |
| jp.nextToken(); |
| |
| Iterator<Integer> it = MAPPER.readerFor(Integer.class).readValues(jp); |
| assertTrue(it.hasNext()); |
| int value = it.next(); |
| assertEquals(1, value); |
| assertTrue(it.hasNext()); |
| value = it.next(); |
| assertEquals(3, value); |
| assertFalse(it.hasNext()); |
| assertFalse(it.hasNext()); |
| } |
| |
| public void testHasNextWithEndArrayManagedParser() throws Exception { |
| final String JSON = "[1,3]"; |
| |
| Iterator<Integer> it = MAPPER.readerFor(Integer.class).readValues(JSON); |
| assertTrue(it.hasNext()); |
| int value = it.next(); |
| assertEquals(1, value); |
| assertTrue(it.hasNext()); |
| value = it.next(); |
| assertEquals(3, value); |
| assertFalse(it.hasNext()); |
| assertFalse(it.hasNext()); |
| } |
| |
| /* |
| /********************************************************** |
| /* Unit tests; non-root arrays |
| /********************************************************** |
| */ |
| |
| public void testNonRootBeans() throws Exception |
| { |
| final String JSON = "{\"leaf\":[{\"a\":3},{\"a\":27}]}"; |
| JsonParser jp = MAPPER.getFactory().createParser(JSON); |
| assertToken(JsonToken.START_OBJECT, jp.nextToken()); |
| assertToken(JsonToken.FIELD_NAME, jp.nextToken()); |
| assertToken(JsonToken.START_ARRAY, jp.nextToken()); |
| // can either advance to first START_OBJECT, or clear current token; |
| // explicitly passed JsonParser MUST point to the first token of |
| // the first element |
| assertToken(JsonToken.START_OBJECT, jp.nextToken()); |
| |
| Iterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(jp); |
| |
| assertTrue(it.hasNext()); |
| Bean b = it.next(); |
| assertEquals(3, b.a); |
| assertTrue(it.hasNext()); |
| b = it.next(); |
| assertEquals(27, b.a); |
| assertFalse(it.hasNext()); |
| jp.close(); |
| } |
| |
| public void testNonRootMapsWithParser() throws Exception |
| { |
| final String JSON = "[{\"a\":3},{\"a\":27}]"; |
| JsonParser jp = MAPPER.getFactory().createParser(JSON); |
| assertToken(JsonToken.START_ARRAY, jp.nextToken()); |
| |
| // can either advance to first START_OBJECT, or clear current token; |
| // explicitly passed JsonParser MUST point to the first token of |
| // the first element |
| jp.clearCurrentToken(); |
| |
| Iterator<Map<?,?>> it = MAPPER.readerFor(Map.class).readValues(jp); |
| |
| assertTrue(it.hasNext()); |
| Map<?,?> map = it.next(); |
| assertEquals(1, map.size()); |
| assertEquals(Integer.valueOf(3), map.get("a")); |
| assertTrue(it.hasNext()); |
| map = it.next(); |
| assertEquals(1, map.size()); |
| assertEquals(Integer.valueOf(27), map.get("a")); |
| assertFalse(it.hasNext()); |
| jp.close(); |
| } |
| |
| public void testNonRootMapsWithObjectReader() throws Exception |
| { |
| String JSON = "[{ \"hi\": \"ho\", \"neighbor\": \"Joe\" },\n" |
| +"{\"boy\": \"howdy\", \"huh\": \"what\"}]"; |
| final MappingIterator<Map<String, Object>> iterator = MAPPER |
| .reader() |
| .forType(new TypeReference<Map<String, Object>>(){}) |
| .readValues(JSON); |
| |
| Map<String,Object> map; |
| assertTrue(iterator.hasNext()); |
| map = iterator.nextValue(); |
| assertEquals(2, map.size()); |
| assertTrue(iterator.hasNext()); |
| map = iterator.nextValue(); |
| assertEquals(2, map.size()); |
| assertFalse(iterator.hasNext()); |
| } |
| |
| public void testNonRootArraysUsingParser() throws Exception |
| { |
| final String JSON = "[[1],[3]]"; |
| JsonParser p = MAPPER.getFactory().createParser(JSON); |
| assertToken(JsonToken.START_ARRAY, p.nextToken()); |
| |
| // Important: as of 2.1, START_ARRAY can only be skipped if the |
| // target type is NOT a Collection or array Java type. |
| // So we have to explicitly skip it in this particular case. |
| assertToken(JsonToken.START_ARRAY, p.nextToken()); |
| |
| Iterator<int[]> it = MAPPER.readValues(p, int[].class); |
| |
| assertTrue(it.hasNext()); |
| int[] array = it.next(); |
| assertEquals(1, array.length); |
| assertEquals(1, array[0]); |
| assertTrue(it.hasNext()); |
| array = it.next(); |
| assertEquals(1, array.length); |
| assertEquals(3, array[0]); |
| assertFalse(it.hasNext()); |
| p.close(); |
| } |
| } |