Skip to content

Commit 7a48952

Browse files
committed
Complete initial implementation; passes tests added so far
1 parent cdd66ea commit 7a48952

File tree

3 files changed

+58
-102
lines changed

3 files changed

+58
-102
lines changed

src/main/java/com/fasterxml/jackson/databind/node/ArrayNode.java

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -91,53 +91,47 @@ protected ObjectNode _withObject(JsonPointer origPtr,
9191
}
9292
}
9393
// Either way; must replace or add a new property
94-
return _withObjectCreateTail(currentPtr, preferIndex);
95-
}
96-
97-
protected ObjectNode _withObjectCreateTail(JsonPointer tail, boolean preferIndex)
98-
{
99-
// !!! TBI
100-
if (true) {
101-
throw new Error("Need to create tail for: "+tail);
102-
}
103-
return null;
94+
return _withObjectAddTailElement(currentPtr, preferIndex);
10495
}
10596

106-
/*
107-
@Override
108-
protected ObjectNode _withObjectCreatePath(JsonPointer origPtr,
109-
JsonPointer currentPtr,
110-
OverwriteMode overwriteMode, boolean preferIndex)
97+
protected ObjectNode _withObjectAddTailElement(JsonPointer tail, boolean preferIndex)
11198
{
112-
// With Arrays, bit different; the first entry needs to be index
113-
if (!currentPtr.mayMatchElement()) {
114-
return _reportWrongNodeType(
115-
"`JsonPointer` path \"%s\" must have index for `ArrayNode`; instead has property \"%s\"",
116-
origPtr.toString(),
117-
getClass().getName(),
118-
currentPtr.getMatchingProperty());
99+
final int index = tail.getMatchingIndex();
100+
tail = tail.tail();
101+
102+
// First: did we complete traversal? If so, easy, we got our result
103+
if (tail.matches()) {
104+
ObjectNode result = this.objectNode();
105+
_withObjectSetArrayElement(index, result);
106+
return result;
119107
}
120108

121-
// And we know there's no node at given index
122-
ObjectNode currentNode = this.objectNode();
123-
// One complication: may need to insert nulls
124-
final int ix = currentPtr.getMatchingIndex();
125-
while (ix >= size()) {
126-
add(nullNode());
109+
// Otherwise, do we want Array or Object
110+
if (preferIndex && tail.mayMatchElement()) { // array!
111+
ArrayNode next = this.arrayNode();
112+
_withObjectSetArrayElement(index, next);
113+
return next._withObjectAddTailElement(tail, preferIndex);
127114
}
128-
set(ix, currentNode);
129-
130-
currentPtr = currentPtr.tail();
131-
132-
// Otherwise loop same as with ObjectNode
133-
while (!currentPtr.matches()) {
134-
// Should we try to build Arrays? For now, nope.
135-
currentNode = currentNode.putObject(currentPtr.getMatchingProperty());
136-
currentPtr = currentPtr.tail();
115+
ObjectNode next = this.objectNode();
116+
_withObjectSetArrayElement(index, next);
117+
return next._withObjectAddTailProperty(tail, preferIndex);
118+
}
119+
120+
protected void _withObjectSetArrayElement(int index, JsonNode value) {
121+
// 27-Jul-2022, tatu: Let's make it less likely anyone OOMs by
122+
// humongous index...
123+
if (index >= size()) {
124+
final int max = _nodeFactory.getMaxElementIndexForInsert();
125+
if (index > max) {
126+
_reportWrongNodeOperation("Too big Array index (%d; max %d) to use for insert with `JsonPointer`",
127+
index, max);
128+
}
129+
while (index >= this.size()) {
130+
addNull();
131+
}
137132
}
138-
return (ObjectNode) currentNode;
133+
set(index, value);
139134
}
140-
*/
141135

142136
/*
143137
/**********************************************************

src/main/java/com/fasterxml/jackson/databind/node/JsonNodeFactory.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public class JsonNodeFactory
2020
// with 2.2
2121
private static final long serialVersionUID = 1L;
2222

23+
/**
24+
* Constant that defines maximum {@code JsonPointer} element index we
25+
* use for inserts.
26+
*/
27+
protected final static int MAX_ELEMENT_INDEX_FOR_INSERT = 9999;
28+
2329
private final boolean _cfgBigDecimalExact;
2430

2531
private static final JsonNodeFactory decimalsNormalized
@@ -87,6 +93,19 @@ public static JsonNodeFactory withExactBigDecimals(boolean bigDecimalExact)
8793
return bigDecimalExact ? decimalsAsIs : decimalsNormalized;
8894
}
8995

