Search in sources :

Example 1 with ProcessingException

use of com.pushtorefresh.storio.common.annotations.processor.ProcessingException in project storio by pushtorefresh.

the class StorIOContentResolverProcessor method processAnnotatedExecutables.

/**
     * Processes factory methods or constructors annotated with {@link StorIOContentResolverCreator}.
     *
     * @param roundEnvironment current processing environment
     * @param annotatedClasses map of classes annotated with {@link StorIOContentResolverType}
     */
@Override
protected void processAnnotatedExecutables(@NotNull RoundEnvironment roundEnvironment, @NotNull Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
    final Set<? extends Element> elementsAnnotatedWithStorIOContentResolverCreator = roundEnvironment.getElementsAnnotatedWith(StorIOContentResolverCreator.class);
    for (final Element annotatedElement : elementsAnnotatedWithStorIOContentResolverCreator) {
        final ExecutableElement annotatedExecutableElement = (ExecutableElement) annotatedElement;
        validateAnnotatedExecutable(annotatedExecutableElement);
        final StorIOContentResolverCreatorMeta storIOContentResolverCreatorMeta = new StorIOContentResolverCreatorMeta(annotatedExecutableElement.getEnclosingElement(), annotatedExecutableElement, annotatedExecutableElement.getAnnotation(StorIOContentResolverCreator.class));
        final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta = annotatedClasses.get(storIOContentResolverCreatorMeta.enclosingElement);
        // If class already contains another creator -> throw exception.
        if (storIOContentResolverTypeMeta.creator == null) {
            storIOContentResolverTypeMeta.creator = annotatedExecutableElement;
        } else {
            throw new ProcessingException(annotatedExecutableElement, "Only one creator method or constructor is allowed: " + annotatedExecutableElement.getEnclosingElement().getSimpleName());
        }
    }
}
Also used : StorIOContentResolverTypeMeta(com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta) StorIOContentResolverCreatorMeta(com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverCreatorMeta) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) StorIOContentResolverCreator(com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverCreator) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException)

Example 2 with ProcessingException

use of com.pushtorefresh.storio.common.annotations.processor.ProcessingException in project storio by pushtorefresh.

the class StorIOSQLiteProcessor method processAnnotatedFieldOrMethod.

/**
     * Processes annotated field and returns result of processing or throws exception.
     *
     * @param annotatedField field that was annotated with {@link StorIOSQLiteColumn}
     * @return non-null {@link StorIOSQLiteColumnMeta} with meta information about field
     */
@NotNull
@Override
protected StorIOSQLiteColumnMeta processAnnotatedFieldOrMethod(@NotNull final Element annotatedField) {
    final JavaType javaType;
    try {
        javaType = JavaType.from(annotatedField.getKind() == ElementKind.FIELD ? annotatedField.asType() : ((ExecutableElement) annotatedField).getReturnType());
    } catch (Exception e) {
        throw new ProcessingException(annotatedField, "Unsupported type of field or method for " + StorIOSQLiteColumn.class.getSimpleName() + " annotation, if you need to serialize/deserialize field of that type " + "-> please write your own resolver: " + e.getMessage());
    }
    final StorIOSQLiteColumn storIOSQLiteColumn = annotatedField.getAnnotation(StorIOSQLiteColumn.class);
    if (storIOSQLiteColumn.ignoreNull() && annotatedField.asType().getKind().isPrimitive()) {
        throw new ProcessingException(annotatedField, "ignoreNull should not be used for primitive type: " + annotatedField.getSimpleName());
    }
    final String columnName = storIOSQLiteColumn.name();
    if (columnName.length() == 0) {
        throw new ProcessingException(annotatedField, "Column name is empty: " + annotatedField.getSimpleName());
    }
    return new StorIOSQLiteColumnMeta(annotatedField.getEnclosingElement(), annotatedField, annotatedField.getSimpleName().toString(), javaType, storIOSQLiteColumn);
}
Also used : StorIOSQLiteColumn(com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn) StorIOSQLiteColumnMeta(com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta) JavaType(com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException) SkipNotAnnotatedClassWithAnnotatedParentException(com.pushtorefresh.storio.common.annotations.processor.SkipNotAnnotatedClassWithAnnotatedParentException) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with ProcessingException

use of com.pushtorefresh.storio.common.annotations.processor.ProcessingException in project storio by pushtorefresh.

the class StorIOSQLiteProcessor method validateAnnotatedClassesAndColumns.

@Override
protected void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement, StorIOSQLiteTypeMeta> annotatedClasses) {
    // Check that each annotated class has columns with at least one key column.
    for (final Map.Entry<TypeElement, StorIOSQLiteTypeMeta> annotatedType : annotatedClasses.entrySet()) {
        final StorIOSQLiteTypeMeta storIOSQLiteTypeMeta = annotatedType.getValue();
        if (storIOSQLiteTypeMeta.columns.size() == 0) {
            throw new ProcessingException(annotatedType.getKey(), "Class marked with " + StorIOSQLiteType.class.getSimpleName() + " annotation should have at least one field or method marked with " + StorIOSQLiteColumn.class.getSimpleName() + " annotation: " + storIOSQLiteTypeMeta.simpleName);
        }
        boolean hasAtLeastOneKeyColumn = false;
        for (final StorIOSQLiteColumnMeta columnMeta : storIOSQLiteTypeMeta.columns.values()) {
            if (columnMeta.storIOColumn.key()) {
                hasAtLeastOneKeyColumn = true;
                break;
            }
        }
        if (!hasAtLeastOneKeyColumn) {
            throw new ProcessingException(annotatedType.getKey(), "Class marked with " + StorIOSQLiteType.class.getSimpleName() + " annotation should have at least one KEY field or method marked with " + StorIOSQLiteColumn.class.getSimpleName() + " annotation: " + storIOSQLiteTypeMeta.simpleName);
        }
        if (storIOSQLiteTypeMeta.needCreator && storIOSQLiteTypeMeta.creator == null) {
            throw new ProcessingException(annotatedType.getKey(), "Class marked with " + StorIOSQLiteType.class.getSimpleName() + " annotation needs factory method or constructor marked with " + StorIOSQLiteCreator.class.getSimpleName() + " annotation: " + storIOSQLiteTypeMeta.simpleName);
        }
        if (storIOSQLiteTypeMeta.needCreator && storIOSQLiteTypeMeta.creator.getParameters().size() != storIOSQLiteTypeMeta.columns.size()) {
            throw new ProcessingException(annotatedType.getKey(), "Class marked with " + StorIOSQLiteType.class.getSimpleName() + " annotation needs factory method or constructor marked with " + StorIOSQLiteCreator.class.getSimpleName() + " annotation with the same amount of parameters as the number of columns: " + storIOSQLiteTypeMeta.simpleName);
        }
    }
}
Also used : StorIOSQLiteColumnMeta(com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta) StorIOSQLiteTypeMeta(com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta) TypeElement(javax.lang.model.element.TypeElement) Map(java.util.Map) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException)

Example 4 with ProcessingException

use of com.pushtorefresh.storio.common.annotations.processor.ProcessingException in project storio by pushtorefresh.

the class StorIOSQLiteProcessor method processAnnotatedClass.

/**
     * Processes annotated class.
     *
     * @param classElement type element annotated with {@link StorIOSQLiteType}
     * @param elementUtils utils for working with elementUtils
     * @return result of processing as {@link StorIOSQLiteTypeMeta}
     */
@NotNull
@Override
protected StorIOSQLiteTypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils) {
    final StorIOSQLiteType storIOSQLiteType = classElement.getAnnotation(StorIOSQLiteType.class);
    final String tableName = storIOSQLiteType.table();
    if (tableName.length() == 0) {
        throw new ProcessingException(classElement, "Table name of " + classElement.getSimpleName() + " annotated with " + StorIOSQLiteType.class.getSimpleName() + " is empty");
    }
    final String simpleName = classElement.getSimpleName().toString();
    final String packageName = elementUtils.getPackageOf(classElement).getQualifiedName().toString();
    return new StorIOSQLiteTypeMeta(simpleName, packageName, storIOSQLiteType, classElement.getModifiers().contains(Modifier.ABSTRACT));
}
Also used : StorIOSQLiteTypeMeta(com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta) StorIOSQLiteType(com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with ProcessingException

use of com.pushtorefresh.storio.common.annotations.processor.ProcessingException in project storio by pushtorefresh.

the class StorIOContentResolverProcessor method processAnnotatedFieldsOrMethods.

/**
     * Processes fields annotated with {@link StorIOContentResolverColumn}
     *
     * @param roundEnvironment current processing environment
     * @param annotatedClasses map of classes annotated with {@link StorIOContentResolverType}
     */
@Override
protected void processAnnotatedFieldsOrMethods(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
    final Set<? extends Element> elementsAnnotatedWithStorIOContentResolverColumn = roundEnvironment.getElementsAnnotatedWith(StorIOContentResolverColumn.class);
    for (final Element annotatedFieldElement : elementsAnnotatedWithStorIOContentResolverColumn) {
        try {
            validateAnnotatedFieldOrMethod(annotatedFieldElement);
            final StorIOContentResolverColumnMeta storIOContentResolverColumnMeta = processAnnotatedFieldOrMethod(annotatedFieldElement);
            final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta = annotatedClasses.get(storIOContentResolverColumnMeta.enclosingElement);
            // If class already contains column with same name -> throw an exception.
            if (storIOContentResolverTypeMeta.columns.containsKey(storIOContentResolverColumnMeta.storIOColumn.name())) {
                throw new ProcessingException(annotatedFieldElement, "Column name already used in this class: " + storIOContentResolverColumnMeta.storIOColumn.name());
            }
            // If field annotation applied to both fields and methods in a same class.
            if ((storIOContentResolverTypeMeta.needCreator && !storIOContentResolverColumnMeta.isMethod()) || (!storIOContentResolverTypeMeta.needCreator && storIOContentResolverColumnMeta.isMethod() && !storIOContentResolverTypeMeta.columns.isEmpty())) {
                throw new ProcessingException(annotatedFieldElement, "Can't apply " + StorIOContentResolverColumn.class.getSimpleName() + " annotation to both fields and methods in a same class: " + storIOContentResolverTypeMeta.simpleName);
            }
            // If column needs creator then enclosing class needs it as well.
            if (!storIOContentResolverTypeMeta.needCreator && storIOContentResolverColumnMeta.isMethod()) {
                storIOContentResolverTypeMeta.needCreator = true;
            }
            // Put meta column info.
            storIOContentResolverTypeMeta.columns.put(storIOContentResolverColumnMeta.storIOColumn.name(), storIOContentResolverColumnMeta);
        } catch (SkipNotAnnotatedClassWithAnnotatedParentException e) {
            messager.printMessage(WARNING, e.getMessage());
        }
    }
}
Also used : StorIOContentResolverTypeMeta(com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) SkipNotAnnotatedClassWithAnnotatedParentException(com.pushtorefresh.storio.common.annotations.processor.SkipNotAnnotatedClassWithAnnotatedParentException) StorIOContentResolverColumnMeta(com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta) ProcessingException(com.pushtorefresh.storio.common.annotations.processor.ProcessingException)

Aggregations

ProcessingException (com.pushtorefresh.storio.common.annotations.processor.ProcessingException)9 TypeElement (javax.lang.model.element.TypeElement)6 SkipNotAnnotatedClassWithAnnotatedParentException (com.pushtorefresh.storio.common.annotations.processor.SkipNotAnnotatedClassWithAnnotatedParentException)4 StorIOSQLiteTypeMeta (com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta)4 Element (javax.lang.model.element.Element)4 ExecutableElement (javax.lang.model.element.ExecutableElement)4 StorIOContentResolverColumnMeta (com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta)3 StorIOContentResolverTypeMeta (com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta)3 StorIOSQLiteColumnMeta (com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta)3 NotNull (org.jetbrains.annotations.NotNull)3 JavaType (com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType)2 Map (java.util.Map)2 StorIOContentResolverColumn (com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverColumn)1 StorIOContentResolverCreator (com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverCreator)1 StorIOContentResolverCreatorMeta (com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverCreatorMeta)1 StorIOSQLiteColumn (com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn)1 StorIOSQLiteCreator (com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteCreator)1 StorIOSQLiteType (com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType)1 StorIOSQLiteCreatorMeta (com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteCreatorMeta)1 HashMap (java.util.HashMap)1