1 package com.fasterxml.jackson.databind.seq; 2 3 import java.io.*; 4 import java.util.*; 5 6 import com.fasterxml.jackson.core.*; 7 import com.fasterxml.jackson.core.type.TypeReference; 8 9 import com.fasterxml.jackson.databind.BaseMapTest; 10 import com.fasterxml.jackson.databind.MappingIterator; 11 import com.fasterxml.jackson.databind.ObjectMapper; 12 import com.fasterxml.jackson.databind.ObjectReader; 13 14 @SuppressWarnings("resource") 15 public class ReadValuesTest extends BaseMapTest 16 { 17 static class Bean { 18 public int a; 19 20 @Override equals(Object o)21 public boolean equals(Object o) { 22 if (o == null || o.getClass() != getClass()) return false; 23 Bean other = (Bean) o; 24 return other.a == this.a; 25 } hashCode()26 @Override public int hashCode() { return a; } 27 } 28 29 /* 30 /********************************************************** 31 /* Unit tests; root-level value sequences via Mapper 32 /********************************************************** 33 */ 34 35 private enum Source { 36 STRING, 37 INPUT_STREAM, 38 READER, 39 BYTE_ARRAY, 40 BYTE_ARRAY_OFFSET 41 ; 42 } 43 44 private final ObjectMapper MAPPER = new ObjectMapper(); 45 testRootBeans()46 public void testRootBeans() throws Exception 47 { 48 for (Source src : Source.values()) { 49 _testRootBeans(src); 50 } 51 } 52 _iterator(ObjectReader r, String json, Source srcType)53 private <T> MappingIterator<T> _iterator(ObjectReader r, 54 String json, 55 Source srcType) throws IOException 56 { 57 switch (srcType) { 58 case BYTE_ARRAY: 59 return r.readValues(json.getBytes("UTF-8")); 60 case BYTE_ARRAY_OFFSET: 61 { 62 ByteArrayOutputStream out = new ByteArrayOutputStream(); 63 out.write(0); 64 out.write(0); 65 out.write(0); 66 out.write(json.getBytes("UTF-8")); 67 out.write(0); 68 out.write(0); 69 out.write(0); 70 byte[] b = out.toByteArray(); 71 return r.readValues(b, 3, b.length-6); 72 } 73 case INPUT_STREAM: 74 return r.readValues(new ByteArrayInputStream(json.getBytes("UTF-8"))); 75 case READER: 76 return r.readValues(new StringReader(json)); 77 case STRING: 78 default: 79 return r.readValues(json); 80 } 81 } 82 _testRootBeans(Source srcType)83 private void _testRootBeans(Source srcType) throws Exception 84 { 85 final String JSON = "{\"a\":3}{\"a\":27} "; 86 87 MappingIterator<Bean> it = _iterator(MAPPER.readerFor(Bean.class), 88 JSON, srcType); 89 assertNotNull(it.getCurrentLocation()); 90 assertTrue(it.hasNext()); 91 Bean b = it.next(); 92 assertEquals(3, b.a); 93 assertTrue(it.hasNext()); 94 b = it.next(); 95 assertEquals(27, b.a); 96 assertFalse(it.hasNext()); 97 it.close(); 98 99 // Also, test 'readAll()' 100 it = _iterator(MAPPER.readerFor(Bean.class), JSON, srcType); 101 List<Bean> all = it.readAll(); 102 assertEquals(2, all.size()); 103 it.close(); 104 105 it = _iterator(MAPPER.readerFor(Bean.class), "{\"a\":3}{\"a\":3}", srcType); 106 Set<Bean> set = it.readAll(new HashSet<Bean>()); 107 assertEquals(HashSet.class, set.getClass()); 108 assertEquals(1, set.size()); 109 assertEquals(3, set.iterator().next().a); 110 it.close(); 111 } 112 testRootBeansInArray()113 public void testRootBeansInArray() throws Exception 114 { 115 final String JSON = "[{\"a\":6}, {\"a\":-7}]"; 116 117 MappingIterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(JSON); 118 119 assertNotNull(it.getCurrentLocation()); 120 assertTrue(it.hasNext()); 121 Bean b = it.next(); 122 assertEquals(6, b.a); 123 assertTrue(it.hasNext()); 124 b = it.next(); 125 assertEquals(-7, b.a); 126 assertFalse(it.hasNext()); 127 it.close(); 128 129 // Also, test 'readAll()' 130 it = MAPPER.readerFor(Bean.class).readValues(JSON); 131 List<Bean> all = it.readAll(); 132 assertEquals(2, all.size()); 133 it.close(); 134 135 it = MAPPER.readerFor(Bean.class).readValues("[{\"a\":4},{\"a\":4}]"); 136 Set<Bean> set = it.readAll(new HashSet<Bean>()); 137 assertEquals(HashSet.class, set.getClass()); 138 assertEquals(1, set.size()); 139 assertEquals(4, set.iterator().next().a); 140 } 141 testRootMaps()142 public void testRootMaps() throws Exception 143 { 144 final String JSON = "{\"a\":3}{\"a\":27} "; 145 Iterator<Map<?,?>> it = MAPPER.readerFor(Map.class).readValues(JSON); 146 147 assertNotNull(((MappingIterator<?>) it).getCurrentLocation()); 148 assertTrue(it.hasNext()); 149 Map<?,?> map = it.next(); 150 assertEquals(1, map.size()); 151 assertEquals(Integer.valueOf(3), map.get("a")); 152 assertTrue(it.hasNext()); 153 assertNotNull(((MappingIterator<?>) it).getCurrentLocation()); 154 map = it.next(); 155 assertEquals(1, map.size()); 156 assertEquals(Integer.valueOf(27), map.get("a")); 157 assertFalse(it.hasNext()); 158 } 159 160 /* 161 /********************************************************** 162 /* Unit tests; root-level value sequences via JsonParser 163 /********************************************************** 164 */ 165 testRootBeansWithParser()166 public void testRootBeansWithParser() throws Exception 167 { 168 final String JSON = "{\"a\":3}{\"a\":27} "; 169 JsonParser jp = MAPPER.createParser(JSON); 170 171 Iterator<Bean> it = jp.readValuesAs(Bean.class); 172 173 assertTrue(it.hasNext()); 174 Bean b = it.next(); 175 assertEquals(3, b.a); 176 assertTrue(it.hasNext()); 177 b = it.next(); 178 assertEquals(27, b.a); 179 assertFalse(it.hasNext()); 180 } 181 testRootArraysWithParser()182 public void testRootArraysWithParser() throws Exception 183 { 184 final String JSON = "[1][3]"; 185 JsonParser jp = MAPPER.createParser(JSON); 186 187 // NOTE: We must point JsonParser to the first element; if we tried to 188 // use "managed" accessor, it would try to advance past START_ARRAY. 189 assertToken(JsonToken.START_ARRAY, jp.nextToken()); 190 191 Iterator<int[]> it = MAPPER.readerFor(int[].class).readValues(jp); 192 assertTrue(it.hasNext()); 193 int[] array = it.next(); 194 assertEquals(1, array.length); 195 assertEquals(1, array[0]); 196 assertTrue(it.hasNext()); 197 array = it.next(); 198 assertEquals(1, array.length); 199 assertEquals(3, array[0]); 200 assertFalse(it.hasNext()); 201 } 202 testHasNextWithEndArray()203 public void testHasNextWithEndArray() throws Exception { 204 final String JSON = "[1,3]"; 205 JsonParser jp = MAPPER.createParser(JSON); 206 207 // NOTE: We must point JsonParser to the first element; if we tried to 208 // use "managed" accessor, it would try to advance past START_ARRAY. 209 assertToken(JsonToken.START_ARRAY, jp.nextToken()); 210 jp.nextToken(); 211 212 Iterator<Integer> it = MAPPER.readerFor(Integer.class).readValues(jp); 213 assertTrue(it.hasNext()); 214 int value = it.next(); 215 assertEquals(1, value); 216 assertTrue(it.hasNext()); 217 value = it.next(); 218 assertEquals(3, value); 219 assertFalse(it.hasNext()); 220 assertFalse(it.hasNext()); 221 } 222 testHasNextWithEndArrayManagedParser()223 public void testHasNextWithEndArrayManagedParser() throws Exception { 224 final String JSON = "[1,3]"; 225 226 Iterator<Integer> it = MAPPER.readerFor(Integer.class).readValues(JSON); 227 assertTrue(it.hasNext()); 228 int value = it.next(); 229 assertEquals(1, value); 230 assertTrue(it.hasNext()); 231 value = it.next(); 232 assertEquals(3, value); 233 assertFalse(it.hasNext()); 234 assertFalse(it.hasNext()); 235 } 236 237 /* 238 /********************************************************** 239 /* Unit tests; non-root arrays 240 /********************************************************** 241 */ 242 testNonRootBeans()243 public void testNonRootBeans() throws Exception 244 { 245 final String JSON = "{\"leaf\":[{\"a\":3},{\"a\":27}]}"; 246 JsonParser jp = MAPPER.createParser(JSON); 247 assertToken(JsonToken.START_OBJECT, jp.nextToken()); 248 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); 249 assertToken(JsonToken.START_ARRAY, jp.nextToken()); 250 // can either advance to first START_OBJECT, or clear current token; 251 // explicitly passed JsonParser MUST point to the first token of 252 // the first element 253 assertToken(JsonToken.START_OBJECT, jp.nextToken()); 254 255 Iterator<Bean> it = MAPPER.readerFor(Bean.class).readValues(jp); 256 257 assertTrue(it.hasNext()); 258 Bean b = it.next(); 259 assertEquals(3, b.a); 260 assertTrue(it.hasNext()); 261 b = it.next(); 262 assertEquals(27, b.a); 263 assertFalse(it.hasNext()); 264 jp.close(); 265 } 266 testNonRootMapsWithParser()267 public void testNonRootMapsWithParser() throws Exception 268 { 269 final String JSON = "[{\"a\":3},{\"a\":27}]"; 270 JsonParser jp = MAPPER.createParser(JSON); 271 assertToken(JsonToken.START_ARRAY, jp.nextToken()); 272 273 // can either advance to first START_OBJECT, or clear current token; 274 // explicitly passed JsonParser MUST point to the first token of 275 // the first element 276 jp.clearCurrentToken(); 277 278 Iterator<Map<?,?>> it = MAPPER.readerFor(Map.class).readValues(jp); 279 280 assertTrue(it.hasNext()); 281 Map<?,?> map = it.next(); 282 assertEquals(1, map.size()); 283 assertEquals(Integer.valueOf(3), map.get("a")); 284 assertTrue(it.hasNext()); 285 map = it.next(); 286 assertEquals(1, map.size()); 287 assertEquals(Integer.valueOf(27), map.get("a")); 288 assertFalse(it.hasNext()); 289 jp.close(); 290 } 291 testNonRootMapsWithObjectReader()292 public void testNonRootMapsWithObjectReader() throws Exception 293 { 294 String JSON = "[{ \"hi\": \"ho\", \"neighbor\": \"Joe\" },\n" 295 +"{\"boy\": \"howdy\", \"huh\": \"what\"}]"; 296 final MappingIterator<Map<String, Object>> iterator = MAPPER 297 .reader() 298 .forType(new TypeReference<Map<String, Object>>(){}) 299 .readValues(JSON); 300 301 Map<String,Object> map; 302 assertTrue(iterator.hasNext()); 303 map = iterator.nextValue(); 304 assertEquals(2, map.size()); 305 assertTrue(iterator.hasNext()); 306 map = iterator.nextValue(); 307 assertEquals(2, map.size()); 308 assertFalse(iterator.hasNext()); 309 } 310 testNonRootArraysUsingParser()311 public void testNonRootArraysUsingParser() throws Exception 312 { 313 final String JSON = "[[1],[3]]"; 314 JsonParser p = MAPPER.createParser(JSON); 315 assertToken(JsonToken.START_ARRAY, p.nextToken()); 316 317 // Important: as of 2.1, START_ARRAY can only be skipped if the 318 // target type is NOT a Collection or array Java type. 319 // So we have to explicitly skip it in this particular case. 320 assertToken(JsonToken.START_ARRAY, p.nextToken()); 321 322 Iterator<int[]> it = MAPPER.readValues(p, int[].class); 323 324 assertTrue(it.hasNext()); 325 int[] array = it.next(); 326 assertEquals(1, array.length); 327 assertEquals(1, array[0]); 328 assertTrue(it.hasNext()); 329 array = it.next(); 330 assertEquals(1, array.length); 331 assertEquals(3, array[0]); 332 assertFalse(it.hasNext()); 333 p.close(); 334 } 335 testEmptyIterator()336 public void testEmptyIterator() throws Exception 337 { 338 MappingIterator<Object> empty = MappingIterator.emptyIterator(); 339 340 assertFalse(empty.hasNext()); 341 assertFalse(empty.hasNextValue()); 342 343 empty.close(); 344 } 345 } 346