1 package com.fasterxml.jackson.databind.node; 2 3 import java.io.*; 4 import java.math.BigDecimal; 5 import java.math.BigInteger; 6 import java.util.ArrayList; 7 8 import com.fasterxml.jackson.core.*; 9 import com.fasterxml.jackson.databind.*; 10 import com.fasterxml.jackson.databind.exc.MismatchedInputException; 11 import com.fasterxml.jackson.databind.node.ArrayNode; 12 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 13 import com.fasterxml.jackson.databind.node.TextNode; 14 import com.fasterxml.jackson.databind.node.TreeTraversingParser; 15 import static java.util.Arrays.asList; 16 17 /** 18 * Additional tests for {@link ArrayNode} container class. 19 */ 20 public class ArrayNodeTest 21 extends BaseMapTest 22 { testDirectCreation()23 public void testDirectCreation() throws IOException 24 { 25 ArrayNode n = new ArrayNode(JsonNodeFactory.instance); 26 assertStandardEquals(n); 27 assertFalse(n.elements().hasNext()); 28 assertFalse(n.fieldNames().hasNext()); 29 assertTrue(n.isEmpty()); 30 TextNode text = TextNode.valueOf("x"); 31 n.add(text); 32 assertEquals(1, n.size()); 33 assertFalse(n.isEmpty()); 34 assertFalse(0 == n.hashCode()); 35 assertTrue(n.elements().hasNext()); 36 // no field names for arrays 37 assertFalse(n.fieldNames().hasNext()); 38 assertNull(n.get("x")); // not used with arrays 39 assertTrue(n.path("x").isMissingNode()); 40 assertSame(text, n.get(0)); 41 42 // single element, so: 43 assertFalse(n.has("field")); 44 assertFalse(n.hasNonNull("field")); 45 assertTrue(n.has(0)); 46 assertTrue(n.hasNonNull(0)); 47 assertFalse(n.has(1)); 48 assertFalse(n.hasNonNull(1)); 49 50 // add null node too 51 n.add((JsonNode) null); 52 assertEquals(2, n.size()); 53 assertTrue(n.get(1).isNull()); 54 assertTrue(n.has(1)); 55 assertFalse(n.hasNonNull(1)); 56 // change to text 57 n.set(1, text); 58 assertSame(text, n.get(1)); 59 n.set(0, null); 60 assertTrue(n.get(0).isNull()); 61 62 // and finally, clear it all 63 ArrayNode n2 = new ArrayNode(JsonNodeFactory.instance); 64 n2.add("foobar"); 65 assertFalse(n.equals(n2)); 66 n.addAll(n2); 67 assertEquals(3, n.size()); 68 69 assertFalse(n.get(0).isTextual()); 70 assertNotNull(n.remove(0)); 71 assertEquals(2, n.size()); 72 assertTrue(n.get(0).isTextual()); 73 assertNull(n.remove(-1)); 74 assertNull(n.remove(100)); 75 assertEquals(2, n.size()); 76 77 ArrayList<JsonNode> nodes = new ArrayList<JsonNode>(); 78 nodes.add(text); 79 n.addAll(nodes); 80 assertEquals(3, n.size()); 81 assertNull(n.get(10000)); 82 assertNull(n.remove(-4)); 83 84 TextNode text2 = TextNode.valueOf("b"); 85 n.insert(0, text2); 86 assertEquals(4, n.size()); 87 assertSame(text2, n.get(0)); 88 89 assertNotNull(n.addArray()); 90 assertEquals(5, n.size()); 91 n.addPOJO("foo"); 92 assertEquals(6, n.size()); 93 94 n.removeAll(); 95 assertEquals(0, n.size()); 96 } 97 testDirectCreation2()98 public void testDirectCreation2() throws IOException 99 { 100 JsonNodeFactory f = objectMapper().getNodeFactory(); 101 ArrayList<JsonNode> list = new ArrayList<>(); 102 list.add(f.booleanNode(true)); 103 list.add(f.textNode("foo")); 104 ArrayNode n = new ArrayNode(f, list); 105 assertEquals(2, n.size()); 106 assertTrue(n.get(0).isBoolean()); 107 assertTrue(n.get(1).isTextual()); 108 109 // also, should fail with invalid set attempt 110 try { 111 n.set(2, f.nullNode()); 112 fail("Should not pass"); 113 } catch (IndexOutOfBoundsException e) { 114 verifyException(e, "illegal index"); 115 } 116 n.insert(1, (String) null); 117 assertEquals(3, n.size()); 118 assertTrue(n.get(0).isBoolean()); 119 assertTrue(n.get(1).isNull()); 120 assertTrue(n.get(2).isTextual()); 121 122 n.removeAll(); 123 n.insert(0, (JsonNode) null); 124 assertEquals(1, n.size()); 125 assertTrue(n.get(0).isNull()); 126 } 127 testArrayViaMapper()128 public void testArrayViaMapper() throws Exception 129 { 130 final String JSON = "[[[-0.027512,51.503221],[-0.008497,51.503221],[-0.008497,51.509744],[-0.027512,51.509744]]]"; 131 132 JsonNode n = objectMapper().readTree(JSON); 133 assertNotNull(n); 134 assertTrue(n.isArray()); 135 ArrayNode an = (ArrayNode) n; 136 assertEquals(1, an.size()); 137 ArrayNode an2 = (ArrayNode) n.get(0); 138 assertTrue(an2.isArray()); 139 assertEquals(4, an2.size()); 140 } 141 testAdds()142 public void testAdds() 143 { 144 ArrayNode n = new ArrayNode(JsonNodeFactory.instance); 145 assertNotNull(n.addArray()); 146 assertNotNull(n.addObject()); 147 n.addPOJO("foobar"); 148 n.add(1); 149 n.add(1L); 150 n.add(0.5); 151 n.add(0.5f); 152 n.add(new BigDecimal("0.2")); 153 n.add(BigInteger.TEN); 154 assertEquals(9, n.size()); 155 assertFalse(n.isEmpty()); 156 157 assertNotNull(n.insertArray(0)); 158 assertNotNull(n.insertObject(0)); 159 n.insertPOJO(2, "xxx"); 160 assertEquals(12, n.size()); 161 162 n.insert(0, BigInteger.ONE); 163 n.insert(0, new BigDecimal("0.1")); 164 assertEquals(14, n.size()); 165 } 166 testNullAdds()167 public void testNullAdds() 168 { 169 JsonNodeFactory f = objectMapper().getNodeFactory(); 170 ArrayNode array = f.arrayNode(14); 171 172 array.add((BigDecimal) null); 173 array.add((BigInteger) null); 174 array.add((Boolean) null); 175 array.add((byte[]) null); 176 array.add((Double) null); 177 array.add((Float) null); 178 array.add((Integer) null); 179 array.add((JsonNode) null); 180 array.add((Long) null); 181 array.add((String) null); 182 183 assertEquals(10, array.size()); 184 185 for (JsonNode node : array) { 186 assertTrue(node.isNull()); 187 } 188 } 189 testAddAllWithNullInCollection()190 public void testAddAllWithNullInCollection() 191 { 192 // preparation 193 final ArrayNode array = JsonNodeFactory.instance.arrayNode(); 194 195 // test 196 array.addAll(asList(null, JsonNodeFactory.instance.objectNode())); 197 198 // assertions 199 assertEquals(2, array.size()); 200 201 for (JsonNode node : array) { 202 assertNotNull(node); 203 } 204 assertEquals(NullNode.getInstance(), array.get(0)); 205 } 206 testNullInserts()207 public void testNullInserts() 208 { 209 JsonNodeFactory f = objectMapper().getNodeFactory(); 210 ArrayNode array = f.arrayNode(3); 211 212 array.insert(0, (BigDecimal) null); 213 array.insert(0, (BigInteger) null); 214 array.insert(0, (Boolean) null); 215 // Offsets out of the range are fine; negative become 0; 216 // super big just add at the end 217 array.insert(-56, (byte[]) null); 218 array.insert(0, (Double) null); 219 array.insert(200, (Float) null); 220 array.insert(0, (Integer) null); 221 array.insert(1, (JsonNode) null); 222 array.insert(array.size(), (Long) null); 223 array.insert(1, (String) null); 224 225 assertEquals(10, array.size()); 226 227 for (JsonNode node : array) { 228 assertTrue(node.isNull()); 229 } 230 } 231 testNullChecking()232 public void testNullChecking() 233 { 234 ArrayNode a1 = JsonNodeFactory.instance.arrayNode(); 235 ArrayNode a2 = JsonNodeFactory.instance.arrayNode(); 236 // used to throw NPE before fix: 237 a1.addAll(a2); 238 assertEquals(0, a1.size()); 239 assertEquals(0, a2.size()); 240 241 a2.addAll(a1); 242 assertEquals(0, a1.size()); 243 assertEquals(0, a2.size()); 244 } 245 testNullChecking2()246 public void testNullChecking2() 247 { 248 ObjectMapper mapper = new ObjectMapper(); 249 ArrayNode src = mapper.createArrayNode(); 250 ArrayNode dest = mapper.createArrayNode(); 251 src.add("element"); 252 dest.addAll(src); 253 } 254 testParser()255 public void testParser() throws Exception 256 { 257 ArrayNode n = new ArrayNode(JsonNodeFactory.instance); 258 n.add(123); 259 TreeTraversingParser p = new TreeTraversingParser(n, null); 260 p.setCodec(null); 261 assertNull(p.getCodec()); 262 assertNotNull(p.getParsingContext()); 263 assertTrue(p.getParsingContext().inRoot()); 264 assertNotNull(p.getTokenLocation()); 265 assertNotNull(p.getCurrentLocation()); 266 assertNull(p.getEmbeddedObject()); 267 assertNull(p.currentNode()); 268 269 //assertNull(p.getNumberType()); 270 271 assertToken(JsonToken.START_ARRAY, p.nextToken()); 272 assertNotNull(p.getParsingContext()); 273 assertTrue(p.getParsingContext().inArray()); 274 p.skipChildren(); 275 assertToken(JsonToken.END_ARRAY, p.currentToken()); 276 p.close(); 277 278 p = new TreeTraversingParser(n, null); 279 p.nextToken(); 280 assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); 281 assertEquals(JsonParser.NumberType.INT, p.getNumberType()); 282 p.close(); 283 } 284 testArrayNodeEquality()285 public void testArrayNodeEquality() 286 { 287 ArrayNode n1 = new ArrayNode(null); 288 ArrayNode n2 = new ArrayNode(null); 289 290 assertTrue(n1.equals(n2)); 291 assertTrue(n2.equals(n1)); 292 293 n1.add(TextNode.valueOf("Test")); 294 295 assertFalse(n1.equals(n2)); 296 assertFalse(n2.equals(n1)); 297 298 n2.add(TextNode.valueOf("Test")); 299 300 assertTrue(n1.equals(n2)); 301 assertTrue(n2.equals(n1)); 302 } 303 testSimpleArray()304 public void testSimpleArray() throws Exception 305 { 306 ArrayNode result = objectMapper().createArrayNode(); 307 308 assertTrue(result.isArray()); 309 assertType(result, ArrayNode.class); 310 311 assertFalse(result.isObject()); 312 assertFalse(result.isNumber()); 313 assertFalse(result.isNull()); 314 assertFalse(result.isTextual()); 315 316 // and let's add stuff... 317 result.add(false); 318 result.insertNull(0); 319 320 // should be equal to itself no matter what 321 assertEquals(result, result); 322 assertFalse(result.equals(null)); // but not to null 323 324 // plus see that we can access stuff 325 assertEquals(NullNode.instance, result.path(0)); 326 assertEquals(NullNode.instance, result.get(0)); 327 assertEquals(BooleanNode.FALSE, result.path(1)); 328 assertEquals(BooleanNode.FALSE, result.get(1)); 329 assertEquals(2, result.size()); 330 331 assertNull(result.get(-1)); 332 assertNull(result.get(2)); 333 JsonNode missing = result.path(2); 334 assertTrue(missing.isMissingNode()); 335 assertTrue(result.path(-100).isMissingNode()); 336 337 // then construct and compare 338 ArrayNode array2 = objectMapper().createArrayNode(); 339 array2.addNull(); 340 array2.add(false); 341 assertEquals(result, array2); 342 343 // plus remove entries 344 JsonNode rm1 = array2.remove(0); 345 assertEquals(NullNode.instance, rm1); 346 assertEquals(1, array2.size()); 347 assertEquals(BooleanNode.FALSE, array2.get(0)); 348 assertFalse(result.equals(array2)); 349 350 JsonNode rm2 = array2.remove(0); 351 assertEquals(BooleanNode.FALSE, rm2); 352 assertEquals(0, array2.size()); 353 } 354 testSimpleMismatch()355 public void testSimpleMismatch() throws Exception 356 { 357 ObjectMapper mapper = objectMapper(); 358 try { 359 mapper.readValue(" 123 ", ArrayNode.class); 360 fail("Should not pass"); 361 } catch (MismatchedInputException e) { 362 verifyException(e, "from Integer value (token `JsonToken.VALUE_NUMBER_INT`)"); 363 } 364 } 365 } 366