com.evrythng.java.wrapper.mapping.TypeMapDeserializer.java Source code

Java tutorial

Introduction

Here is the source code for com.evrythng.java.wrapper.mapping.TypeMapDeserializer.java

Source

/*
 * (c) Copyright Reserved EVRYTHNG Limited 2016. All rights reserved.
 * Use of this material is subject to license.
 * Copying and unauthorised use of this material strictly prohibited.
 */
package com.evrythng.java.wrapper.mapping;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Base class for deserializers with a type map.
 *
 **/
public abstract class TypeMapDeserializer<T> extends Deserializer<T> {

    private static final long serialVersionUID = 1L;

    private Map<String, Class<? extends T>> registry = new HashMap<>();
    private Map<Class<? extends T>, String> reverseRegistry = new HashMap<>();
    private String typeFieldName;

    protected TypeMapDeserializer(final Class<?> cls, final String fieldName) {
        super(cls);
        this.typeFieldName = fieldName;
    }

    public void registerType(final String type, final Class<? extends T> objectClass) {

        registry.put(type, objectClass);
        reverseRegistry.put(objectClass, type);
    }

    @Override
    public T deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException {

        ObjectCodec codec = jp.getCodec();
        ObjectMapper mapper = (ObjectMapper) codec;
        ObjectNode root = mapper.readTree(jp);
        JsonNode type = root.get(typeFieldName);
        final String sType = type == null ? null : type.textValue();

        Class<? extends T> clazz = resolveClass(sType);

        return codec.treeToValue(root, clazz);
    }

    protected Class<? extends T> resolveClass(final String type) {

        Class<? extends T> clazz = registry.get(type);
        if (clazz == null) {
            throw new IllegalArgumentException(
                    this.getValueClass().getSimpleName() + " type '" + type + "' is not recognized.");
        }
        return clazz;
    }

    public <U extends T> String getObjectType(final Class<U> objectClass) {
        return reverseRegistry.get(objectClass);
    }

    public String getTypeFieldName() {
        return typeFieldName;
    }
}