ProtoDeserializers.java
/*
* Copyright 2022 Proto Utils Authors
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package net.morimekta.proto.jackson.adapter;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.module.SimpleDeserializers;
import com.fasterxml.jackson.databind.type.MapType;
import com.google.protobuf.Message;
import net.morimekta.proto.ProtoEnum;
import static net.morimekta.proto.ProtoEnum.getEnumDescriptorUnchecked;
import static net.morimekta.proto.ProtoMessage.getMessageDescriptor;
/**
* Deserializer handler for complex proto types.
*/
public class ProtoDeserializers
extends SimpleDeserializers {
/** {@inheritDoc} */
@Override
public JsonDeserializer<?> findMapDeserializer(MapType type,
DeserializationConfig config,
BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer,
JsonDeserializer<?> elementDeserializer)
throws JsonMappingException {
if (ProtoEnum.isProtoEnumClass(type.getKeyType().getRawClass())) {
return new ProtoMapDeserializer<>(
type.getRawClass(),
createEnumKeyDeserializer(type.getKeyType().getRawClass()),
type.getContentType());
}
return super.findMapDeserializer(type,
config,
beanDesc,
keyDeserializer,
elementTypeDeserializer,
elementDeserializer);
}
/** {@inheritDoc} */
@Override
public JsonDeserializer<?> findEnumDeserializer(Class<?> type,
DeserializationConfig config,
BeanDescription beanDesc) throws JsonMappingException {
if (ProtoEnum.isProtoEnumClass(type)) {
try {
return createEnumDeserializer(type);
} catch (IllegalArgumentException e) {
throw new JsonMappingException(null, e.getMessage(), e);
}
}
return super.findEnumDeserializer(type, config, beanDesc);
}
/** {@inheritDoc} */
@Override
public JsonDeserializer<?> findBeanDeserializer(JavaType type,
DeserializationConfig config,
BeanDescription beanDesc) throws JsonMappingException {
if (Message.class.isAssignableFrom(type.getRawClass())) {
try {
return this.createMessageDeserializer(type.getRawClass(), config);
} catch (IllegalArgumentException e) {
throw new JsonMappingException(null, e.getMessage(), e);
}
}
return super.findBeanDeserializer(type, config, beanDesc);
}
private JsonDeserializer<?> createMessageDeserializer(Class<?> type, DeserializationConfig config) {
return new ProtoMessageDeserializer<>(getMessageDescriptor(type), config);
}
@SuppressWarnings("rawtypes")
private JsonDeserializer<?> createEnumDeserializer(Class<?> type) {
return new ProtoEnumDeserializer(getEnumDescriptorUnchecked(type));
}
private KeyDeserializer createEnumKeyDeserializer(Class<?> type) {
return new ProtoEnumKeyDeserializer(getEnumDescriptorUnchecked(type));
}
}