Commit 05020569 authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

added utils

parent 861721e4
......@@ -141,4 +141,19 @@ data class PlanTypeRaw(
data class MultiTourRaw(
val multiTourId:Int
)
data class ErrorRaw(
val code:Int,
val message:String
)
data class AppVersionRaw(
val current_version : String,
val download_url : String?,
val message : String?,
val critical : Boolean,
val errors : List<ErrorRaw>?
)
\ No newline at end of file
package com.biganto.visual.roompark.data.repository.api.retrofit.util
import com.biganto.visual.roompark.data.repository.api.retrofit.raw.ErrorRaw
import com.biganto.visual.roompark.domain.custom_exception.parseException
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import java.lang.reflect.Type
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
class ErrorsListDeserializer: JsonDeserializer<List<ErrorRaw>> {
override fun deserialize(json: JsonElement, typeOfT: Type, ctx: JsonDeserializationContext): List<ErrorRaw> {
val vals = ArrayList<ErrorRaw>()
when {
json.isJsonArray -> for (e in json.asJsonArray) {
vals.add(ctx.deserialize<Any>(e, ErrorRaw::class.java) as ErrorRaw)
}
json.isJsonObject -> vals.add(ctx.deserialize<Any>(json, ErrorRaw::class.java) as ErrorRaw)
else -> throw RuntimeException("Unexpected JSON type: " + json.javaClass)
}
if (vals.isEmpty())
return vals
throw parseException(vals.first()) //-> for now throws only first!
}
}
\ No newline at end of file
package com.biganto.visual.roompark.data.repository.api.retrofit.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* Created by Vladislav Bogdashkin on 15.10.2018.
*/
public final class NullOnEmptyConverterFactory extends Converter.Factory {
private NullOnEmptyConverterFactory() {
}
public static Converter.Factory create() {
return new NullOnEmptyConverterFactory();
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
final Converter<ResponseBody, ?> delegate = retrofit.nextResponseBodyConverter(this, type, annotations);
return (Converter<ResponseBody, Object>) body -> {
if (body.contentLength() == 0) {
return null;
}
if (body.contentLength() == 2/*equals OK*/)
// if (body.string().equals("OK")) -> can't read value because we can read stream only once
return null;
return delegate.convert(body);
};
}
}
\ No newline at end of file
package com.biganto.visual.roompark.data.repository.api.retrofit.util
import android.annotation.SuppressLint
import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
import java.text.SimpleDateFormat
import java.util.*
/**
* Created by Vladislav Bogdashkin on 09.06.2018.
*/
class DateSerializer : JsonSerializer<Date> {
@SuppressLint("SimpleDateFormat")
override fun serialize(srcDate: Date?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement? {
if (srcDate == null)
return null
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+hh:mm")
val formatted = dateFormat.format(srcDate)
return JsonPrimitive(formatted)
}
}
package com.biganto.visual.roompark.data.repository.api.retrofit.util
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import java.lang.reflect.Type
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
*/
class SingleElementToListDeserializer<T>(private val clazz: Class<T>) : JsonDeserializer<List<T>> {
@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): List<T> {
val resultList = arrayListOf<T>()
if (json.isJsonArray) {
for (e in json.asJsonArray) {
resultList.add(context.deserialize<T>(e, clazz))
}
} else if (json.isJsonObject) {
resultList.add(context.deserialize<T>(json, clazz))
} else {
throw RuntimeException("Unexpected JSON type: " + json.javaClass)
}
return resultList
}
}
\ No newline at end of file
package com.biganto.visual.roompark.data.repository.api.retrofit.util
import com.biganto.visual.roompark.data.service.version_control.IAppVersionControl
import okhttp3.Interceptor
import okhttp3.Response
/**
* Created by Vladislav Bogdashkin on 26.04.2019.
*/
class VersionValidationInterceptor(private val versionControl: IAppVersionControl)
: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
// if (!versionControl.appVersionValid)
// if (!chain.request().url().encodedPath().contains(GET_APP_VERSION))
// versionControl.validateVersion()
return chain.proceed(chain.request())
}
}
\ No newline at end of file
package com.biganto.visual.roompark.data.service.version_control
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import com.biganto.visual.roompark.BuildConfig
import com.biganto.visual.roompark.data.repository.api.retrofit.raw.AppVersionRaw
import com.jakewharton.rxrelay2.BehaviorRelay
import dagger.Module
import dagger.Provides
import io.reactivex.Observable
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
/**
* Created by Vladislav Bogdashkin on 12.10.2018.
*/
@Module
class AppVersionModule @Inject constructor(val context: Context){
private val manager = AppVersionManager(context)
@Provides
@Singleton
fun provideVersionListener(): IAppVersionControl {
return manager
}
@Provides
@Singleton
fun provideAppVersionNotifier(): IAppVersionNotifier {
return manager
}
}
@Singleton
class AppVersionManager @Inject constructor(val context: Context)
: IAppVersionControl, IAppVersionNotifier {
override fun processAppVersionResponse(): Observable<UpdateAppModel> {
return notifier
}
// val api : IApi by lazy {
// RoomParkApplication.component.api()
// }
// lateinit var notifier : IAppVersionNotifier
private val notifier = BehaviorRelay.create<UpdateAppModel>()
private var appVersionStatus = AppVersionStatus.UNCHECKED
override val appVersionValid: Boolean
get() = appVersionStatus == AppVersionStatus.VALID
private var buildVersion: String = BuildConfig.VERSION_NAME
override fun validateVersion() {
// api.getAppVersion().subscribe(::mergeVersion, Timber::e).dispose()
}
private fun mergeVersion(apiAppVersion: AppVersionRaw){
Timber.d("Got new version info (current: $buildVersion, incoming: $apiAppVersion")
appVersionStatus = AppVersionStatus.VALID
// region Code in spoiler not used in current version
// if (apiAppVersion.current_version!=buildVersion)
// appVersionStatus = AppVersionStatus.OUTDATED
// if (apiAppVersion.critical && appVersionStatus == AppVersionStatus.OUTDATED)
// appVersionStatus = AppVersionStatus.CRITICAL
//endregion
if (apiAppVersion.critical && appVersionStatus == AppVersionStatus.OUTDATED)
appVersionStatus = AppVersionStatus.CRITICAL
if (appVersionStatus == AppVersionStatus.CRITICAL)
sendIntentToUpdate(apiAppVersion)
}
private fun sendIntentToUpdate(apiAppVersion: AppVersionRaw){
val updInfo = UpdateAppModel(
currentVersion = buildVersion,
newVersion = apiAppVersion.current_version,
isCritical = apiAppVersion.critical,
downloadUrl = apiAppVersion.download_url,
message = apiAppVersion.message
)
notifier.accept(updInfo)
}
}
interface IAppVersionControl{
val appVersionValid: Boolean
fun validateVersion()
}
interface IAppVersionNotifier{
fun processAppVersionResponse():Observable<UpdateAppModel>
}
enum class AppVersionStatus{
OUTDATED,
CRITICAL,
VALID,
UNCHECKED
}
data class UpdateAppModel(
val currentVersion : String,
val newVersion : String,
val isCritical : Boolean,
val message : String?,
val downloadUrl : String?
) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.readByte() != 0.toByte(),
parcel.readString(),
parcel.readString()) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(currentVersion)
parcel.writeString(newVersion)
parcel.writeByte(if (isCritical) 1 else 0)
parcel.writeString(message)
parcel.writeString(downloadUrl)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<UpdateAppModel> {
override fun createFromParcel(parcel: Parcel): UpdateAppModel {
return UpdateAppModel(parcel)
}
override fun newArray(size: Int): Array<UpdateAppModel?> {
return arrayOfNulls(size)
}
}
}
class AppVersionNotCheckedException(message:String): Exception(message)
\ No newline at end of file
......@@ -2,6 +2,7 @@ package com.biganto.visual.roompark.domain.custom_exception
import androidx.annotation.StringRes
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.data.repository.api.retrofit.raw.ErrorRaw
/**
* Created by Vladislav Bogdashkin on 09.04.2019.
......@@ -133,7 +134,18 @@ sealed class CustomApiException(val code:Int,@StringRes val messageStringId: In
}
fun parseException(err: ErrorRaw):CustomApiException{
return when(err.code){
CUSTOM_API_ERROR_RESPONSE_CODE_100 -> CustomApiException.NotAuthorizedException()
CUSTOM_API_ERROR_RESPONSE_CODE_101 -> CustomApiException.TokenSyntaxException()
CUSTOM_API_ERROR_RESPONSE_CODE_102 -> CustomApiException.UserWithTokenNotFoundException()
CUSTOM_API_ERROR_RESPONSE_CODE_103 -> CustomApiException.TokenEstimatedException()
CUSTOM_API_ERROR_RESPONSE_CODE_104 -> CustomApiException.UserBannedException()
CUSTOM_API_ERROR_RESPONSE_CODE_111 -> CustomApiException.WrongLoginException()
CUSTOM_API_ERROR_RESPONSE_CODE_112 -> CustomApiException.WrongPasswordException()
else -> CustomApiException.UnknownCustomApiException(err.code, CUSTOM_API_ERROR_DEFAULT_MESSAGE_ID)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment