Home > Net >  Referencing a type or class through an enum value?
Referencing a type or class through an enum value?

Time:11-07

I'm new to Kotlin, thank you for your patience!

I'm working on the code below, to try and figure out if it's possible to associate the enum value defined, with the intended class and type for reference elsewhere, and to use that defined relationship to eliminate the "when" clause from 5 to 1.

The issue I run into is the line referencing types with angle brackets, is there a way or a way around it, using the enum value I've defined?

GenericCsvParser<SnowflakeReserveItem>()

Where I want to get to is

fun persistSnowflakeData(
        inputStream: InputStream,
        dataType: SnowflakeDataType,
    ){ 
        val sfItems = GenericCsvParser<dataType.value>()
        .parse(inputStream, datatype.value)
        .toList()

        snowflakeItemRepository.saveAll(sfItems)
     }

The code right now:

fun persistSnowflakeData(
        inputStream: InputStream,
        dataType: SnowflakeDataType,
    ) {
        when (dataType) {
            SNOWFLAKE_RESERVE_BOOKING -> {
                val sfItems = GenericCsvParser<SnowflakeReserveItem>()
                    .parse(inputStream, SnowflakeReserveItem::class.java)
                    .toList()
                snowflakeItemRepository.saveAll(sfItems)
            }
            SNOWFLAKE_MEMBERSHIP_TERM -> {
                val sfItems = GenericCsvParser<SnowflakeMembershipTerm>()
                    .parse(inputStream, SnowflakeMembershipTerm::class.java)
                    .toList()
                snowflakeMembershipTermRepository.saveAll(sfItems)
            }
            SNOWFLAKE_MEMBERSHIP_BOOKING -> {
                val sfItems = GenericCsvParser<SnowflakeMembershipOrderBooking>()
                    .parse(inputStream, SnowflakeMembershipOrderBooking::class.java)
                    .toList()
                snowflakeMembershipItemRepository.saveAll(sfItems)
            }
            SNOWFLAKE_OFFLINE_SALE_BOOKING -> {
                val sfItems = GenericCsvParser<SnowflakeOfflineItem>()
                    .parse(inputStream, SnowflakeOfflineItem::class.java)
                    .toList()
                snowflakeOfflineItemRepository.saveAll(sfItems)
            }

            SNOWFLAKE_ONLINE_SALE_BOOKING -> {
                val sfItems = GenericCsvParser<SnowflakeOnlineItem>()
                    .parse(inputStream, SnowflakeOnlineItem::class.java)
                    .toList()
                snowflakeOnlineItemRepository.saveAll(sfItems)
            }
        }
    }
    enum class SnowflakeDataType(clazz: Class<*>) {
        SNOWFLAKE_RESERVE_BOOKING(SnowflakeReserveItem::class.java),
        SNOWFLAKE_MEMBERSHIP_TERM(SnowflakeMembershipTerm::class.java),
        SNOWFLAKE_MEMBERSHIP_BOOKING(SnowflakeMembershipOrderBooking::class.java),
        SNOWFLAKE_OFFLINE_SALE_BOOKING(SnowflakeOfflineItem::class.java),
        SNOWFLAKE_ONLINE_SALE_BOOKING(SnowflakeOnlineItem::class.java)
    }

CodePudding user response:

I would suggest using Reified type parameters

interface ItemRepository<T> {
    fun saveAll(item: T)
}

//...

inline fun <reified T> persistSnowflakeData(
    inputStream: InputStream,
    repository: ItemRepository<T>,
) { 
    val items = GenericCsvParser<T>()
        .parse(inputStream, T::class.java)
        .toList()

    repository.saveAll(items)
}

snowflakeItemRepository, snowflakeMembershipTermRepository and others item repositories should implement ItemRepository.

Then you can call the function as follows:

//...
persistSnowflakeData(inputStream, snowflakeItemRepository)
//...
persistSnowflakeData(inputStream, snowflakeMembershipTermRepository)
//...
  • Related