<commit_before>package com.arconsis.android.datarobot.builder.schema.reader;

import com.arconsis.android.datarobot.builder.schema.data.ColumnValidation;
import com.arconsis.android.datarobot.builder.schema.data.ValidatorInfo;
import com.arconsis.android.datarobot.builder.schema.visitor.ColumnDeclaredTypeRetrievalVisitor;
import com.arconsis.android.datarobot.builder.schema.visitor.DefaultTypeVisitor;
import com.arconsis.android.datarobot.builder.schema.visitor.ValidatorAllowedTypeRetrievalVisitor;
import com.arconsis.android.datarobot.validation.Validator;

import javax.annotation.processing.Messager;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <NAME>
 * @author <NAME>
 */
public class ColumnValidationReader implements Reader<ColumnValidation> {

    public static final String VALIDATOR_VALUE_METHOD_NAME = "value";

    private VariableElement column;
    private Elements elements;
    private final Messager messager;

    public ColumnValidationReader(final VariableElement column, final Elements elements, final Messager messager) {
        this.column = column;
        this.elements = elements;
        this.messager = messager;
    }

    @Override
    public ColumnValidation read() {
        ColumnValidation columnValidation = new ColumnValidation();

        List<? extends AnnotationMirror> annotationMirrors = column.getAnnotationMirrors();
        for (AnnotationMirror variableAnnotationMirror : annotationMirrors) {
            Element element = variableAnnotationMirror.getAnnotationType().asElement();
            for (AnnotationMirror annotationTypeMirror : element.getAnnotationMirrors()) {
                if (isValidatorAnnotation(annotationTypeMirror)) {
                    String validatorClass = getValidatorClass(annotationTypeMirror, element);
                    String validatorAnnotation = element.toString();
                    Map<String, Object> parameter = getValidationParameter(variableAnnotationMirror);
                    if (isParameterTypesValid(parameter)) {
                        columnValidation.add(new ValidatorInfo(validatorClass, validatorAnnotation, parameter));
                    } else {
                        messager.printMessage(Diagnostic.Kind.ERROR, "Validator annotation " + validatorAnnotation + " has invalid parameters types. Allowed are numbers (primitive and boxed) and String", element);
                    }
                }
            }
        }

        return columnValidation;
    }

    private boolean isParameterTypesValid(Map<String, Object> parameter) {
        for (Object paramValue : parameter.values()) {
            if (!isValid(paramValue)) {
                return false;
            }
        }
        return true;
    }

    private boolean isValid(Object value) {
        Class<?> paramType = value.getClass();
        return paramType.equals(java.lang.String.class)  //
                || paramType.equals(java.lang.Integer.class) //
                || paramType.equals(java.lang.Float.class) //
                || paramType.equals(java.lang.Double.class) //
                || paramType.equals(java.lang.Long.class) //
                || paramType.equals(java.lang.Short.class);
    }

    private boolean isValidatorAnnotation(AnnotationMirror mirror) {
        return mirror.getAnnotationType().asElement().toString().equals(Validator.class.getCanonicalName());
    }

