Skip to content
Browse files

Add module with common annotations processing logic

  • Loading branch information...
1 parent d674259 commit 5ed18e6a350aab1ab349f61f3514e87e968ba52c @nikitin-da nikitin-da committed
Showing with 611 additions and 824 deletions.
  1. +2 −1 build.gradle
  2. +3 −2 settings.gradle
  3. +16 −0 storio-common-annotations-processor/build.gradle
  4. +3 −0 storio-common-annotations-processor/gradle.properties
  5. +2 −2 ...sor/src/main/java/com/pushtorefresh/storio/common}/annotations/processor/ProcessingException.java
  6. +225 −0 ...c/main/java/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java
  7. +10 −0 ...rocessor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Common.java
  8. +12 −0 ...c/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java
  9. +1 −1 .../src/main/java/com/pushtorefresh/storio/common}/annotations/processor/introspection/JavaType.java
  10. +73 −0 ...in/java/com/pushtorefresh/storio/common/annotations/processor/introspection/StorIOColumnMeta.java
  11. +67 −0 ...main/java/com/pushtorefresh/storio/common/annotations/processor/introspection/StorIOTypeMeta.java
  12. +15 −15 .../test/java/com/pushtorefresh/storio/common}/annotations/processor/introspection/JavaTypeTest.java
  13. +1 −0 storio-content-resolver-annotations-processor/build.gradle
  14. +0 −31 ...main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/ProcessingException.java
  15. +40 −112 ...om/pushtorefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java
  16. +0 −10 ...src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/Common.java
  17. +5 −4 .../pushtorefresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java
  18. +21 −20 ...com/pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java
  19. +7 −6 ...com/pushtorefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java
  20. +3 −3 .../java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/QueryGenerator.java
  21. +0 −62 ...n/java/com/pushtorefresh/storio/contentresolver/annotations/processor/introspection/JavaType.java
  22. +5 −58 ...h/storio/contentresolver/annotations/processor/introspection/StorIOContentResolverColumnMeta.java
  23. +4 −56 ...esh/storio/contentresolver/annotations/processor/introspection/StorIOContentResolverTypeMeta.java
  24. +1 −1 ...pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGeneratorTest.java
  25. +0 −126 ...va/com/pushtorefresh/storio/contentresolver/annotations/processor/introspection/JavaTypeTest.java
  26. +1 −0 storio-sqlite-annotations-processor/build.gradle
  27. +39 −157 ...or/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java
  28. +0 −10 ...rocessor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/Common.java
  29. +5 −4 .../java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java
  30. +21 −20 ...ain/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java
  31. +7 −6 ...ain/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java
  32. +3 −3 .../src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/QueryGenerator.java
  33. +10 −57 ...a/com/pushtorefresh/storio/sqlite/annotations/processor/introspection/StorIOSQLiteColumnMeta.java
  34. +8 −56 ...ava/com/pushtorefresh/storio/sqlite/annotations/processor/introspection/StorIOSQLiteTypeMeta.java
  35. +1 −1 ...java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGeneratorTest.java
View
3 build.gradle
@@ -74,8 +74,9 @@ ext.libraries = [
storIOSQLite : project(':storio-sqlite'),
storIOContentResolver : project(':storio-content-resolver'),
storIOSQLiteAnnotations : project(':storio-sqlite-annotations'),
- storIOSQLiteAnnotationsProcessor : project(':storio-sqlite-annotations-processor'),
storIOContentResolverAnnotations : project(':storio-content-resolver-annotations'),
+ storIOCommonAnnotationsProcessor : project(':storio-common-annotations-processor'),
+ storIOSQLiteAnnotationsProcessor : project(':storio-sqlite-annotations-processor'),
storIOContentResolverAnnotationsProcessor : project(':storio-content-resolver-annotations-processor'),
storIOTestCommon : project(':storio-test-common'),
View
5 settings.gradle
@@ -4,9 +4,10 @@ include ':storio-sqlite'
include ':storio-content-resolver'
include ':storio-sqlite-annotations'
-include ':storio-sqlite-annotations-processor'
-
include ':storio-content-resolver-annotations'
+
+include ':storio-common-annotations-processor'
+include ':storio-sqlite-annotations-processor'
include ':storio-content-resolver-annotations-processor'
include ':storio-test-without-rxjava'
View
16 storio-common-annotations-processor/build.gradle
@@ -0,0 +1,16 @@
+apply plugin: 'java'
+
+targetCompatibility = '1.6'
+sourceCompatibility = '1.6'
+
+dependencies {
+ compile libraries.intellijAnnotations
+ compile libraries.autoService
+ compile libraries.javaPoet
+
+ testCompile libraries.junit
+ testCompile libraries.assertJ
+ testCompile libraries.mockitoCore
+}
+
+apply from: '../gradle/publish-java-lib.gradle'
View
3 storio-common-annotations-processor/gradle.properties
@@ -0,0 +1,3 @@
+POM_NAME=common-annotations-processor
+POM_ARTIFACT_ID=common-annotations-processor
+POM_PACKAGING=jar
View
4 ...ations/processor/ProcessingException.java → ...ations/processor/ProcessingException.java
@@ -1,4 +1,4 @@
-package com.pushtorefresh.storio.sqlite.annotations.processor;
+package com.pushtorefresh.storio.common.annotations.processor;
import org.jetbrains.annotations.NotNull;
@@ -28,4 +28,4 @@ public ProcessingException(@NotNull Element element, @NotNull String message) {
public Element element() {
return element;
}
-}
+}
View
225 ...ava/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java
@@ -0,0 +1,225 @@
+package com.pushtorefresh.storio.common.annotations.processor;
+
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOColumnMeta;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOTypeMeta;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+import static javax.lang.model.element.ElementKind.CLASS;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+/**
+ * Base annotation processor for StorIO
+ * <p>
+ * It'll process annotations to generate StorIO Object-Mapping
+ * <p>
+ * Addition: Annotation Processor should work fast and be optimized because it's part of compilation
+ * We don't want to annoy developers, who use StorIO
+ */
+// Generate file with annotation processor declaration via another Annotation Processor!
+public abstract class StorIOAnnotationsProcessor
+ <TypeMeta extends StorIOTypeMeta, ColumnMeta extends StorIOColumnMeta>
+ extends AbstractProcessor {
+
+ private Filer filer;
+ private Elements elementUtils;
+ private Messager messager;
+
+ /**
+ * Processes class annotations
+ *
+ * @param roundEnvironment environment
+ * @return non-null unmodifiable map(element, typeMeta)
+ */
+ @NotNull
+ private Map<TypeElement, TypeMeta> processAnnotatedClasses(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Elements elementUtils) {
+ final Set<? extends Element> elementsAnnotatedWithStorIOType
+ = roundEnvironment.getElementsAnnotatedWith(getTypeAnnotationClass());
+
+ final Map<TypeElement, TypeMeta> results
+ = new HashMap<TypeElement, TypeMeta>(elementsAnnotatedWithStorIOType.size());
+
+ for (final Element annotatedElement : elementsAnnotatedWithStorIOType) {
+ final TypeElement classElement = validateAnnotatedClass(annotatedElement);
+ final TypeMeta typeMeta = processAnnotatedClass(classElement, elementUtils);
+ results.put(classElement, typeMeta);
+ }
+
+ return Collections.unmodifiableMap(results);
+ }
+
+ /**
+ * Checks that annotated element satisfies all required conditions
+ *
+ * @param annotatedElement an annotated type
+ * @return {@link TypeElement} object
+ */
+ @NotNull
+ private TypeElement validateAnnotatedClass(@NotNull final Element annotatedElement) {
+ // we expect here that annotatedElement is Class, annotation requires that via @Target
+ final TypeElement annotatedTypeElement = (TypeElement) annotatedElement;
+
+ if (annotatedTypeElement.getModifiers().contains(PRIVATE)) {
+ throw new ProcessingException(
+ annotatedElement,
+ getTypeAnnotationClass().getSimpleName() + " can not be applied to private class: " + annotatedTypeElement.getQualifiedName()
+ );
+ }
+
+ return annotatedTypeElement;
+ }
+
+ /**
+ * Checks that element annotated with {@link StorIOColumnMeta} satisfies all required conditions
+ *
+ * @param annotatedField an annotated field
+ */
+ protected void validateAnnotatedField(@NotNull final Element annotatedField) {
+ // we expect here that annotatedElement is Field, annotation requires that via @Target
+
+ final Element enclosingElement = annotatedField.getEnclosingElement();
+
+ if (!enclosingElement.getKind().equals(CLASS)) {
+ throw new ProcessingException(
+ annotatedField,
+ "Please apply " + getTypeAnnotationClass().getSimpleName() + " to fields of class: " + annotatedField.getSimpleName()
+ );
+ }
+
+ if (enclosingElement.getAnnotation(getTypeAnnotationClass()) == null) {
+ throw new ProcessingException(
+ annotatedField,
+ "Please annotate class " + enclosingElement.getSimpleName() + " with " + getTypeAnnotationClass().getSimpleName()
+ );
+ }
+
+ if (annotatedField.getModifiers().contains(PRIVATE)) {
+ throw new ProcessingException(
+ annotatedField,
+ getColumnAnnotationClass().getSimpleName() + " can not be applied to private field: " + annotatedField.getSimpleName()
+ );
+ }
+
+ if (annotatedField.getModifiers().contains(FINAL)) {
+ throw new ProcessingException(
+ annotatedField,
+ getColumnAnnotationClass().getSimpleName() + " can not be applied to final field: " + annotatedField.getSimpleName()
+ );
+ }
+ }
+
+ @Override
+ public synchronized void init(@NotNull final ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ filer = processingEnv.getFiler();
+ elementUtils = processingEnv.getElementUtils(); // why class name is "Elements" but method "getElementUtils()", OKAY..
+ messager = processingEnv.getMessager();
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latestSupported();
+ }
+
+ //endregion
+
+ /**
+ * For those who don't familiar with Annotation Processing API — this is the main method of Annotation Processor lifecycle
+ * <p>
+ * It will be called after Java Compiler will find lang elements annotated with annotations from {@link #getSupportedAnnotationTypes()}
+ *
+ * @param annotations set of annotations
+ * @param roundEnv environment of current processing round
+ * @return true if annotation processor should not be invoked in next rounds of annotation processing, false otherwise
+ */
+ @Override
+ public boolean process(@Nullable final Set<? extends TypeElement> annotations, @NotNull final RoundEnvironment roundEnv) {
+ try {
+ final Map<TypeElement, TypeMeta> annotatedClasses = processAnnotatedClasses(roundEnv, elementUtils);
+
+ processAnnotatedFields(roundEnv, annotatedClasses);
+
+ validateAnnotatedClassesAndColumns(annotatedClasses);
+
+ final ResolverGenerator<TypeMeta> putResolverGenerator = createPutResolver();
+ final ResolverGenerator<TypeMeta> getResolverGenerator = createGetResolver();
+ final ResolverGenerator<TypeMeta> deleteResolverGenerator = createDeleteResolver();
+
+ for (TypeMeta typeMeta : annotatedClasses.values()) {
+ putResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
+ getResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
+ deleteResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
+ }
+ } catch (ProcessingException e) {
+ messager.printMessage(ERROR, e.getMessage(), e.element());
+ } catch (Exception e) {
+ messager.printMessage(ERROR, "Problem occurred with StorIOProcessor: " + e.getMessage());
+ }
+
+ return true;
+ }
+
+ /**
+ * Processes annotated class
+ *
+ * @param classElement type element
+ * @param elementUtils utils for working with elementUtils
+ * @return result of processing as {@link TypeMeta}
+ */
+ @NotNull
+ protected abstract TypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils);
+
+ /**
+ * Processes fields
+ *
+ * @param roundEnvironment current processing environment
+ * @param annotatedClasses map of annotated classes
+ */
+ protected abstract void processAnnotatedFields(@NotNull final RoundEnvironment roundEnvironment, @NotNull Map<TypeElement, TypeMeta> annotatedClasses);
+
+ /**
+ * Processes annotated field and returns result of processing or throws exception
+ *
+ * @param annotatedField field that was annotated as column
+ * @return non-null {@link StorIOColumnMeta} with meta information about field
+ */
+ @NotNull
+ protected abstract ColumnMeta processAnnotatedField(@NotNull final Element annotatedField);
+
+ protected abstract void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement, TypeMeta> annotatedClasses);
+
+ @NotNull
+ protected abstract Class<? extends Annotation> getTypeAnnotationClass();
+
+ @NotNull
+ protected abstract Class<? extends Annotation> getColumnAnnotationClass();
+
+ @NotNull
+ protected abstract ResolverGenerator<TypeMeta> createPutResolver();
+
+ @NotNull
+ protected abstract ResolverGenerator<TypeMeta> createGetResolver();
+
+ @NotNull
+ protected abstract ResolverGenerator<TypeMeta> createDeleteResolver();
+}
View
10 .../src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Common.java
@@ -0,0 +1,10 @@
+package com.pushtorefresh.storio.common.annotations.processor.generate;
+
+import com.squareup.javapoet.ClassName;
+
+public class Common {
+
+ public static final ClassName ANDROID_NON_NULL_ANNOTATION_CLASS_NAME = ClassName.get("android.support.annotation", "NonNull");
+
+ public static final String INDENT = " "; // 4 spaces
+}
View
12 ...ava/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java
@@ -0,0 +1,12 @@
+package com.pushtorefresh.storio.common.annotations.processor.generate;
+
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOTypeMeta;
+import com.squareup.javapoet.JavaFile;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface ResolverGenerator <TypeMeta extends StorIOTypeMeta> {
+
+ @NotNull
+ JavaFile generateJavaFile(@NotNull TypeMeta typeMeta);
+}
View
2 ...ons/processor/introspection/JavaType.java → ...ons/processor/introspection/JavaType.java
@@ -1,4 +1,4 @@
-package com.pushtorefresh.storio.sqlite.annotations.processor.introspection;
+package com.pushtorefresh.storio.common.annotations.processor.introspection;
import org.jetbrains.annotations.NotNull;
View
73 ...com/pushtorefresh/storio/common/annotations/processor/introspection/StorIOColumnMeta.java
@@ -0,0 +1,73 @@
+package com.pushtorefresh.storio.common.annotations.processor.introspection;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.annotation.Annotation;
+
+import javax.lang.model.element.Element;
+
+public class StorIOColumnMeta <ColumnAnnotation extends Annotation> {
+
+ @NotNull
+ public final Element enclosingElement;
+
+ @NotNull
+ public final Element element;
+
+ @NotNull
+ public final String fieldName;
+
+ @NotNull
+ public final JavaType javaType;
+
+ @NotNull
+ public final ColumnAnnotation storIOColumn;
+
+ public StorIOColumnMeta(
+ @NotNull Element enclosingElement,
+ @NotNull Element element,
+ @NotNull String fieldName,
+ @NotNull JavaType javaType, @NotNull ColumnAnnotation storIOColumn) {
+ this.enclosingElement = enclosingElement;
+ this.element = element;
+ this.fieldName = fieldName;
+ this.javaType = javaType;
+ this.storIOColumn = storIOColumn;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ StorIOColumnMeta<?> that = (StorIOColumnMeta<?>) o;
+
+ if (!enclosingElement.equals(that.enclosingElement)) return false;
+ if (!element.equals(that.element)) return false;
+ if (!fieldName.equals(that.fieldName)) return false;
+ if (javaType != that.javaType) return false;
+ return storIOColumn.equals(that.storIOColumn);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = enclosingElement.hashCode();
+ result = 31 * result + element.hashCode();
+ result = 31 * result + fieldName.hashCode();
+ result = 31 * result + javaType.hashCode();
+ result = 31 * result + storIOColumn.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "StorIOColumnMeta{" +
+ "enclosingElement=" + enclosingElement +
+ ", element=" + element +
+ ", fieldName='" + fieldName + '\'' +
+ ", javaType=" + javaType +
+ ", storIOColumn=" + storIOColumn +
+ '}';
+ }
+}
View
67 ...a/com/pushtorefresh/storio/common/annotations/processor/introspection/StorIOTypeMeta.java
@@ -0,0 +1,67 @@
+package com.pushtorefresh.storio.common.annotations.processor.introspection;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+public class StorIOTypeMeta <TypeAnnotation extends Annotation, ColumnMeta extends StorIOColumnMeta> {
+
+ @NotNull
+ public final String simpleName;
+
+ @NotNull
+ public final String packageName;
+
+ @NotNull
+ public final TypeAnnotation storIOType;
+
+ /**
+ * Yep, this is MODIFIABLE Map, please use it carefully
+ */
+ @NotNull
+ public final Map<String, ColumnMeta> columns = new HashMap<String, ColumnMeta>();
+
+ public StorIOTypeMeta(
+ @NotNull String simpleName,
+ @NotNull String packageName,
+ @NotNull TypeAnnotation storIOType) {
+ this.simpleName = simpleName;
+ this.packageName = packageName;
+ this.storIOType = storIOType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ StorIOTypeMeta<?, ?> that = (StorIOTypeMeta<?, ?>) o;
+
+ if (!simpleName.equals(that.simpleName)) return false;
+ if (!packageName.equals(that.packageName)) return false;
+ if (!storIOType.equals(that.storIOType)) return false;
+ return columns.equals(that.columns);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = simpleName.hashCode();
+ result = 31 * result + packageName.hashCode();
+ result = 31 * result + storIOType.hashCode();
+ result = 31 * result + columns.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "StorIOTypeMeta{" +
+ "simpleName='" + simpleName + '\'' +
+ ", packageName='" + packageName + '\'' +
+ ", storIOType=" + storIOType +
+ ", columns=" + columns +
+ '}';
+ }
+}
View
30 ...processor/introspection/JavaTypeTest.java → ...processor/introspection/JavaTypeTest.java
@@ -1,4 +1,4 @@
-package com.pushtorefresh.storio.sqlite.annotations.processor.introspection;
+package com.pushtorefresh.storio.common.annotations.processor.introspection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -7,20 +7,20 @@
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BOOLEAN;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BYTE_ARRAY;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.DOUBLE;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.FLOAT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.INTEGER;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.LONG;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.LONG_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.SHORT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.SHORT_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.STRING;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BYTE_ARRAY;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.STRING;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
View
1 storio-content-resolver-annotations-processor/build.gradle
@@ -5,6 +5,7 @@ sourceCompatibility = '1.6'
dependencies {
compile libraries.storIOContentResolverAnnotations
+ compile libraries.storIOCommonAnnotationsProcessor
compile libraries.intellijAnnotations
compile libraries.autoService
compile libraries.javaPoet
View
31 ...a/com/pushtorefresh/storio/contentresolver/annotations/processor/ProcessingException.java
@@ -1,31 +0,0 @@
-package com.pushtorefresh.storio.contentresolver.annotations.processor;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.lang.model.element.Element;
-
-/**
- * Useful for logging errors from AnnotationProcessor,
- * stores reference to {@link Element} that caused exception so IDE will show developer where is the problem
- */
-public class ProcessingException extends RuntimeException {
-
- /**
- * Element that caused exception
- */
- @NotNull
- private final Element element;
-
- public ProcessingException(@NotNull Element element, @NotNull String message) {
- super(message);
- this.element = element;
- }
-
- /**
- * @return non-null element that caused exception
- */
- @NotNull
- public Element element() {
- return element;
- }
-}
View
152 ...orefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java
@@ -1,29 +1,27 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor;
import com.google.auto.service.AutoService;
+import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
+import com.pushtorefresh.storio.common.annotations.processor.StorIOAnnotationsProcessor;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverColumn;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverType;
import com.pushtorefresh.storio.contentresolver.annotations.processor.generate.DeleteResolverGenerator;
import com.pushtorefresh.storio.contentresolver.annotations.processor.generate.GetResolverGenerator;
import com.pushtorefresh.storio.contentresolver.annotations.processor.generate.PutResolverGenerator;
-import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
+import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
@@ -31,7 +29,6 @@
import static javax.lang.model.element.ElementKind.CLASS;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.tools.Diagnostic.Kind.ERROR;
/**
* Annotation processor for StorIOContentResolver
@@ -43,53 +40,17 @@
*/
// Generate file with annotation processor declaration via another Annotation Processor!
@AutoService(Processor.class)
-public class StorIOContentResolverProcessor extends AbstractProcessor {
+public class StorIOContentResolverProcessor extends StorIOAnnotationsProcessor<StorIOContentResolverTypeMeta, StorIOContentResolverColumnMeta> {
- private Filer filer;
- private Elements elementUtils;
- private Messager messager;
-
- /**
- * Processes class annotations
- *
- * @param roundEnvironment environment
- * @return non-null unmodifiable map(element, typeMeta)
- */
- private static Map<TypeElement, StorIOContentResolverTypeMeta> processAnnotatedClasses(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Elements elementUtils) {
- final Set<? extends Element> elementsAnnotatedWithStorIOContentResolverType
- = roundEnvironment.getElementsAnnotatedWith(StorIOContentResolverType.class);
-
- final Map<TypeElement, StorIOContentResolverTypeMeta> results
- = new HashMap<TypeElement, StorIOContentResolverTypeMeta>(elementsAnnotatedWithStorIOContentResolverType.size());
-
- for (final Element annotatedElement : elementsAnnotatedWithStorIOContentResolverType) {
- final TypeElement classElement = validateAnnotatedClass(annotatedElement);
- final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta = processAnnotatedClass(classElement, elementUtils);
- results.put(classElement, storIOContentResolverTypeMeta);
- }
-
- return results;
- }
-
- /**
- * Checks that element annotated with {@link StorIOContentResolverType} satisfies all required conditions
- *
- * @param annotatedElement element annotated with {@link StorIOContentResolverType}
- * @return {@link TypeElement} object
- */
@NotNull
- private static TypeElement validateAnnotatedClass(@NotNull final Element annotatedElement) {
- // we expect here that annotatedElement is Class, annotation requires that via @Target
- TypeElement annotatedTypeElement = (TypeElement) annotatedElement;
+ @Override
+ public Set<String> getSupportedAnnotationTypes() {
+ final Set<String> supportedAnnotations = new HashSet<String>(2);
- if (annotatedTypeElement.getModifiers().contains(PRIVATE)) {
- throw new ProcessingException(
- annotatedElement,
- StorIOContentResolverType.class.getSimpleName() + " can not be applied to private class: " + annotatedTypeElement.getQualifiedName()
- );
- }
+ supportedAnnotations.add(StorIOContentResolverType.class.getCanonicalName());
+ supportedAnnotations.add(StorIOContentResolverColumn.class.getCanonicalName());
- return annotatedTypeElement;
+ return supportedAnnotations;
}
/**
@@ -100,7 +61,8 @@ private static TypeElement validateAnnotatedClass(@NotNull final Element annotat
* @return result of processing as {@link StorIOContentResolverTypeMeta}
*/
@NotNull
- private static StorIOContentResolverTypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils) {
+ @Override
+ protected StorIOContentResolverTypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils) {
final StorIOContentResolverType storIOContentResolverType = classElement.getAnnotation(StorIOContentResolverType.class);
final String uri = storIOContentResolverType.uri();
@@ -124,7 +86,8 @@ private static StorIOContentResolverTypeMeta processAnnotatedClass(@NotNull Type
* @param roundEnvironment current processing environment
* @param annotatedClasses map of classes annotated with {@link StorIOContentResolverType}
*/
- private void processAnnotatedFields(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
+ @Override
+ protected void processAnnotatedFields(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
final Set<? extends Element> elementsAnnotatedWithStorIOContentResolverColumn
= roundEnvironment.getElementsAnnotatedWith(StorIOContentResolverColumn.class);
@@ -152,14 +115,13 @@ private void processAnnotatedFields(@NotNull final RoundEnvironment roundEnviron
}
}
- //region Processing of annotated classes
-
/**
* Checks that element annotated with {@link StorIOContentResolverColumn} satisfies all required conditions
*
* @param annotatedField element annotated with {@link StorIOContentResolverColumn}
*/
- private static void validateAnnotatedField(@NotNull final Element annotatedField) {
+ @Override
+ protected void validateAnnotatedField(@NotNull final Element annotatedField) {
// we expect here that annotatedElement is Field, annotation requires that via @Target
final Element enclosingElement = annotatedField.getEnclosingElement();
@@ -200,7 +162,8 @@ private static void validateAnnotatedField(@NotNull final Element annotatedField
* @return non-null {@link StorIOContentResolverColumnMeta} with meta information about field
*/
@NotNull
- private static StorIOContentResolverColumnMeta processAnnotatedField(@NotNull final Element annotatedField) {
+ @Override
+ protected StorIOContentResolverColumnMeta processAnnotatedField(@NotNull final Element annotatedField) {
final JavaType javaType;
try {
@@ -232,7 +195,8 @@ private static StorIOContentResolverColumnMeta processAnnotatedField(@NotNull fi
);
}
- private static void validateAnnotatedClassesAndColumns(@NotNull final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
+ @Override
+ protected void validateAnnotatedClassesAndColumns(@NotNull final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses) {
// check that each annotated class has columns with at least one key column
for (Map.Entry<TypeElement, StorIOContentResolverTypeMeta> annotatedClass : annotatedClasses.entrySet()) {
if (annotatedClass.getValue().columns.isEmpty()) {
@@ -247,7 +211,7 @@ private static void validateAnnotatedClassesAndColumns(@NotNull final Map<TypeEl
boolean hasAtLeastOneKeyColumn = false;
for (final StorIOContentResolverColumnMeta columnMeta : annotatedClass.getValue().columns.values()) {
- if (columnMeta.storIOContentResolverColumn.key()) {
+ if (columnMeta.storIOColumn.key()) {
hasAtLeastOneKeyColumn = true;
break;
}
@@ -262,70 +226,34 @@ private static void validateAnnotatedClassesAndColumns(@NotNull final Map<TypeEl
}
}
}
- //endregion
-
- //region Processing of annotated fields
+ @NotNull
@Override
- public synchronized void init(ProcessingEnvironment processingEnv) {
- super.init(processingEnv);
- filer = processingEnv.getFiler();
- elementUtils = processingEnv.getElementUtils(); // why class name is "Elements" but method "getElementUtils()", OKAY..
- messager = processingEnv.getMessager();
+ protected Class<? extends Annotation> getTypeAnnotationClass() {
+ return StorIOContentResolverType.class;
}
+ @NotNull
@Override
- public Set<String> getSupportedAnnotationTypes() {
- final Set<String> supportedAnnotations = new HashSet<String>(2);
-
- supportedAnnotations.add(StorIOContentResolverType.class.getCanonicalName());
- supportedAnnotations.add(StorIOContentResolverColumn.class.getCanonicalName());
-
- return supportedAnnotations;
+ protected Class<? extends Annotation> getColumnAnnotationClass() {
+ return StorIOContentResolverColumn.class;
}
+ @NotNull
@Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latestSupported();
+ protected ResolverGenerator<StorIOContentResolverTypeMeta> createPutResolver() {
+ return new PutResolverGenerator();
}
- //endregion
-
- /**
- * For those who don't familiar with Annotation Processing API — this is the main method of Annotation Processor lifecycle
- * <p>
- * It will be called after Java Compiler will find lang elements annotated with annotations from {@link #getSupportedAnnotationTypes()}
- *
- * @param annotations set of annotations
- * @param roundEnv environment of current processing round
- * @return true if annotation processor should not be invoked in next rounds of annotation processing, false otherwise
- */
+ @NotNull
@Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- try {
- final Map<TypeElement, StorIOContentResolverTypeMeta> annotatedClasses
- = processAnnotatedClasses(roundEnv, elementUtils);
-
- processAnnotatedFields(roundEnv, annotatedClasses);
-
- validateAnnotatedClassesAndColumns(annotatedClasses);
-
- final PutResolverGenerator putResolverGenerator = new PutResolverGenerator();
- final GetResolverGenerator getResolverGenerator = new GetResolverGenerator();
- final DeleteResolverGenerator deleteResolverGenerator = new DeleteResolverGenerator();
-
- for (final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta : annotatedClasses.values()) {
- putResolverGenerator.generateJavaFile(storIOContentResolverTypeMeta).writeTo(filer);
- getResolverGenerator.generateJavaFile(storIOContentResolverTypeMeta).writeTo(filer);
- deleteResolverGenerator.generateJavaFile(storIOContentResolverTypeMeta).writeTo(filer);
- }
-
- } catch (ProcessingException e) {
- messager.printMessage(ERROR, e.getMessage(), e.element());
- } catch (Exception e) {
- messager.printMessage(ERROR, "Problem occurred with StorIOContentResolverProcessor: " + e.getMessage());
- }
+ protected ResolverGenerator<StorIOContentResolverTypeMeta> createGetResolver() {
+ return new GetResolverGenerator();
+ }
- return true;
+ @NotNull
+ @Override
+ protected ResolverGenerator<StorIOContentResolverTypeMeta> createDeleteResolver() {
+ return new DeleteResolverGenerator();
}
}
View
10 .../java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/Common.java
@@ -1,10 +0,0 @@
-package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
-
-import com.squareup.javapoet.ClassName;
-
-class Common {
-
- static final ClassName ANDROID_NON_NULL_ANNOTATION_CLASS_NAME = ClassName.get("android.support.annotation", "NonNull");
-
- static final String INDENT = " "; // 4 spaces
-}
View
9 ...efresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java
@@ -1,5 +1,6 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
@@ -12,12 +13,12 @@
import java.util.Map;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class DeleteResolverGenerator {
+public class DeleteResolverGenerator implements ResolverGenerator<StorIOContentResolverTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
@@ -54,7 +55,7 @@ private MethodSpec createMapToDeleteQueryMethodSpec(@NotNull final StorIOContent
INDENT + ".where($S)\n" +
INDENT + ".whereArgs($L)\n" +
INDENT + ".build();\n",
- storIOContentResolverTypeMeta.storIOContentResolverType.uri(),
+ storIOContentResolverTypeMeta.storIOType.uri(),
where.get(QueryGenerator.WHERE_CLAUSE),
where.get(QueryGenerator.WHERE_ARGS))
.build();
View
41 ...torefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java
@@ -1,7 +1,8 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
-import com.pushtorefresh.storio.contentresolver.annotations.processor.ProcessingException;
-import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType;
+import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
import com.squareup.javapoet.ClassName;
@@ -13,25 +14,25 @@
import org.jetbrains.annotations.NotNull;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.INDENT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BOOLEAN;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BYTE_ARRAY;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.DOUBLE;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.FLOAT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.INTEGER;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.LONG;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.LONG_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.SHORT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.SHORT_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.STRING;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BYTE_ARRAY;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.STRING;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class GetResolverGenerator {
+public class GetResolverGenerator implements ResolverGenerator<StorIOContentResolverTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
@@ -65,7 +66,7 @@ private MethodSpec createMapFromCursorMethodSpec(@NotNull StorIOContentResolverT
.addCode("\n");
for (final StorIOContentResolverColumnMeta columnMeta : storIOContentResolverTypeMeta.columns.values()) {
- final String columnIndex = "cursor.getColumnIndex(\"" + columnMeta.storIOContentResolverColumn.name() + "\")";
+ final String columnIndex = "cursor.getColumnIndex(\"" + columnMeta.storIOColumn.name() + "\")";
final String getFromCursor;
View
13 ...torefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java
@@ -1,5 +1,6 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
import com.squareup.javapoet.ClassName;
@@ -13,12 +14,12 @@
import java.util.Map;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class PutResolverGenerator {
+public class PutResolverGenerator implements ResolverGenerator<StorIOContentResolverTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
@@ -54,7 +55,7 @@ private MethodSpec createMapToInsertQueryMethodSpec(@NotNull final StorIOContent
.addCode("return InsertQuery.builder()\n" +
INDENT + ".uri($S)\n" +
INDENT + ".build();\n",
- storIOContentResolverTypeMeta.storIOContentResolverType.uri())
+ storIOContentResolverTypeMeta.storIOType.uri())
.build();
}
@@ -76,7 +77,7 @@ private MethodSpec createMapToUpdateQueryMethodSpec(@NotNull final StorIOContent
INDENT + ".where($S)\n" +
INDENT + ".whereArgs($L)\n" +
INDENT + ".build();\n",
- storIOContentResolverTypeMeta.storIOContentResolverType.uri(),
+ storIOContentResolverTypeMeta.storIOType.uri(),
where.get(QueryGenerator.WHERE_CLAUSE),
where.get(QueryGenerator.WHERE_ARGS))
.build();
@@ -99,7 +100,7 @@ private MethodSpec createMapToContentValuesMethodSpec(@NotNull final StorIOConte
for (final StorIOContentResolverColumnMeta columnMeta : storIOContentResolverTypeMeta.columns.values()) {
builder.addStatement(
"contentValues.put($S, $L)",
- columnMeta.storIOContentResolverColumn.name(),
+ columnMeta.storIOColumn.name(),
"object." + columnMeta.fieldName
);
}
View
6 ...m/pushtorefresh/storio/contentresolver/annotations/processor/generate/QueryGenerator.java
@@ -24,10 +24,10 @@
int i = 0;
for (final StorIOContentResolverColumnMeta columnMeta : storIOContentResolverTypeMeta.columns.values()) {
- if (columnMeta.storIOContentResolverColumn.key()) {
+ if (columnMeta.storIOColumn.key()) {
if (i == 0) {
whereClause
- .append(columnMeta.storIOContentResolverColumn.name())
+ .append(columnMeta.storIOColumn.name())
.append(" = ?");
whereArgs
@@ -37,7 +37,7 @@
} else {
whereClause
.append(" AND ")
- .append(columnMeta.storIOContentResolverColumn.name())
+ .append(columnMeta.storIOColumn.name())
.append(" = ?");
whereArgs
View
62 ...om/pushtorefresh/storio/contentresolver/annotations/processor/introspection/JavaType.java
@@ -1,62 +0,0 @@
-package com.pushtorefresh.storio.contentresolver.annotations.processor.introspection;
-
-import org.jetbrains.annotations.NotNull;
-
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-public enum JavaType {
-
- BOOLEAN,
- BOOLEAN_OBJECT,
- SHORT,
- SHORT_OBJECT,
- INTEGER,
- INTEGER_OBJECT,
- LONG,
- LONG_OBJECT,
- FLOAT,
- FLOAT_OBJECT,
- DOUBLE,
- DOUBLE_OBJECT,
- STRING,
- BYTE_ARRAY;
-
- @NotNull
- public static JavaType from(@NotNull TypeMirror typeMirror) {
- final TypeKind typeKind = typeMirror.getKind();
- final String typeName = typeMirror.toString(); // fqn of type, for example java.lang.String
-
- if (typeKind == TypeKind.BOOLEAN) {
- return BOOLEAN;
- } else if (Boolean.class.getCanonicalName().equals(typeName)) {
- return BOOLEAN_OBJECT;
- } else if (typeKind == TypeKind.SHORT) {
- return SHORT;
- } else if (Short.class.getCanonicalName().equals(typeName)) {
- return SHORT_OBJECT;
- } else if (typeKind == TypeKind.INT) {
- return INTEGER;
- } else if (Integer.class.getCanonicalName().equals(typeName)) {
- return INTEGER_OBJECT;
- } else if (typeKind == TypeKind.LONG) {
- return LONG;
- } else if (Long.class.getCanonicalName().equals(typeName)) {
- return LONG_OBJECT;
- } else if (typeKind == TypeKind.FLOAT) {
- return FLOAT;
- } else if (Float.class.getCanonicalName().equals(typeName)) {
- return FLOAT_OBJECT;
- } else if (typeKind == TypeKind.DOUBLE) {
- return DOUBLE;
- } else if (Double.class.getCanonicalName().equals(typeName)) {
- return DOUBLE_OBJECT;
- } else if (String.class.getCanonicalName().equals(typeName)) {
- return STRING;
- } else if (byte[].class.getCanonicalName().equals(typeName)) {
- return BYTE_ARRAY;
- } else {
- throw new IllegalArgumentException("Unsupported type: " + typeMirror);
- }
- }
-}
View
63 .../contentresolver/annotations/processor/introspection/StorIOContentResolverColumnMeta.java
@@ -1,74 +1,21 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.introspection;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOColumnMeta;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverColumn;
import org.jetbrains.annotations.NotNull;
import javax.lang.model.element.Element;
-public class StorIOContentResolverColumnMeta {
-
- @NotNull
- public final Element enclosingElement;
-
- @NotNull
- public final Element element;
-
- @NotNull
- public final String fieldName;
-
- @NotNull
- public final JavaType javaType;
-
- @NotNull
- public final StorIOContentResolverColumn storIOContentResolverColumn;
+public class StorIOContentResolverColumnMeta extends StorIOColumnMeta<StorIOContentResolverColumn> {
public StorIOContentResolverColumnMeta(
@NotNull Element enclosingElement,
@NotNull Element element,
@NotNull String fieldName,
@NotNull JavaType javaType,
- @NotNull StorIOContentResolverColumn storIOContentResolverColumn) {
- this.enclosingElement = enclosingElement;
- this.element = element;
- this.fieldName = fieldName;
- this.javaType = javaType;
- this.storIOContentResolverColumn = storIOContentResolverColumn;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- StorIOContentResolverColumnMeta that = (StorIOContentResolverColumnMeta) o;
-
- if (!enclosingElement.equals(that.enclosingElement)) return false;
- if (!element.equals(that.element)) return false;
- if (!fieldName.equals(that.fieldName)) return false;
- if (javaType != that.javaType) return false;
- return storIOContentResolverColumn.equals(that.storIOContentResolverColumn);
-
- }
-
- @Override
- public int hashCode() {
- int result = enclosingElement.hashCode();
- result = 31 * result + element.hashCode();
- result = 31 * result + fieldName.hashCode();
- result = 31 * result + javaType.hashCode();
- result = 31 * result + storIOContentResolverColumn.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "StorIOContentResolverColumnMeta{" +
- "enclosingElement=" + enclosingElement +
- ", element=" + element +
- ", fieldName='" + fieldName + '\'' +
- ", javaType=" + javaType +
- ", storIOContentResolverColumn=" + storIOContentResolverColumn +
- '}';
+ @NotNull StorIOContentResolverColumn storIOColumn) {
+ super(enclosingElement, element, fieldName, javaType, storIOColumn);
}
}
View
60 ...io/contentresolver/annotations/processor/introspection/StorIOContentResolverTypeMeta.java
@@ -1,68 +1,16 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.introspection;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOTypeMeta;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverType;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
-import java.util.Map;
-
-public class StorIOContentResolverTypeMeta {
-
- @NotNull
- public final String simpleName;
-
- @NotNull
- public final String packageName;
-
- @NotNull
- public final StorIOContentResolverType storIOContentResolverType;
-
- /**
- * Yep, this is MODIFIABLE Map, please use it carefully
- */
- @NotNull
- public final Map<String, StorIOContentResolverColumnMeta> columns = new HashMap<String, StorIOContentResolverColumnMeta>();
+public class StorIOContentResolverTypeMeta extends StorIOTypeMeta<StorIOContentResolverType, StorIOContentResolverColumnMeta> {
public StorIOContentResolverTypeMeta(
@NotNull String simpleName,
@NotNull String packageName,
- @NotNull StorIOContentResolverType storIOContentResolverType) {
- this.simpleName = simpleName;
- this.packageName = packageName;
- this.storIOContentResolverType = storIOContentResolverType;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- StorIOContentResolverTypeMeta that = (StorIOContentResolverTypeMeta) o;
-
- if (!simpleName.equals(that.simpleName)) return false;
- if (!packageName.equals(that.packageName)) return false;
- if (!storIOContentResolverType.equals(that.storIOContentResolverType)) return false;
- return columns.equals(that.columns);
-
- }
-
- @Override
- public int hashCode() {
- int result = simpleName.hashCode();
- result = 31 * result + packageName.hashCode();
- result = 31 * result + storIOContentResolverType.hashCode();
- result = 31 * result + columns.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "StorIOContentResolverTypeMeta{" +
- "simpleName='" + simpleName + '\'' +
- ", packageName='" + packageName + '\'' +
- ", storIOContentResolverType=" + storIOContentResolverType +
- ", columns=" + columns +
- '}';
+ @NotNull StorIOContentResolverType storIOType) {
+ super(simpleName, packageName, storIOType);
}
}
View
2 ...fresh/storio/contentresolver/annotations/processor/generate/GetResolverGeneratorTest.java
@@ -1,8 +1,8 @@
package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverColumn;
import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverType;
-import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
import com.squareup.javapoet.JavaFile;
View
126 ...ushtorefresh/storio/contentresolver/annotations/processor/introspection/JavaTypeTest.java
@@ -1,126 +0,0 @@
-package com.pushtorefresh.storio.contentresolver.annotations.processor.introspection;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.junit.Test;
-
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BOOLEAN;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.BYTE_ARRAY;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.DOUBLE;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.FLOAT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.INTEGER;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.LONG;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.LONG_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.SHORT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.SHORT_OBJECT;
-import static com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.JavaType.STRING;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class JavaTypeTest {
-
- @NotNull
- private static TypeMirror mockTypeMirror(@Nullable TypeKind typeKind, @Nullable String typeName) {
- final TypeMirror typeMirror = mock(TypeMirror.class);
-
- when(typeMirror.getKind())
- .thenReturn(typeKind);
-
- when(typeMirror.toString())
- .thenReturn(typeName);
-
- return typeMirror;
- }
-
- @Test
- public void fromBoolean() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.BOOLEAN, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(BOOLEAN);
- }
-
- @Test
- public void fromBooleanObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Boolean.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(BOOLEAN_OBJECT);
- }
-
- @Test
- public void fromShort() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.SHORT, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(SHORT);
- }
-
- @Test
- public void fromShortObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Short.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(SHORT_OBJECT);
- }
-
- @Test
- public void fromInteger() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.INT, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(INTEGER);
- }
-
- @Test
- public void fromIntegerObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Integer.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(INTEGER_OBJECT);
- }
-
- @Test
- public void fromLong() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.LONG, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(LONG);
- }
-
- @Test
- public void fromLongObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Long.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(LONG_OBJECT);
- }
-
- @Test
- public void fromFloat() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.FLOAT, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(FLOAT);
- }
-
- @Test
- public void fromFloatObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Float.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(FLOAT_OBJECT);
- }
-
- @Test
- public void fromDouble() {
- final TypeMirror typeMirror = mockTypeMirror(TypeKind.DOUBLE, null);
- assertThat(JavaType.from(typeMirror)).isEqualTo(DOUBLE);
- }
-
- @Test
- public void fromDoubleObject() {
- final TypeMirror typeMirror = mockTypeMirror(null, Double.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(DOUBLE_OBJECT);
- }
-
- @Test
- public void fromString() {
- final TypeMirror typeMirror = mockTypeMirror(null, String.class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(STRING);
- }
-
- @Test
- public void fromByteArray() {
- final TypeMirror typeMirror = mockTypeMirror(null, byte[].class.getCanonicalName());
- assertThat(JavaType.from(typeMirror)).isEqualTo(BYTE_ARRAY);
- }
-}
View
1 storio-sqlite-annotations-processor/build.gradle
@@ -5,6 +5,7 @@ sourceCompatibility = '1.6'
dependencies {
compile libraries.storIOSQLiteAnnotations
+ compile libraries.storIOCommonAnnotationsProcessor
compile libraries.intellijAnnotations
compile libraries.autoService
compile libraries.javaPoet
View
196 ...ain/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java
@@ -1,39 +1,31 @@
package com.pushtorefresh.storio.sqlite.annotations.processor;
import com.google.auto.service.AutoService;
+import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
+import com.pushtorefresh.storio.common.annotations.processor.StorIOAnnotationsProcessor;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
import com.pushtorefresh.storio.sqlite.annotations.processor.generate.DeleteResolverGenerator;
import com.pushtorefresh.storio.sqlite.annotations.processor.generate.GetResolverGenerator;
import com.pushtorefresh.storio.sqlite.annotations.processor.generate.PutResolverGenerator;
-import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
import org.jetbrains.annotations.NotNull;
-import java.util.Collections;
-import java.util.HashMap;
+import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
-import static javax.lang.model.element.ElementKind.CLASS;
-import static javax.lang.model.element.Modifier.FINAL;
-import static javax.lang.model.element.Modifier.PRIVATE;
-import static javax.tools.Diagnostic.Kind.ERROR;
-
/**
* Annotation processor for StorIOSQLite
* <p>
@@ -44,54 +36,17 @@
*/
// Generate file with annotation processor declaration via another Annotation Processor!
@AutoService(Processor.class)
-public class StorIOSQLiteProcessor extends AbstractProcessor {
-
- private Filer filer;
- private Elements elementUtils;
- private Messager messager;
-
- /**
- * Processes class annotations
- *
- * @param roundEnvironment environment
- * @return non-null unmodifiable map(element, typeMeta)
- */
- @NotNull
- private static Map<TypeElement, StorIOSQLiteTypeMeta> processAnnotatedClasses(@NotNull final RoundEnvironment roundEnvironment, @NotNull final Elements elementUtils) {
- final Set<? extends Element> elementsAnnotatedWithStorIOSQLiteType
- = roundEnvironment.getElementsAnnotatedWith(StorIOSQLiteType.class);
-
- final Map<TypeElement, StorIOSQLiteTypeMeta> results
- = new HashMap<TypeElement, StorIOSQLiteTypeMeta>(elementsAnnotatedWithStorIOSQLiteType.size());
-
- for (final Element annotatedElement : elementsAnnotatedWithStorIOSQLiteType) {
- final TypeElement classElement = validateAnnotatedClass(annotatedElement);
- final StorIOSQLiteTypeMeta storIOSQLiteTypeMeta = processAnnotatedClass(classElement, elementUtils);
- results.put(classElement, storIOSQLiteTypeMeta);
- }
+public class StorIOSQLiteProcessor extends StorIOAnnotationsProcessor<StorIOSQLiteTypeMeta, StorIOSQLiteColumnMeta> {
- return Collections.unmodifiableMap(results);
- }
-
- /**
- * Checks that element annotated with {@link StorIOSQLiteType} satisfies all required conditions
- *
- * @param annotatedElement element annotated with {@link StorIOSQLiteType}
- * @return {@link TypeElement} object
- */
@NotNull
- private static TypeElement validateAnnotatedClass(@NotNull final Element annotatedElement) {
- // we expect here that annotatedElement is Class, annotation requires that via @Target
- final TypeElement annotatedTypeElement = (TypeElement) annotatedElement;
+ @Override
+ public Set<String> getSupportedAnnotationTypes() {
+ final Set<String> supportedAnnotations = new HashSet<String>(2);
- if (annotatedTypeElement.getModifiers().contains(PRIVATE)) {
- throw new ProcessingException(
- annotatedElement,
- StorIOSQLiteType.class.getSimpleName() + " can not be applied to private class: " + annotatedTypeElement.getQualifiedName()
- );
- }
+ supportedAnnotations.add(StorIOSQLiteType.class.getCanonicalName());
+ supportedAnnotations.add(StorIOSQLiteColumn.class.getCanonicalName());
- return annotatedTypeElement;
+ return supportedAnnotations;
}
/**
@@ -102,7 +57,8 @@ private static TypeElement validateAnnotatedClass(@NotNull final Element annotat
* @return result of processing as {@link StorIOSQLiteTypeMeta}
*/
@NotNull
- private static StorIOSQLiteTypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils) {
+ @Override
+ protected StorIOSQLiteTypeMeta processAnnotatedClass(@NotNull TypeElement classElement, @NotNull Elements elementUtils) {
final StorIOSQLiteType storIOSQLiteType = classElement.getAnnotation(StorIOSQLiteType.class);
final String tableName = storIOSQLiteType.table();
@@ -126,7 +82,8 @@ private static StorIOSQLiteTypeMeta processAnnotatedClass(@NotNull TypeElement c
* @param roundEnvironment current processing environment
* @param annotatedClasses map of classes annotated with {@link StorIOSQLiteType}
*/
- private static void processAnnotatedFields(@NotNull final RoundEnvironment roundEnvironment, @NotNull Map<TypeElement, StorIOSQLiteTypeMeta> annotatedClasses) {
+ @Override
+ protected void processAnnotatedFields(@NotNull final RoundEnvironment roundEnvironment, @NotNull Map<TypeElement, StorIOSQLiteTypeMeta> annotatedClasses) {
final Set<? extends Element> elementsAnnotatedWithStorIOSQLiteColumn
= roundEnvironment.getElementsAnnotatedWith(StorIOSQLiteColumn.class);
@@ -147,53 +104,12 @@ private static void processAnnotatedFields(@NotNull final RoundEnvironment round
// Put meta column info
// If class already contains column with same name -> throw exception
- if (storIOSQLiteTypeMeta.columns.put(storIOSQLiteColumnMeta.storIOSQLiteColumn.name(), storIOSQLiteColumnMeta) != null) {
+ if (storIOSQLiteTypeMeta.columns.put(storIOSQLiteColumnMeta.storIOColumn.name(), storIOSQLiteColumnMeta) != null) {
throw new ProcessingException(annotatedFieldElement, "Column name already used in this class");
}
}
}
- //region Processing of annotated classes
-
- /**
- * Checks that element annotated with {@link StorIOSQLiteColumn} satisfies all required conditions
- *
- * @param annotatedField element annotated with {@link StorIOSQLiteColumn}
- */
- private static void validateAnnotatedField(@NotNull final Element annotatedField) {
- // we expect here that annotatedElement is Field, annotation requires that via @Target
-
- final Element enclosingElement = annotatedField.getEnclosingElement();
-
- if (!enclosingElement.getKind().equals(CLASS)) {
- throw new ProcessingException(
- annotatedField,
- "Please apply " + StorIOSQLiteType.class.getSimpleName() + " to fields of class: " + annotatedField.getSimpleName()
- );
- }
-
- if (enclosingElement.getAnnotation(StorIOSQLiteType.class) == null) {
- throw new ProcessingException(
- annotatedField,
- "Please annotate class " + enclosingElement.getSimpleName() + " with " + StorIOSQLiteType.class.getSimpleName()
- );
- }
-
- if (annotatedField.getModifiers().contains(PRIVATE)) {
- throw new ProcessingException(
- annotatedField,
- StorIOSQLiteColumn.class.getSimpleName() + " can not be applied to private field: " + annotatedField.getSimpleName()
- );
- }
-
- if (annotatedField.getModifiers().contains(FINAL)) {
- throw new ProcessingException(
- annotatedField,
- StorIOSQLiteColumn.class.getSimpleName() + " can not be applied to final field: " + annotatedField.getSimpleName()
- );
- }
- }
-
/**
* Processes annotated field and returns result of processing or throws exception
*
@@ -201,7 +117,8 @@ private static void validateAnnotatedField(@NotNull final Element annotatedField
* @return non-null {@link StorIOSQLiteColumnMeta} with meta information about field
*/
@NotNull
- private static StorIOSQLiteColumnMeta processAnnotatedField(@NotNull final Element annotatedField) {
+ @Override
+ protected StorIOSQLiteColumnMeta processAnnotatedField(@NotNull final Element annotatedField) {
final JavaType javaType;
try {
@@ -232,7 +149,8 @@ private static StorIOSQLiteColumnMeta processAnnotatedField(@NotNull final Eleme
);
}
- private static void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement, StorIOSQLiteTypeMeta> annotatedClasses) {
+ @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> annotatedClass : annotatedClasses.entrySet()) {
if (annotatedClass.getValue().columns.size() == 0) {
@@ -247,7 +165,7 @@ private static void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement,
boolean hasAtLeastOneKeyColumn = false;
for (final StorIOSQLiteColumnMeta columnMeta : annotatedClass.getValue().columns.values()) {
- if (columnMeta.storIOSQLiteColumn.key()) {
+ if (columnMeta.storIOColumn.key()) {
hasAtLeastOneKeyColumn = true;
break;
}
@@ -263,69 +181,33 @@ private static void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement,
}
}
- //endregion
-
- //region Processing of annotated fields
-
+ @NotNull
@Override
- public synchronized void init(ProcessingEnvironment processingEnv) {
- super.init(processingEnv);
- filer = processingEnv.getFiler();
- elementUtils = processingEnv.getElementUtils(); // why class name is "Elements" but method "getElementUtils()", OKAY..
- messager = processingEnv.getMessager();
+ protected Class<? extends Annotation> getTypeAnnotationClass() {
+ return StorIOSQLiteType.class;
}
+ @NotNull
@Override
- public Set<String> getSupportedAnnotationTypes() {
- final Set<String> supportedAnnotations = new HashSet<String>(2);
-
- supportedAnnotations.add(StorIOSQLiteType.class.getCanonicalName());
- supportedAnnotations.add(StorIOSQLiteColumn.class.getCanonicalName());
-
- return supportedAnnotations;
+ protected Class<? extends Annotation> getColumnAnnotationClass() {
+ return StorIOSQLiteColumn.class;
}
+ @NotNull
@Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latestSupported();
+ protected ResolverGenerator<StorIOSQLiteTypeMeta> createPutResolver() {
+ return new PutResolverGenerator();
}
- //endregion
-
- /**
- * For those who don't familiar with Annotation Processing API — this is the main method of Annotation Processor lifecycle
- * <p>
- * It will be called after Java Compiler will find lang elements annotated with annotations from {@link #getSupportedAnnotationTypes()}
- *
- * @param annotations set of annotations
- * @param roundEnv environment of current processing round
- * @return true if annotation processor should not be invoked in next rounds of annotation processing, false otherwise
- */
+ @NotNull
@Override
- public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
- try {
- final Map<TypeElement, StorIOSQLiteTypeMeta> annotatedClasses
- = processAnnotatedClasses(roundEnv, elementUtils);
-
- processAnnotatedFields(roundEnv, annotatedClasses);
-
- validateAnnotatedClassesAndColumns(annotatedClasses);
-
- final PutResolverGenerator putResolverGenerator = new PutResolverGenerator();
- final GetResolverGenerator getResolverGenerator = new GetResolverGenerator();
- final DeleteResolverGenerator deleteResolverGenerator = new DeleteResolverGenerator();
-
- for (StorIOSQLiteTypeMeta storIOSQLiteTypeMeta : annotatedClasses.values()) {
- putResolverGenerator.generateJavaFile(storIOSQLiteTypeMeta).writeTo(filer);
- getResolverGenerator.generateJavaFile(storIOSQLiteTypeMeta).writeTo(filer);
- deleteResolverGenerator.generateJavaFile(storIOSQLiteTypeMeta).writeTo(filer);
- }
- } catch (ProcessingException e) {
- messager.printMessage(ERROR, e.getMessage(), e.element());
- } catch (Exception e) {
- messager.printMessage(ERROR, "Problem occurred with StorIOSQLiteProcessor: " + e.getMessage());
- }
+ protected ResolverGenerator<StorIOSQLiteTypeMeta> createGetResolver() {
+ return new GetResolverGenerator();
+ }
- return true;
+ @NotNull
+ @Override
+ protected ResolverGenerator<StorIOSQLiteTypeMeta> createDeleteResolver() {
+ return new DeleteResolverGenerator();
}
}
View
10 .../src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/Common.java
@@ -1,10 +0,0 @@
-package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
-
-import com.squareup.javapoet.ClassName;
-
-class Common {
-
- static final ClassName ANDROID_NON_NULL_ANNOTATION_CLASS_NAME = ClassName.get("android.support.annotation", "NonNull");
-
- static final String INDENT = " "; // 4 spaces
-}
View
9 ...m/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java
@@ -1,5 +1,6 @@
package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
@@ -12,12 +13,12 @@
import java.util.Map;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class DeleteResolverGenerator {
+public class DeleteResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
@@ -54,7 +55,7 @@ private MethodSpec createMapToDeleteQueryMethodSpec(@NotNull StorIOSQLiteTypeMet
INDENT + ".where($S)\n" +
INDENT + ".whereArgs($L)\n" +
INDENT + ".build();\n",
- storIOSQLiteTypeMeta.storIOSQLiteType.table(),
+ storIOSQLiteTypeMeta.storIOType.table(),
where.get(QueryGenerator.WHERE_CLAUSE),
where.get(QueryGenerator.WHERE_ARGS))
.build();
View
41 .../com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java
@@ -1,7 +1,8 @@
package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
-import com.pushtorefresh.storio.sqlite.annotations.processor.ProcessingException;
-import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType;
+import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
import com.squareup.javapoet.ClassName;
@@ -13,25 +14,25 @@
import org.jetbrains.annotations.NotNull;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.INDENT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BOOLEAN;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.BYTE_ARRAY;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.DOUBLE;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.FLOAT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.INTEGER;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.LONG;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.LONG_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.SHORT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.SHORT_OBJECT;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType.STRING;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BOOLEAN_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.BYTE_ARRAY;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.DOUBLE_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.FLOAT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.INTEGER_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.LONG_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.SHORT_OBJECT;
+import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.STRING;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class GetResolverGenerator {
+public class GetResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
@@ -65,7 +66,7 @@ private MethodSpec createMapFromCursorMethodSpec(@NotNull StorIOSQLiteTypeMeta s
.addCode("\n");
for (final StorIOSQLiteColumnMeta columnMeta : storIOSQLiteTypeMeta.columns.values()) {
- final String columnIndex = "cursor.getColumnIndex(\"" + columnMeta.storIOSQLiteColumn.name() + "\")";
+ final String columnIndex = "cursor.getColumnIndex(\"" + columnMeta.storIOColumn.name() + "\")";
final String getFromCursor;
View
13 .../com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java
@@ -1,5 +1,6 @@
package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
+import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
import com.squareup.javapoet.ClassName;
@@ -13,12 +14,12 @@
import java.util.Map;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
-import static com.pushtorefresh.storio.sqlite.annotations.processor.generate.Common.INDENT;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.ANDROID_NON_NULL_ANNOTATION_CLASS_NAME;
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
-public class PutResolverGenerator {
+public class PutResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
@NotNull
public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
@@ -53,7 +54,7 @@ private MethodSpec createMapToInsertQueryMethodSpec(@NotNull StorIOSQLiteTypeMet
.addCode("return InsertQuery.builder()\n" +
INDENT + ".table($S)\n" +
INDENT + ".build();\n",
- storIOSQLiteTypeMeta.storIOSQLiteType.table())
+ storIOSQLiteTypeMeta.storIOType.table())
.build();
}
@@ -75,7 +76,7 @@ private MethodSpec createMapToUpdateQueryMethodSpec(@NotNull StorIOSQLiteTypeMet
INDENT + ".where($S)\n" +
INDENT + ".whereArgs($L)\n" +
INDENT + ".build();\n",
- storIOSQLiteTypeMeta.storIOSQLiteType.table(),
+ storIOSQLiteTypeMeta.storIOType.table(),
where.get(QueryGenerator.WHERE_CLAUSE),
where.get(QueryGenerator.WHERE_ARGS))
.build();
@@ -98,7 +99,7 @@ private MethodSpec createMapToContentValuesMethodSpec(@NotNull StorIOSQLiteTypeM
for (StorIOSQLiteColumnMeta columnMeta : storIOSQLiteTypeMeta.columns.values()) {
builder.addStatement(
"contentValues.put($S, $L)",
- columnMeta.storIOSQLiteColumn.name(),
+ columnMeta.storIOColumn.name(),
"object." + columnMeta.fieldName
);
}
View
6 ...n/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/QueryGenerator.java
@@ -22,10 +22,10 @@
int i = 0;
for (final StorIOSQLiteColumnMeta columnMeta : storIOSQLiteTypeMeta.columns.values()) {
- if (columnMeta.storIOSQLiteColumn.key()) {
+ if (columnMeta.storIOColumn.key()) {
if (i == 0) {
whereClause
- .append(columnMeta.storIOSQLiteColumn.name())
+ .append(columnMeta.storIOColumn.name())
.append(" = ?");
whereArgs
@@ -35,7 +35,7 @@
} else {
whereClause
.append(" AND ")
- .append(columnMeta.storIOSQLiteColumn.name())
+ .append(columnMeta.storIOColumn.name())
.append(" = ?");
whereArgs
View
67 ...shtorefresh/storio/sqlite/annotations/processor/introspection/StorIOSQLiteColumnMeta.java
@@ -1,68 +1,21 @@
package com.pushtorefresh.storio.sqlite.annotations.processor.introspection;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOColumnMeta;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import org.jetbrains.annotations.NotNull;
import javax.lang.model.element.Element;
-public class StorIOSQLiteColumnMeta {
+public class StorIOSQLiteColumnMeta extends StorIOColumnMeta<StorIOSQLiteColumn> {
- @NotNull
- public final Element enclosingElement;
-
- @NotNull
- public final Element element;
-
- @NotNull
- public final String fieldName;
-
- @NotNull
- public final JavaType javaType;
-
- @NotNull
- public final StorIOSQLiteColumn storIOSQLiteColumn;
-
- public StorIOSQLiteColumnMeta(@NotNull Element enclosingElement, @NotNull Element element, @NotNull String fieldName, @NotNull JavaType javaType, @NotNull StorIOSQLiteColumn storIOSQLiteColumn) {
- this.enclosingElement = enclosingElement;
- this.element = element;
- this.fieldName = fieldName;
- this.javaType = javaType;
- this.storIOSQLiteColumn = storIOSQLiteColumn;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- StorIOSQLiteColumnMeta that = (StorIOSQLiteColumnMeta) o;
-
- if (!enclosingElement.equals(that.enclosingElement)) return false;
- if (!element.equals(that.element)) return false;
- if (!fieldName.equals(that.fieldName)) return false;
- if (javaType != that.javaType) return false;
- return storIOSQLiteColumn.equals(that.storIOSQLiteColumn);
- }
-
- @Override
- public int hashCode() {
- int result = enclosingElement.hashCode();
- result = 31 * result + element.hashCode();
- result = 31 * result + fieldName.hashCode();
- result = 31 * result + javaType.hashCode();
- result = 31 * result + storIOSQLiteColumn.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "StorIOSQLiteColumnMeta{" +
- "enclosingElement=" + enclosingElement +
- ", element=" + element +
- ", fieldName='" + fieldName + '\'' +
- ", javaType=" + javaType +
- ", storIOSQLiteColumn=" + storIOSQLiteColumn +
- '}';
+ public StorIOSQLiteColumnMeta(
+ @NotNull Element enclosingElement,
+ @NotNull Element element,
+ @NotNull String fieldName,
+ @NotNull JavaType javaType,
+ @NotNull StorIOSQLiteColumn storIOColumn) {
+ super(enclosingElement, element, fieldName, javaType, storIOColumn);
}
}
View
64 ...pushtorefresh/storio/sqlite/annotations/processor/introspection/StorIOSQLiteTypeMeta.java
@@ -1,64 +1,16 @@
package com.pushtorefresh.storio.sqlite.annotations.processor.introspection;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOTypeMeta;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
import org.jetbrains.annotations.NotNull;
-import java.util.HashMap;
-import java.util.Map;
+public class StorIOSQLiteTypeMeta extends StorIOTypeMeta<StorIOSQLiteType, StorIOSQLiteColumnMeta> {
-public class StorIOSQLiteTypeMeta {
-
- @NotNull
- public final String simpleName;
-
- @NotNull
- public final String packageName;
-
- @NotNull
- public final StorIOSQLiteType storIOSQLiteType;
-
- /**
- * Yep, this is MODIFIABLE Map, please use it carefully
- */
- @NotNull
- public final Map<String, StorIOSQLiteColumnMeta> columns = new HashMap<String, StorIOSQLiteColumnMeta>();
-
- public StorIOSQLiteTypeMeta(@NotNull String simpleName, @NotNull String packageName, @NotNull StorIOSQLiteType storIOSQLiteType) {
- this.simpleName = simpleName;
- this.packageName = packageName;
- this.storIOSQLiteType = storIOSQLiteType;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- StorIOSQLiteTypeMeta that = (StorIOSQLiteTypeMeta) o;
-
- if (!simpleName.equals(that.simpleName)) return false;
- if (!packageName.equals(that.packageName)) return false;
- if (!storIOSQLiteType.equals(that.storIOSQLiteType)) return false;
- return columns.equals(that.columns);
- }
-
- @Override
- public int hashCode() {
- int result = simpleName.hashCode();
- result = 31 * result + packageName.hashCode();
- result = 31 * result + storIOSQLiteType.hashCode();
- result = 31 * result + columns.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "StorIOSQLiteTypeMeta{" +
- "simpleName='" + simpleName + '\'' +
- ", packageName='" + packageName + '\'' +
- ", storIOSQLiteType=" + storIOSQLiteType +
- ", columns=" + columns +
- '}';
+ public StorIOSQLiteTypeMeta(
+ @NotNull String simpleName,
+ @NotNull String packageName,
+ @NotNull StorIOSQLiteType storIOType) {
+ super(simpleName, packageName, storIOType);
}
-}
+}
View
2 .../pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGeneratorTest.java
@@ -2,7 +2,7 @@
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
-import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.JavaType;
+import com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
import com.squareup.javapoet.JavaFile;

0 comments on commit 5ed18e6

Please sign in to comment.
Something went wrong with that request. Please try again.