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

com.github.tonivade.zeromock.api.Deserializers Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2020, Antonio Gabriel Muñoz Conejo 
 * Distributed under the terms of the MIT License
 */
package com.github.tonivade.zeromock.api;

import static java.util.Objects.isNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;

import javax.xml.bind.DataBindingException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.data.ImmutableArray;
import com.github.tonivade.purefun.data.ImmutableList;
import com.github.tonivade.purefun.data.ImmutableMap;
import com.github.tonivade.purefun.data.ImmutableSet;
import com.github.tonivade.purefun.data.ImmutableTree;
import com.github.tonivade.purefun.data.ImmutableTreeMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;

public final class Deserializers {
  
  private Deserializers() {}
  
  public static Function1 json() {
    return plain().andThen(asJson());
  }
  
  public static  Function1 xmlToObject(Class clazz) {
    return bytes -> Deserializers.fromXml(bytes, clazz);
  }
  
  public static  Function1 jsonToObject(Function1 deserializer) {
    return plain().andThen(deserializer);
  }
  
  public static  Function1 jsonToObject(Class clazz) {
    return jsonToObject(fromJson(clazz));
  }
  
  public static  Function1 jsonTo(Type type) {
    return jsonToObject(fromJson(type));
  }
  
  public static Function1 plain() {
    return Bytes::asString;
  }
  
  private static Function1 asJson() {
    return JsonParser::parseString;
  }
  
  private static  Function1 fromJson(Type type) {
    return json -> fromJson(json, type);
  }

  private static Gson buildGson() {
    return new GsonBuilder()
        .registerTypeAdapter(ImmutableList.class, DeserializerAdapters.IMMUTABLE_LIST)
        .registerTypeAdapter(ImmutableArray.class, DeserializerAdapters.IMMUTABLE_ARRAY)
        .registerTypeAdapter(ImmutableSet.class, DeserializerAdapters.IMMUTABLE_SET)
        .registerTypeAdapter(ImmutableTree.class, DeserializerAdapters.IMMUTABLE_TREE)
        .registerTypeAdapter(ImmutableMap.class, DeserializerAdapters.IMMUTABLE_MAP)
        .registerTypeAdapter(ImmutableTreeMap.class, DeserializerAdapters.IMMUTABLE_TREEMAP)
        .create();
  }
  
  @SuppressWarnings("unchecked")
  private static  T fromXml(Bytes bytes, Class clazz) {
    try (InputStream input = new ByteArrayInputStream(bytes.toArray())) {
      JAXBContext context = JAXBContext.newInstance(clazz);
      Unmarshaller unmarshaller = context.createUnmarshaller();
      return (T) unmarshaller.unmarshal(input);
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    } catch (JAXBException e) {
      throw new DataBindingException(e);
    }
  }

  private static  T fromJson(String json, Type type) {
    if (isNull(json) || json.isEmpty()) {
      throw new JsonSyntaxException("body cannot be null or empty");
    }
    return buildGson().fromJson(json, type);
  }
}

class DeserializerAdapters {

  static final JsonDeserializer> IMMUTABLE_LIST = 
      (json, typeOfT, context) -> ImmutableList.from(context.>deserialize(json, List.class));

  static final JsonDeserializer> IMMUTABLE_SET = 
      (json, typeOfT, context) -> ImmutableSet.from(context.>deserialize(json, List.class));

  static final JsonDeserializer> IMMUTABLE_ARRAY = 
      (json, typeOfT, context) -> ImmutableArray.from(context.>deserialize(json, List.class));

  static final JsonDeserializer> IMMUTABLE_TREE = 
      (json, typeOfT, context) -> ImmutableTree.from(context.>deserialize(json, List.class));

  static final JsonDeserializer> IMMUTABLE_MAP = 
      (json, typeOfT, context) -> ImmutableMap.from(context.>deserialize(json, Map.class));

  static final JsonDeserializer> IMMUTABLE_TREEMAP = 
      (json, typeOfT, context) -> ImmutableTreeMap.from(context.>deserialize(json, NavigableMap.class));
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy