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

cd.connect.jetty.redis.JsonSerializer Maven / Gradle / Ivy

package cd.connect.jetty.redis;

import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class JsonSerializer extends SerializerSkeleton {
  private static final Logger log = LoggerFactory.getLogger(JsonSerializer.class);
  public ObjectMapper mapper;

  @Override
  public void start() {
    mapper = new ObjectMapper();
    mapper.disable(SerializationFeature.WRAP_ROOT_VALUE);

    mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
    mapper.configure(SerializationFeature.INDENT_OUTPUT, false);
    mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, false);
    mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    mapper.setVisibility(new VisibilityChecker.Std(ANY, ANY, ANY, ANY, ANY));

    super.start();
  }

  @Override
  public void stop() {
    super.stop();
    mapper = null;
  }

  @Override
  public String serialize(Object o) throws SerializerException {
    try {
      return mapper.writeValueAsString(o);
    } catch (IOException e) {
      throw new SerializerException(e);
    }
  }

  @Override
  public String serializeSessionAttributes(Map map) throws SerializerException {
    ArrayNode array = mapper.createArrayNode();
    for (Entry entry : map.entrySet()) {
      array.add(convertToNode(entry.getKey(), entry.getValue()));
    }
    ObjectNode n = mapper.createObjectNode();
    n.set("attibutes", array);
    try {
      return mapper.writeValueAsString(n);
    } catch (IOException e) {
      throw new SerializerException(e);
    }
  }



  private JsonNode convertToNode(String key, Object value) {
    JsonNode valueToTree = mapper.valueToTree(value);

    ObjectNode o;

    if (valueToTree.isObject()) {
      o = (ObjectNode) valueToTree;
      o.put("attributeName", key);
      o.put("attributeType", value.getClass().getName());
    } else {
      o = mapper.createObjectNode();
      o.put("value", value.toString());
      o.put("attributeName", key);
      o.put("attributeType", value.getClass().getName());
    }

    return o;
  }

  @Override
  public  T deserialize(String o, Class targetType) throws SerializerException {
    try {
      return mapper.readValue(o, targetType);
    } catch (IOException e) {
      throw new SerializerException(e);
    }
  }

  private static ConcurrentHashMap constructors = new ConcurrentHashMap<>();

  private Object getInstance(String attributeType, String value) {
    Constructor c = constructors.get(attributeType);
    if (c == null) {
      try {
        c = Class.forName(attributeType).getConstructor(String.class);
        if (c != null) {
          constructors.put(attributeType, c);
        }
      } catch (NoSuchMethodException|ClassNotFoundException e) {
        log.error("Cannot create {} from {}", value, attributeType);
      }
    }

    if (c != null) {
      try {
        return c.newInstance(value);
      } catch (InstantiationException|IllegalAccessException|InvocationTargetException e) {
        log.error("Cannot create {} from {}", value, attributeType);
      }
    }

    return null;
  }

  @Override
  public Map deserializeSessionAttributes(String o) throws SerializerException {
    Map ret = new ConcurrentHashMap<>();
    try {
      JsonNode arrNode = mapper.readTree(o).get("attibutes");
      if (arrNode.isArray()) {
        for (final JsonNode objNode : arrNode) {
          JsonNode name = objNode.get("attributeName");
          JsonNode type = objNode.get("attributeType");
          if (name != null && type != null) {
            String attributeName = name.asText();
            String attributeType = type.asText();
            if (attributeType.startsWith("java.lang.")) {
              ret.put(attributeName, getInstance(attributeType, objNode.get("value").asText()));
            } else {
              ret.put(attributeName, mapper.treeToValue(objNode, Class.forName(attributeType)));
            }
          }
        }
      }
    } catch (JsonProcessingException e) {
      throw new SerializerException(e);
    } catch (IOException e) {
      throw new SerializerException(e);
    } catch (ClassNotFoundException e) {
      throw new SerializerException(e);
    }
    return ret;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy