From 899519757aa278897856221948339befe0ddb091 Mon Sep 17 00:00:00 2001
From: Anton Pogonets <anton.pogonets@filmon.com>
Date: Tue, 22 Dec 2015 21:39:48 +0200
Subject: [PATCH] add mapping generation

---
 .../processor/StorIOAnnotationsProcessor.java      | 19 ++++---
 .../annotations/processor/generate/Generator.java  | 12 +++++
 .../processor/generate/ResolverGenerator.java      | 12 -----
 .../processor/StorIOContentResolverProcessor.java  | 15 ++++--
 .../generate/DeleteResolverGenerator.java          | 13 +++--
 .../processor/generate/GetResolverGenerator.java   | 13 +++--
 .../processor/generate/MappingGenerator.java       | 59 ++++++++++++++++++++++
 .../processor/generate/PutResolverGenerator.java   | 13 +++--
 .../processor/generate/MappingGeneratorTest.java   | 48 ++++++++++++++++++
 .../ContentResolverTypeMapping.java                |  6 +--
 storio-sample-app/build.gradle                     |  3 ++
 .../pushtorefresh/storio/sample/db/DbModule.java   | 20 ++------
 .../storio/sample/db/entities/Tweet.java           |  7 +++
 .../storio/sample/provider/meta/TweetMeta.java     |  5 +-
 .../processor/StorIOSQLiteProcessor.java           | 15 ++++--
 .../generate/DeleteResolverGenerator.java          | 13 +++--
 .../processor/generate/GetResolverGenerator.java   | 13 +++--
 .../processor/generate/MappingGenerator.java       | 59 ++++++++++++++++++++++
 .../processor/generate/PutResolverGenerator.java   | 13 +++--
 .../processor/generate/MappingGeneratorTest.java   | 49 ++++++++++++++++++
 .../storio/sqlite/SQLiteTypeMapping.java           |  6 +--
 21 files changed, 345 insertions(+), 68 deletions(-)
 create mode 100644 storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Generator.java
 delete mode 100644 storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java
 create mode 100644 storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGenerator.java
 create mode 100644 storio-content-resolver-annotations-processor/src/test/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGeneratorTest.java
 create mode 100644 storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGenerator.java
 create mode 100644 storio-sqlite-annotations-processor/src/test/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGeneratorTest.java

diff --git a/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java b/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java
index 70d38ca..bc7c386 100644
--- a/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java
+++ b/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/StorIOAnnotationsProcessor.java
@@ -1,6 +1,6 @@
 package com.pushtorefresh.storio.common.annotations.processor;
 
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOColumnMeta;
 import com.pushtorefresh.storio.common.annotations.processor.introspection.StorIOTypeMeta;
 
@@ -161,14 +161,16 @@ public boolean process(@Nullable final Set<? extends TypeElement> annotations, @
 
             validateAnnotatedClassesAndColumns(annotatedClasses);
 
-            final ResolverGenerator<TypeMeta> putResolverGenerator = createPutResolver();
-            final ResolverGenerator<TypeMeta> getResolverGenerator = createGetResolver();
-            final ResolverGenerator<TypeMeta> deleteResolverGenerator = createDeleteResolver();
+            final Generator<TypeMeta> putResolverGenerator = createPutResolver();
+            final Generator<TypeMeta> getResolverGenerator = createGetResolver();
+            final Generator<TypeMeta> deleteResolverGenerator = createDeleteResolver();
+            final Generator<TypeMeta> mappingGenerator = createMapping();
 
             for (TypeMeta typeMeta : annotatedClasses.values()) {
                 putResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
                 getResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
                 deleteResolverGenerator.generateJavaFile(typeMeta).writeTo(filer);
+                mappingGenerator.generateJavaFile(typeMeta).writeTo(filer);
             }
         } catch (ProcessingException e) {
             messager.printMessage(ERROR, e.getMessage(), e.element());
@@ -215,11 +217,14 @@ public boolean process(@Nullable final Set<? extends TypeElement> annotations, @
     protected abstract Class<? extends Annotation> getColumnAnnotationClass();
 
     @NotNull
-    protected abstract ResolverGenerator<TypeMeta> createPutResolver();
+    protected abstract Generator<TypeMeta> createPutResolver();
 
     @NotNull
-    protected abstract ResolverGenerator<TypeMeta> createGetResolver();
+    protected abstract Generator<TypeMeta> createGetResolver();
 
     @NotNull
-    protected abstract ResolverGenerator<TypeMeta> createDeleteResolver();
+    protected abstract Generator<TypeMeta> createDeleteResolver();
+
+    @NotNull
+    protected abstract Generator<TypeMeta> createMapping();
 }
diff --git a/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Generator.java b/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Generator.java
new file mode 100644
index 0000000..f626d77
--- /dev/null
+++ b/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/Generator.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 Generator<TypeMeta extends StorIOTypeMeta> {
+
+    @NotNull
+    JavaFile generateJavaFile(@NotNull TypeMeta typeMeta);
+}
diff --git a/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java b/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java
deleted file mode 100644
index 861d7c8..0000000
--- a/storio-common-annotations-processor/src/main/java/com/pushtorefresh/storio/common/annotations/processor/generate/ResolverGenerator.java
+++ /dev/null
@@ -1,12 +0,0 @@
-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);
-}
diff --git a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java
index 21c7a05..7ac0a0f 100644
--- a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java
+++ b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/StorIOContentResolverProcessor.java
@@ -3,12 +3,13 @@
 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.generate.Generator;
 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.MappingGenerator;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.generate.PutResolverGenerator;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
