JSONResultFormatter.java
package org.example.apiInteraction.resultFormatting;
import org.jetbrains.annotations.NotNull;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.SerializationFeature;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.node.ArrayNode;
import tools.jackson.databind.node.ObjectNode;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class JSONResultFormatter implements CustomFormatter {
private static final DateTimeFormatter ISO8601 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
private String sourceName;
private final ObjectMapper mapper;
public JSONResultFormatter(String sourceName) {
this.sourceName = sourceName;
this.mapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.build();
}
public String format(String jsonPayload, String existingContent) {
List<ObjectNode> records = parseExisting(existingContent);
int nextId = maxId(records) + 1;
JsonNode data = mapper.readTree(jsonPayload);
records.add(buildEnvelope(data, nextId));
return mapper.writeValueAsString(records);
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
private List<ObjectNode> parseExisting(String content) {
if (content == null || content.isBlank()) {
return new ArrayList<>();
}
ArrayNode array = (ArrayNode) mapper.readTree(content);
return mapper.convertValue(array, new TypeReference<>() {
});
}
private int maxId(@NotNull List<ObjectNode> records) {
return records.stream()
.mapToInt(r -> r.path("id").asInt(0))
.max()
.orElse(0);
}
private @NotNull ObjectNode buildEnvelope(JsonNode data, int id) {
ObjectNode envelope = mapper.createObjectNode();
envelope.put("id", id);
envelope.put("source", sourceName);
envelope.put("timestamp", currentTimestamp());
envelope.set("data", data);
return envelope;
}
private @NotNull String currentTimestamp() {
return OffsetDateTime.now(ZoneOffset.UTC).format(ISO8601);
}
}