    private String getValidatorClass(AnnotationMirror mirror, Element element) {
        Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = mirror.getElementValues();
        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
            if (entry.getKey().getSimpleName().toString().equals(VALIDATOR_VALUE_METHOD_NAME)) {
                AnnotationValue value = entry.getValue();
                TypeElement acceptedType = value.accept(new ValidatorAllowedTypeRetrievalVisitor(column, messager), null);
                TypeElement actualType = column.accept(new ColumnDeclaredTypeRetrievalVisitor(), null);
                TypeKind columnTypeKind = column.asType().getKind();

                if (columnTypeKind.isPrimitive() && compareTypeWithPrimitive(acceptedType, columnTypeKind)) {
                    return value.getValue().toString();
                } else if (!columnTypeKind.isPrimitive() && compareTypeWithDeclared(acceptedType, actualType)) {
                    return value.getValue().toString();
                } else {<commit_msg>Added byte as a supported type<commit_after>package com.arconsis.android.datarobot.builder.schema.reader;

import com.arconsis.android.datarobot.builder.schema.data.ColumnValidation;
import com.arconsis.android.datarobot.builder.schema.data.ValidatorInfo;
import com.arconsis.android.datarobot.builder.schema.visitor.ColumnDeclaredTypeRetrievalVisitor;
import com.arconsis.android.datarobot.builder.schema.visitor.DefaultTypeVisitor;
import com.arconsis.android.datarobot.builder.schema.visitor.ValidatorAllowedTypeRetrievalVisitor;
import com.arconsis.android.datarobot.validation.Validator;

import javax.annotation.processing.Messager;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <NAME>
 * @author <NAME>
 */
public class ColumnValidationReader implements Reader<ColumnValidation> {

    public static final String VALIDATOR_VALUE_METHOD_NAME = "value";

    private VariableElement column;
    private Elements elements;
    private final Messager messager;

    public ColumnValidationReader(final VariableElement column, final Elements elements, final Messager messager) {
        this.column = column;
        this.elements = elements;
        this.messager = messager;
    }

    @Override
    public ColumnValidation read() {
        ColumnValidation columnValidation = new ColumnValidation();

        List<? extends AnnotationMirror> annotationMirrors = column.getAnnotationMirrors();
        for (AnnotationMirror variableAnnotationMirror : annotationMirrors) {
            Element element = variableAnnotationMirror.getAnnotationType().asElement();
            for (AnnotationMirror annotationTypeMirror : element.getAnnotationMirrors()) {
                if (isValidatorAnnotation(annotationTypeMirror)) {
                    String validatorClass = getValidatorClass(annotationTypeMirror, element);
                    String validatorAnnotation = element.toString();
                    Map<String, Object> parameter = getValidationParameter(variableAnnotationMirror);
                    if (isParameterTypesValid(parameter)) {
                        columnValidation.add(new ValidatorInfo(validatorClass, validatorAnnotation, parameter));
                    } else {
                        messager.printMessage(Diagnostic.Kind.ERROR, "Validator annotation " + validatorAnnotation + " has invalid parameters types. Allowed are numbers (primitive and boxed) and String", element);
                    }
                }
            }
        }

        return columnValidation;
    }

    private boolean isParameterTypesValid(Map<String, Object> parameter) {
        for (Object paramValue : parameter.values()) {
            if (!isValid(paramValue)) {
                return false;
            }
        }
        return true;
    }

    private boolean isValid(Object value) {
        Class<?> paramType = value.getClass();
        return paramType.equals(java.lang.String.class)  //
                || paramType.equals(java.lang.Integer.class) //
                || paramType.equals(java.lang.Float.class) //
                || paramType.equals(java.lang.Double.class) //
                || paramType.equals(java.lang.Long.class) //
                || paramType.equals(java.lang.Short.class) //
                || paramType.equals(java.lang.Byte.class);
    }

    private boolean isValidatorAnnotation(AnnotationMirror mirror) {
        return mirror.getAnnotationType().asElement().toString().equals(Validator.class.getCanonicalName());
    }

    private String getValidatorClass(AnnotationMirror mirror, Element element) {
        Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = mirror.getElementValues();
        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
            if (entry.getKey().getSimpleName().toString().equals(VALIDATOR_VALUE_METHOD_NAME)) {
                AnnotationValue value = entry.getValue();
                TypeElement acceptedType = value.accept(new ValidatorAllowedTypeRetrievalVisitor(column, messager), null);
                TypeElement actualType = column.accept(new ColumnDeclaredTypeRetrievalVisitor(), null);
                TypeKind columnTypeKind = column.asType().getKind();

                if (columnTypeKind.isPrimitive() && compareTypeWithPrimitive(acceptedType, columnTypeKind)) {
                    return value.getValue().toString();
                } else if (!columnTypeKind.isPrimitive() && compareTypeWithDeclared(acceptedType, actualType)) {
                    return value.getValue().toString();
                } else {
{'fraction_non_alphanumeric': 0.09581086686022397, 'fraction_numerical': 0.0, 'mean_word_length': 3.0237797246558196, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '6446027', 'n_tokens_mistral': 2436, 'n_tokens_neox': 2336, 'n_words': 460}