@@ -288,19 +289,25 @@ protected void validateAnnotatedClassesAndColumns(@NotNull final Map<TypeElement
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOContentResolverTypeMeta> createPutResolver() {
+    protected Generator<StorIOContentResolverTypeMeta> createPutResolver() {
         return new PutResolverGenerator();
     }
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOContentResolverTypeMeta> createGetResolver() {
+    protected Generator<StorIOContentResolverTypeMeta> createGetResolver() {
         return new GetResolverGenerator();
     }
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOContentResolverTypeMeta> createDeleteResolver() {
+    protected Generator<StorIOContentResolverTypeMeta> createDeleteResolver() {
         return new DeleteResolverGenerator();
     }
+
+    @NotNull
+    @Override
+    protected Generator<StorIOContentResolverTypeMeta> createMapping() {
+        return new MappingGenerator();
+    }
 }
diff --git a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java
index 1182c48..69813ce 100644
--- a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java
+++ b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/DeleteResolverGenerator.java
@@ -1,6 +1,6 @@
 package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
 
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.JavaFile;
@@ -18,13 +18,20 @@
 import static javax.lang.model.element.Modifier.PROTECTED;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class DeleteResolverGenerator implements ResolverGenerator<StorIOContentResolverTypeMeta> {
+public class DeleteResolverGenerator implements Generator<StorIOContentResolverTypeMeta> {
+
+    private static final String SUFFIX = "StorIOContentResolverDeleteResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOContentResolverTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
         final ClassName storIOContentResolverTypeClassName = ClassName.get(storIOContentResolverTypeMeta.packageName, storIOContentResolverTypeMeta.simpleName);
 
-        final TypeSpec deleteResolver = TypeSpec.classBuilder(storIOContentResolverTypeClassName.simpleName() + "StorIOContentResolverDeleteResolver")
+        final TypeSpec deleteResolver = TypeSpec.classBuilder(generateName(storIOContentResolverTypeMeta))
                 .addJavadoc("Generated resolver for Delete Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.contentresolver.operations.delete", "DefaultDeleteResolver"), storIOContentResolverTypeClassName))
diff --git a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java
index 66cd173..556f024 100644
--- a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java
+++ b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/GetResolverGenerator.java
@@ -1,7 +1,7 @@
 package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
 
 import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 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;
@@ -32,13 +32,20 @@
 import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.STRING;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class GetResolverGenerator implements ResolverGenerator<StorIOContentResolverTypeMeta> {
+public class GetResolverGenerator implements Generator<StorIOContentResolverTypeMeta> {
+
+    private static final String SUFFIX = "StorIOContentResolverGetResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOContentResolverTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
         final ClassName storIOContentResolverTypeClassName = ClassName.get(storIOContentResolverTypeMeta.packageName, storIOContentResolverTypeMeta.simpleName);
 
-        final TypeSpec getResolver = TypeSpec.classBuilder(storIOContentResolverTypeMeta.simpleName + "StorIOContentResolverGetResolver")
+        final TypeSpec getResolver = TypeSpec.classBuilder(generateName(storIOContentResolverTypeMeta))
                 .addJavadoc("Generated resolver for Get Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.contentresolver.operations.get", "DefaultGetResolver"), storIOContentResolverTypeClassName))
diff --git a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGenerator.java b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGenerator.java
new file mode 100644
index 0000000..7d6260f
--- /dev/null
+++ b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGenerator.java
@@ -0,0 +1,59 @@
+package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
+
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
+import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+
+import org.jetbrains.annotations.NotNull;
+
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+public class MappingGenerator implements Generator<StorIOContentResolverTypeMeta> {
+
+    public static final String SUFFIX = "ContentResolverTypeMapping";
+
+    @NotNull
+    @Override
+    public JavaFile generateJavaFile(@NotNull StorIOContentResolverTypeMeta storIOSQLiteTypeMeta) {
+        final ClassName storIOSQLiteTypeClassName = ClassName.get(
+                storIOSQLiteTypeMeta.packageName, storIOSQLiteTypeMeta.simpleName);
+
+        ClassName superclass = ClassName.get("com.pushtorefresh.storio.contentresolver", SUFFIX);
+        ParameterizedTypeName superclassParametrized =
+                ParameterizedTypeName.get(superclass, storIOSQLiteTypeClassName);
+
+
+        final TypeSpec mapping = TypeSpec.classBuilder(storIOSQLiteTypeMeta.simpleName + SUFFIX)
+                .addJavadoc("Generated mapping with collection of resolvers\n")
+                .addModifiers(PUBLIC)
+                .superclass(superclassParametrized)
+                .addMethod(createConstructor(storIOSQLiteTypeMeta))
+                .build();
+
+        return JavaFile
+                .builder(storIOSQLiteTypeMeta.packageName, mapping)
+                .indent(INDENT)
+                .build();
+    }
+
+    @NotNull
+    private MethodSpec createConstructor(StorIOContentResolverTypeMeta storIOSQLiteTypeMeta) {
+        final ClassName putResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                PutResolverGenerator.generateName(storIOSQLiteTypeMeta));
+        final ClassName getResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                GetResolverGenerator.generateName(storIOSQLiteTypeMeta));
+        final ClassName deleteResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                DeleteResolverGenerator.generateName(storIOSQLiteTypeMeta));
+
+        return MethodSpec.constructorBuilder()
+                .addModifiers(PUBLIC)
+                .addStatement("super(new $T(),\nnew $T(),\nnew $T())",
+                        putResolver, getResolver, deleteResolver)
+                .build();
+    }
+}
diff --git a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java
index d9087a9..22c5093 100644
--- a/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java
+++ b/storio-content-resolver-annotations-processor/src/main/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/PutResolverGenerator.java
@@ -1,6 +1,6 @@
 package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
 
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverColumnMeta;
 import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
 import com.squareup.javapoet.ClassName;
@@ -19,13 +19,20 @@
 import static javax.lang.model.element.Modifier.PROTECTED;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class PutResolverGenerator  implements ResolverGenerator<StorIOContentResolverTypeMeta> {
+public class PutResolverGenerator  implements Generator<StorIOContentResolverTypeMeta> {
+
+    private static final String SUFFIX = "StorIOContentResolverPutResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOContentResolverTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull final StorIOContentResolverTypeMeta storIOContentResolverTypeMeta) {
         final ClassName storIOContentResolverTypeClassName = ClassName.get(storIOContentResolverTypeMeta.packageName, storIOContentResolverTypeMeta.simpleName);
 
-        final TypeSpec putResolver = TypeSpec.classBuilder(storIOContentResolverTypeMeta.simpleName + "StorIOContentResolverPutResolver")
+        final TypeSpec putResolver = TypeSpec.classBuilder(generateName(storIOContentResolverTypeMeta))
                 .addJavadoc("Generated resolver for Put Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.contentresolver.operations.put", "DefaultPutResolver"), storIOContentResolverTypeClassName))
diff --git a/storio-content-resolver-annotations-processor/src/test/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGeneratorTest.java b/storio-content-resolver-annotations-processor/src/test/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGeneratorTest.java
new file mode 100644
index 0000000..77eea79
--- /dev/null
+++ b/storio-content-resolver-annotations-processor/src/test/java/com/pushtorefresh/storio/contentresolver/annotations/processor/generate/MappingGeneratorTest.java
@@ -0,0 +1,48 @@
+package com.pushtorefresh.storio.contentresolver.annotations.processor.generate;
+
+import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverType;
+import com.pushtorefresh.storio.contentresolver.annotations.processor.introspection.StorIOContentResolverTypeMeta;
+import com.squareup.javapoet.JavaFile;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class MappingGeneratorTest {
+    @Test
+    public void generateJavaFile() throws IOException {
+        final StorIOContentResolverType storIOSQLiteType = mock(StorIOContentResolverType.class);
+
+        final StorIOContentResolverTypeMeta storIOSQLiteTypeMeta = new StorIOContentResolverTypeMeta(
+                "TestItem",
+                "com.test",
+                storIOSQLiteType
+        );
+
+        MappingGenerator mappingGenerator = new MappingGenerator();
+        final JavaFile javaFile = mappingGenerator.generateJavaFile(storIOSQLiteTypeMeta);
+        final StringBuilder out = new StringBuilder();
+        javaFile.writeTo(out);
+
+
+        String result = "package com.test;\n" +
+                "\n" +
+                "import com.pushtorefresh.storio.contentresolver.ContentResolverTypeMapping;\n" +
+                "\n" +
+                "/**\n" +
+                " * Generated mapping with collection of resolvers\n" +
+                " */\n" +
+                "public class TestItemContentResolverTypeMapping extends ContentResolverTypeMapping<TestItem> {\n" +
+                "    public TestItemContentResolverTypeMapping() {\n" +
+                "        super(new TestItemStorIOContentResolverPutResolver(),\n" +
+                "                new TestItemStorIOContentResolverGetResolver(),\n" +
+                "                new TestItemStorIOContentResolverDeleteResolver());\n" +
+                "    }\n" +
+                "}\n";
+
+        assertThat(out.toString()).isEqualTo(result);
+    }
+}
\ No newline at end of file
diff --git a/storio-content-resolver/src/main/java/com/pushtorefresh/storio/contentresolver/ContentResolverTypeMapping.java b/storio-content-resolver/src/main/java/com/pushtorefresh/storio/contentresolver/ContentResolverTypeMapping.java
index 3dc3750..e0e0820 100644
--- a/storio-content-resolver/src/main/java/com/pushtorefresh/storio/contentresolver/ContentResolverTypeMapping.java
+++ b/storio-content-resolver/src/main/java/com/pushtorefresh/storio/contentresolver/ContentResolverTypeMapping.java
@@ -24,9 +24,9 @@
     @NonNull
     private final DeleteResolver<T> deleteResolver;
 
