Skip to content

Commit

Permalink
[converters] preserve annotation so we can include type converter sub…
Browse files Browse the repository at this point in the history
…types in lib. Add subtypes to the converter so consumers can safely provide subtypes.
  • Loading branch information
agrosner committed Jan 1, 2017
1 parent 0aa5b47 commit a6eb846
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 6 deletions.
Expand Up @@ -10,7 +10,13 @@
* Description: Marks a class as being a TypeConverter. A type converter will turn a non-model, non-SQLiteTyped class into
* a valid database type.
*/
@Retention(RetentionPolicy.SOURCE)
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface TypeConverter {

/**
* @return Specify a set of subclasses by which the {@link TypeConverter} registers for. For
* each one, this will create a new instance of the converter.
*/
Class<?>[] allowedSubtypes() default {};
}
@@ -1,11 +1,13 @@
package com.raizlabs.android.dbflow.converter;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
* Author: andrewgrosner
* Description: Defines how we store and retrieve a {@link java.util.Calendar}
*/
@com.raizlabs.android.dbflow.annotation.TypeConverter(allowedSubtypes = {GregorianCalendar.class})
public class CalendarConverter extends TypeConverter<Long, Calendar> {

@Override
Expand Down
@@ -1,11 +1,14 @@
package com.raizlabs.android.dbflow.converter;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

/**
* Author: andrewgrosner
* Description: Defines how we store and retrieve a {@link java.sql.Date}
*/
@com.raizlabs.android.dbflow.annotation.TypeConverter(allowedSubtypes = {Time.class, Timestamp.class})
public class SqlDateConverter extends TypeConverter<Long, Date> {

@Override
Expand Down
Expand Up @@ -155,7 +155,7 @@ class TypeConverterHandler : BaseContainerHandler<TypeConverter>() {
override fun onProcessElement(processorManager: ProcessorManager, element: Element) {
if (element is TypeElement) {
val className = ProcessorUtils.fromTypeMirror(element.asType(), processorManager)
val converterDefinition = className?.let { TypeConverterDefinition(it, element.asType(), processorManager) }
val converterDefinition = className?.let { TypeConverterDefinition(it, element.asType(), processorManager, element) }
converterDefinition?.let {
if (VALIDATOR.validate(processorManager, converterDefinition)) {
// allow user overrides from default.
Expand Down
Expand Up @@ -29,14 +29,21 @@ class DatabaseHolderDefinition(private val processorManager: ProcessorManager) :
override val typeSpec: TypeSpec
get() {
val typeBuilder = TypeSpec.classBuilder(this.className)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.superclass(ClassNames.DATABASE_HOLDER)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.superclass(ClassNames.DATABASE_HOLDER)

val constructor = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC)

processorManager.getTypeConverters().forEach {
constructor.addStatement("\$L.put(\$T.class, new \$T())",
DatabaseHandler.TYPE_CONVERTER_MAP_FIELD_NAME, it.modelTypeName, it.className)
DatabaseHandler.TYPE_CONVERTER_MAP_FIELD_NAME, it.modelTypeName, it.className)

if (it.allowedSubTypes?.isNotEmpty() ?: false) {
it.allowedSubTypes?.forEach { subType ->
constructor.addStatement("\$L.put(\$T.class, new \$T())",
DatabaseHandler.TYPE_CONVERTER_MAP_FIELD_NAME, subType, it.className)
}
}
}

processorManager.getDatabaseHolderDefinitionMap().forEach { databaseDefinition ->
Expand Down
@@ -1,26 +1,44 @@
package com.raizlabs.android.dbflow.processor.definition

import com.raizlabs.android.dbflow.annotation.TypeConverter
import com.raizlabs.android.dbflow.processor.ClassNames
import com.raizlabs.android.dbflow.processor.ProcessorManager
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
import javax.lang.model.element.TypeElement
import javax.lang.model.type.DeclaredType
import javax.lang.model.type.MirroredTypesException
import javax.lang.model.type.TypeMirror

/**
* Description: Holds data about type converters in order to write them.
*/
class TypeConverterDefinition(val className: ClassName,
typeMirror: TypeMirror, manager: ProcessorManager) {
typeMirror: TypeMirror, manager: ProcessorManager,
typeElement: TypeElement? = null) {

var modelTypeName: TypeName? = null
private set

var dbTypeName: TypeName? = null
private set

var allowedSubTypes: List<TypeName>? = null

init {

val annotation = typeElement?.getAnnotation(TypeConverter::class.java)
if (annotation != null) {
val allowedSubTypes: MutableList<TypeName> = mutableListOf()
try {
annotation.allowedSubtypes;
} catch (e: MirroredTypesException) {
val types = e.typeMirrors
types.forEach { allowedSubTypes.add(TypeName.get(it)) }
}
this.allowedSubTypes = allowedSubTypes
}

val types = manager.typeUtils

var typeConverterSuper: DeclaredType? = null
Expand Down

0 comments on commit a6eb846

Please sign in to comment.