diff --git a/KotlinOutputFiles/AbstractDateJsonAdapter.kt b/KotlinOutputFiles/AbstractDateJsonAdapter.kt new file mode 100644 index 0000000..4b00431 --- /dev/null +++ b/KotlinOutputFiles/AbstractDateJsonAdapter.kt @@ -0,0 +1,44 @@ +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonEncodingException +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import org.joda.time.format.DateTimeFormat +import org.joda.time.format.DateTimeFormatter +import java.util.Arrays + +abstract class AbstractDateJsonAdapter( + private val formats: Array +) : JsonAdapter() { + + companion object { + private const val CANT_FIND_ANY_FORMATTERS = "Can't find any DateTimeFormatter" + } + + private val formatters = formats.map(DateTimeFormat::forPattern) + + override fun fromJson(reader: JsonReader): T? { + val dateTimeString = reader.nextString() + formatters.forEachIndexed { index, dateTimeFormatter -> + try { + return fromJsonInner(dateTimeString, dateTimeFormatter) + } catch (e: IllegalArgumentException) { + if (index == formatters.lastIndex) { + throw JsonEncodingException("$dateTimeString doesn't fit any of the formats ${Arrays.toString(formats)}") + } + } + } + throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS) + } + + override fun toJson(writer: JsonWriter, value: T?) { + if (formatters.isEmpty()) throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS) + value?.let { + writer.value(toJsonInner(value, formatters.first())) + } ?: throw JsonEncodingException("Value can't be null") + } + + abstract fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): T + + abstract fun toJsonInner(value: T?, dateTimeFormatter: DateTimeFormatter) : String? + +} diff --git a/KotlinOutputFiles/DateFactory.kt b/KotlinOutputFiles/DateFactory.kt new file mode 100644 index 0000000..165eca2 --- /dev/null +++ b/KotlinOutputFiles/DateFactory.kt @@ -0,0 +1,23 @@ +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import org.joda.time.DateTime +import org.joda.time.LocalDate +import java.lang.reflect.Type + +class DateFactory : JsonAdapter.Factory { + + override fun create(type: Type, annotations: MutableSet, moshi: Moshi): JsonAdapter<*>? { + return when (type.typeName) { + DateTime::class.java.typeName -> DateTimeJsonAdapter(getPatterns(annotations)) + LocalDate::class.java.typeName -> LocalDateJsonAdapter(getPatterns(annotations)) + else -> null + } + } + + private fun getPatterns(annotations: MutableSet) = annotations + .map { it as? Format } + .firstOrNull() + ?.patterns + ?: throw IllegalArgumentException("You should use Format annotation for DateTime and LocalDate fields") + +} diff --git a/KotlinOutputFiles/DateTimeJsonAdapter.kt b/KotlinOutputFiles/DateTimeJsonAdapter.kt new file mode 100644 index 0000000..b383822 --- /dev/null +++ b/KotlinOutputFiles/DateTimeJsonAdapter.kt @@ -0,0 +1,16 @@ +import org.joda.time.DateTime +import org.joda.time.format.DateTimeFormatter + +class DateTimeJsonAdapter( + formats: Array +) : AbstractDateJsonAdapter(formats) { + + override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): DateTime { + return DateTime.parse(value, dateTimeFormatter) + } + + override fun toJsonInner(value: DateTime?, dateTimeFormatter: DateTimeFormatter): String? { + return value?.toString(dateTimeFormatter) + } + +} diff --git a/KotlinOutputFiles/Format.kt b/KotlinOutputFiles/Format.kt new file mode 100644 index 0000000..07e39ce --- /dev/null +++ b/KotlinOutputFiles/Format.kt @@ -0,0 +1,5 @@ +import com.squareup.moshi.JsonQualifier + +@JsonQualifier +@Target(AnnotationTarget.FIELD) +annotation class Format(val patterns: Array) diff --git a/KotlinOutputFiles/LocalDateJsonAdapter.kt b/KotlinOutputFiles/LocalDateJsonAdapter.kt new file mode 100644 index 0000000..2aec04a --- /dev/null +++ b/KotlinOutputFiles/LocalDateJsonAdapter.kt @@ -0,0 +1,16 @@ +import org.joda.time.LocalDate +import org.joda.time.format.DateTimeFormatter + +class LocalDateJsonAdapter( + formats: Array +) : AbstractDateJsonAdapter(formats) { + + override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): LocalDate { + return LocalDate.parse(value, dateTimeFormatter) + } + + override fun toJsonInner(value: LocalDate?, dateTimeFormatter: DateTimeFormatter): String? { + return value?.toString(dateTimeFormatter) + } + +}