-    private ContentResolverTypeMapping(@NonNull PutResolver<T> putResolver,
-                                       @NonNull GetResolver<T> getResolver,
-                                       @NonNull DeleteResolver<T> deleteResolver) {
+    protected ContentResolverTypeMapping(@NonNull PutResolver<T> putResolver,
+                                         @NonNull GetResolver<T> getResolver,
+                                         @NonNull DeleteResolver<T> deleteResolver) {
         this.putResolver = putResolver;
         this.getResolver = getResolver;
         this.deleteResolver = deleteResolver;
diff --git a/storio-sample-app/build.gradle b/storio-sample-app/build.gradle
index f4fb0dc..36f493b 100644
--- a/storio-sample-app/build.gradle
+++ b/storio-sample-app/build.gradle
@@ -54,6 +54,9 @@ dependencies {
     compile libraries.storIOSQLiteAnnotations
     apt libraries.storIOSQLiteAnnotationsProcessor
 
+    compile libraries.storIOContentResolverAnnotations
+    apt libraries.storIOContentResolverAnnotationsProcessor
+
     compile libraries.dagger
     apt libraries.daggerCompiler
 
diff --git a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/DbModule.java b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/DbModule.java
index b377e3a..429b791 100644
--- a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/DbModule.java
+++ b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/DbModule.java
@@ -5,14 +5,10 @@
 import android.support.annotation.NonNull;
 
 import com.pushtorefresh.storio.sample.db.entities.Tweet;
-import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLiteDeleteResolver;
-import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLiteGetResolver;
-import com.pushtorefresh.storio.sample.db.entities.TweetStorIOSQLitePutResolver;
+import com.pushtorefresh.storio.sample.db.entities.TweetSQLiteTypeMapping;
 import com.pushtorefresh.storio.sample.db.entities.TweetWithUser;
 import com.pushtorefresh.storio.sample.db.entities.User;
-import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLiteDeleteResolver;
-import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLiteGetResolver;
-import com.pushtorefresh.storio.sample.db.entities.UserStorIOSQLitePutResolver;
+import com.pushtorefresh.storio.sample.db.entities.UserSQLiteTypeMapping;
 import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserDeleteResolver;
 import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserGetResolver;
 import com.pushtorefresh.storio.sample.db.resolvers.TweetWithUserPutResolver;
@@ -39,16 +35,8 @@
     public StorIOSQLite provideStorIOSQLite(@NonNull SQLiteOpenHelper sqLiteOpenHelper) {
         return DefaultStorIOSQLite.builder()
                 .sqliteOpenHelper(sqLiteOpenHelper)
-                .addTypeMapping(Tweet.class, SQLiteTypeMapping.<Tweet>builder()
-                        .putResolver(new TweetStorIOSQLitePutResolver())
-                        .getResolver(new TweetStorIOSQLiteGetResolver())
-                        .deleteResolver(new TweetStorIOSQLiteDeleteResolver())
-                        .build())
-                .addTypeMapping(User.class, SQLiteTypeMapping.<User>builder()
-                        .putResolver(new UserStorIOSQLitePutResolver())
-                        .getResolver(new UserStorIOSQLiteGetResolver())
-                        .deleteResolver(new UserStorIOSQLiteDeleteResolver())
-                        .build())
+.addTypeMapping(Tweet.class, new TweetSQLiteTypeMapping())
+.addTypeMapping(User.class, new UserSQLiteTypeMapping())
                 .addTypeMapping(TweetWithUser.class, SQLiteTypeMapping.<TweetWithUser>builder()
                         .putResolver(new TweetWithUserPutResolver())
                         .getResolver(new TweetWithUserGetResolver())
diff --git a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/entities/Tweet.java b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/entities/Tweet.java
index e621f73..5f87da2 100644
--- a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/entities/Tweet.java
+++ b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/db/entities/Tweet.java
@@ -3,7 +3,10 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
+import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverColumn;
+import com.pushtorefresh.storio.contentresolver.annotations.StorIOContentResolverType;
 import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
+import com.pushtorefresh.storio.sample.provider.meta.TweetMeta;
 import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteColumn;
 import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
 
@@ -14,6 +17,7 @@
 // Which will generate type mapping code in compile time,
 // You just need to link it in your code.
 @StorIOSQLiteType(table = TweetsTable.TABLE)
+@StorIOContentResolverType(uri = TweetMeta.URI_STRING)
 public class Tweet {
 
     /**
@@ -21,14 +25,17 @@
      */
     @Nullable
     @StorIOSQLiteColumn(name = TweetsTable.COLUMN_ID, key = true)
+    @StorIOContentResolverColumn(name = TweetsTable.COLUMN_ID, key = true)
     Long id;
 
     @NonNull
     @StorIOSQLiteColumn(name = TweetsTable.COLUMN_AUTHOR)
+    @StorIOContentResolverColumn(name = TweetsTable.COLUMN_AUTHOR)
     String author;
 
     @NonNull
     @StorIOSQLiteColumn(name = TweetsTable.COLUMN_CONTENT)
+    @StorIOContentResolverColumn(name = TweetsTable.COLUMN_CONTENT)
     String content;
 
     // leave default constructor for AutoGenerated code!
diff --git a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/provider/meta/TweetMeta.java b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/provider/meta/TweetMeta.java
index 8fdc14c..beba4f6 100644
--- a/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/provider/meta/TweetMeta.java
+++ b/storio-sample-app/src/main/java/com/pushtorefresh/storio/sample/provider/meta/TweetMeta.java
@@ -21,7 +21,10 @@
 public class TweetMeta {
 
     @NonNull
-    public static final Uri CONTENT_URI = Uri.parse("content://" + SampleContentProvider.AUTHORITY + "/tweets");
+    public static final String URI_STRING = "content://" + SampleContentProvider.AUTHORITY + "/tweets";
+
+    @NonNull
+    public static final Uri CONTENT_URI = Uri.parse(URI_STRING);
 
     @NonNull
     public static final PutResolver<Tweet> PUT_RESOLVER = new DefaultPutResolver<Tweet>() {
diff --git a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java
index 746a0f9..03effb2 100644
--- a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java
+++ b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/StorIOSQLiteProcessor.java
@@ -3,12 +3,13 @@
 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.generate.Generator;
 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.MappingGenerator;
 import com.pushtorefresh.storio.sqlite.annotations.processor.generate.PutResolverGenerator;
 import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
 import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
@@ -195,19 +196,25 @@ protected void validateAnnotatedClassesAndColumns(@NotNull Map<TypeElement, Stor
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOSQLiteTypeMeta> createPutResolver() {
+    protected Generator<StorIOSQLiteTypeMeta> createPutResolver() {
         return new PutResolverGenerator();
     }
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOSQLiteTypeMeta> createGetResolver() {
+    protected Generator<StorIOSQLiteTypeMeta> createGetResolver() {
         return new GetResolverGenerator();
     }
 
     @NotNull
     @Override
-    protected ResolverGenerator<StorIOSQLiteTypeMeta> createDeleteResolver() {
+    protected Generator<StorIOSQLiteTypeMeta> createDeleteResolver() {
         return new DeleteResolverGenerator();
     }
+
+    @NotNull
+    @Override
+    protected Generator<StorIOSQLiteTypeMeta> createMapping() {
+        return new MappingGenerator();
+    }
 }
diff --git a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java
index 9640986..e4371c0 100644
--- a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java
+++ b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/DeleteResolverGenerator.java
@@ -1,6 +1,6 @@
 package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
 
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
 import com.squareup.javapoet.ClassName;
 import com.squareup.javapoet.JavaFile;
@@ -18,13 +18,20 @@
 import static javax.lang.model.element.Modifier.PROTECTED;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class DeleteResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
+public class DeleteResolverGenerator implements Generator<StorIOSQLiteTypeMeta> {
+
+    public static final String SUFFIX = "StorIOSQLiteDeleteResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
         final ClassName storIOSQLiteTypeClassName = ClassName.get(storIOSQLiteTypeMeta.packageName, storIOSQLiteTypeMeta.simpleName);
 
-        final TypeSpec deleteResolver = TypeSpec.classBuilder(storIOSQLiteTypeMeta.simpleName + "StorIOSQLiteDeleteResolver")
+        final TypeSpec deleteResolver = TypeSpec.classBuilder(generateName(storIOSQLiteTypeMeta))
                 .addJavadoc("Generated resolver for Delete Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.sqlite.operations.delete", "DefaultDeleteResolver"), storIOSQLiteTypeClassName))
diff --git a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java
index 2da3be7..f50ad2b 100644
--- a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java
+++ b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/GetResolverGenerator.java
@@ -1,7 +1,7 @@
 package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
 
 import com.pushtorefresh.storio.common.annotations.processor.ProcessingException;
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 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;
@@ -32,13 +32,20 @@
 import static com.pushtorefresh.storio.common.annotations.processor.introspection.JavaType.STRING;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class GetResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
+public class GetResolverGenerator implements Generator<StorIOSQLiteTypeMeta> {
+
+    public static final String SUFFIX = "StorIOSQLiteGetResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
         final ClassName storIOSQLiteTypeClassName = ClassName.get(storIOSQLiteTypeMeta.packageName, storIOSQLiteTypeMeta.simpleName);
 
-        final TypeSpec getResolver = TypeSpec.classBuilder(storIOSQLiteTypeMeta.simpleName + "StorIOSQLiteGetResolver")
+        final TypeSpec getResolver = TypeSpec.classBuilder(generateName(storIOSQLiteTypeMeta))
                 .addJavadoc("Generated resolver for Get Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.sqlite.operations.get", "DefaultGetResolver"), storIOSQLiteTypeClassName))
diff --git a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGenerator.java b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGenerator.java
new file mode 100644
index 0000000..72372aa
--- /dev/null
+++ b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGenerator.java
@@ -0,0 +1,59 @@
+package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
+
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
+import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+
+import org.jetbrains.annotations.NotNull;
+
+import static com.pushtorefresh.storio.common.annotations.processor.generate.Common.INDENT;
+import static javax.lang.model.element.Modifier.PUBLIC;
+
+public class MappingGenerator implements Generator<StorIOSQLiteTypeMeta> {
+
+    public static final String SUFFIX = "SQLiteTypeMapping";
+
+    @NotNull
+    @Override
+    public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
+        final ClassName storIOSQLiteTypeClassName = ClassName.get(
+                storIOSQLiteTypeMeta.packageName, storIOSQLiteTypeMeta.simpleName);
+
+        ClassName superclass = ClassName.get("com.pushtorefresh.storio.sqlite", SUFFIX);
+        ParameterizedTypeName superclassParametrized =
+                ParameterizedTypeName.get(superclass, storIOSQLiteTypeClassName);
+
+
+        final TypeSpec mapping = TypeSpec.classBuilder(storIOSQLiteTypeMeta.simpleName + SUFFIX)
+                .addJavadoc("Generated mapping with collection of resolvers\n")
+                .addModifiers(PUBLIC)
+                .superclass(superclassParametrized)
+                .addMethod(createConstructor(storIOSQLiteTypeMeta))
+                .build();
+
+        return JavaFile
+                .builder(storIOSQLiteTypeMeta.packageName, mapping)
+                .indent(INDENT)
+                .build();
+    }
+
+    @NotNull
+    private MethodSpec createConstructor(StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
+        final ClassName putResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                PutResolverGenerator.generateName(storIOSQLiteTypeMeta));
+        final ClassName getResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                GetResolverGenerator.generateName(storIOSQLiteTypeMeta));
+        final ClassName deleteResolver = ClassName.get(storIOSQLiteTypeMeta.packageName,
+                DeleteResolverGenerator.generateName(storIOSQLiteTypeMeta));
+
+        return MethodSpec.constructorBuilder()
+                .addModifiers(PUBLIC)
+                .addStatement("super(new $T(),\nnew $T(),\nnew $T())",
+                        putResolver, getResolver, deleteResolver)
+                .build();
+    }
+}
diff --git a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java
index f4bb604..34ec1a9 100644
--- a/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java
+++ b/storio-sqlite-annotations-processor/src/main/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/PutResolverGenerator.java
@@ -1,6 +1,6 @@
 package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
 
-import com.pushtorefresh.storio.common.annotations.processor.generate.ResolverGenerator;
+import com.pushtorefresh.storio.common.annotations.processor.generate.Generator;
 import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteColumnMeta;
 import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
 import com.squareup.javapoet.ClassName;
@@ -19,13 +19,20 @@
 import static javax.lang.model.element.Modifier.PROTECTED;
 import static javax.lang.model.element.Modifier.PUBLIC;
 
-public class PutResolverGenerator implements ResolverGenerator<StorIOSQLiteTypeMeta> {
+public class PutResolverGenerator implements Generator<StorIOSQLiteTypeMeta> {
+
+    public static final String SUFFIX = "StorIOSQLitePutResolver";
+
+    @NotNull
+    public static String generateName(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
+        return storIOSQLiteTypeMeta.simpleName + SUFFIX;
+    }
 
     @NotNull
     public JavaFile generateJavaFile(@NotNull StorIOSQLiteTypeMeta storIOSQLiteTypeMeta) {
         final ClassName storIOSQLiteTypeClassName = ClassName.get(storIOSQLiteTypeMeta.packageName, storIOSQLiteTypeMeta.simpleName);
 
-        final TypeSpec putResolver = TypeSpec.classBuilder(storIOSQLiteTypeMeta.simpleName + "StorIOSQLitePutResolver")
+        final TypeSpec putResolver = TypeSpec.classBuilder(generateName(storIOSQLiteTypeMeta))
                 .addJavadoc("Generated resolver for Put Operation\n")
                 .addModifiers(PUBLIC)
                 .superclass(ParameterizedTypeName.get(ClassName.get("com.pushtorefresh.storio.sqlite.operations.put", "DefaultPutResolver"), storIOSQLiteTypeClassName))
diff --git a/storio-sqlite-annotations-processor/src/test/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGeneratorTest.java b/storio-sqlite-annotations-processor/src/test/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGeneratorTest.java
new file mode 100644
index 0000000..07fa005
--- /dev/null
+++ b/storio-sqlite-annotations-processor/src/test/java/com/pushtorefresh/storio/sqlite/annotations/processor/generate/MappingGeneratorTest.java
@@ -0,0 +1,49 @@
+package com.pushtorefresh.storio.sqlite.annotations.processor.generate;
+
+import com.pushtorefresh.storio.sqlite.annotations.StorIOSQLiteType;
+import com.pushtorefresh.storio.sqlite.annotations.processor.introspection.StorIOSQLiteTypeMeta;
+import com.squareup.javapoet.JavaFile;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class MappingGeneratorTest {
+    @Test
+    public void generateJavaFile() throws IOException {
+        final StorIOSQLiteType storIOSQLiteType = mock(StorIOSQLiteType.class);
+
+        final StorIOSQLiteTypeMeta storIOSQLiteTypeMeta = new StorIOSQLiteTypeMeta(
+                "TestItem",
+                "com.test",
+                storIOSQLiteType
+        );
+
+        MappingGenerator mappingGenerator = new MappingGenerator();
+        final JavaFile javaFile = mappingGenerator.generateJavaFile(storIOSQLiteTypeMeta);
+        final StringBuilder out = new StringBuilder();
+        javaFile.writeTo(out);
+
+
+        String result =
+                "package com.test;\n" +
+                "\n" +
+                "import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;\n" +
+                "\n" +
+                "/**\n" +
+                " * Generated mapping with collection of resolvers\n" +
+                " */\n" +
+                "public class TestItemSQLiteTypeMapping extends SQLiteTypeMapping<TestItem> {\n" +
+                "    public TestItemSQLiteTypeMapping() {\n" +
+                "        super(new TestItemStorIOSQLitePutResolver(),\n" +
+                "                new TestItemStorIOSQLiteGetResolver(),\n" +
+                "                new TestItemStorIOSQLiteDeleteResolver());\n" +
+                "    }\n" +
+                "}\n";
+
+        assertThat(out.toString()).isEqualTo(result);
+    }
+}
\ No newline at end of file
diff --git a/storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/SQLiteTypeMapping.java b/storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/SQLiteTypeMapping.java
index c7d6b4a..25633dd 100644
--- a/storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/SQLiteTypeMapping.java
+++ b/storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/SQLiteTypeMapping.java
@@ -24,9 +24,9 @@
     @NonNull
     private final DeleteResolver<T> deleteResolver;
 
-    SQLiteTypeMapping(@NonNull PutResolver<T> putResolver,
-                      @NonNull GetResolver<T> getResolver,
-                      @NonNull DeleteResolver<T> deleteResolver) {
+    protected SQLiteTypeMapping(@NonNull PutResolver<T> putResolver,
+                                @NonNull GetResolver<T> getResolver,
+                                @NonNull DeleteResolver<T> deleteResolver) {
         this.putResolver = putResolver;
         this.getResolver = getResolver;
         this.deleteResolver = deleteResolver;
