All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arangodb.internal.serde.JacksonUtils Maven / Gradle / Ivy

There is a newer version: 7.16.0
Show newest version
package com.arangodb.internal.serde;

import com.arangodb.internal.ShadedProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class JacksonUtils {
    private static final Logger LOG = LoggerFactory.getLogger(JacksonUtils.class);

    private JacksonUtils() {
    }

    public interface Version {
        int getMajorVersion();

        int getMinorVersion();

        String toString();
    }

    public interface StreamReadConstraints {

        interface Static {
            Builder builder();
        }

        interface Builder {
            Builder maxNumberLength(final int maxNumLen);

            Builder maxStringLength(int maxStringLen);

            Builder maxNestingDepth(int maxNestingDepth);

            Builder maxNameLength(int maxNameLen);

            Builder maxDocumentLength(long maxDocLen);

            StreamReadConstraints build();
        }
    }

    public interface StreamWriteConstraints {
        interface Static {
            Builder builder();
        }

        interface Builder {
            Builder maxNestingDepth(int maxNestingDepth);

            StreamWriteConstraints build();
        }
    }

    public interface JsonFactory {
        Version version();

        @SuppressWarnings("UnusedReturnValue")
        JsonFactory setStreamReadConstraints(StreamReadConstraints src);

        @SuppressWarnings("UnusedReturnValue")
        JsonFactory setStreamWriteConstraints(StreamWriteConstraints swc);
    }

    /**
     * Configure JsonFactory with permissive StreamReadConstraints and StreamWriteConstraints.
     * It uses reflection to avoid compilation errors with older Jackson versions.
     * It uses dynamic package names to be compatible with shaded Jackson.
     *
     * @param jf JsonFactory to configure
     */
    public static void tryConfigureJsonFactory(Object jf) {
        try {
            configureJsonFactory(jf);
        } catch (Throwable t) {
            LOG.warn("Got exception while configuring JsonFactory, skipping...", t);
        }
    }

    private static void configureJsonFactory(Object jf) throws Exception {
        JsonFactory proxy = ShadedProxy.of(JsonFactory.class, jf);
        Version version = proxy.version();
        LOG.debug("Detected Jackson version: {}", version);

        // get pkg name dynamically, to support shaded Jackson
        String basePkg = jf.getClass().getPackage().getName();

        if (isAtLeastVersion(version, 2, 15)) {
            Class srcClass = Class.forName(basePkg + "." + StreamReadConstraints.class.getSimpleName());
            StreamReadConstraints.Builder builder = ShadedProxy.of(StreamReadConstraints.Static.class, srcClass)
                    .builder()
                    .maxNumberLength(Integer.MAX_VALUE)
                    .maxStringLength(Integer.MAX_VALUE)
                    .maxNestingDepth(Integer.MAX_VALUE);
            if (isAtLeastVersion(version, 2, 16)) {
                builder = builder
                        .maxNameLength(Integer.MAX_VALUE)
                        .maxDocumentLength(Long.MAX_VALUE);
            } else {
                LOG.debug("Skipping configuring StreamReadConstraints maxNameLength");
                LOG.debug("Skipping configuring StreamReadConstraints maxDocumentLength");
            }
            proxy.setStreamReadConstraints(builder.build());
        } else {
            LOG.debug("Skipping configuring StreamReadConstraints");
        }

        if (isAtLeastVersion(version, 2, 16)) {
            LOG.debug("Configuring StreamWriteConstraints ...");
            Class swcClass = Class.forName(basePkg + "." + StreamWriteConstraints.class.getSimpleName());
            StreamWriteConstraints swc = ShadedProxy.of(StreamWriteConstraints.Static.class, swcClass)
                    .builder()
                    .maxNestingDepth(Integer.MAX_VALUE)
                    .build();
            proxy.setStreamWriteConstraints(swc);
        } else {
            LOG.debug("Skipping configuring StreamWriteConstraints");
        }
    }

    @SuppressWarnings("SameParameterValue")
    private static boolean isAtLeastVersion(Version version, int major, int minor) {
        int currentMajor = version.getMajorVersion();
        int currentMinor = version.getMinorVersion();
        return currentMajor > major || (currentMajor == major && currentMinor >= minor);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy