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

io.airlift.json.RecordAutoDetectModule Maven / Gradle / Ivy

There is a newer version: 285
Show newest version
package io.airlift.json;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.RecordComponent;
import java.util.Set;
import java.util.stream.Stream;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

public class RecordAutoDetectModule
        extends SimpleModule
{
    @Deprecated(forRemoval = true)
    @Retention(RUNTIME)
    @Target(TYPE)
    public @interface LegacyRecordIntrospection {}

    @Override
    public void setupModule(SetupContext context)
    {
        super.setupModule(context);
        context.insertAnnotationIntrospector(new Introspector());
    }

    private static class Introspector
            extends AnnotationIntrospector
    {
        private static final VisibilityChecker.Std RECORD_VISIBILITY_CHECKER = VisibilityChecker.Std.defaultInstance()
                .withGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
                .withCreatorVisibility(JsonAutoDetect.Visibility.DEFAULT)
                .withFieldVisibility(JsonAutoDetect.Visibility.DEFAULT)
                .withIsGetterVisibility(JsonAutoDetect.Visibility.DEFAULT);

        @Override
        public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, VisibilityChecker checker)
        {
            if (ac.getRawType().isRecord()) {
                JsonAutoDetect overrideAnnotation = ac.getRawType().getAnnotation(JsonAutoDetect.class);
                if (overrideAnnotation != null) {
                    return VisibilityChecker.Std.construct(JsonAutoDetect.Value.from(overrideAnnotation));
                }
                if (ac.getRawType().isAnnotationPresent(LegacyRecordIntrospection.class)) {
                    return RECORD_VISIBILITY_CHECKER;
                }
                return new RecordVisibilityChecker(ac.getRawType().asSubclass(Record.class));
            }
            return checker;
        }

        @Override
        public Version version()
        {
            return Version.unknownVersion();
        }
    }

    private static class RecordVisibilityChecker
            implements VisibilityChecker
    {
        private final Set componentNames;

        public RecordVisibilityChecker(Class recordClass)
        {
            componentNames = Stream.of(recordClass.getRecordComponents())
                    .map(RecordComponent::getName)
                    .collect(toImmutableSet());
        }

        @Override
        public RecordVisibilityChecker with(JsonAutoDetect annotation)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withOverrides(JsonAutoDetect.Value value)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker with(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withVisibility(PropertyAccessor propertyAccessor, JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withGetterVisibility(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withIsGetterVisibility(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withSetterVisibility(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withCreatorVisibility(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public RecordVisibilityChecker withFieldVisibility(JsonAutoDetect.Visibility visibility)
        {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean isGetterVisible(Method method)
        {
            if (!Modifier.isPublic(method.getModifiers())) {
                return false;
            }
            return componentNames.contains(method.getName());
        }

        @Override
        public boolean isGetterVisible(AnnotatedMethod annotatedMethod)
        {
            return isGetterVisible(annotatedMethod.getAnnotated());
        }

        @Override
        public boolean isIsGetterVisible(Method method)
        {
            return false;
        }

        @Override
        public boolean isIsGetterVisible(AnnotatedMethod annotatedMethod)
        {
            return false;
        }

        @Override
        public boolean isSetterVisible(Method method)
        {
            return false;
        }

        @Override
        public boolean isSetterVisible(AnnotatedMethod annotatedMethod)
        {
            return false;
        }

        @Override
        public boolean isCreatorVisible(Member member)
        {
            return true;
        }

        @Override
        public boolean isCreatorVisible(AnnotatedMember annotatedMember)
        {
            return true;
        }

        @Override
        public boolean isFieldVisible(Field field)
        {
            return false;
        }

        @Override
        public boolean isFieldVisible(AnnotatedField field)
        {
            return false;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy