Skip to content

Commit 309d907

Browse files
committed
Fix JsonNodeDriver for nested side tables
1 parent cf5261f commit 309d907

File tree

3 files changed

+25
-28
lines changed

3 files changed

+25
-28
lines changed

bosk-jackson/src/main/java/works/bosk/jackson/JsonNodeDriver.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package works.bosk.jackson;
22

3-
import com.fasterxml.jackson.core.JsonProcessingException;
43
import com.fasterxml.jackson.databind.JsonNode;
54
import com.fasterxml.jackson.databind.ObjectMapper;
65
import java.io.IOException;
@@ -110,10 +109,9 @@ private <T> void doReplacement(NodeInfo nodeInfo, String lastSegment, T newValue
110109

111110
void traceCurrentState(String description) {
112111
if (LOGGER.isTraceEnabled()) {
113-
try {
114-
LOGGER.trace("State {} {}:\n{}", ++updateNumber, description, mapper.writerWithDefaultPrettyPrinter().writeValueAsString(currentRoot));
115-
} catch (JsonProcessingException e) {
116-
throw new IllegalStateException(e);
112+
LOGGER.trace("State {} {}:\n{}", ++updateNumber, description, currentRoot.toPrettyString());
113+
if (updateNumber == 9) {
114+
LOGGER.trace("Stopping at update {}", updateNumber);
117115
}
118116
}
119117
}

bosk-jackson/src/main/java/works/bosk/jackson/JsonNodeSurgeon.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import static java.util.Objects.requireNonNull;
2222
import static works.bosk.jackson.JsonNodeSurgeon.ReplacementStyle.ID_ONLY;
2323
import static works.bosk.jackson.JsonNodeSurgeon.ReplacementStyle.PLAIN;
24-
import static works.bosk.jackson.JsonNodeSurgeon.ReplacementStyle.WRAPPED_ENTITY;
24+
import static works.bosk.jackson.JsonNodeSurgeon.ReplacementStyle.WRAPPED;
2525

2626
/**
2727
* Utilities to find and modify the {@link JsonNode} corresponding to
@@ -56,7 +56,7 @@ record ArrayElement(ArrayNode parent, int elementIndex) implements NodeLocation
5656
* <p>
5757
* (Note that the parent {@link JsonNode} is not always the node corresponding
5858
* to the {@link Reference#enclosingReference enclosing reference}.
59-
* They're two related but different concepts. See {@link ReplacementStyle#WRAPPED_ENTITY WRAPPED_ENTITY}.)
59+
* They're two related but different concepts. See {@link ReplacementStyle#WRAPPED WRAPPED_ENTITY}.)
6060
*/
6161
record NonexistentParent() implements NodeLocation {}
6262
}
@@ -78,8 +78,7 @@ public enum ReplacementStyle {
7878

7979
/**
8080
* Use an {@link ObjectNode} having a single member whose name is the desired
81-
* entity's {@link works.bosk.Entity#id id} and whose value is the serialized
82-
* form of the desired entity.
81+
* last segment of the {@link Reference} pointing at the desired node,
8382
*
8483
* <p>
8584
* Note that this is the style that causes the {@link NodeInfo#valueLocation value location}
@@ -93,7 +92,7 @@ public enum ReplacementStyle {
9392
* something other than {@link NonexistentParent NonexistentParent})
9493
* and will indicate where the wrapper object should be.
9594
*/
96-
WRAPPED_ENTITY,
95+
WRAPPED,
9796
}
9897

9998
/**
@@ -125,8 +124,8 @@ static NodeInfo idOnly(NodeLocation theLocation) {
125124
return new NodeInfo(theLocation, theLocation, ID_ONLY);
126125
}
127126

128-
static NodeInfo wrappedEntity(NodeLocation valueLocation, NodeLocation replacementLocation) {
129-
return new NodeInfo(valueLocation, replacementLocation, WRAPPED_ENTITY);
127+
static NodeInfo wrapped(NodeLocation valueLocation, NodeLocation replacementLocation) {
128+
return new NodeInfo(valueLocation, replacementLocation, WRAPPED);
130129
}
131130
}
132131

@@ -174,30 +173,33 @@ public NodeInfo nodeInfo(JsonNode doc, Reference<?> ref) {
174173
return NodeInfo.idOnly(new ArrayElement(ids, ids.size()));
175174
} else if (Catalog.class.isAssignableFrom(enclosingRef.targetClass())) {
176175
if (parent == null) {
177-
return NodeInfo.wrappedEntity(new NonexistentParent(), new NonexistentParent());
176+
return NodeInfo.wrapped(new NonexistentParent(), new NonexistentParent());
178177
} else {
179178
String entryID = ref.path().lastSegment();
180179
NodeLocation element = findArrayElementWithId(parent, entryID);
181180
JsonNode elementNode = getNode(element, doc);
182181
if (elementNode == null) {
183182
// Doesn't exist yet
184-
return NodeInfo.wrappedEntity (new NonexistentParent(), element);
183+
return NodeInfo.wrapped(new NonexistentParent(), element);
185184
} else {
186-
return NodeInfo.wrappedEntity (getMapEntryValueLocation(elementNode, entryID), element);
185+
return NodeInfo.wrapped(getMapEntryValueLocation(elementNode, entryID), element);
187186
}
188187
}
189188
} else if (SideTable.class.isAssignableFrom(enclosingRef.targetClass())) {
190189
if (parent == null) {
191-
return NodeInfo.wrappedEntity(new NonexistentParent(), new NonexistentParent());
190+
NodeLocation valueLocation = new NonexistentParent();
191+
return NodeInfo.wrapped(valueLocation, new NonexistentParent());
192192
} else {
193193
String entryID = ref.path().lastSegment();
194194
NodeLocation element = findArrayElementWithId(parent.get("valuesById"), entryID);
195195
JsonNode elementNode = getNode(element, doc);
196196
if (elementNode == null) {
197197
// Doesn't exist yet
198-
return NodeInfo.wrappedEntity(new NonexistentParent(), element);
198+
NodeLocation valueLocation = new NonexistentParent();
199+
return NodeInfo.wrapped(valueLocation, element);
199200
} else {
200-
return NodeInfo.wrappedEntity(getMapEntryValueLocation(elementNode, entryID), element);
201+
NodeLocation valueLocation = getMapEntryValueLocation(elementNode, entryID);
202+
return NodeInfo.wrapped(valueLocation, element);
201203
}
202204
}
203205
}
@@ -219,7 +221,7 @@ private static NodeLocation findArrayElementWithId(JsonNode entries, String id)
219221
ObjectNode entryObject = (ObjectNode) entries.get(i);
220222
var properties = entryObject.properties();
221223
if (properties.size() != 1) {
222-
throw new NotYetImplementedException(properties.toString());
224+
throw new NotYetImplementedException("SO MANY PROPERTIES" + properties);
223225
}
224226
Map.Entry<String, JsonNode> entry = properties.iterator().next();
225227
if (id.equals(entry.getKey())) {
@@ -269,11 +271,8 @@ public JsonNode replacementNode(NodeInfo nodeInfo, String lastSegment, Supplier<
269271
return switch (nodeInfo.replacementStyle()) {
270272
case PLAIN -> newValue.get();
271273
case ID_ONLY -> new TextNode(lastSegment);
272-
case WRAPPED_ENTITY -> {
273-
JsonNode entityNode = newValue.get();
274-
String id = entityNode.get("id").textValue();
275-
yield new ObjectNode(JsonNodeFactory.instance, Map.of(id, entityNode));
276-
}
274+
case WRAPPED -> new ObjectNode(JsonNodeFactory.instance)
275+
.set(lastSegment, newValue.get());
277276
};
278277
}
279278

bosk-jackson/src/test/java/works/bosk/jackson/JsonNodeSurgeonTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,14 @@ void catalogEntry() throws IOException, InterruptedException {
152152
JsonNode catalogArray = doc.get("catalog");
153153
JsonNode catalogEntry = catalogArray.get(0);
154154
{
155-
NodeInfo expected = NodeInfo.wrappedEntity(
155+
NodeInfo expected = NodeInfo.wrapped(
156156
new ObjectMember((ObjectNode) catalogEntry, "testEntry"),
157157
new ArrayElement((ArrayNode) catalogArray, 0));
158158
NodeInfo actual = surgeon.nodeInfo(doc, refs.catalogEntry(id));
159159
assertEquals(expected, actual);
160160
}
161161
{
162-
NodeInfo expected = NodeInfo.wrappedEntity(
162+
NodeInfo expected = NodeInfo.wrapped(
163163
new NonexistentParent(),
164164
new ArrayElement((ArrayNode) catalogArray, 1));
165165
NodeInfo actual = surgeon.nodeInfo(doc, refs.catalogEntry(Identifier.from("NONEXISTENT")));
@@ -212,14 +212,14 @@ void sideTableEntry() throws IOException, InterruptedException {
212212
JsonNode valuesById = doc.get("sideTable").get("valuesById");
213213
JsonNode entry = valuesById.get(0);
214214
{
215-
NodeInfo expected = NodeInfo.wrappedEntity(
215+
NodeInfo expected = NodeInfo.wrapped(
216216
new ObjectMember((ObjectNode) entry, "testKey"),
217217
new ArrayElement((ArrayNode) valuesById, 0));
218218
NodeInfo actual = surgeon.nodeInfo(doc, refs.sideTableEntry(id));
219219
assertEquals(expected, actual);
220220
}
221221
{
222-
NodeInfo expected = NodeInfo.wrappedEntity(
222+
NodeInfo expected = NodeInfo.wrapped(
223223
new NonexistentParent(),
224224
new ArrayElement((ArrayNode) valuesById, 1));
225225
NodeInfo actual = surgeon.nodeInfo(doc, refs.sideTableEntry(Identifier.from("NONEXISTENT")));

0 commit comments

Comments
 (0)