Search in sources :

Example 1 with Serializer

use of io.micronaut.serde.Serializer in project micronaut-data by micronaut-projects.

the class DataEncoderContext method findCustomSerializer.

@Override
public <T, D extends Serializer<? extends T>> D findCustomSerializer(Class<? extends D> serializerClass) throws SerdeException {
    if (serializerClass == IdSerializer.class) {
        IdSerializer idSerializer = new IdSerializer() {

            @Override
            public Serializer<Object> createSpecific(EncoderContext encoderContext, Argument<?> type) throws SerdeException {
                boolean isGeneratedObjectIdAsString = type.isAssignableFrom(String.class) && type.isAnnotationPresent(GeneratedValue.class);
                if (isGeneratedObjectIdAsString) {
                    Serializer<? super ObjectId> objectIdSerializer = findSerializer(OBJECT_ID);
                    return (encoder, encoderContext2, stringType, value) -> {
                        String stringId = (String) value;
                        objectIdSerializer.serialize(encoder, encoderContext2, OBJECT_ID, new ObjectId(stringId));
                    };
                }
                return (Serializer<Object>) findSerializer(type);
            }

            @Override
            public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) {
                throw new IllegalStateException("Create specific call is required!");
            }
        };
        return (D) idSerializer;
    }
    if (serializerClass == CustomConverterSerializer.class) {
        CustomConverterSerializer customConverterSerializer = new CustomConverterSerializer() {

            @Override
            public Serializer<Object> createSpecific(EncoderContext encoderContext, Argument<?> type) throws SerdeException {
                Class<?> converterClass = type.getAnnotationMetadata().classValue(MappedProperty.class, "converter").orElseThrow(IllegalStateException::new);
                Class<Object> converterPersistedType = type.getAnnotationMetadata().classValue(MappedProperty.class, "converterPersistedType").orElseThrow(IllegalStateException::new);
                Argument<Object> convertedType = Argument.of(converterPersistedType);
                Serializer<? super Object> serializer = findSerializer(convertedType);
                AttributeConverter<Object, Object> converter = attributeConverterRegistry.getConverter(converterClass);
                return new Serializer<Object>() {

                    @Override
                    public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) throws IOException {
                        if (value == null) {
                            encoder.encodeNull();
                            return;
                        }
                        Object converted = converter.convertToPersistedValue(value, ConversionContext.of(type));
                        if (converted == null) {
                            encoder.encodeNull();
                            return;
                        }
                        serializer.serialize(encoder, context, convertedType, converted);
                    }
                };
            }

            @Override
            public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) {
                throw new IllegalStateException("Create specific call is required!");
            }
        };
        return (D) customConverterSerializer;
    }
    return parent.findCustomSerializer(serializerClass);
}
Also used : IdPropertyNamingStrategy(io.micronaut.data.document.serde.IdPropertyNamingStrategy) PropertyReference(io.micronaut.serde.reference.PropertyReference) PropertyNamingStrategy(io.micronaut.serde.config.naming.PropertyNamingStrategy) IOException(java.io.IOException) CodecRegistry(org.bson.codecs.configuration.CodecRegistry) Internal(io.micronaut.core.annotation.Internal) Encoder(io.micronaut.serde.Encoder) CustomConverterSerializer(io.micronaut.data.document.serde.CustomConverterSerializer) SerializationReference(io.micronaut.serde.reference.SerializationReference) ConversionContext(io.micronaut.core.convert.ConversionContext) Serializer(io.micronaut.serde.Serializer) MappedProperty(io.micronaut.data.annotation.MappedProperty) CodecBsonDecoder(io.micronaut.serde.bson.custom.CodecBsonDecoder) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) IdSerializer(io.micronaut.data.document.serde.IdSerializer) Codec(org.bson.codecs.Codec) ObjectId(org.bson.types.ObjectId) IterableCodec(org.bson.codecs.IterableCodec) Argument(io.micronaut.core.type.Argument) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) ConversionService(io.micronaut.core.convert.ConversionService) AttributeConverterRegistry(io.micronaut.data.model.runtime.AttributeConverterRegistry) AttributeConverter(io.micronaut.data.model.runtime.convert.AttributeConverter) SerdeException(io.micronaut.serde.exceptions.SerdeException) Argument(io.micronaut.core.type.Argument) ObjectId(org.bson.types.ObjectId) IdSerializer(io.micronaut.data.document.serde.IdSerializer) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) Encoder(io.micronaut.serde.Encoder) MappedProperty(io.micronaut.data.annotation.MappedProperty) CustomConverterSerializer(io.micronaut.data.document.serde.CustomConverterSerializer) CustomConverterSerializer(io.micronaut.data.document.serde.CustomConverterSerializer) Serializer(io.micronaut.serde.Serializer) IdSerializer(io.micronaut.data.document.serde.IdSerializer)

Example 2 with Serializer

use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.

the class CustomizedMapSerializer method createSpecific.

@Override
public Serializer<Map<K, V>> createSpecific(EncoderContext context, Argument<? extends Map<K, V>> type) throws SerdeException {
    final Argument[] generics = type.getTypeParameters();
    final boolean hasGenerics = ArrayUtils.isNotEmpty(generics) && generics.length != 2;
    if (hasGenerics) {
        final Argument<V> valueGeneric = (Argument<V>) generics[1];
        final Serializer<V> valSerializer = (Serializer<V>) context.findSerializer(valueGeneric).createSpecific(context, valueGeneric);
        return new Serializer<Map<K, V>>() {

            @Override
            public void serialize(Encoder encoder, EncoderContext context, Argument<? extends Map<K, V>> type, Map<K, V> value) throws IOException {
                final Encoder childEncoder = encoder.encodeObject(type);
                for (K k : value.keySet()) {
                    encodeMapKey(context, childEncoder, k);
                    final V v = value.get(k);
                    if (v == null) {
                        childEncoder.encodeNull();
                    } else {
                        valSerializer.serialize(childEncoder, context, valueGeneric, v);
                    }
                }
                childEncoder.finishStructure();
            }

            @Override
            public boolean isEmpty(EncoderContext context, Map<K, V> value) {
                return CollectionUtils.isEmpty(value);
            }
        };
    } else {
        return new Serializer<Map<K, V>>() {

            @Override
            public void serialize(Encoder encoder, EncoderContext context, Argument<? extends Map<K, V>> type, Map<K, V> value) throws IOException {
                // slow path, lookup each value serializer
                final Encoder childEncoder = encoder.encodeObject(type);
                for (Map.Entry<K, V> entry : value.entrySet()) {
                    encodeMapKey(context, childEncoder, entry.getKey());
                    final V v = entry.getValue();
                    if (v == null) {
                        childEncoder.encodeNull();
                    } else {
                        @SuppressWarnings("unchecked") final Argument<V> valueGeneric = (Argument<V>) Argument.of(v.getClass());
                        final Serializer<? super V> valSerializer = context.findSerializer(valueGeneric).createSpecific(context, valueGeneric);
                        valSerializer.serialize(childEncoder, context, valueGeneric, v);
                    }
                }
                childEncoder.finishStructure();
            }

            @Override
            public boolean isEmpty(EncoderContext context, Map<K, V> value) {
                return CollectionUtils.isEmpty(value);
            }
        };
    }
}
Also used : Argument(io.micronaut.core.type.Argument) Encoder(io.micronaut.serde.Encoder) Map(java.util.Map) CustomizableSerializer(io.micronaut.serde.util.CustomizableSerializer) Serializer(io.micronaut.serde.Serializer)

Example 3 with Serializer

use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.

the class ObjectSerializer method createSpecific.

@Override
public Serializer<Object> createSpecific(EncoderContext encoderContext, Argument<? extends Object> type) {
    if (type.equalsType(Argument.OBJECT_ARGUMENT)) {
        // dynamic type resolving
        return new RuntimeTypeSerializer(encoderContext);
    } else {
        SerBean<Object> serBean;
        try {
            serBean = getSerBean(type, encoderContext).get();
        } catch (IntrospectionException e) {
            return createRuntimeSerializer(encoderContext, type, e);
        }
        final AnnotationMetadata annotationMetadata = type.getAnnotationMetadata();
        if (serBean.hasJsonValue()) {
            return new Serializer<Object>() {

                @Override
                public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) throws IOException {
                    serBean.initialize(context);
                    SerBean.SerProperty<Object, Object> jsonValue = serBean.jsonValue;
                    final Object v = jsonValue.get(value);
                    serBean.jsonValue.serializer.serialize(encoder, context, jsonValue.argument, v);
                }

                @Override
                public boolean isEmpty(EncoderContext context, Object value) {
                    try {
                        serBean.initialize(context);
                    } catch (SerdeException e) {
                        throw new RuntimeException(e);
                    }
                    return serBean.jsonValue.serializer.isEmpty(context, serBean.jsonValue.get(value));
                }

                @Override
                public boolean isAbsent(EncoderContext context, Object value) {
                    try {
                        serBean.initialize(context);
                    } catch (SerdeException e) {
                        throw new RuntimeException(e);
                    }
                    return serBean.jsonValue.serializer.isAbsent(context, serBean.jsonValue.get(value));
                }
            };
        } else if (annotationMetadata.isAnnotationPresent(SerdeConfig.SerIgnored.class) || annotationMetadata.isAnnotationPresent(SerdeConfig.META_ANNOTATION_PROPERTY_ORDER) || annotationMetadata.isAnnotationPresent(SerdeConfig.SerIncluded.class)) {
            final String[] ignored = annotationMetadata.stringValues(SerdeConfig.SerIgnored.class);
            final String[] included = annotationMetadata.stringValues(SerdeConfig.SerIncluded.class);
            List<String> order = Arrays.asList(annotationMetadata.stringValues(SerdeConfig.META_ANNOTATION_PROPERTY_ORDER));
            final boolean hasIgnored = ArrayUtils.isNotEmpty(ignored);
            final boolean hasIncluded = ArrayUtils.isNotEmpty(included);
            Set<String> ignoreSet = hasIgnored ? CollectionUtils.setOf(ignored) : null;
            Set<String> includedSet = hasIncluded ? CollectionUtils.setOf(included) : null;
            if (!order.isEmpty() || hasIgnored || hasIncluded) {
                return new CustomizedObjectSerializer<Object>(serBean) {

                    @Override
                    protected List<SerBean.SerProperty<Object, Object>> getWriteProperties(SerBean<Object> serBean) {
                        final List<SerBean.SerProperty<Object, Object>> writeProperties = new ArrayList<>(super.getWriteProperties(serBean));
                        if (!order.isEmpty()) {
                            writeProperties.sort(Comparator.comparingInt(o -> order.indexOf(o.name)));
                        }
                        if (hasIgnored) {
                            writeProperties.removeIf(p -> ignoreSet.contains(p.name));
                        }
                        if (hasIncluded) {
                            writeProperties.removeIf(p -> !includedSet.contains(p.name));
                        }
                        return writeProperties;
                    }
                };
            }
        }
        Serializer<Object> outer;
        if (serBean.simpleBean) {
            outer = new SimpleObjectSerializer<>(serBean);
        } else {
            outer = new CustomizedObjectSerializer<>(serBean);
        }
        if (serBean.subtyped) {
            return new RuntimeTypeSerializer(encoderContext) {

                @Override
                protected Serializer<Object> tryToFindSerializer(EncoderContext context, Object value) throws SerdeException {
                    if (value.getClass().equals(type.getType())) {
                        return outer;
                    } else {
                        return super.tryToFindSerializer(context, value);
                    }
                }
            };
        } else {
            return outer;
        }
    }
}
Also used : CustomizableSerializer(io.micronaut.serde.util.CustomizableSerializer) Arrays(java.util.Arrays) ArrayUtils(io.micronaut.core.util.ArrayUtils) TypeKey(io.micronaut.serde.support.util.TypeKey) Internal(io.micronaut.core.annotation.Internal) Encoder(io.micronaut.serde.Encoder) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Primary(io.micronaut.context.annotation.Primary) Serializer(io.micronaut.serde.Serializer) SerializationConfiguration(io.micronaut.serde.config.SerializationConfiguration) SerdeConfig(io.micronaut.serde.config.annotation.SerdeConfig) Map(java.util.Map) SerdeIntrospections(io.micronaut.serde.SerdeIntrospections) Argument(io.micronaut.core.type.Argument) SupplierUtil(io.micronaut.core.util.SupplierUtil) IntrospectionException(io.micronaut.core.beans.exceptions.IntrospectionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Singleton(jakarta.inject.Singleton) Set(java.util.Set) IOException(java.io.IOException) List(java.util.List) CollectionUtils(io.micronaut.core.util.CollectionUtils) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Comparator(java.util.Comparator) SerdeException(io.micronaut.serde.exceptions.SerdeException) Set(java.util.Set) Argument(io.micronaut.core.type.Argument) IntrospectionException(io.micronaut.core.beans.exceptions.IntrospectionException) SerdeException(io.micronaut.serde.exceptions.SerdeException) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Encoder(io.micronaut.serde.Encoder) ArrayList(java.util.ArrayList) List(java.util.List) CustomizableSerializer(io.micronaut.serde.util.CustomizableSerializer) Serializer(io.micronaut.serde.Serializer) SerdeConfig(io.micronaut.serde.config.annotation.SerdeConfig)

Example 4 with Serializer

use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.

the class OptionalSerializer method createSpecific.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Serializer<Optional<T>> createSpecific(EncoderContext encoderContext, Argument<? extends Optional<T>> type) throws SerdeException {
    final Argument[] generics = type.getTypeParameters();
    if (ArrayUtils.isEmpty(generics)) {
        throw new SerdeException("Serializing raw optionals is for type: " + type);
    }
    final Argument<?>[] generics1 = type.getTypeParameters();
    if (ArrayUtils.isEmpty(generics1)) {
        throw new SerdeException("Serializing raw optionals is not supported for type: " + type);
    }
    // noinspection unchecked
    final Argument<T> generic = (Argument<T>) generics1[0];
    final Serializer<? super T> componentSerializer = encoderContext.findSerializer(generic).createSpecific(encoderContext, generic);
    return new Serializer<Optional<T>>() {

        @Override
        public void serialize(Encoder encoder, EncoderContext context, Argument<? extends Optional<T>> type, Optional<T> value) throws IOException {
            final Argument<?>[] generics1 = type.getTypeParameters();
            if (ArrayUtils.isEmpty(generics1)) {
                throw new SerdeException("Serializing raw optionals is not supported for type: " + type);
            }
            // noinspection unchecked
            final Argument<T> generic = (Argument<T>) generics1[0];
            final T o = value.orElse(null);
            if (o != null) {
                componentSerializer.serialize(encoder, context, generic, o);
            } else {
                encoder.encodeNull();
            }
        }

        @Override
        public boolean isEmpty(EncoderContext context, Optional<T> value) {
            Optional o = value;
            if (value != null && o.isPresent()) {
                return componentSerializer.isEmpty(context, (T) o.get());
            }
            return true;
        }

        @Override
        public boolean isAbsent(EncoderContext context, Optional<T> value) {
            return value == null || !value.isPresent();
        }
    };
}
Also used : Argument(io.micronaut.core.type.Argument) Optional(java.util.Optional) Encoder(io.micronaut.serde.Encoder) SerdeException(io.micronaut.serde.exceptions.SerdeException) CustomizableSerializer(io.micronaut.serde.util.CustomizableSerializer) Serializer(io.micronaut.serde.Serializer)

Example 5 with Serializer

use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.

the class OptionalValuesSerializer method createSpecific.

@Override
public Serializer<OptionalValues<V>> createSpecific(EncoderContext context, Argument<? extends OptionalValues<V>> type) throws SerdeException {
    Argument<?>[] generics = type.getTypeParameters();
    if (ArrayUtils.isEmpty(generics)) {
        throw new SerdeException("Cannot serialize raw OptionalValues");
    }
    Argument<V> generic = (Argument<V>) generics[0];
    Serializer<V> valueSerializer = (Serializer<V>) context.findSerializer(generic).createSpecific(context, generic);
    return new Serializer<OptionalValues<V>>() {

        @Override
        public void serialize(Encoder encoder, EncoderContext context, Argument<? extends OptionalValues<V>> type, OptionalValues<V> value) throws IOException {
            Objects.requireNonNull(value, "Value cannot be null");
            Encoder objectEncoder = encoder.encodeObject(type);
            for (CharSequence key : value) {
                Optional<V> opt = value.get(key);
                if (opt.isPresent()) {
                    objectEncoder.encodeKey(key.toString());
                    valueSerializer.serialize(encoder, context, generic, opt.get());
                }
            }
            objectEncoder.finishStructure();
        }
    };
}
Also used : Argument(io.micronaut.core.type.Argument) Encoder(io.micronaut.serde.Encoder) SerdeException(io.micronaut.serde.exceptions.SerdeException) CustomizableSerializer(io.micronaut.serde.util.CustomizableSerializer) Serializer(io.micronaut.serde.Serializer) OptionalValues(io.micronaut.core.value.OptionalValues)

Aggregations

Serializer (io.micronaut.serde.Serializer)10 Argument (io.micronaut.core.type.Argument)9 Encoder (io.micronaut.serde.Encoder)9 SerdeException (io.micronaut.serde.exceptions.SerdeException)9 CustomizableSerializer (io.micronaut.serde.util.CustomizableSerializer)6 Map (java.util.Map)4 Internal (io.micronaut.core.annotation.Internal)2 IntrospectionException (io.micronaut.core.beans.exceptions.IntrospectionException)2 IdSerializer (io.micronaut.data.document.serde.IdSerializer)2 RuntimePersistentEntity (io.micronaut.data.model.runtime.RuntimePersistentEntity)2 TypeKey (io.micronaut.serde.support.util.TypeKey)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Primary (io.micronaut.context.annotation.Primary)1 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)1 BeanProperty (io.micronaut.core.beans.BeanProperty)1 ConversionContext (io.micronaut.core.convert.ConversionContext)1 ConversionService (io.micronaut.core.convert.ConversionService)1 ArrayUtils (io.micronaut.core.util.ArrayUtils)1