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

com.sap.cloud.sdk.frameworks.jaxrs.GsonMessageBodyProvider Maven / Gradle / Ivy

There is a newer version: 3.78.0
Show newest version
/*
 * Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
 */

package com.sap.cloud.sdk.frameworks.jaxrs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import com.google.gson.Gson;
import com.google.json.JsonSanitizer;
import com.sap.cloud.sdk.cloudplatform.servlet.response.ResponseGsonBuilder;

/**
 * Message body reader and writer for JSON in JAX-RS.
 */
@Provider
@Consumes( MediaType.APPLICATION_JSON )
@Produces( MediaType.APPLICATION_JSON )
public class GsonMessageBodyProvider implements MessageBodyWriter, MessageBodyReader
{
    @Nullable
    private Gson gson;

    private Gson getGson()
    {
        if( gson == null ) {
            gson = new ResponseGsonBuilder().create();
        }

        return gson;
    }

    @Override
    public boolean isReadable(
        final Class type,
        final Type genericType,
        final Annotation[] annotations,
        final MediaType mediaType )
    {
        return true;
    }

    @Override
    public boolean isWriteable(
        final Class type,
        final Type genericType,
        final Annotation[] annotations,
        final MediaType mediaType )
    {
        return true;
    }

    @Override
    public long getSize(
        final Object t,
        final Class type,
        final Type genericType,
        final Annotation[] annotations,
        final MediaType mediaType )
    {
        return -1;
    }

    private String getJsonString( final InputStream entityStream )
        throws IOException
    {
        final StringBuilder stringBuilder = new StringBuilder();
        try( final Reader reader = new BufferedReader(new InputStreamReader(entityStream, StandardCharsets.UTF_8)) ) {
            int character;
            while( (character = reader.read()) != -1 ) {
                stringBuilder.append((char) character);
            }
        }
        return stringBuilder.toString();
    }

    @Override
    public Object readFrom(
        final Class type,
        final Type genericType,
        final Annotation[] annotations,
        final MediaType mediaType,
        final MultivaluedMap httpHeaders,
        final InputStream entityStream )
        throws IOException
    {
        final String jsonString = getJsonString(entityStream);

        final Type jsonType;
        if( ((Class) type) == genericType.getClass() ) {
            jsonType = type;
        } else {
            jsonType = genericType;
        }

        return getGson().fromJson(JsonSanitizer.sanitize(jsonString), jsonType);
    }

    @Override
    public void writeTo(
        final Object t,
        final Class type,
        final Type genericType,
        final Annotation[] annotations,
        final MediaType mediaType,
        final MultivaluedMap httpHeaders,
        final OutputStream entityStream )
        throws IOException
    {
        try(
            final OutputStreamWriter writer =
                new OutputStreamWriter(entityStream, StandardCharsets.UTF_8.toString()) ) {
            final Type jsonType;
            if( type == genericType.getClass() ) {
                jsonType = type;
            } else {
                jsonType = genericType;
            }
            getGson().toJson(t, jsonType, writer);
        }
    }
}