001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2026 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.api.model.json;
011
012import com.fasterxml.jackson.annotation.JsonProperty;
013import tools.jackson.core.JacksonException;
014import tools.jackson.core.JsonGenerator;
015import tools.jackson.databind.ObjectMapper;
016import tools.jackson.databind.SerializationContext;
017import tools.jackson.databind.ValueSerializer;
018import tools.jackson.databind.annotation.JsonSerialize;
019import tools.jackson.databind.json.JsonMapper;
020
021import java.util.Collection;
022import java.util.List;
023
024import static java.util.Objects.nonNull;
025
026/**
027 * N.B. GGG. If you ever add a high cardinality element to {@link AuditEventJson}, you must reflect that change in this
028 * class as well, or else CSV exporting will stop working.
029 *
030 * This abstract class serves as a mixin for serialization purposes, ensuring that collections of high-cardinality
031 * JSON model elements are serialized as strings. This is achieved using the {@link HighCardinalityStringifyingSerializer}.
032 * The serialized string representation is only currently used for CSV export.
033 */
034public abstract class StringifiedCollectionMixin {
035
036        @JsonSerialize(using = HighCardinalityStringifyingSerializer.class)
037        @JsonProperty("headers")
038        private Collection<AuditEventHeaderJson> myHeaders;
039
040        @JsonSerialize(using = HighCardinalityStringifyingSerializer.class)
041        @JsonProperty("targetResources")
042        private List<AuditEventTargetResourceJson> myTargetResources;
043
044        @JsonSerialize(using = HighCardinalityStringifyingSerializer.class)
045        @JsonProperty("targetModules")
046        private Collection<AuditEventTargetModuleJson> myTargetModules;
047
048        @JsonSerialize(using = HighCardinalityStringifyingSerializer.class)
049        @JsonProperty("targetUsers")
050        private Collection<AuditEventTargetUserJson> myTargetUsers;
051
052        /**
053         * This class strictly exists to serialize high cardinality elements into a string, for CSV export. See {@link StringifiedCollectionMixin}
054         * to see how we use it.
055         */
056        public static class HighCardinalityStringifyingSerializer extends ValueSerializer<Collection<?>> {
057
058                private final ObjectMapper myObjectMapper =
059                                JsonMapper.builderWithJackson2Defaults().build();
060
061                @Override
062                public void serialize(Collection theValue, JsonGenerator theGen, SerializationContext theSerializationContext)
063                                throws JacksonException {
064                        if (nonNull(theValue)) {
065                                theGen.writeString(myObjectMapper.writeValueAsString(theValue));
066                        }
067                }
068        }
069}