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

org.droitateddb.builder.schema.reader.ColumnValidationReader Maven / Gradle / Ivy

Go to download

droitatedDB is a lightweight framework, which frees you from the burden of dealing with Androids SQLite database directly if you don't want to and let's you access it directly if you have to.

There is a newer version: 0.1.8
Show newest version
package org.droitateddb.builder.schema.reader;

import org.droitateddb.builder.schema.data.ColumnValidation;
import org.droitateddb.builder.schema.data.ValidatorInfo;
import org.droitateddb.builder.schema.visitor.ColumnDeclaredTypeRetrievalVisitor;
import org.droitateddb.builder.schema.visitor.DefaultTypeVisitor;
import org.droitateddb.builder.schema.visitor.ValidatorAllowedTypeRetrievalVisitor;
import org.droitateddb.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 Falk Appel
 * @author Alexander Frank
 */
public class ColumnValidationReader implements Reader {

    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 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 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 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 elementValues = mirror.getElementValues();
        for (Map.Entry 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 {
                    messager.printMessage(Diagnostic.Kind.ERROR, "The validator annotation " + element.toString() + " is not allowed on this type of column. Accepted is " + acceptedType.toString(), column);
                    return null;

                }
            }
        }
        messager.printMessage(Diagnostic.Kind.ERROR, "No value set for Validator annotation", mirror.getAnnotationType().asElement());
        return null;
    }

    private boolean compareTypeWithPrimitive(TypeElement acceptedType, TypeKind columnTypeKind) {
        return acceptedType.getQualifiedName().toString().equals(getBoxedClassName(columnTypeKind)) || acceptedType.getQualifiedName().toString().equals(Number.class.getCanonicalName());
    }

    private boolean compareTypeWithDeclared(TypeElement acceptedType, TypeElement actualType) {
        if (acceptedType.getQualifiedName().equals(actualType.getQualifiedName())) {
            return true;
        }

        TypeMirror superclass = actualType.getSuperclass();
        if (superclass.getKind().equals(TypeKind.NONE)) {
            return false;
        } else {
            TypeElement superTypeElement = superclass.accept(new DefaultTypeVisitor() {
                @Override
                public TypeElement visitDeclared(DeclaredType t, Void aVoid) {
                    return (TypeElement) t.asElement();
                }
            }, null);
            return compareTypeWithDeclared(acceptedType, superTypeElement);
        }
    }

    private String getBoxedClassName(TypeKind kind) {
        switch (kind) {
            case LONG:
                return Long.class.getCanonicalName();
            case INT:
                return Integer.class.getCanonicalName();
            case BYTE:
                return Byte.class.getCanonicalName();
            case SHORT:
                return Short.class.getCanonicalName();
            case FLOAT:
                return Float.class.getCanonicalName();
            case DOUBLE:
                return Double.class.getCanonicalName();
            default:
                return "Unknown";
        }
    }

    private Map getValidationParameter(AnnotationMirror mirror) {
        Map elementValues = elements.getElementValuesWithDefaults(mirror);
        Map parameter = new HashMap();
        for (Map.Entry elem : elementValues.entrySet()) {
            parameter.put(elem.getKey().getSimpleName().toString(), elem.getValue().getValue());
        }
        return parameter;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy