All Downloads are FREE. Search and download functionalities are using the official Maven repository.

carboncopy.compiler.builder.BindingManager.kt Maven / Gradle / Ivy

package carboncopy.compiler.builder


import carboncopy.annotations.CarbonCopy
import com.google.auto.common.MoreElements
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
import javax.annotation.processing.ProcessingEnvironment
import javax.lang.model.element.Element
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.Modifier
import javax.tools.Diagnostic


/**
 * Holds the [ProcessingEnvironment] and starting point of the copy process
 *
 * @author js
 */
class BindingManager(private val processingEnvironment: ProcessingEnvironment, val classElement: Element, private val converterClassBuilder: TypeSpec.Builder) {

    internal val packageName = MoreElements.getPackage(classElement).qualifiedName.toString()
    internal val originalClassName = classElement.simpleName.toString()
    internal val ignoredFields = classElement.getAnnotation(CarbonCopy::class.java).ignoredFields
    private val copyNameGiven: String? = classElement.getAnnotation(CarbonCopy::class.java).name
    internal val copyClassName = if (copyNameGiven.isNullOrEmpty()) originalClassName + "POJO" else copyNameGiven!!
    internal val filer = processingEnvironment.filer
    private val elementUtils = processingEnvironment.elementUtils
    internal var sourceToCopyMethodBuilder: MethodSpec.Builder? = null
    internal var copyToSourceMethodBuilder: MethodSpec.Builder? = null
    private val CONVERTER_METHOD_NAME = "convert"
    private val CONVERTER_METHOD_PARAMETER_NAME = "source"


    /**
     * Called to start the carbon copy creation
     */
    fun generateCarbonCopy() {
        if (canCreateSourceInstance()) {
            copyToSourceMethodBuilder = createConverterMethod(ClassName.get(classElement.asType()), ClassName.get(packageName, copyClassName), CONVERTER_METHOD_PARAMETER_NAME)
        } else {
            processingEnvironment.messager.printMessage(Diagnostic.Kind.WARNING, "No default constructor found for ${classElement.simpleName}")
        }
        sourceToCopyMethodBuilder = createConverterMethod(ClassName.get(packageName, copyClassName), ClassName.get(classElement.asType()), CONVERTER_METHOD_PARAMETER_NAME)
        val carbonCopyBuilder = CarbonCopyClassBuilder(this)
        carbonCopyBuilder.build()

        if (copyToSourceMethodBuilder != null) {
            converterClassBuilder.addMethod(copyToSourceMethodBuilder!!.addStatement("return copy").build())
        }
        converterClassBuilder.addMethod(sourceToCopyMethodBuilder!!.addStatement("return copy").build())
    }

    /**
     * Create the covert method for this class
     */
    private fun createConverterMethod(returnType: TypeName, parameterType: TypeName, parameterName: String) =
            MethodSpec.methodBuilder(CONVERTER_METHOD_NAME)
                    .returns(returnType)
                    .addParameter(parameterType, parameterName)
                    .addModifiers(Modifier.STATIC, Modifier.PUBLIC)
                    .addJavadoc("Converts {@link \$T} -> {@link \$T}\n", parameterType, returnType)
                    .addStatement("\$T copy = new $returnType()", returnType)


    /**
     * Returns a [Element] for the given class
     */
    fun getElement(className: String): Element? {
        var filteredClassName = className
        val templateStart = className.indexOf('<')
        if (templateStart != -1) {
            filteredClassName = className.substring(0, templateStart).trim { it <= ' ' }
        }
        return elementUtils.getTypeElement(filteredClassName)
    }

    private fun canCreateSourceInstance() =
            classElement.enclosedElements.any {
                it.simpleName.toString() == ""
                        && it is ExecutableElement
                        && it.modifiers.contains(Modifier.PUBLIC)
                        && it.parameters.isEmpty()
            }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy