JsonRecordSerializer implements Callable<Void> { public Void call() { var state = State.IS_PRIMITIVE; final int nrOfRevisions = revisions.length; final int length = (nrOfRevisions == 1 && revisions[0] < 0) ? resourceMgr.getMostRecentRevisionNumber() : nrOfRevisions; for (int i = 1; i <= length; i++) { try (final JsonNodeReadOnlyTrx rtx = resourceMgr.beginNodeReadOnlyTrx((nrOfRevisions == 1 && revisions[0] < 0) ? i : revisions[i - 1])) { rtx.moveToDocumentRoot(); if (rtx.hasFirstChild()) { rtx.moveToFirstChild(); var jsonSerializer = new JsonSerializer.Builder(rtx.getResourceManager(), out, revisions).startNodeKey(rtx.getNodeKey()) .serializeStartNodeWithBrackets(false) .serializeTimestamp(serializeTimestamp) .withMetaData(withMetaData) .withNodeKeyAndChildCountMetaData( withNodeKeyAndChildNodeKeyMetaData) .withNodeKeyMetaData( withNodeKeyMetaData) .build(); jsonSerializer.emitNode(rtx); if (rtx.isObject()) { state = State.IS_OBJECT; } else if (rtx.isArray()) { state = State.IS_ARRAY; } if (rtx.hasFirstChild()) { boolean hasMoved = false; if (lastTopLevelNodeKey != 0) { rtx.moveTo(lastTopLevelNodeKey); if (rtx.hasRightSibling()) { rtx.moveToRightSibling(); hasMoved = true; } } else { rtx.moveToFirstChild(); hasMoved = true; } if (hasMoved) { var nodeKey = rtx.getNodeKey(); jsonSerializer = new JsonSerializer.Builder(rtx.getResourceManager(), out, revisions).startNodeKey(nodeKey) .serializeStartNodeWithBrackets( false) .maxLevel(maxLevel) .serializeTimestamp( serializeTimestamp) .withMetaData(withMetaData) .withNodeKeyAndChildCountMetaData( withNodeKeyAndChildNodeKeyMetaData) .withNodeKeyMetaData( withNodeKeyMetaData) .build(); jsonSerializer.call(); if (rtx.isObjectKey() && (withMetaData || withNodeKeyAndChildNodeKeyMetaData || withNodeKeyMetaData)) { out.append("}"); } rtx.moveTo(nodeKey); if (rtx.hasRightSibling()) { for (int j = 1; j < numberOfRecords && rtx.hasRightSibling(); j++) { rtx.moveToRightSibling(); nodeKey = rtx.getNodeKey(); out.append(","); if (rtx.isObjectKey() && (withMetaData || withNodeKeyAndChildNodeKeyMetaData || withNodeKeyMetaData)) { out.append("{"); } jsonSerializer = new JsonSerializer.Builder(rtx.getResourceManager(), out, revisions).startNodeKey(nodeKey) .serializeStartNodeWithBrackets( false) .maxLevel(maxLevel) .serializeTimestamp( serializeTimestamp) .withMetaData(withMetaData) .withNodeKeyAndChildCountMetaData( withNodeKeyAndChildNodeKeyMetaData) .withNodeKeyMetaData( withNodeKeyMetaData) .build(); jsonSerializer.call(); if (rtx.isObjectKey() && (withMetaData || withNodeKeyAndChildNodeKeyMetaData || withNodeKeyMetaData)) { out.append("}"); } rtx.moveTo(nodeKey); } } } } if (state == State.IS_OBJECT) { if (withMetaData || withNodeKeyAndChildNodeKeyMetaData || withNodeKeyMetaData) { out.append("]"); } out.append("}"); } else if (state == State.IS_ARRAY) { if (withMetaData || withNodeKeyAndChildNodeKeyMetaData || withNodeKeyMetaData) { out.append("]}"); } else { out.append("]"); } } } } catch (final IOException e) { throw new UncheckedIOException(e); } } return null; } private  JsonRecordSerializer(final JsonResourceManager resourceMgr, final Builder builder,
      final @Nonnegative int revision, final int... revisions); static Builder newBuilder(final JsonResourceManager resMgr, final int numberOfRecords, final Writer writer,
      final int... revisions); static Builder newBuilder(final JsonResourceManager resMgr, final int numberOfRecords,
      final @Nonnegative long nodeKey, final Writer writer, final JsonSerializerProperties properties,
      final int... revisions); Void call();  }
