<commit_before>package com.kryptnostic.kodex.v1.models;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kryptnostic.crypto.Ciphertext;
import com.kryptnostic.crypto.v1.ciphers.BlockCiphertext;
import com.kryptnostic.crypto.v1.ciphers.CryptoService;
import com.kryptnostic.kodex.v1.exceptions.types.SecurityConfigurationException;
import com.kryptnostic.kodex.v1.security.SecurityConfigurationMapping;
import com.kryptnostic.kodex.v1.serialization.jackson.KodexObjectMapperFactory;

public class AesEncryptable<T> extends Encryptable<T> {

    /**
     * 
     */
    private static final long serialVersionUID = -5071733999235074270L;
    private static ObjectMapper mapper = ( new KodexObjectMapperFactory() ).getObjectMapper(null);

    public AesEncryptable(T data) {
        super(data);
    }

    public AesEncryptable(BlockCiphertext ciphertext, BlockCiphertext className) {
        super(ciphertext, className);
    }

    @JsonCreator
    public AesEncryptable(@JsonProperty(FIELD_ENCRYPTED_DATA) BlockCiphertext ciphertext,
            @JsonProperty(FIELD_ENCRYPTED_CLASS_NAME) BlockCiphertext className,
            @JacksonInject SecurityConfigurationMapping mapping) throws JsonParseException, JsonMappingException,
            IOException, ClassNotFoundException, SecurityConfigurationException {
        super(ciphertext, className, mapping);
    }

    @Override
    protected Encryptable<T> encryptWith(SecurityConfigurationMapping service) throws JsonProcessingException,
            SecurityConfigurationException {
        @SuppressWarnings("rawtypes")
        CryptoService crypto = service.get(AesEncryptable.class, CryptoService.class);

        BlockCiphertext encryptedData = null;
        BlockCiphertext encryptedClassName = null;
        try {
            encryptedData = crypto.encrypt(mapper.writeValueAsString(getData()));
            encryptedClassName = crypto.encrypt(getClassName());
        } catch (InvalidKeyException e) {
            wrapSecurityConfigurationException(e);
        } catch (InvalidKeySpecException e) {
            wrapSecurityConfigurationException(e);
        } catch (NoSuchAlgorithmException e) {
            wrapSecurityConfigurationException(e);
        } catch (NoSuchPaddingException e) {
            wrapSecurityConfigurationException(e);
        } catch (IllegalBlockSizeException e) {
            wrapSecurityConfigurationException(e);
        } catch (BadPaddingException e) {
            wrapSecurityConfigurationException(e);
        } catch (InvalidParameterSpecException e) {
            wrapSecurityConfigurationException(e);
        }
        return new AesEncryptable<T>(encryptedData, encryptedClassName);

    }

    private void wrapSecurityConfigurationException(Exception e) throws SecurityConfigurationException {
        throw new SecurityConfigurationException("Error occurred while trying to encrypt or decrypt data.", e);
    }

    @Override
    protected Encryptable<T> decryptWith(SecurityConfigurationMapping service) throws JsonParseException,
            JsonMappingException, IOException, ClassNotFoundException, SecurityConfigurationException {
        CryptoService crypto = service.get(AesEncryptable.class, CryptoService.class);
        String className = null;
        String objectString = null;
        try {
            className = crypto.decrypt((BlockCiphertext) getEncryptedClassName());
            objectString = crypto.decrypt((BlockCiphertext) getEncryptedData());
        } catch (InvalidKeyException e) {
            wrapSecurityConfigurationException(e);
        } catch (InvalidAlgorithmParameterException e) {
            wrapSecurityConfigurationException(e);
        } catch (NoSuchAlgorithmException e) {
            wrapSecurityConfigurationException(e);
        } catch (NoSuchPaddingException e) {
            wrapSecurityConfigurationException(e);
        } catch (InvalidKeySpecException e) {
            wrapSecurityConfigurationException(e);
        } catch (IllegalBlockSizeException e) {
            wrapSecurityConfigurationException(e);
        } catch (BadPaddingException e) {
            wrapSecurityConfigurationException(e);
        }

        @SuppressWarnings("unchecked")
        T obj = mapper.<T> readValue(objectString, (Class<T>) Class.forName(className));
        return new AesEncryptable<T>(obj);
    }

    @Override
    protected Encryptable<T> createEncrypted(Ciphertext ciphertext, Ciphertext className) {
        return new AesEncryptable<T>((BlockCiphertext) ciphertext, (BlockCiphertext) className);
    }

    @Override
    protected boolean canDecryptWith(SecurityConfigurationMapping mapping) {
        if (mapping == null) {
            return false;
        }
        return mapping.contains(AesEncryptable.class, CryptoService.class);
    }

    // TODO: a little bit yucky. we should centralize this config
    public static void setObjectMapper(ObjectMapper mapper) {
        AesEncryptable.mapper = mapper;
    }

}<commit_msg>formatting<commit_after>package com.kryptnostic.kodex.v1.models;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kryptnostic.crypto.Ciphertext;
import com.kryptnostic.crypto.v1.ciphers.BlockCiphertext;
import com.kryptnostic.crypto.v1.ciphers.CryptoService;
import com.kryptnostic.kodex.v1.exceptions.types.SecurityConfigurationException;
import com.kryptnostic.kodex.v1.security.SecurityConfigurationMapping;
import com.kryptnostic.kodex.v1.serialization.jackson.KodexObjectMapperFactory;

public class AesEncryptable<T> extends Encryptable<T> {
    private static final long   serialVersionUID = -5071733999235074270L;
    private static ObjectMapper mapper           = ( new KodexObjectMapperFactory() ).getObjectMapper( null );

    public AesEncryptable( T data ) {
        super( data );
    }

    public AesEncryptable( BlockCiphertext ciphertext, BlockCiphertext className ) {
        super( ciphertext, className );
    }

    @JsonCreator
    public AesEncryptable(
            @JsonProperty( FIELD_ENCRYPTED_DATA ) BlockCiphertext ciphertext,
            @JsonProperty( FIELD_ENCRYPTED_CLASS_NAME ) BlockCiphertext className,
            @JacksonInject SecurityConfigurationMapping mapping ) throws JsonParseException,
            JsonMappingException,
            IOException,
            ClassNotFoundException,
            SecurityConfigurationException {
        super( ciphertext, className, mapping );
    }

    @Override
    protected Encryptable<T> encryptWith( SecurityConfigurationMapping service ) throws JsonProcessingException,
            SecurityConfigurationException {
        CryptoService crypto = service.get( AesEncryptable.class, CryptoService.class );

        BlockCiphertext encryptedData = null;
        BlockCiphertext encryptedClassName = null;
        try {
            encryptedData = crypto.encrypt( mapper.writeValueAsString( getData() ) );
            encryptedClassName = crypto.encrypt( getClassName() );
        } catch ( InvalidKeyException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( InvalidKeySpecException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( NoSuchAlgorithmException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( NoSuchPaddingException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( IllegalBlockSizeException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( BadPaddingException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( InvalidParameterSpecException e ) {
            wrapSecurityConfigurationException( e );
        }
        return new AesEncryptable<T>( encryptedData, encryptedClassName );

    }

    private void wrapSecurityConfigurationException( Exception e ) throws SecurityConfigurationException {
        throw new SecurityConfigurationException( "Error occurred while trying to encrypt or decrypt data.", e );
    }

    @Override
    protected Encryptable<T> decryptWith( SecurityConfigurationMapping service ) throws JsonParseException,
            JsonMappingException, IOException, ClassNotFoundException, SecurityConfigurationException {
        CryptoService crypto = service.get( AesEncryptable.class, CryptoService.class );
        String className = null;
        String objectString = null;
        try {
            className = crypto.decrypt( (BlockCiphertext) getEncryptedClassName() );
            objectString = crypto.decrypt( (BlockCiphertext) getEncryptedData() );
        } catch ( InvalidKeyException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( InvalidAlgorithmParameterException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( NoSuchAlgorithmException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( NoSuchPaddingException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( InvalidKeySpecException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( IllegalBlockSizeException e ) {
            wrapSecurityConfigurationException( e );
        } catch ( BadPaddingException e ) {
            wrapSecurityConfigurationException( e );
        }

        @SuppressWarnings( "unchecked" )
        T obj = mapper.<T> readValue( objectString, (Class<T>) Class.forName( className ) );
        return new AesEncryptable<T>( obj );
    }

    @Override
    protected Encryptable<T> createEncrypted( Ciphertext ciphertext, Ciphertext className ) {
        return new AesEncryptable<T>( (BlockCiphertext) ciphertext, (BlockCiphertext) className );
    }

    @Override
    protected boolean canDecryptWith( SecurityConfigurationMapping mapping ) {
        if ( mapping == null ) {
            return false;
        }
        return mapping.contains( AesEncryptable.class, CryptoService.class );
    }

    // TODO: a little bit yucky. we should centralize this config
    public static void setObjectMapper( ObjectMapper mapper ) {
        AesEncryptable.mapper = mapper;
    }

}
{'fraction_non_alphanumeric': 0.07586978987254564, 'fraction_numerical': 0.004305890458146745, 'mean_word_length': 3.602853745541023, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 14}, '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': '3750494', 'n_tokens_mistral': 3001, 'n_tokens_neox': 2871, 'n_words': 599}