<commit_before>package gov.nih.nci.cabig.ctms.audit;

import gov.nih.nci.cabig.ctms.audit.dao.DataAuditRepository;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditEvent;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditEventValue;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditInfo;
import gov.nih.nci.cabig.ctms.audit.domain.Operation;
import gov.nih.nci.cabig.ctms.audit.exception.AuditSystemException;
import gov.nih.nci.cabig.ctms.audit.util.AuditUtil;
import gov.nih.nci.cabig.ctms.lang.ComparisonTools;
import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author <NAME>
 * @author <NAME>
 */
public class AuditInterceptorImpl extends EmptyInterceptor {

    /** The Constant log. */
    private static final Logger log = LoggerFactory.getLogger(AuditInterceptorImpl.class);

    private static final ThreadLocal<AuditSession> sessions = new ThreadLocal<AuditSession>();

    /** The Constant ENTITY_MODE. */
    private static final EntityMode ENTITY_MODE = EntityMode.POJO;

    /** The data audit dao. */
    private DataAuditRepository dataAuditRepository;

    private List<String> auditableEntities = new ArrayList<String>();

    private final String HIBERNATE_BACK_REF_STRING = "Backref";

    private boolean auditAll = false;

    private void appendEventValues(final DataAuditEvent parent, final Type propertyType, final String propertyName,
                                   final Object previousState, final Object currentState) {
        List<DataAuditEventValue> values = Collections.emptyList();
        if (ignoreCurrentStateForThisType(propertyType) || propertyName.indexOf(HIBERNATE_BACK_REF_STRING) > 0) {
            // none
        }
        else if (propertyType.isComponentType()) {
            values = decomposeComponent((AbstractComponentType) propertyType, propertyName, previousState, currentState);
        }
        else {
            String prevValue = scalarAuditableValue(previousState);
            String curValue = scalarAuditableValue(currentState);
            if (prevValue != null && curValue != null && prevValue.equals(curValue)) {
                // do not log it..it might be because of lazy ManyToOne or
                // OneToOne
                // fetching..
            }
            else if (prevValue == null && curValue == null) {
                // do not log it..
            }
            else {
                values = Arrays.asList(new DataAuditEventValue(propertyName, prevValue, curValue));

            }
        }
        for (DataAuditEventValue value : values) {
            parent.addValue(value);
        }
    }

    private boolean auditable(final Object entity) {
        if (auditAll) {
            return true;
        }
        else if (auditableEntities.contains(entity.getClass().getName())) {
            return true;
        }
        // auditable &= entity instanceof Object;
        // auditable &= entity.getClass().getName().indexOf("auditing") < 0;
        // if (auditable) {
        // return true;
        // }
        //
        else {
            log.debug("No auditing for instances of " + entity.getClass().getName());
            return false;
        }
    }

    private void closeAuditSession() {
        getAuditSession().close();
        sessions.set(null);
    }

    // TODO: this only handles one level of components
    private List<DataAuditEventValue> decomposeComponent(final AbstractComponentType propertyType,
                                                         final String propertyName, final Object previousState, final Object currentState) {
        Object[] componentPrevState = previousState == null ? null : propertyType.getPropertyValues(previousState,
            ENTITY_MODE);
        Object[] componentCurState = currentState == null ? null : propertyType.getPropertyValues(currentState,
            ENTITY_MODE);
        List<Integer> differences = findDifferences(componentCurState, componentPrevState, null);
        List<DataAuditEventValue> values = new ArrayList<DataAuditEventValue>(differences.size());
        for (Integer index : differences) {
            String compPropertyName = propertyName + '.' + propertyType.getPropertyNames()[index];
            values.add(new DataAuditEventValue(compPropertyName, previousState == null ? null
                : scalarAuditableValue(componentPrevState[index]), currentState == null ? null
                : scalarAuditableValue(componentCurState[index])));
        }
        return values;
    }

    // package-level for testing
    List<Integer> findDifferences(final Object[] currentState, final Object[] previousState, final Type[] types) {

        List<Integer> differences = new ArrayList<Integer>();<commit_msg>Update for Hibernate 3.6 compatibility.<commit_after>package gov.nih.nci.cabig.ctms.audit;

import gov.nih.nci.cabig.ctms.audit.dao.DataAuditRepository;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditEvent;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditEventValue;
import gov.nih.nci.cabig.ctms.audit.domain.DataAuditInfo;
import gov.nih.nci.cabig.ctms.audit.domain.Operation;
import gov.nih.nci.cabig.ctms.audit.exception.AuditSystemException;
import gov.nih.nci.cabig.ctms.audit.util.AuditUtil;
import gov.nih.nci.cabig.ctms.lang.ComparisonTools;
import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.type.CollectionType;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author <NAME>
 * @author <NAME>
 */
public class AuditInterceptorImpl extends EmptyInterceptor {

    /** The Constant log. */
    private static final Logger log = LoggerFactory.getLogger(AuditInterceptorImpl.class);

    private static final ThreadLocal<AuditSession> sessions = new ThreadLocal<AuditSession>();

    /** The Constant ENTITY_MODE. */
    private static final EntityMode ENTITY_MODE = EntityMode.POJO;

    /** The data audit dao. */
    private DataAuditRepository dataAuditRepository;

    private List<String> auditableEntities = new ArrayList<String>();

    private final String HIBERNATE_BACK_REF_STRING = "Backref";

    private boolean auditAll = false;

    private void appendEventValues(final DataAuditEvent parent, final Type propertyType, final String propertyName,
                                   final Object previousState, final Object currentState) {
        List<DataAuditEventValue> values = Collections.emptyList();
        if (ignoreCurrentStateForThisType(propertyType) || propertyName.indexOf(HIBERNATE_BACK_REF_STRING) > 0) {
            // none
        }
        else if (propertyType.isComponentType()) {
            values = decomposeComponent((CompositeType) propertyType, propertyName, previousState, currentState);
        }
        else {
            String prevValue = scalarAuditableValue(previousState);
            String curValue = scalarAuditableValue(currentState);
            if (prevValue != null && curValue != null && prevValue.equals(curValue)) {
                // do not log it..it might be because of lazy ManyToOne or
                // OneToOne
                // fetching..
            }
            else if (prevValue == null && curValue == null) {
                // do not log it..
            }
            else {
                values = Arrays.asList(new DataAuditEventValue(propertyName, prevValue, curValue));

            }
        }
        for (DataAuditEventValue value : values) {
            parent.addValue(value);
        }
    }

    private boolean auditable(final Object entity) {
        if (auditAll) {
            return true;
        }
        else if (auditableEntities.contains(entity.getClass().getName())) {
            return true;
        }
        // auditable &= entity instanceof Object;
        // auditable &= entity.getClass().getName().indexOf("auditing") < 0;
        // if (auditable) {
        // return true;
        // }
        //
        else {
            log.debug("No auditing for instances of " + entity.getClass().getName());
            return false;
        }
    }

    private void closeAuditSession() {
        getAuditSession().close();
        sessions.set(null);
    }

    // TODO: this only handles one level of components
    private List<DataAuditEventValue> decomposeComponent(final CompositeType propertyType,
                                                         final String propertyName, final Object previousState, final Object currentState) {
        Object[] componentPrevState = previousState == null ? null : propertyType.getPropertyValues(previousState,
            ENTITY_MODE);
        Object[] componentCurState = currentState == null ? null : propertyType.getPropertyValues(currentState,
            ENTITY_MODE);
        List<Integer> differences = findDifferences(componentCurState, componentPrevState, null);
        List<DataAuditEventValue> values = new ArrayList<DataAuditEventValue>(differences.size());
        for (Integer index : differences) {
            String compPropertyName = propertyName + '.' + propertyType.getPropertyNames()[index];
            values.add(new DataAuditEventValue(compPropertyName, previousState == null ? null
                : scalarAuditableValue(componentPrevState[index]), currentState == null ? null
                : scalarAuditableValue(componentCurState[index])));
        }
        return values;
    }

    // package-level for testing
    List<Integer> findDifferences(final Object[] currentState, final Object[] previousState, final Type[] types) {

        List<Integer> differences = new ArrayList<Integer>();
{'fraction_non_alphanumeric': 0.09879148283138309, 'fraction_numerical': 0.0009591406100134279, 'mean_word_length': 2.8124314442413163, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5630630', 'n_tokens_mistral': 2850, 'n_tokens_neox': 2781, 'n_words': 617}