<commit_before>package com.kryptnostic.api.v1.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kryptnostic.kodex.v1.crypto.keys.CryptoServiceLoader;
import com.kryptnostic.kodex.v1.serialization.jackson.KodexObjectMapperFactory;

/**
 * A {@link Converter} which uses Jackson for reading and writing entities.
 *
 * @author <NAME> (<EMAIL>)
 */
public class JacksonConverter implements Converter {
    private static final String MIME_TYPE = "application/json; charset=UTF-8";
    private static final Logger logger = LoggerFactory.getLogger( JacksonConverter.class );
    private final ObjectMapper  objectMapper;

    public JacksonConverter() {
        this.objectMapper = KodexObjectMapperFactory.getObjectMapper();
    }
    
    public JacksonConverter( CryptoServiceLoader securityConfig ) {
        this.objectMapper = KodexObjectMapperFactory.getObjectMapper( securityConfig );
    }

    @Override
    public Object fromBody( TypedInput body, Type type ) throws ConversionException {
        try {
            JavaType javaType = objectMapper.getTypeFactory().constructType( type );
            InputStream in = body.in();
            if ( in.available() == 0 ) {
                return null;
            }
            return objectMapper.readValue( body.in(), javaType );
        } catch ( IOException e ) {
            logger.error( "Unable to deserialize object of type {}", type );
            try {
                logger.error("Representation: {}" , IOUtils.toString( body.in() ) );
            } catch ( IOException e1 ) {
                throw new ConversionException( e1 );
            }
            throw new ConversionException( e );
        }
    }

    @Override
    public TypedOutput toBody( Object object ) {
        try {
            String json = objectMapper.writeValueAsString( object );
            return new TypedByteArray( MIME_TYPE, json.getBytes( "UTF-8" ) );
        } catch ( JsonProcessingException e ) {
            throw new AssertionError( e );
        } catch ( UnsupportedEncodingException e ) {
            throw new AssertionError( e );
        }
    }
}<commit_msg>Added support for octet stream in converter<commit_after>package com.kryptnostic.api.v1.utils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import retrofit.converter.ConversionException;
import retrofit.converter.Converter;
import retrofit.mime.TypedByteArray;
import retrofit.mime.TypedInput;
import retrofit.mime.TypedOutput;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kryptnostic.kodex.v1.crypto.keys.CryptoServiceLoader;
import com.kryptnostic.kodex.v1.serialization.jackson.KodexObjectMapperFactory;

/**
 * A {@link Converter} that handles both json and byte arrays. Based off work by <NAME>
 * (<EMAIL>)
 * 
 * @author <NAME> &lt;<EMAIL>&gt;
 *
 */
public class JacksonConverter implements Converter {
    private static final String JSON_MIME_TYPE = "application/json; charset=UTF-8";
    private static final String BYTE_MIME_TYPE = "application/octet-stream";
    private static final Logger logger         = LoggerFactory.getLogger( JacksonConverter.class );
    private final ObjectMapper  objectMapper;

    public JacksonConverter() {
        this.objectMapper = KodexObjectMapperFactory.getObjectMapper();
    }

    public JacksonConverter( CryptoServiceLoader securityConfig ) {
        this.objectMapper = KodexObjectMapperFactory.getObjectMapper( securityConfig );
    }

    @Override
    public Object fromBody( TypedInput body, Type type ) throws ConversionException {
        try {
            if ( StringUtils.equals( body.mimeType(), BYTE_MIME_TYPE ) ) {
                return IOUtils.toByteArray( body.in() );
            }

            JavaType javaType = objectMapper.getTypeFactory().constructType( type );

            InputStream in = body.in();

            if ( in.available() == 0 ) {
                return null;
            }

            return objectMapper.readValue( body.in(), javaType );
        } catch ( IOException e ) {
            logger.error( "Unable to deserialize object of type {} from body with mime-type {}.",
                    type,
                    body.mimeType(),
                    e );
            throw new ConversionException( e );
        }
    }

    @Override
    public TypedOutput toBody( Object object ) {
        if ( byte[].class.isAssignableFrom( object.getClass() ) ) {
            return new TypedByteArray( BYTE_MIME_TYPE, (byte[]) object );
        }
        try {
            byte[] json = objectMapper.writeValueAsBytes( object );
            return new TypedByteArray( JSON_MIME_TYPE, json );// json.getBytes( "UTF-8" )
        } catch ( JsonProcessingException e ) {
            throw new AssertionError( e );
        } /*
           * catch ( UnsupportedEncodingException e ) { throw new AssertionError( e ); }
           */
    }
}
{'fraction_non_alphanumeric': 0.09595782073813708, 'fraction_numerical': 0.0033391915641476275, 'mean_word_length': 2.855691056910569, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4554980', 'n_tokens_mistral': 1598, 'n_tokens_neox': 1548, 'n_words': 365}