gsonpath.generator.extension.range.intrange.IntRangeExtension.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gsonpath-compiler Show documentation
Show all versions of gsonpath-compiler Show documentation
An annotation processor which generates Type Adapters for the Google Gson library
package gsonpath.generator.extension.range.intrange
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.CodeBlock
import gsonpath.ProcessingException
import gsonpath.compiler.ExtensionFieldMetadata
import gsonpath.compiler.GsonPathExtension
import gsonpath.generator.extension.getAnnotationMirror
import gsonpath.generator.extension.getAnnotationValueObject
import gsonpath.generator.extension.range.handleRangeValue
import gsonpath.model.FieldType
import gsonpath.util.codeBlock
import javax.annotation.processing.ProcessingEnvironment
import javax.lang.model.element.AnnotationMirror
/**
* A {@link GsonPathExtension} that supports the '@IntRange' annotation.
*/
class IntRangeExtension : GsonPathExtension {
private val boxedInt = ClassName.get("java.lang", "Integer")
private val boxedLong = ClassName.get("java.lang", "Long")
override val extensionName: String
get() = "'IntRange' Annotation"
override fun createCodePostReadResult(
processingEnvironment: ProcessingEnvironment,
extensionFieldMetadata: ExtensionFieldMetadata): GsonPathExtension.ExtensionResult? {
val (fieldInfo, variableName, jsonPath) = extensionFieldMetadata
val intRangeAnnotation: AnnotationMirror =
getAnnotationMirror(fieldInfo.element, "android.support.annotation", "IntRange")
?: getAnnotationMirror(fieldInfo.element, "gsonpath.extension.annotation", "IntRange")
?: return null
// Ensure that the field is either a integer, or a long.
val typeName = fieldInfo.fieldType.typeName.let {
if (fieldInfo.fieldType is FieldType.Primitive) {
it.box()
} else {
it
}
}
if (typeName != boxedInt && typeName != boxedLong) {
throw ProcessingException("Unexpected type found for field annotated with 'IntRange', only " +
"integers and longs are allowed.", fieldInfo.element)
}
val validationCodeBlock = codeBlock {
handleFrom(intRangeAnnotation, jsonPath, variableName)
handleTo(intRangeAnnotation, jsonPath, variableName)
}
if (!validationCodeBlock.isEmpty) {
return GsonPathExtension.ExtensionResult(validationCodeBlock)
}
return null
}
/**
* Adds the range 'from' validation if the fromValue does not equal the floor-value.
*
* @param intRangeAnnotationMirror the annotation to obtain the range values
* @param jsonPath the json path of the field being validated
* @param variableName the name of the variable that is assigned back to the fieldName
*/
private fun CodeBlock.Builder.handleFrom(intRangeAnnotationMirror: AnnotationMirror, jsonPath: String,
variableName: String): CodeBlock.Builder {
val fromValue: Long = getAnnotationValueObject(intRangeAnnotationMirror, "from") as Long? ?: return this
if (fromValue == java.lang.Long.MIN_VALUE) {
return this
}
return handleRangeValue(fromValue.toString(), true, true, jsonPath, variableName)
}
/**
* Adds the range 'to' validation if the toValue does not equal the ceiling-value.
*
* @param intRangeAnnotationMirror the annotation to obtain the range values
* @param jsonPath the json path of the field being validated
* @param variableName the name of the variable that is assigned back to the fieldName
*/
private fun CodeBlock.Builder.handleTo(intRangeAnnotationMirror: AnnotationMirror, jsonPath: String,
variableName: String): CodeBlock.Builder {
val toValue: Long = getAnnotationValueObject(intRangeAnnotationMirror, "to") as Long? ?: return this
if (toValue == java.lang.Long.MAX_VALUE) {
return this
}
return handleRangeValue(toValue.toString(), false, true, jsonPath, variableName)
}
}