mardi 30 juillet 2019

Mapping data classes with non-constructor methods

I have the following model classes set up in my Android project which I'm attempting to convert from one type to the other (API Response models to Room Database Entity models) but am running into an issue which I cannot seem to get past.

data class TeamResponse(
    val id:String,
    val name:String,
    val teamMembers:List<TeamMember>
)

data class TeamMemberResponse(
    val id:String,
    val firstName:String,
    val lastName:String
)

data class TeamEntity(
    val id:String,
    val name:String,
    val lastRefresh:Date
) {
    @Ignore var teamMembers:List<TeamMemberEntity>
}

data class TeamMemberEntity(
    val id:String,
    val firstName:String,
    val lastName:String,
    val lastRefresh:Date
)

To convert these, I set up the kotlin-reflect JAR in the project and was attempting use Extension methods to convert these from one object type to the other:

fun Team.toTeamEntity() = with(::TeamEntity) {
    val propertiesByName = Team::class.memberProperties.associateBy { it.name }
    val teamEntity = this@toTeamEntity
    callBy(parameters.associate { parameter ->
        parameter to when (parameter.name) {
            TeamEntity::lastRefresh.name -> Date()
            TeamEntity::teamMembers.name -> {
                val teamMembers: List<TeamMember> = propertiesByName[paramName]?.get(this@toTeamEntity) as List<TeamMember>
                teamMembers.map { it.toTeamMemberEntity() }
            }
            else -> propertiesByName[parameter.name]?.get(this@toTeamEntity)
        }
    })
}

fun TeamMember.toTeamMemberEntity() = with(::TeamMemberEntity) {
    val propertiesByName = TeamMember::class.memberProperties.associateBy { it.name }
    callBy(parameters.associate { parameter ->
        parameter to when (parameter.name) {
            TeamMemberEntity::lastRefresh.name -> Date()
            TeamMemberEntity::user.name -> (propertiesByName[parameter.name]?.get(this@toTeamMemberEntity) as User).toUserEntity()
            else -> propertiesByName[parameter.name]?.get(this@toTeamMemberEntity)
        }
    })
}

However, when this functionality runs, the parameters object used in callBy only contains the items in the data class's generated constructor, it seems.

What am I doing wrong here to get all member properties of the *Entity classes so I can fully convert these objects without having to write this out manually?





Aucun commentaire:

Enregistrer un commentaire