use of io.micronaut.serde.Serializer in project micronaut-data by micronaut-projects.
the class DataSerdeRegistry method findCustomSerializer.
@Override
public <T, D extends Serializer<? extends T>> D findCustomSerializer(Class<? extends D> serializerClass) throws SerdeException {
if (serializerClass == OneRelationSerializer.class) {
OneRelationSerializer oneRelationSerializer = new OneRelationSerializer() {
@Override
public Serializer<Object> createSpecific(EncoderContext encoderContext, Argument<?> type) throws SerdeException {
RuntimePersistentEntity entity = runtimeEntityRegistry.getEntity(type.getType());
if (entity.getIdentity() == null) {
throw new SerdeException("Cannot find ID of entity type: " + type);
}
BeanProperty property = entity.getIdentity().getProperty();
Argument<?> idType = entity.getIdentity().getArgument();
Serializer<Object> idSerializer = encoderContext.findCustomSerializer(IdSerializer.class).createSpecific(encoderContext, idType);
return new Serializer<Object>() {
@Override
public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) throws IOException {
Object id = property.get(value);
if (id == null) {
encoder.encodeNull();
} else {
Encoder en = encoder.encodeObject(type);
en.encodeKey(MongoUtils.ID);
idSerializer.serialize(en, context, idType, id);
en.finishStructure();
}
}
};
}
@Override
public void serialize(Encoder encoder, EncoderContext context, Argument<? extends Object> type, Object value) throws IOException {
throw new IllegalStateException("Create specific call is required!");
}
};
return (D) oneRelationSerializer;
}
if (serializerClass == ManyRelationSerializer.class) {
ManyRelationSerializer manyRelationSerializer = new ManyRelationSerializer() {
@Override
public void serialize(Encoder encoder, EncoderContext context, Argument<?> type, Object value) throws IOException {
encoder.encodeNull();
}
};
return (D) manyRelationSerializer;
}
return defaultSerdeRegistry.findCustomSerializer(serializerClass);
}
use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.
the class CustomizedObjectSerializer method serialize.
@Override
public final void serialize(Encoder encoder, EncoderContext context, Argument<? extends T> type, T value) throws IOException {
try {
serBean.initialize(context);
Encoder childEncoder = encoder.encodeObject(type);
if (serBean.wrapperProperty != null) {
childEncoder.encodeKey(serBean.wrapperProperty);
childEncoder = childEncoder.encodeObject(type);
}
for (SerBean.SerProperty<Object, Object> property : getWriteProperties(serBean)) {
final Object v = property.get(value);
final String backRef = property.backRef;
if (backRef != null) {
final PropertyReference<Object, Object> ref = context.resolveReference(new SerializationReference<>(backRef, serBean.introspection, property.argument, v, property.serializer));
if (ref == null) {
continue;
}
}
final Serializer<Object> serializer = property.serializer;
switch(property.include) {
case NON_NULL:
if (v == null) {
continue;
}
break;
case NON_ABSENT:
if (serializer.isAbsent(context, v)) {
continue;
}
break;
case NON_EMPTY:
if (serializer.isEmpty(context, v)) {
continue;
}
break;
case NEVER:
continue;
default:
}
if (property.views != null && !context.hasView(property.views)) {
continue;
}
final String managedRef = property.managedRef;
if (managedRef != null) {
context.pushManagedRef(new SerializationReference<>(managedRef, serBean.introspection, property.argument, value, property.serializer));
}
try {
childEncoder.encodeKey(property.name);
if (v == null) {
childEncoder.encodeNull();
} else {
serializer.serialize(childEncoder, context, property.argument, v);
}
} finally {
if (managedRef != null) {
context.popManagedRef();
}
}
}
final SerBean.SerProperty<Object, Object> anyGetter = serBean.anyGetter;
if (anyGetter != null) {
final Object data = anyGetter.get(value);
if (data instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) data;
if (CollectionUtils.isNotEmpty(map)) {
for (Object k : map.keySet()) {
final Object v = map.get(k);
childEncoder.encodeKey(k.toString());
if (v == null) {
childEncoder.encodeNull();
} else {
Argument<?> valueType = anyGetter.argument.getTypeVariable("V").orElse(null);
if (valueType == null || valueType.equalsType(Argument.OBJECT_ARGUMENT)) {
valueType = Argument.of(v.getClass());
}
@SuppressWarnings("unchecked") final Serializer<Object> serializer = (Serializer<Object>) context.findSerializer(valueType);
serializer.serialize(childEncoder, context, valueType, v);
}
}
}
}
}
childEncoder.finishStructure();
} catch (StackOverflowError e) {
throw new SerdeException("Infinite recursion serializing type: " + type.getType().getSimpleName() + " at path " + encoder.currentPath(), e);
} catch (IntrospectionException e) {
throw new SerdeException("Error serializing value at path: " + encoder.currentPath() + ". No serializer found for " + "type: " + type, e);
}
}
use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.
the class OptionalMultiValuesSerializer method createSpecific.
@Override
public Serializer<OptionalMultiValues<V>> createSpecific(EncoderContext context, Argument<? extends OptionalMultiValues<V>> type) throws SerdeException {
final Argument[] generics = type.getTypeParameters();
if (ArrayUtils.isEmpty(generics)) {
throw new SerdeException("Cannot serialize raw OptionalMultiValues");
}
final Argument generic = generics[0];
final Argument listGeneric = Argument.listOf(generic);
Serializer listSerializer = context.findSerializer(listGeneric).createSpecific(context, listGeneric);
Serializer valueSerializer = context.findSerializer(generic).createSpecific(context, generic);
return new Serializer<OptionalMultiValues<V>>() {
@Override
public void serialize(Encoder encoder, EncoderContext context, Argument<? extends OptionalMultiValues<V>> type, OptionalMultiValues<V> value) throws IOException {
Objects.requireNonNull(value, "Values can't be null");
Encoder objectEncoder = encoder.encodeObject(type);
for (CharSequence key : value) {
Optional<? extends List<V>> opt = value.get(key);
if (opt.isPresent()) {
String fieldName = key.toString();
objectEncoder.encodeKey(fieldName);
List<V> list = opt.get();
if (alwaysSerializeErrorsAsList) {
listSerializer.serialize(objectEncoder, context, listGeneric, list);
} else {
if (list.size() == 1) {
valueSerializer.serialize(objectEncoder, context, generic, list.get(0));
} else {
listSerializer.serialize(objectEncoder, context, listGeneric, list);
}
}
}
}
objectEncoder.finishStructure();
}
@Override
public boolean isEmpty(EncoderContext context, OptionalMultiValues<V> value) {
return value == null || value.isEmpty();
}
};
}
use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.
the class StreamSerializer method createSpecific.
@Override
public Serializer<Stream<T>> createSpecific(EncoderContext context, Argument<? extends Stream<T>> type) throws SerdeException {
final Argument[] generics = type.getTypeParameters();
if (ArrayUtils.isEmpty(generics)) {
throw new SerdeException("Cannot serialize raw stream");
}
final Argument generic = generics[0];
final Serializer componentSerializer = context.findSerializer(generic).createSpecific(context, type);
return new Serializer<Stream<T>>() {
@Override
public void serialize(Encoder encoder, EncoderContext context, Argument<? extends Stream<T>> type, Stream<T> value) throws IOException {
if (value == null) {
throw new SerdeException("Stream is required");
}
Encoder arrayEncoder = encoder.encodeArray(type);
Iterator<T> itr = value.iterator();
while (itr.hasNext()) {
componentSerializer.serialize(encoder, context, generic, itr.next());
}
arrayEncoder.finishStructure();
}
};
}
use of io.micronaut.serde.Serializer in project micronaut-serialization by micronaut-projects.
the class DefaultSerdeRegistry method findSerializer.
@Override
public <T> Serializer<? super T> findSerializer(Argument<? extends T> type) throws SerdeException {
Objects.requireNonNull(type, "Type cannot be null");
final TypeKey key = new TypeKey(type);
final Serializer<?> serializer = serializerMap.get(key);
if (serializer != null) {
// noinspection unchecked
return (Serializer<? super T>) serializer;
} else {
List<BeanDefinition<Serializer>> possibles = serializerDefMap.get(type.getType());
if (possibles == null) {
for (Map.Entry<Class<?>, List<BeanDefinition<Serializer>>> entry : serializerDefMap.entrySet()) {
final Class<?> targetType = entry.getKey();
if (targetType.isAssignableFrom(type.getType())) {
possibles = entry.getValue();
final Argument<?>[] params = type.getTypeParameters();
if (ArrayUtils.isNotEmpty(params)) {
// narrow for generics
possibles = new ArrayList<>(possibles);
final Iterator<BeanDefinition<Serializer>> i = possibles.iterator();
while (i.hasNext()) {
final BeanDefinition<Serializer> bd = i.next();
final Argument<?>[] candidateParams = bd.getTypeArguments(Serializer.class).get(0).getTypeParameters();
if (candidateParams.length == params.length) {
for (int j = 0; j < params.length; j++) {
Argument<?> param = params[j];
final Argument<?> candidateParam = candidateParams[j];
if (!((param.getType() == candidateParam.getType()) || (candidateParam.isTypeVariable() && candidateParam.getType().isAssignableFrom(param.getType())))) {
i.remove();
}
}
} else {
i.remove();
}
}
}
break;
}
}
}
if (possibles != null) {
if (possibles.size() == 1) {
final BeanDefinition<Serializer> definition = possibles.iterator().next();
final Serializer locatedSerializer = beanContext.getBean(definition);
serializerMap.put(key, locatedSerializer);
return locatedSerializer;
} else if (possibles.isEmpty()) {
throw new SerdeException("No serializers found for type: " + type);
} else {
final BeanDefinition<Serializer> definition = lastChanceResolve(type, possibles);
final Serializer locatedSerializer = beanContext.getBean(definition);
serializerMap.put(key, locatedSerializer);
return locatedSerializer;
}
} else {
serializerMap.put(key, objectSerializer);
}
}
return objectSerializer;
}
Aggregations