@Test public void serializeObject() { JsonTestHelper.createTestDocument(); try (final var database = Databases.openJsonDatabase(JsonTestHelper.PATHS.PATH1.getFile()); final var resmgr = database.openResourceManager(JsonTestHelper.RESOURCE)) { final var stringWriter = new StringWriter(); final var jsonRecordSerializer = new JsonRecordSerializer.Builder(resmgr, 3, stringWriter).build(); jsonRecordSerializer.call(); final var expected = """ {"foo":["bar",null,2.33],"bar":{"hello":"world","helloo":true},"baz":"hello"} """.strip(); assertEquals(expected, stringWriter.toString()); } }
@Test public void serializeObjectWithLastTopLevelNodeKey() { JsonTestHelper.createTestDocument(); try (final var database = Databases.openJsonDatabase(JsonTestHelper.PATHS.PATH1.getFile()); final var resmgr = database.openResourceManager(JsonTestHelper.RESOURCE)) { final var stringWriter = new StringWriter(); final var jsonRecordSerializer = new JsonRecordSerializer.Builder(resmgr, 3, stringWriter).lastTopLevelNodeKey(7).build(); jsonRecordSerializer.call(); final var expected = """ {"baz":"hello","tada":[{"foo":"bar"},{"baz":false},"boo",{},[]]} """.strip(); assertEquals(expected, stringWriter.toString()); } }
@Test public void serializeObjectWithLastTopLevelNodeKeyAndNoRightSibling() { JsonTestHelper.createTestDocument(); try (final var database = Databases.openJsonDatabase(JsonTestHelper.PATHS.PATH1.getFile()); final var resmgr = database.openResourceManager(JsonTestHelper.RESOURCE)) { final var stringWriter = new StringWriter(); final var jsonRecordSerializer = new JsonRecordSerializer.Builder(resmgr, 3, stringWriter).lastTopLevelNodeKey(15).build(); jsonRecordSerializer.call(); final var expected = """ {} """.strip(); assertEquals(expected, stringWriter.toString()); } }
@Test public void serializeObjectWithMaxLevel() { JsonTestHelper.createTestDocument(); try (final var database = Databases.openJsonDatabase(JsonTestHelper.PATHS.PATH1.getFile()); final var resmgr = database.openResourceManager(JsonTestHelper.RESOURCE)) { final var stringWriter = new StringWriter(); final var jsonRecordSerializer = new JsonRecordSerializer.Builder(resmgr, 3, stringWriter).maxLevel(1).build(); jsonRecordSerializer.call(); final var expected = """ {"foo":[],"bar":{},"baz":"hello"} """.strip(); assertEquals(expected, stringWriter.toString()); } }
@Test public void serializeObjectWithMaxLevelAndMetaData() throws IOException { JsonTestHelper.createTestDocument(); try (final var database = Databases.openJsonDatabase(JsonTestHelper.PATHS.PATH1.getFile()); final var resmgr = database.openResourceManager(JsonTestHelper.RESOURCE)) { final var stringWriter = new StringWriter(); final var jsonRecordSerializer = new JsonRecordSerializer.Builder(resmgr, 3, stringWriter).maxLevel(1).withMetaData(true).build(); jsonRecordSerializer.call(); final var expected = Files.readString(JSON.resolve("serializeObjectWithMaxLevelAndMetaData.json")); assertEquals(expected, stringWriter.toString()); } }