96+
/*
97+
/**********************************************************
98+
/* Metadata/config access
99+
/**********************************************************
100+
*/
101+
102+
/**
103+
* @since 2.14
104+
*/
105+
public int getMaxElementIndexForInsert() {
106+
return MAX_ELEMENT_INDEX_FOR_INSERT;
107+
}
108+
90109
/*
91110
/**********************************************************
92111
/* Factory methods for literal values

src/main/java/com/fasterxml/jackson/databind/node/ObjectNode.java

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ public class ObjectNode
2424
{
2525
private static final long serialVersionUID = 1L; // since 2.10
2626

27-
/**
28-
* Constant that defines maximum {@code JsonPointer} element index we
29-
* use for inserts.
30-
*/
31-
protected final static int MAX_ELEMENT_INDEX_FOR_INSERT = 9999;
32-
3327
// Note: LinkedHashMap for backwards compatibility
3428
protected final Map<String, JsonNode> _children;
3529

@@ -94,77 +88,26 @@ protected ObjectNode _withObject(JsonPointer origPtr,
9488
}
9589
}
9690
// Either way; must replace or add a new property
97-
return _withObjectAddTailProperty(currentPtr, preferIndex, this);
91+
return _withObjectAddTailProperty(currentPtr, preferIndex);
9892
}
9993

100-
protected ObjectNode _withObjectAddTailProperty(JsonPointer tail, boolean preferIndex,
101-
ObjectNode currObject)
94+
protected ObjectNode _withObjectAddTailProperty(JsonPointer tail, boolean preferIndex)
10295
{
10396
final String propName = tail.getMatchingProperty();
10497
tail = tail.tail();
10598

10699
// First: did we complete traversal? If so, easy, we got our result
107100
if (tail.matches()) {
108-
return currObject.putObject(propName);
109-
}
110-
111-
// Otherwise, do we want Array or Object
112-
if (_withObjectChooseArray(tail, preferIndex)) { // array!
113-
return _withObjectAddTailElement(tail, preferIndex,
114-
currObject.putArray(propName));
115-
}
116-
return _withObjectAddTailProperty(tail, preferIndex,
117-
currObject.putObject(propName));
118-
}
119-
120-
protected ObjectNode _withObjectAddTailElement(JsonPointer tail, boolean preferIndex,
121-
ArrayNode currArray)
122-
{
123-
final int index = tail.getMatchingIndex();
124-
tail = tail.tail();
125-
126-
// First: did we complete traversal? If so, easy, we got our result
127-
if (tail.matches()) {
128-
ObjectNode result = currArray.objectNode();
129-
_withObjectSetArrayElement(currArray, index, result);
130-
return result;
101+
return putObject(propName);
131102
}
132103

133104
// Otherwise, do we want Array or Object
134-
if (_withObjectChooseArray(tail, preferIndex)) { // array!
135-
ArrayNode next = currArray.arrayNode();
136-
_withObjectSetArrayElement(currArray, index, next);
137-
return _withObjectAddTailElement(tail, preferIndex, next);
138-
}
139-
ObjectNode next = currArray.objectNode();
140-
_withObjectSetArrayElement(currArray, index, next);
141-
return _withObjectAddTailProperty(tail, preferIndex, next);
142-
}
143-
144-
protected boolean _withObjectChooseArray(JsonPointer ptr, boolean preferIndex)
145-
{
146-
if (preferIndex) {
147-
final int ix = ptr.getMatchingIndex();
148-
if (ix >= 0) {
149-
// 27-Jul-2022, tatu: Let's make it less likely anyone OOMs by
150-
// humongous index...
151-
if (ix <= MAX_ELEMENT_INDEX_FOR_INSERT) {
152-
return true;
153-
}
154-
_reportWrongNodeOperation("Too big Array index (%d; max %d) to use for insert with `JsonPointer`",
155-
ix, MAX_ELEMENT_INDEX_FOR_INSERT, ptr);
156-
}
105+
if (preferIndex && tail.mayMatchElement()) { // array!
106+
return putArray(propName)._withObjectAddTailElement(tail, preferIndex);
157107
}
158-
return false;
108+
return putObject(propName)._withObjectAddTailProperty(tail, preferIndex);
159109
}
160110

161-
protected void _withObjectSetArrayElement(ArrayNode array, int index, JsonNode value) {
162-
while (index >= array.size()) {
163-
array.addNull();
164-
}
165-
array.set(index, value);
166-
}
167-
168111
/*
169112
/**********************************************************
170113
/* Overrides for JsonSerializable.Base

0 commit comments

Comments
 (0)