From d41efb250563a8ab08cd6518e9dd0b6ee5e313fe Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 09:02:08 +0300 Subject: [PATCH 01/54] onStop removeCallbacks added --- lib/src/main/java/com/omega_r/base/tools/DialogManager.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt b/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt index 9223002..49e7c03 100644 --- a/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt +++ b/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt @@ -84,6 +84,7 @@ class DialogManager(private val context: Context, private val showWaitingDelay: } fun onStop() { + handler.removeCallbacks(waitingRunnable) dialogList.forEach { it.dismiss() } From 03f79d6ddaa6f7a0604562cce21ed9fd79bcdb27 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 09:14:47 +0300 Subject: [PATCH 02/54] BasePresenter setWaiting method added --- .../base/mvp/presenters/OmegaPresenter.kt | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index b664947..3736226 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -56,9 +56,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return try { block() } finally { - withContext(Dispatchers.Main) { - viewState.setWaiting(false, waitingText) - } + setWaiting(false, waitingText) } } @@ -72,9 +70,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco try { block() } finally { - withContext(Dispatchers.Main) { - viewState.setWaiting(false, waitingText) - } + setWaiting(false, waitingText) } } } @@ -94,18 +90,13 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco if (hideWaiting) { hideWaiting = false - viewState.setWaiting(false) + setWaiting(false) } } } catch (e: Throwable) { - val handle = errorHandler?.invoke(e) - if (handle != true) { - handleErrors(e) - } + if (errorHandler?.invoke(e) != true) handleErrors(e) } finally { - if (hideWaiting) { - viewState.setWaiting(false) - } + if (hideWaiting) setWaiting(false) } } } @@ -124,6 +115,10 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco ) } + private suspend fun setWaiting(waiting: Boolean, text: Text? = null){ + withContext(Dispatchers.Main) { viewState.setWaiting(waiting, text) } + } + protected fun OmegaRepository.request( strategy: OmegaRepository.Strategy = OmegaRepository.Strategy.CACHE_AND_REMOTE, waiting: Boolean = true, From d2c01fc34cc9c0010d9d1a5b00d61043f70d7650 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 09:24:46 +0300 Subject: [PATCH 03/54] logs added --- lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 7752f20..7031d3b 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -23,12 +23,14 @@ import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.views.findAnnotation import com.omega_r.base.tools.DialogManager import com.omega_r.libs.extensions.context.getColorByAttribute +import com.omega_r.libs.extensions.log.log import com.omega_r.libs.omegatypes.Text import com.omegar.libs.omegalaunchers.ActivityLauncher import com.omegar.libs.omegalaunchers.BaseIntentLauncher import com.omegar.libs.omegalaunchers.DialogFragmentLauncher import com.omegar.libs.omegalaunchers.FragmentLauncher import com.omegar.mvp.MvpAppCompatActivity +import kotlin.math.log /** * Created by Anton Knyazev on 04.04.2019. @@ -159,6 +161,7 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { } override fun setWaiting(waiting: Boolean, text: Text?) { + log("setWaiting $waiting") dialogManager.setWaiting(waiting, text) } From c4cad5472ad5ba60cca2835fcb411e8ac5444eb0 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 10:00:02 +0300 Subject: [PATCH 04/54] OmegaActivity onStop method updated --- .../com/omega_r/base/components/OmegaActivity.kt | 2 +- .../omega_r/base/mvp/presenters/OmegaPresenter.kt | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 7031d3b..3b74b23 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -284,8 +284,8 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { } override fun onStop() { - super.onStop() dialogManager.onStop() + super.onStop() } override fun exit() { diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 3736226..9b9f108 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -56,7 +56,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return try { block() } finally { - setWaiting(false, waitingText) + viewState.setWaiting(false, waitingText) } } @@ -70,7 +70,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco try { block() } finally { - setWaiting(false, waitingText) + viewState.setWaiting(false, waitingText) } } } @@ -90,13 +90,13 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco if (hideWaiting) { hideWaiting = false - setWaiting(false) + viewState.setWaiting(false) } } } catch (e: Throwable) { if (errorHandler?.invoke(e) != true) handleErrors(e) } finally { - if (hideWaiting) setWaiting(false) + if (hideWaiting) viewState.setWaiting(false) } } } @@ -115,10 +115,6 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco ) } - private suspend fun setWaiting(waiting: Boolean, text: Text? = null){ - withContext(Dispatchers.Main) { viewState.setWaiting(waiting, text) } - } - protected fun OmegaRepository.request( strategy: OmegaRepository.Strategy = OmegaRepository.Strategy.CACHE_AND_REMOTE, waiting: Boolean = true, From b63659fc39c2b098359b63003e0155057621e75d Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 11:19:24 +0300 Subject: [PATCH 05/54] block and setWaiting swiped --- .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 9b9f108..d796b6f 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -86,12 +86,11 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco var hideWaiting = waiting try { for (item in channel) { - block?.invoke(viewState, item) - if (hideWaiting) { hideWaiting = false viewState.setWaiting(false) } + block?.invoke(viewState, item) } } catch (e: Throwable) { if (errorHandler?.invoke(e) != true) handleErrors(e) From 4bd5aac39577bff84f6484570cfbad67613fd1c1 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 11:29:07 +0300 Subject: [PATCH 06/54] DialogManager LockScreenDialog dismiss added --- .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 3 ++- lib/src/main/java/com/omega_r/base/tools/DialogManager.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index d796b6f..9b9f108 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -86,11 +86,12 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco var hideWaiting = waiting try { for (item in channel) { + block?.invoke(viewState, item) + if (hideWaiting) { hideWaiting = false viewState.setWaiting(false) } - block?.invoke(viewState, item) } } catch (e: Throwable) { if (errorHandler?.invoke(e) != true) handleErrors(e) diff --git a/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt b/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt index 49e7c03..c46b238 100644 --- a/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt +++ b/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt @@ -21,7 +21,7 @@ class DialogManager(private val context: Context, private val showWaitingDelay: private var waitingText: Text? = null private val waitingRunnable = Runnable { - lockingDialog?.hide() + lockingDialog?.dismiss() lockingDialog = null if (waitingDialog == null) { From ee0c043db321710b23292c0c3cbc1f162d001f50 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 8 Nov 2019 12:16:00 +0300 Subject: [PATCH 07/54] Logs removed --- .../main/java/com/omega_r/base/components/OmegaActivity.kt | 5 +---- .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 3b74b23..7752f20 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -23,14 +23,12 @@ import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.views.findAnnotation import com.omega_r.base.tools.DialogManager import com.omega_r.libs.extensions.context.getColorByAttribute -import com.omega_r.libs.extensions.log.log import com.omega_r.libs.omegatypes.Text import com.omegar.libs.omegalaunchers.ActivityLauncher import com.omegar.libs.omegalaunchers.BaseIntentLauncher import com.omegar.libs.omegalaunchers.DialogFragmentLauncher import com.omegar.libs.omegalaunchers.FragmentLauncher import com.omegar.mvp.MvpAppCompatActivity -import kotlin.math.log /** * Created by Anton Knyazev on 04.04.2019. @@ -161,7 +159,6 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { } override fun setWaiting(waiting: Boolean, text: Text?) { - log("setWaiting $waiting") dialogManager.setWaiting(waiting, text) } @@ -284,8 +281,8 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { } override fun onStop() { - dialogManager.onStop() super.onStop() + dialogManager.onStop() } override fun exit() { diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 9b9f108..d786642 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -94,7 +94,8 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } } } catch (e: Throwable) { - if (errorHandler?.invoke(e) != true) handleErrors(e) + val handle = errorHandler?.invoke(e) + if (handle != true) handleErrors(e) } finally { if (hideWaiting) viewState.setWaiting(false) } From bcec350dca9ccfe9af1ce315e266f2715b5eec6a Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Tue, 19 Nov 2019 14:56:04 +0300 Subject: [PATCH 08/54] Fixed review --- .../base/mvp/presenters/OmegaPresenter.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index d786642..b664947 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -56,7 +56,9 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return try { block() } finally { - viewState.setWaiting(false, waitingText) + withContext(Dispatchers.Main) { + viewState.setWaiting(false, waitingText) + } } } @@ -70,7 +72,9 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco try { block() } finally { - viewState.setWaiting(false, waitingText) + withContext(Dispatchers.Main) { + viewState.setWaiting(false, waitingText) + } } } } @@ -95,9 +99,13 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } } catch (e: Throwable) { val handle = errorHandler?.invoke(e) - if (handle != true) handleErrors(e) + if (handle != true) { + handleErrors(e) + } } finally { - if (hideWaiting) viewState.setWaiting(false) + if (hideWaiting) { + viewState.setWaiting(false) + } } } } From 2ab7207085daa9126d0909b0e60e82cea7e049d0 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 20 Nov 2019 10:55:28 +0300 Subject: [PATCH 09/54] Add implementation getPermissionState --- .../com/omega_r/base/simple/MainPresenter.kt | 5 ++- lib/build.gradle | 4 +-- .../omega_r/base/components/OmegaComponent.kt | 36 +++++++++++++++---- .../base/mvp/presenters/OmegaPresenter.kt | 11 +++--- .../com/omega_r/base/mvp/views/OmegaView.kt | 4 +++ .../remote/CoroutineCallAdapterFactory.kt | 5 +-- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt index 234ed14..d44f864 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt @@ -1,5 +1,6 @@ package com.omega_r.base.simple +import android.Manifest import com.omega_r.base.enitity.contains import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.presenters.OmegaPresenter @@ -25,7 +26,9 @@ class MainPresenter : OmegaPresenter() { viewState.setWaiting(false) } - + launch { + viewState.showToast(Text.from(getPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE).toString())) + } // viewState.showMessage(Text.from("test"), Action(Text.from("Test")) { diff --git a/lib/build.gradle b/lib/build.gradle index bbca5e0..33f6109 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -62,10 +62,10 @@ dependencies { api 'com.github.Omega-R:OmegaLaunchers:1.0.2' api 'com.github.Omega-R:OmegaExtensions:1.0.3' - api "com.squareup.retrofit2:retrofit:2.6.1" + api "com.squareup.retrofit2:retrofit:2.6.2" api "com.squareup.moshi:moshi-kotlin:1.8.0" - implementation 'com.google.android.material:material:1.1.0-beta01' + implementation 'com.google.android.material:material:1.2.0-alpha01' } repositories { diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt b/lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt index c85d268..08b00be 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt @@ -3,8 +3,10 @@ package com.omega_r.base.components import android.app.Activity import android.app.Dialog import android.content.Intent +import android.content.pm.PackageManager import android.view.View import android.widget.Toast +import androidx.core.content.ContextCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.omega_r.base.binders.OmegaBindable @@ -17,6 +19,7 @@ import com.omega_r.base.mvp.model.setButtons import com.omega_r.base.mvp.model.setPositiveButton import com.omega_r.libs.omegatypes.Text import com.omegar.libs.omegalaunchers.Launcher +import kotlinx.coroutines.CompletableDeferred import java.io.Serializable /** @@ -29,7 +32,7 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { val presenter: OmegaPresenter - fun createMessage(message: Text, action: Action? = null): Dialog { + fun createMessage(message: Text, action: Action? = null): Dialog { return MaterialAlertDialogBuilder(getContext()!!) .setCancelable(true) .setMessage(message.getCharSequence(getContext()!!)).apply { @@ -47,7 +50,13 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { .create() } - fun createQuery(message: Text, title: Text?, positiveAction: Action, negativeAction: Action, neutralAction: Action?): Dialog { + fun createQuery( + message: Text, + title: Text?, + positiveAction: Action, + negativeAction: Action, + neutralAction: Action? + ): Dialog { return MaterialAlertDialogBuilder(getContext()!!) .setTitle(title?.getCharSequence(getContext()!!)) .setMessage(message.getCharSequence(getContext()!!)) @@ -59,13 +68,18 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { fun getViewForSnackbar(): View override fun showBottomMessage(message: Text, action: Action?) { - Snackbar.make(getViewForSnackbar(), message.getCharSequence(getContext()!!)!!, Snackbar.LENGTH_LONG) + Snackbar.make( + getViewForSnackbar(), + message.getCharSequence(getContext()!!)!!, + Snackbar.LENGTH_LONG + ) .setAction(action) .show() } override fun showToast(message: Text) { - Toast.makeText(getContext(), message.getCharSequence(getContext()!!), Toast.LENGTH_LONG).show() + Toast.makeText(getContext(), message.getCharSequence(getContext()!!), Toast.LENGTH_LONG) + .show() } override fun launch(launcher: Launcher) { @@ -73,13 +87,14 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { } fun onLaunchResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { - return presenter.onLaunchResult(requestCode, resultCode == Activity.RESULT_OK, + return presenter.onLaunchResult( + requestCode, resultCode == Activity.RESULT_OK, data?.getSerializableExtra(KEY_RESULT) ) } override fun setResult(success: Boolean, data: Serializable?) { - val resultCode = if (success) Activity.RESULT_OK else Activity.RESULT_CANCELED + val resultCode = if (success) Activity.RESULT_OK else Activity.RESULT_CANCELED if (data != null) { setResult(resultCode, Intent().putExtra(KEY_RESULT, data)) } else { @@ -91,4 +106,13 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { fun setResult(resultCode: Int, intent: Intent) + override fun requestGetPermission(permission: String, deferred: CompletableDeferred) { + deferred.complete( + ContextCompat.checkSelfPermission( + getContext()!!, + permission + ) == PackageManager.PERMISSION_GRANTED + ) + } + } \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index b664947..2254bba 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -33,7 +33,6 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco private val permissionsCallbacks: MutableMap, ((Boolean) -> Unit)?> by lazy { mutableMapOf, ((Boolean) -> Unit)?>() } - protected val intentBuilder get() = OmegaIntentBuilder @@ -183,11 +182,13 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } @Suppress("UNUSED_PARAMETER") - protected fun getPermissionState(permissionName: String): Boolean { - return false + protected suspend fun getPermissionState(permissionName: String): Boolean { + val deferred = CompletableDeferred() + viewState.requestGetPermission(permissionName, deferred) + return deferred.await() } - fun requestPermission(vararg permissions: String, resultCallback: (Boolean) -> Unit) { + protected fun requestPermission(vararg permissions: String, resultCallback: (Boolean) -> Unit) { val permissionList = permissions.toList() permissionsCallbacks[permissionList] = resultCallback @@ -198,7 +199,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco ) } - fun onPermissionResult( + protected fun onPermissionResult( requestCode: Int, permissions: Array, grantResults: IntArray diff --git a/lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt b/lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt index 6096f6b..0757a8e 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt @@ -11,6 +11,7 @@ import com.omegar.mvp.viewstate.strategy.AddToEndSingleStrategy import com.omegar.mvp.viewstate.strategy.AddToEndStrategy import com.omegar.mvp.viewstate.strategy.OneExecutionStateStrategy import com.omegar.mvp.viewstate.strategy.StateStrategyType +import kotlinx.coroutines.CompletableDeferred import java.io.Serializable import kotlin.reflect.KAnnotatedElement @@ -56,6 +57,9 @@ interface OmegaView : MvpView { @StateStrategyType(OneExecutionStateStrategy::class) fun requestPermissions(requestCode: Int, vararg permissions: String) + @StateStrategyType(OneExecutionStateStrategy::class) + fun requestGetPermission(permission: String, deferred: CompletableDeferred) + @StateStrategyType(OneExecutionStateStrategy::class) fun exit() diff --git a/lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt b/lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt index 0babe89..f99aec5 100644 --- a/lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt +++ b/lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt @@ -48,10 +48,7 @@ class CoroutineCallAdapterFactory (private val parent: Job? = null, val rawDeferredType = getRawType(responseType) return if (rawDeferredType == Response::class.java) { - if (responseType !is ParameterizedType) { - throw IllegalStateException( - "Response must be parameterized as Response or Response") - } + check(responseType is ParameterizedType) { "Response must be parameterized as Response or Response" } ResponseCallAdapter(getParameterUpperBound(0, responseType), parent, errorConverter) } else { BodyCallAdapter(responseType, parent, errorConverter) From 5109f0d775694fa73b6a1c70fc69f09c913a3abd Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Thu, 21 Nov 2019 12:47:36 +0300 Subject: [PATCH 10/54] OmegaRepository: open, processResult --- .idea/modules.xml | 3 ++ .../com/omega_r/base/data/OmegaRepository.kt | 50 ++++++++++--------- .../omega_r/base/data/sources/CacheSource.kt | 12 +++-- .../base/mvp/presenters/OmegaPresenter.kt | 2 +- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/.idea/modules.xml b/.idea/modules.xml index 2588e5f..4ebd0e5 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,9 @@ + + + diff --git a/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt index 121313d..fb31619 100644 --- a/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -15,21 +15,25 @@ import kotlinx.coroutines.channels.produce */ @Suppress("UNCHECKED_CAST") @UseExperimental(ExperimentalCoroutinesApi::class) -class OmegaRepository(vararg sources: SOURCE) { +open class OmegaRepository(vararg sources: SOURCE) { private val job = SupervisorJob() - private val coroutineScope = CoroutineScope(Dispatchers.Default + job) + protected val coroutineScope = CoroutineScope(Dispatchers.Default + job) - private val remoteSource = sources.firstOrNull { it.type == Source.Type.REMOTE } + protected val remoteSource = sources.firstOrNull { it.type == Source.Type.REMOTE } - private val memoryCacheSource = + protected val memoryCacheSource = sources.firstOrNull { it.type == Source.Type.MEMORY_CACHE } as? CacheSource - private val fileCacheSource = + protected val fileCacheSource = sources.firstOrNull { it.type == Source.Type.FILE_CACHE } as? CacheSource - private val defaultSource = sources.firstOrNull { it.type == Source.Type.DEFAULT } + protected val defaultSource = sources.firstOrNull { it.type == Source.Type.DEFAULT } + + protected open suspend fun processResult(result: R, sourceType: Source.Type): R { + return result + } fun createChannel( strategy: Strategy = CACHE_AND_REMOTE, @@ -61,7 +65,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (remoteSource != null) { remoteException = ignoreException { - val result = block(remoteSource) + val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) fileCacheSource?.update(result) @@ -71,7 +75,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (defaultSource != null) { ignoreException { - return send(block(defaultSource)) + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } @@ -85,14 +89,14 @@ class OmegaRepository(vararg sources: SOURCE) { private suspend fun ProducerScope.applyOnlyCache(block: suspend SOURCE.() -> R) { if (memoryCacheSource != null) { ignoreException { - send(block(memoryCacheSource as SOURCE)) + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { ignoreException { - val result = block(fileCacheSource as SOURCE) + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) return @@ -101,7 +105,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (defaultSource != null) { ignoreException { - return send(block(defaultSource)) + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } @@ -112,7 +116,7 @@ class OmegaRepository(vararg sources: SOURCE) { var remoteException: Exception? = null if (remoteSource != null) { remoteException = ignoreException { - val result = block(remoteSource) + val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) fileCacheSource?.update(result) @@ -124,14 +128,14 @@ class OmegaRepository(vararg sources: SOURCE) { if (memoryCacheSource != null) { cacheException = ignoreException { - send(block(memoryCacheSource as SOURCE)) + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { cacheException = ignoreException { - val result = block(fileCacheSource as SOURCE) + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) return @@ -140,7 +144,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (defaultSource != null) { cacheException = ignoreException { - return send(block(defaultSource)) + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } if (remoteSource == null) { @@ -156,13 +160,13 @@ class OmegaRepository(vararg sources: SOURCE) { if (memoryCacheSource != null) { cacheException = ignoreException { - send(block(memoryCacheSource as SOURCE)) + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { cacheException = ignoreException { - val result = block(fileCacheSource as SOURCE) + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) return @@ -173,7 +177,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (remoteSource != null) { remoteException = ignoreException { - val result = block(remoteSource) + val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) fileCacheSource?.update(result) @@ -183,7 +187,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (defaultSource != null) { cacheException = ignoreException { - return send(block(defaultSource)) + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } @@ -201,7 +205,7 @@ class OmegaRepository(vararg sources: SOURCE) { var cacheException: Exception? = null if (memoryCacheSource != null) { cacheException = ignoreException { - val result = block(memoryCacheSource as SOURCE) + val result = processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) if (isActive && !isClosedForSend) { send(result) @@ -211,7 +215,7 @@ class OmegaRepository(vararg sources: SOURCE) { } if (fileCacheSource != null) { cacheException = ignoreException { - val result = block(fileCacheSource as SOURCE) + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) if (isActive && !isClosedForSend) { send(result) memoryCacheSource?.update(result) @@ -223,7 +227,7 @@ class OmegaRepository(vararg sources: SOURCE) { if (defaultSource != null) { cacheException = ignoreException { if (isActive && !isClosedForSend) { - send(block(defaultSource)) + send(processResult(block(defaultSource), Source.Type.DEFAULT)) } return@async null } @@ -234,7 +238,7 @@ class OmegaRepository(vararg sources: SOURCE) { val remoteException = if (remoteSource != null) { ignoreException { - val result = block(remoteSource) + val result = processResult(block(remoteSource), Source.Type.REMOTE) cacheReturnDeferred.cancel() send(result) channel.close() diff --git a/lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt b/lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt index f5aefa0..afc33b5 100644 --- a/lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt +++ b/lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt @@ -11,11 +11,13 @@ interface CacheSource : Source { data?.forEach { updateItem(it) } } - fun update(data: Any?) { - if (data is List<*>) { - updateItems(data) - } else { - updateItem(data) + suspend fun update(data: Any?) { + when (data) { + is Unit -> { + // nothing + } + is List<*> -> updateItems(data) + else -> updateItem(data) } } diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 2254bba..6a3b1eb 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -199,7 +199,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco ) } - protected fun onPermissionResult( + fun onPermissionResult( requestCode: Int, permissions: Array, grantResults: IntArray From 835c1234ca52f0dd4058cece049e5c1357a5cb80 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Thu, 21 Nov 2019 16:26:23 +0300 Subject: [PATCH 11/54] Fix OmegaRepository --- .../com/omega_r/base/data/OmegaRepository.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt index fb31619..132456f 100644 --- a/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -21,16 +21,22 @@ open class OmegaRepository(vararg sources: SOURCE) { protected val coroutineScope = CoroutineScope(Dispatchers.Default + job) - protected val remoteSource = sources.firstOrNull { it.type == Source.Type.REMOTE } + protected val remoteSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.REMOTE } - protected val memoryCacheSource = + protected val memorySource: SOURCE? + get() = memoryCacheSource as SOURCE? + + protected val fileSource: SOURCE? + get() = fileCacheSource as SOURCE? + + protected val defaultSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.DEFAULT } + + private val memoryCacheSource = sources.firstOrNull { it.type == Source.Type.MEMORY_CACHE } as? CacheSource - protected val fileCacheSource = + private val fileCacheSource = sources.firstOrNull { it.type == Source.Type.FILE_CACHE } as? CacheSource - protected val defaultSource = sources.firstOrNull { it.type == Source.Type.DEFAULT } - protected open suspend fun processResult(result: R, sourceType: Source.Type): R { return result } @@ -205,7 +211,8 @@ open class OmegaRepository(vararg sources: SOURCE) { var cacheException: Exception? = null if (memoryCacheSource != null) { cacheException = ignoreException { - val result = processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) + val result = + processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) if (isActive && !isClosedForSend) { send(result) @@ -215,7 +222,8 @@ open class OmegaRepository(vararg sources: SOURCE) { } if (fileCacheSource != null) { cacheException = ignoreException { - val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + val result = + processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) if (isActive && !isClosedForSend) { send(result) memoryCacheSource?.update(result) From 0905b010e4cbd07aa01ad781446e55acaa68abdf Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Thu, 21 Nov 2019 18:28:47 +0300 Subject: [PATCH 12/54] Add errorHandler for request with return unit --- .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 6a3b1eb..d5b2410 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -126,10 +126,11 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco protected fun OmegaRepository.request( strategy: OmegaRepository.Strategy = OmegaRepository.Strategy.CACHE_AND_REMOTE, waiting: Boolean = true, + errorHandler: ((Throwable) -> Boolean)? = null, sourceBlock: suspend S.() -> Unit ) { createChannel(strategy, sourceBlock) - .request(waiting = waiting) + .request(waiting = waiting, errorHandler = errorHandler) } fun hideQueryOrMessage() = viewState.hideQueryOrMessage() From 75160b309b6db80e9ef66beef6e6d456081872f4 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Mon, 2 Dec 2019 19:06:26 +0300 Subject: [PATCH 13/54] Add default error strings Add Logs --- .../com/omega_r/base/data/sources/Source.kt | 2 - .../main/java/com/omega_r/base/logs/Log.kt | 16 ++++++ .../java/com/omega_r/base/logs/LogManager.kt | 17 ++++++ .../base/mvp/presenters/OmegaPresenter.kt | 55 ++++++++++++++----- lib/src/main/res/values/strings.xml | 6 ++ 5 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 lib/src/main/java/com/omega_r/base/logs/Log.kt create mode 100644 lib/src/main/java/com/omega_r/base/logs/LogManager.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/Source.kt b/lib/src/main/java/com/omega_r/base/data/sources/Source.kt index 20d5b4b..c37cb9b 100644 --- a/lib/src/main/java/com/omega_r/base/data/sources/Source.kt +++ b/lib/src/main/java/com/omega_r/base/data/sources/Source.kt @@ -1,7 +1,5 @@ package com.omega_r.base.data.sources -import com.omega_r.base.errors.AppException - /** * Created by Anton Knyazev on 2019-05-28. */ diff --git a/lib/src/main/java/com/omega_r/base/logs/Log.kt b/lib/src/main/java/com/omega_r/base/logs/Log.kt new file mode 100644 index 0000000..826e1ee --- /dev/null +++ b/lib/src/main/java/com/omega_r/base/logs/Log.kt @@ -0,0 +1,16 @@ +package com.omega_r.base.logs + +/** + * Created by Anton Knyazev on 2019-12-02. + */ +interface Log { + + fun log(level: Level, message: String, throwable: Throwable? = null) + + enum class Level { + + DEBUG, INFO, WARNING, ERROR + + } + +} \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt new file mode 100644 index 0000000..d15c896 --- /dev/null +++ b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt @@ -0,0 +1,17 @@ +package com.omega_r.base.logs + +import java.util.concurrent.CopyOnWriteArrayList + +/** + * Created by Anton Knyazev on 2019-12-02. + */ +class LogManager { + + val logs: List = CopyOnWriteArrayList() + + fun log(level: Log.Level, message: String, throwable: Throwable?) { + logs.forEach { it.log(level, message, throwable) } + } + + +} \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index d5b2410..0eafebd 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -1,8 +1,11 @@ package com.omega_r.base.mvp.presenters import android.content.pm.PackageManager +import android.content.pm.PackageManager.PERMISSION_GRANTED +import com.omega_r.base.R import com.omega_r.base.data.OmegaRepository import com.omega_r.base.data.sources.Source +import com.omega_r.base.errors.AppException import com.omega_r.base.mvp.views.OmegaView import com.omega_r.libs.omegaintentbuilder.OmegaIntentBuilder import com.omega_r.libs.omegaintentbuilder.interfaces.IntentBuilder @@ -31,7 +34,8 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco override val coroutineContext: CoroutineContext = Dispatchers.Main + job + handler - private val permissionsCallbacks: MutableMap, ((Boolean) -> Unit)?> by lazy { mutableMapOf, ((Boolean) -> Unit)?>() } + private val permissionsCallbacks: MutableMap, ((Boolean) -> Unit)?> + by lazy { mutableMapOf, ((Boolean) -> Unit)?>() } protected val intentBuilder get() = OmegaIntentBuilder @@ -40,6 +44,25 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco throwable.printStackTrace() } + protected open fun getErrorMessage(throwable: Throwable): Text { + return when (throwable) { + is OutOfMemoryError -> Text.from(R.string.error_out_of_memory) + is AppException.NoConnection -> Text.from(R.string.error_no_connection) + is AppException.ServerUnavailable -> Text.from(R.string.error_server_unavailable) + is AppException.NotFound, + is AppException.ServerProblem -> Text.from(R.string.error_server_problem) + is AppException.AccessDenied -> Text.from(R.string.error_access_denied) + + else -> { + getUnknownErrorMessage() + } + } + } + + protected open fun getUnknownErrorMessage(): Text { + return Text.from(R.string.error_unknown) + } + internal open fun attachChildPresenter(childPresenter: OmegaPresenter<*>) { childPresenter.attachParentPresenter(this) } @@ -177,11 +200,6 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco viewState.exit() } - override fun onDestroy() { - super.onDestroy() - job.cancel() - } - @Suppress("UNUSED_PARAMETER") protected suspend fun getPermissionState(permissionName: String): Boolean { val deferred = CompletableDeferred() @@ -193,11 +211,10 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco val permissionList = permissions.toList() permissionsCallbacks[permissionList] = resultCallback - viewState.requestPermissions( - REQUEST_PERMISSION_BASE + permissionsCallbacks.keys.indexOf( - permissionList - ), *permissions - ) + val requestCode = + REQUEST_PERMISSION_BASE + permissionsCallbacks.keys.indexOf(permissionList) + + viewState.requestPermissions(requestCode, *permissions) } fun onPermissionResult( @@ -206,14 +223,18 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco grantResults: IntArray ): Boolean { val permissionList = permissions.toList() - if (requestCode >= REQUEST_PERMISSION_BASE && permissionsCallbacks.contains(permissionList)) { - permissionsCallbacks[permissionList]?.invoke(grantResults.firstOrNull { it != PackageManager.PERMISSION_GRANTED } == null) + if (requestCode >= REQUEST_PERMISSION_BASE && permissionsCallbacks.contains(permissionList)){ + val success = + grantResults.firstOrNull { it != PERMISSION_GRANTED } == null + permissionsCallbacks[permissionList]?.invoke(success) permissionsCallbacks[permissionList] = null return true } else { val permissionResults = - permissions.mapIndexed { index, permission -> permission to (grantResults[index] == PackageManager.PERMISSION_GRANTED) } - .toMap() + permissions.mapIndexed { index, permission -> + val success = grantResults[index] == PERMISSION_GRANTED + permission to success + }.toMap() return onPermissionResult(requestCode, permissionResults) } @@ -226,5 +247,9 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return false } + override fun onDestroy() { + super.onDestroy() + job.cancel() + } } \ No newline at end of file diff --git a/lib/src/main/res/values/strings.xml b/lib/src/main/res/values/strings.xml index a3d4696..9d43c63 100644 --- a/lib/src/main/res/values/strings.xml +++ b/lib/src/main/res/values/strings.xml @@ -1,3 +1,9 @@ Loading\u2026 + Insufficient memory to perform the operation + Please check your internet connection or try again later + The server is temporarily unavailable. Please try again later. + Access denied + Sorry, Some error occurred on the server. Please, try your request again later. + Unknown error occurred, please try again later From 60a46a1c44e6c831b49ee7e11560d4106713f800 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Tue, 3 Dec 2019 17:45:14 +0300 Subject: [PATCH 14/54] Reactoring log --- build.gradle | 2 +- .../com/omega_r/base/logs/AndroidLogger.kt | 21 +++++++++++++++ .../java/com/omega_r/base/logs/LogManager.kt | 26 ++++++++++++++++--- .../omega_r/base/logs/{Log.kt => Logger.kt} | 6 ++--- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt rename lib/src/main/java/com/omega_r/base/logs/{Log.kt => Logger.kt} (58%) diff --git a/build.gradle b/build.gradle index 1cc56bb..e6d30e4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ ext { }// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.31' + ext.kotlin_version = '1.3.61' repositories { google() jcenter() diff --git a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt new file mode 100644 index 0000000..c7e02b5 --- /dev/null +++ b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt @@ -0,0 +1,21 @@ +package com.omega_r.base.logs + +import android.util.Log +import com.omega_r.base.logs.Logger.Level.* + +/** + * Created by Anton Knyazev on 03.12.2019. + */ +class AndroidLogger: Logger { + + override fun log(level: Logger.Level, tag: String, message: String, throwable: Throwable?) { + when (level) { + DEBUG -> Log.d(tag, message, throwable) + INFO -> Log.i(tag, message, throwable) + WARNING -> Log.w(tag, message, throwable) + ERROR -> Log.e(tag, message, throwable) + } + } + + +} \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt index d15c896..c7dc3e2 100644 --- a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt +++ b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt @@ -1,17 +1,35 @@ package com.omega_r.base.logs +import com.omega_r.libs.extensions.log.log import java.util.concurrent.CopyOnWriteArrayList /** * Created by Anton Knyazev on 2019-12-02. */ -class LogManager { +object LogManager { - val logs: List = CopyOnWriteArrayList() + private val loggers: List = CopyOnWriteArrayList() - fun log(level: Log.Level, message: String, throwable: Throwable?) { - logs.forEach { it.log(level, message, throwable) } + fun isEmpty() = loggers.isEmpty() + + fun log( + level: Logger.Level = Logger.Level.DEBUG, + throwable: Throwable? = null, + tag: String, + message: String + ) { + loggers.forEach { it.log(level, tag, message, throwable) } } + inline fun T.log( + level: Logger.Level = Logger.Level.DEBUG, + throwable: Throwable? = null, + tag: String = T::class.java.simpleName, + messageBlock: () -> String + ) { + if (!isEmpty()) { + log(level, throwable, tag, messageBlock()) + } + } } \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/logs/Log.kt b/lib/src/main/java/com/omega_r/base/logs/Logger.kt similarity index 58% rename from lib/src/main/java/com/omega_r/base/logs/Log.kt rename to lib/src/main/java/com/omega_r/base/logs/Logger.kt index 826e1ee..1734922 100644 --- a/lib/src/main/java/com/omega_r/base/logs/Log.kt +++ b/lib/src/main/java/com/omega_r/base/logs/Logger.kt @@ -3,9 +3,9 @@ package com.omega_r.base.logs /** * Created by Anton Knyazev on 2019-12-02. */ -interface Log { +interface Logger { - fun log(level: Level, message: String, throwable: Throwable? = null) + fun log(level: Level, tag: String, message: String, throwable: Throwable? = null) enum class Level { @@ -13,4 +13,4 @@ interface Log { } -} \ No newline at end of file +} From 44addaf93a5fbd91e34cd0781bc71bbb2edb2fa9 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 4 Dec 2019 19:26:35 +0300 Subject: [PATCH 15/54] Refactoring logger --- .idea/dictionaries/antonknyazev.xml | 7 ++ .../com/omega_r/base/simple/MainPresenter.kt | 7 +- lib/build.gradle | 2 +- .../com/omega_r/base/logs/AndroidLogger.kt | 7 +- .../java/com/omega_r/base/logs/LogManager.kt | 65 ++++++++++++++----- .../main/java/com/omega_r/base/logs/Logger.kt | 7 +- .../base/mvp/presenters/OmegaPresenter.kt | 5 +- 7 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 .idea/dictionaries/antonknyazev.xml diff --git a/.idea/dictionaries/antonknyazev.xml b/.idea/dictionaries/antonknyazev.xml new file mode 100644 index 0000000..13fb0ca --- /dev/null +++ b/.idea/dictionaries/antonknyazev.xml @@ -0,0 +1,7 @@ + + + + knyazev + + + \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt index d44f864..2e06c1f 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt @@ -2,6 +2,7 @@ package com.omega_r.base.simple import android.Manifest import com.omega_r.base.enitity.contains +import com.omega_r.base.logs.log import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.presenters.OmegaPresenter import com.omega_r.libs.omegatypes.Text @@ -30,8 +31,10 @@ class MainPresenter : OmegaPresenter() { viewState.showToast(Text.from(getPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE).toString())) } - -// viewState.showMessage(Text.from("test"), Action(Text.from("Test")) { +// viewState.showMe +// log { +// "Message" +// }ssage(Text.from("test"), Action(Text.from("Test")) { // viewState.showToast(Text.from("test")) // }) // diff --git a/lib/build.gradle b/lib/build.gradle index 33f6109..b25c753 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -60,7 +60,7 @@ dependencies { api 'com.github.Omega-R.OmegaTypes:glide:2.0.1' api 'com.github.Omega-R:OmegaIntentBuilder:1.2.0' api 'com.github.Omega-R:OmegaLaunchers:1.0.2' - api 'com.github.Omega-R:OmegaExtensions:1.0.3' + api 'com.github.Omega-R:OmegaExtensions:353da7f' api "com.squareup.retrofit2:retrofit:2.6.2" api "com.squareup.moshi:moshi-kotlin:1.8.0" diff --git a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt index c7e02b5..394327e 100644 --- a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt +++ b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt @@ -8,7 +8,12 @@ import com.omega_r.base.logs.Logger.Level.* */ class AndroidLogger: Logger { - override fun log(level: Logger.Level, tag: String, message: String, throwable: Throwable?) { + override fun log( + level: Logger.Level, + tag: String, + throwable: Throwable?, + message: String? + ) { when (level) { DEBUG -> Log.d(tag, message, throwable) INFO -> Log.i(tag, message, throwable) diff --git a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt index c7dc3e2..e2f41f6 100644 --- a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt +++ b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt @@ -1,35 +1,66 @@ package com.omega_r.base.logs -import com.omega_r.libs.extensions.log.log -import java.util.concurrent.CopyOnWriteArrayList +import androidx.collection.ArraySet +import com.omega_r.base.logs.Logger.Level +import java.util.concurrent.ConcurrentHashMap /** * Created by Anton Knyazev on 2019-12-02. */ object LogManager { - private val loggers: List = CopyOnWriteArrayList() + private val loggersMap: MutableMap> = ConcurrentHashMap() - fun isEmpty() = loggers.isEmpty() + fun isEmpty(level: Level) = loggersMap[level].isNullOrEmpty() - fun log( - level: Logger.Level = Logger.Level.DEBUG, - throwable: Throwable? = null, - tag: String, - message: String - ) { - loggers.forEach { it.log(level, tag, message, throwable) } + fun addLogger(logger: Logger, levels: Array = Level.values()) = apply { + levels.forEach { level: Level -> + loggersMap + .getOrPut(level) { ArraySet() } + .add(logger) + } } - inline fun T.log( - level: Logger.Level = Logger.Level.DEBUG, + fun log( + level: Level = Level.DEBUG, + tag: String, throwable: Throwable? = null, - tag: String = T::class.java.simpleName, - messageBlock: () -> String + message: String? ) { - if (!isEmpty()) { - log(level, throwable, tag, messageBlock()) + loggersMap[level]?.forEach { + it.log(level, tag, throwable, message) } } +} + +inline fun T.log( + level: Level = Level.DEBUG, + tag: String = T::class.java.simpleName, + throwable: Throwable? = null, + messageBlock: () -> String +) { + if (!LogManager.isEmpty(level)) { + LogManager.log( + level = level, + tag = tag, + throwable = throwable, + message = messageBlock() + ) + } +} + +inline fun T.log( + throwable: Throwable, + level: Level = Level.WARNING, + tag: String = T::class.java.simpleName +) { + if (!LogManager.isEmpty(level)) { + LogManager.log( + level = level, + tag = tag, + throwable = throwable, + message = null + ) + } } \ No newline at end of file diff --git a/lib/src/main/java/com/omega_r/base/logs/Logger.kt b/lib/src/main/java/com/omega_r/base/logs/Logger.kt index 1734922..7a2317a 100644 --- a/lib/src/main/java/com/omega_r/base/logs/Logger.kt +++ b/lib/src/main/java/com/omega_r/base/logs/Logger.kt @@ -5,7 +5,12 @@ package com.omega_r.base.logs */ interface Logger { - fun log(level: Level, tag: String, message: String, throwable: Throwable? = null) + fun log( + level: Level, + tag: String, + throwable: Throwable?, + message: String? + ) enum class Level { diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 0eafebd..1883353 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -2,10 +2,12 @@ package com.omega_r.base.mvp.presenters import android.content.pm.PackageManager import android.content.pm.PackageManager.PERMISSION_GRANTED +import androidx.annotation.CallSuper import com.omega_r.base.R import com.omega_r.base.data.OmegaRepository import com.omega_r.base.data.sources.Source import com.omega_r.base.errors.AppException +import com.omega_r.base.logs.log import com.omega_r.base.mvp.views.OmegaView import com.omega_r.libs.omegaintentbuilder.OmegaIntentBuilder import com.omega_r.libs.omegaintentbuilder.interfaces.IntentBuilder @@ -40,8 +42,9 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco protected val intentBuilder get() = OmegaIntentBuilder + @CallSuper protected open fun handleErrors(throwable: Throwable) { - throwable.printStackTrace() + log(throwable) } protected open fun getErrorMessage(throwable: Throwable): Text { From 60ff0b41fbf0f089eb0d5e119086e57ef29f48d1 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Mon, 9 Dec 2019 09:10:40 +0300 Subject: [PATCH 16/54] OmegaRepositoryProcessor added --- .idea/codeStyles/Project.xml | 110 +++++++++++ .idea/dictionaries/R12.xml | 3 + .idea/gradle.xml | 3 + .idea/modules.xml | 5 +- annotations/.gitignore | 1 + annotations/build.gradle | 7 + .../base/annotations/AppOmegaRepository.kt | 5 + .../omega_r/base/annotations/SuspendMethod.kt | 5 + app/build.gradle | 20 +- .../com/omega_r/base/simple/MainSource.kt | 17 ++ .../com/omega_r/base/simple/TestRepository.kt | 12 ++ build.gradle | 10 +- gradle/wrapper/gradle-wrapper.properties | 4 +- lib/build.gradle | 6 +- .../omega_r/base/components/OmegaActivity.kt | 2 +- processor/.gitignore | 1 + processor/build.gradle | 9 + .../processor/OmegaRepositoryProcessor.kt | 184 ++++++++++++++++++ .../javax.annotation.processing.Processor | 1 + settings.gradle | 2 +- 20 files changed, 385 insertions(+), 22 deletions(-) create mode 100644 .idea/dictionaries/R12.xml create mode 100644 annotations/.gitignore create mode 100644 annotations/build.gradle create mode 100644 annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt create mode 100644 annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt create mode 100644 app/src/main/java/com/omega_r/base/simple/MainSource.kt create mode 100644 app/src/main/java/com/omega_r/base/simple/TestRepository.kt create mode 100644 processor/.gitignore create mode 100644 processor/build.gradle create mode 100644 processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt create mode 100644 processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 1bec35e..a22d7de 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,8 +1,118 @@ + diff --git a/.idea/modules.xml b/.idea/modules.xml index 4ebd0e5..c9f54a7 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,11 +3,10 @@ - - - + + \ No newline at end of file diff --git a/annotations/.gitignore b/annotations/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/annotations/.gitignore @@ -0,0 +1 @@ +/build diff --git a/annotations/build.gradle b/annotations/build.gradle new file mode 100644 index 0000000..22a69c4 --- /dev/null +++ b/annotations/build.gradle @@ -0,0 +1,7 @@ +apply plugin: 'kotlin' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + //noinspection DifferentStdlibGradleVersion + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" +} \ No newline at end of file diff --git a/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt b/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt new file mode 100644 index 0000000..7b992f8 --- /dev/null +++ b/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt @@ -0,0 +1,5 @@ +package com.omega_r.base.annotations + +@Retention(AnnotationRetention.SOURCE) +@Target(allowedTargets = [AnnotationTarget.CLASS]) +annotation class AppOmegaRepository \ No newline at end of file diff --git a/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt b/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt new file mode 100644 index 0000000..5f7ae43 --- /dev/null +++ b/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt @@ -0,0 +1,5 @@ +package com.omega_r.base.annotations + +@Retention(AnnotationRetention.SOURCE) +@Target(allowedTargets = [AnnotationTarget.FUNCTION]) +annotation class SuspendMethod \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index c426979..d8704d2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,6 +7,7 @@ android { compileSdkVersion 28 defaultConfig { applicationId "com.omega_r.omegabase.simple" + multiDexEnabled true minSdkVersion 14 targetSdkVersion 28 versionCode 1 @@ -39,18 +40,23 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" - implementation 'androidx.appcompat:appcompat:1.1.0-alpha05' - implementation 'androidx.core:core-ktx:1.1.0-beta01' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.2.0-rc01' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinCorutines_version}" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${kotlinCorutines_version}" - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha5' - testImplementation 'junit:junit:4.13-beta-3' - androidTestImplementation 'androidx.test:runner:1.2.0-beta01' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation project(':lib') kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.7.0' - implementation 'com.github.bumptech.glide:glide:4.9.0' + implementation project(':annotations') + kapt project(':processor') + implementation 'com.github.bumptech.glide:glide:4.9.0' + + testImplementation 'junit:junit:4.13-beta-3' + androidTestImplementation 'androidx.test:runner:1.3.0-alpha02' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha02' } diff --git a/app/src/main/java/com/omega_r/base/simple/MainSource.kt b/app/src/main/java/com/omega_r/base/simple/MainSource.kt new file mode 100644 index 0000000..b9ef992 --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/MainSource.kt @@ -0,0 +1,17 @@ +package com.omega_r.base.simple + +import com.omega_r.base.annotations.AppOmegaRepository +import com.omega_r.base.annotations.SuspendMethod +import com.omega_r.base.data.sources.Source + +@AppOmegaRepository +interface MainSource : Source { + + val per: String + + fun testMethod() + + @SuspendMethod + fun testMethodReturn(kek: String?): String + +} \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/TestRepository.kt b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt new file mode 100644 index 0000000..debf6a9 --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt @@ -0,0 +1,12 @@ +package com.omega_r.base.simple + +import com.omega_r.base.data.OmegaRepository +import kotlinx.coroutines.channels.ReceiveChannel + +class TestRepository(vararg sources: MainSource) : OmegaRepository() { + + fun testMethodReturn(strategy: OmegaRepository.Strategy, kek: String): ReceiveChannel { + return createChannel(strategy) { testMethodReturn(kek) } + } + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1cc56bb..e79a8df 100644 --- a/build.gradle +++ b/build.gradle @@ -5,17 +5,15 @@ ext { }// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.31' + ext.kotlin_version = '1.3.61' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files } } @@ -24,6 +22,10 @@ allprojects { google() jcenter() maven { url 'https://jitpack.io' } + mavenCentral() + maven { + url "https://oss.sonatype.org/content/repositories/snapshots" + } } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c063af..e107ae6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed May 08 11:14:06 MSK 2019 +#Tue Dec 03 09:01:16 MSK 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/lib/build.gradle b/lib/build.gradle index 33f6109..ac39a63 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -1,13 +1,11 @@ apply plugin: 'com.android.library' -apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion 28 - - defaultConfig { minSdkVersion 14 targetSdkVersion 28 @@ -65,7 +63,7 @@ dependencies { api "com.squareup.retrofit2:retrofit:2.6.2" api "com.squareup.moshi:moshi-kotlin:1.8.0" - implementation 'com.google.android.material:material:1.2.0-alpha01' + implementation 'com.google.android.material:material:1.2.0-alpha02' } repositories { diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 7752f20..b5d1360 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -46,7 +46,7 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { override fun getContext(): Context = this override fun onCreate(savedInstanceState: Bundle?) { - this::class.findAnnotation()?.let { + this::class.findAnnotation()?.let { window?.apply { addFlags(it.addFlags) clearFlags(it.clearFlags) diff --git a/processor/.gitignore b/processor/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/processor/.gitignore @@ -0,0 +1 @@ +/build diff --git a/processor/build.gradle b/processor/build.gradle new file mode 100644 index 0000000..0472d91 --- /dev/null +++ b/processor/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'kotlin' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation project(':annotations') + implementation 'com.squareup:kotlinpoet:1.4.4' + implementation 'com.google.auto.service:auto-service:1.0-rc6' + implementation("me.eugeniomarletti.kotlin.metadata:kotlin-metadata:1.4.0") +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt new file mode 100644 index 0000000..18bd6d4 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -0,0 +1,184 @@ +package com.omega_r.base.processor + +import com.google.auto.service.AutoService +import com.omega_r.base.annotations.AppOmegaRepository +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata +import me.eugeniomarletti.kotlin.metadata.classKind +import me.eugeniomarletti.kotlin.metadata.kotlinMetadata +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver +import javax.annotation.processing.AbstractProcessor +import javax.annotation.processing.Messager +import javax.annotation.processing.RoundEnvironment +import javax.lang.model.SourceVersion +import javax.lang.model.element.Element +import javax.lang.model.element.TypeElement +import javax.lang.model.util.Elements +import javax.lang.model.util.Types +import javax.tools.Diagnostic.Kind.ERROR + +private const val UNIT = "kotlin.Unit" + +@AutoService(Process::class) +class OmegaRepositoryProcessor : AbstractProcessor() { + + private val OBJECT_CLASS = ClassName("java.lang", "Object") + private val OMEGA_REPOSITORY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") + private val STRATEGY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") + private val STRATEGY_PARAMETER_SPEC = ParameterSpec("strategy", STRATEGY_CLASS_NAME) + + private val messager: Messager + get() = processingEnv.messager + + private val elements: Elements + get() = processingEnv.elementUtils + + private val typeUtils: Types + get() = processingEnv.typeUtils + + override fun getSupportedAnnotationTypes() = setOf(AppOmegaRepository::class.java.canonicalName) + + override fun getSupportedSourceVersion() = SourceVersion.latest() + + override fun process(elements: Set, environment: RoundEnvironment): Boolean { + val repositoryElements = environment.getElementsAnnotatedWith(AppOmegaRepository::class.java) + repositoryElements.forEach { + generateRepository(it) + } + return true + } + + private fun generateRepository(element: Element) { + val typeMetadata = element.kotlinMetadata + if (element !is TypeElement || typeMetadata !is KotlinClassMetadata) { + messager.printMessage(ERROR, "@AppOmegaRepository can't be applied to $element: must be a Kotlin interface") + return + } + + val proto = typeMetadata.data.classProto + if (proto.classKind != ProtoBuf.Class.Kind.INTERFACE) { + messager.printMessage(ERROR, "@AppOmegaRepository can't be applied to $element: must be a Kotlin interface") + return + } + + val elementPackage = elements.getPackageOf(element).toString() + val fileName = element.getFileName(elementPackage) + + val typeSpec = TypeSpec.classBuilder(fileName) + .addConstructor(element) + .addFunctions(typeMetadata) + .build() + + FileSpec.builder(elementPackage, fileName) + .addType(typeSpec) + .build() + .writeTo(processingEnv.filer) + } + + private fun Element.getFileName(elementPackage: String): String { + return this.toString() + .removePrefix("$elementPackage.") + .removeSuffix("Source") + .plus("AppOmegaRepository") + } + + private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { + val className = ClassName.bestGuess(element.toString()) + return superclass(OMEGA_REPOSITORY_CLASS_NAME.parameterizedBy(className)) + .addModifiers(KModifier.OPEN) + .addSuperclassConstructorParameter("*sources") + .primaryConstructor( + FunSpec.constructorBuilder() + .addParameter("sources", ClassName.bestGuess(element.toString()), KModifier.VARARG) + .build() + ) + } + + private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata): TypeSpec.Builder { + val nameResolver = kotlinMetadata.data.nameResolver + val classData = kotlinMetadata.data.classProto + + classData.functionList.forEach { function -> + val returnType = nameResolver.getString(function.returnType.className).formatType() + when (returnType) { + UNIT -> addUnitFunction(nameResolver, function) + else -> addChannelFunction(nameResolver, function) + } + } + return this + } + + private fun TypeSpec.Builder.addUnitFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { + val funcName = resolver.getName(function) + val parameters = generateParameters(resolver, function) + val arguments = parameters.subList(1, parameters.size) + .map { it.name } + .joinToString() + +// ONLY_REMOTE, +// ONLY_CACHE, +// REMOTE_ELSE_CACHE, +// CACHE_ELSE_REMOTE, +// CACHE_AND_REMOTE, +// MEMORY_ELSE_CACHE_AND_REMOTE + + val codeBlock = CodeBlock.builder() + .add("when(strategy) {\n") + .add("OmegaRepository.Strategy.ONLY_REMOTE -> remoteSource?.$funcName($arguments)\n") + .add("OmegaRepository.Strategy.ONLY_CACHE -> { \n") + .add("fileSource?.$funcName($arguments)\n") + .add("memorySource?.$funcName($arguments)\n") + .add("} \n") + .add("else -> { \n") + .add("// TODO: Future functional \n") + .add("} \n") + .add("}") + + return addFunction( + FunSpec.builder(funcName) + .addModifiers(KModifier.SUSPEND, KModifier.OPEN, KModifier.PROTECTED) + .addParameters(parameters) + .addComment("TODO: Future functional") + .addCode(codeBlock.build()) + .build() + ) + } + + private fun TypeSpec.Builder.addChannelFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { + val funcName = resolver.getName(function) + val parameters = generateParameters(resolver, function) + val arguments = parameters.subList(1, parameters.size) + .map { it.name } + .joinToString() + + val codeBlock = CodeBlock.builder() + .add("return createChannel(strategy) { $funcName($arguments) }\n\n") + .build() + + return addFunction( + FunSpec.builder(funcName) + .addParameters(parameters) + .addCode(codeBlock) + .build() + ) + } + + private fun generateParameters(resolver: NameResolver, function: Function): List { + val list = mutableListOf(STRATEGY_PARAMETER_SPEC) + list += function.valueParameterList.map { parameter -> + val name = resolver.getString(parameter.name) + val className = ClassName.bestGuess(resolver.getString(parameter.type.className).formatType()) + ParameterSpec(name, className.copy(nullable = parameter.type.nullable)) + + } + return list + } + + private fun NameResolver.getName(function: Function): String = getString(function.name) + + private fun String.formatType(): String = replace("/", ".") + +} \ No newline at end of file diff --git a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..93d2c9b --- /dev/null +++ b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +com.omega_r.base.processor.OmegaRepositoryProcessor \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 3cbe249..e114a06 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':lib' +include ':app', ':lib', ':processor', ':annotations' From 1c46269b44e07c2cd0068adac6ca5adc6ebdf190 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Mon, 9 Dec 2019 11:18:26 +0300 Subject: [PATCH 17/54] Code generation updated --- ...pOmegaRepository.kt => OmegaRepository.kt} | 2 +- .../omega_r/base/annotations/SuspendMethod.kt | 5 - .../com/omega_r/base/simple/MainSource.kt | 6 +- processor/build.gradle | 2 + .../processor/OmegaRepositoryProcessor.kt | 91 ++++++------------- 5 files changed, 35 insertions(+), 71 deletions(-) rename annotations/src/main/java/com/omega_r/base/annotations/{AppOmegaRepository.kt => OmegaRepository.kt} (78%) delete mode 100644 annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt diff --git a/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt b/annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt similarity index 78% rename from annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt rename to annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt index 7b992f8..90b6800 100644 --- a/annotations/src/main/java/com/omega_r/base/annotations/AppOmegaRepository.kt +++ b/annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt @@ -2,4 +2,4 @@ package com.omega_r.base.annotations @Retention(AnnotationRetention.SOURCE) @Target(allowedTargets = [AnnotationTarget.CLASS]) -annotation class AppOmegaRepository \ No newline at end of file +annotation class OmegaRepository \ No newline at end of file diff --git a/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt b/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt deleted file mode 100644 index 5f7ae43..0000000 --- a/annotations/src/main/java/com/omega_r/base/annotations/SuspendMethod.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.omega_r.base.annotations - -@Retention(AnnotationRetention.SOURCE) -@Target(allowedTargets = [AnnotationTarget.FUNCTION]) -annotation class SuspendMethod \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/MainSource.kt b/app/src/main/java/com/omega_r/base/simple/MainSource.kt index b9ef992..32c8d18 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainSource.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainSource.kt @@ -1,17 +1,15 @@ package com.omega_r.base.simple -import com.omega_r.base.annotations.AppOmegaRepository -import com.omega_r.base.annotations.SuspendMethod +import com.omega_r.base.annotations.OmegaRepository import com.omega_r.base.data.sources.Source -@AppOmegaRepository +@OmegaRepository interface MainSource : Source { val per: String fun testMethod() - @SuspendMethod fun testMethodReturn(kek: String?): String } \ No newline at end of file diff --git a/processor/build.gradle b/processor/build.gradle index 0472d91..ed4735c 100644 --- a/processor/build.gradle +++ b/processor/build.gradle @@ -5,5 +5,7 @@ dependencies { implementation project(':annotations') implementation 'com.squareup:kotlinpoet:1.4.4' implementation 'com.google.auto.service:auto-service:1.0-rc6' + implementation 'net.ltgt.gradle.incap:incap:0.2' + implementation 'net.ltgt.gradle.incap:incap-processor:0.2' implementation("me.eugeniomarletti.kotlin.metadata:kotlin-metadata:1.4.0") } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index 18bd6d4..0e58c6c 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -1,7 +1,7 @@ package com.omega_r.base.processor import com.google.auto.service.AutoService -import com.omega_r.base.annotations.AppOmegaRepository +import com.omega_r.base.annotations.OmegaRepository import com.squareup.kotlinpoet.* import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata @@ -10,6 +10,8 @@ import me.eugeniomarletti.kotlin.metadata.kotlinMetadata import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver +import net.ltgt.gradle.incap.IncrementalAnnotationProcessor +import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType import javax.annotation.processing.AbstractProcessor import javax.annotation.processing.Messager import javax.annotation.processing.RoundEnvironment @@ -23,12 +25,13 @@ import javax.tools.Diagnostic.Kind.ERROR private const val UNIT = "kotlin.Unit" @AutoService(Process::class) +@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING) class OmegaRepositoryProcessor : AbstractProcessor() { - private val OBJECT_CLASS = ClassName("java.lang", "Object") private val OMEGA_REPOSITORY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") private val STRATEGY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") private val STRATEGY_PARAMETER_SPEC = ParameterSpec("strategy", STRATEGY_CLASS_NAME) + private val CONSUME_EACH_MEMBER_NAME = MemberName("kotlinx.coroutines.channels", "consumeEach") private val messager: Messager get() = processingEnv.messager @@ -36,15 +39,12 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private val elements: Elements get() = processingEnv.elementUtils - private val typeUtils: Types - get() = processingEnv.typeUtils - - override fun getSupportedAnnotationTypes() = setOf(AppOmegaRepository::class.java.canonicalName) + override fun getSupportedAnnotationTypes() = setOf(OmegaRepository::class.java.canonicalName) override fun getSupportedSourceVersion() = SourceVersion.latest() override fun process(elements: Set, environment: RoundEnvironment): Boolean { - val repositoryElements = environment.getElementsAnnotatedWith(AppOmegaRepository::class.java) + val repositoryElements = environment.getElementsAnnotatedWith(OmegaRepository::class.java) repositoryElements.forEach { generateRepository(it) } @@ -82,7 +82,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { return this.toString() .removePrefix("$elementPackage.") .removeSuffix("Source") - .plus("AppOmegaRepository") + .plus("OmegaGeneratedRepository") } private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { @@ -100,68 +100,34 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata): TypeSpec.Builder { val nameResolver = kotlinMetadata.data.nameResolver val classData = kotlinMetadata.data.classProto - - classData.functionList.forEach { function -> - val returnType = nameResolver.getString(function.returnType.className).formatType() - when (returnType) { - UNIT -> addUnitFunction(nameResolver, function) - else -> addChannelFunction(nameResolver, function) - } + classData.functionList.forEach { + addFunction(nameResolver, it) } return this } - private fun TypeSpec.Builder.addUnitFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { - val funcName = resolver.getName(function) - val parameters = generateParameters(resolver, function) - val arguments = parameters.subList(1, parameters.size) - .map { it.name } - .joinToString() - -// ONLY_REMOTE, -// ONLY_CACHE, -// REMOTE_ELSE_CACHE, -// CACHE_ELSE_REMOTE, -// CACHE_AND_REMOTE, -// MEMORY_ELSE_CACHE_AND_REMOTE - - val codeBlock = CodeBlock.builder() - .add("when(strategy) {\n") - .add("OmegaRepository.Strategy.ONLY_REMOTE -> remoteSource?.$funcName($arguments)\n") - .add("OmegaRepository.Strategy.ONLY_CACHE -> { \n") - .add("fileSource?.$funcName($arguments)\n") - .add("memorySource?.$funcName($arguments)\n") - .add("} \n") - .add("else -> { \n") - .add("// TODO: Future functional \n") - .add("} \n") - .add("}") - - return addFunction( - FunSpec.builder(funcName) - .addModifiers(KModifier.SUSPEND, KModifier.OPEN, KModifier.PROTECTED) - .addParameters(parameters) - .addComment("TODO: Future functional") - .addCode(codeBlock.build()) - .build() - ) - } - - private fun TypeSpec.Builder.addChannelFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { + private fun TypeSpec.Builder.addFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { val funcName = resolver.getName(function) - val parameters = generateParameters(resolver, function) - val arguments = parameters.subList(1, parameters.size) - .map { it.name } - .joinToString() + val parameterSpecs = generateParameters(resolver, function) + val arguments = parameterSpecs.subList(1, parameterSpecs.size).joinToString { it.name } + val isUnitFunction = function.isUnitFunction(resolver) + + val codeBlockBuilder = CodeBlock.builder().apply { + if (isUnitFunction) { + addStatement("createChannel(strategy) { $funcName($arguments) }.%M{}", CONSUME_EACH_MEMBER_NAME) + } else { + add("return createChannel(strategy) { $funcName($arguments) }\n\n") + } + }.build() - val codeBlock = CodeBlock.builder() - .add("return createChannel(strategy) { $funcName($arguments) }\n\n") - .build() + val modifiers: MutableList = mutableListOf(KModifier.OPEN) + if (isUnitFunction) modifiers.add(KModifier.SUSPEND) return addFunction( FunSpec.builder(funcName) - .addParameters(parameters) - .addCode(codeBlock) + .addModifiers(modifiers) + .addParameters(parameterSpecs) + .addCode(codeBlockBuilder) .build() ) } @@ -177,6 +143,9 @@ class OmegaRepositoryProcessor : AbstractProcessor() { return list } + private fun Function.isUnitFunction(resolver: NameResolver) = + resolver.getString(returnType.className).formatType() == UNIT + private fun NameResolver.getName(function: Function): String = getString(function.name) private fun String.formatType(): String = replace("/", ".") From 33af222b32b7edcd6fdce2406d59125a7e3e0f62 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Mon, 9 Dec 2019 11:28:27 +0300 Subject: [PATCH 18/54] Maven plugin imported --- annotations/build.gradle | 2 ++ app/build.gradle | 2 -- build.gradle | 1 + lib/build.gradle | 6 +++++- processor/build.gradle | 2 ++ 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/annotations/build.gradle b/annotations/build.gradle index 22a69c4..41916ab 100644 --- a/annotations/build.gradle +++ b/annotations/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'kotlin' +apply plugin: 'com.github.dcendents.android-maven' +group = 'com.github.Omega-R.OmegaBase' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) diff --git a/app/build.gradle b/app/build.gradle index d8704d2..6642016 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -49,8 +49,6 @@ dependencies { implementation project(':lib') kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.7.0' - - implementation project(':annotations') kapt project(':processor') implementation 'com.github.bumptech.glide:glide:4.9.0' diff --git a/build.gradle b/build.gradle index e79a8df..a30d680 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } } diff --git a/lib/build.gradle b/lib/build.gradle index 06146ca..872d33c 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -3,6 +3,9 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' +apply plugin: 'com.github.dcendents.android-maven' +group = 'com.github.Omega-R' + android { compileSdkVersion 28 @@ -58,7 +61,8 @@ dependencies { api 'com.github.Omega-R.OmegaTypes:glide:2.0.1' api 'com.github.Omega-R:OmegaIntentBuilder:1.2.0' api 'com.github.Omega-R:OmegaLaunchers:1.0.2' - api 'com.github.Omega-R:OmegaExtensions:353da7f' + api 'com.github.Omega-R:OmegaExtensions:1.0.3' + api project(':annotations') api "com.squareup.retrofit2:retrofit:2.6.2" api "com.squareup.moshi:moshi-kotlin:1.8.0" diff --git a/processor/build.gradle b/processor/build.gradle index ed4735c..8b92480 100644 --- a/processor/build.gradle +++ b/processor/build.gradle @@ -1,4 +1,6 @@ apply plugin: 'kotlin' +apply plugin: 'com.github.dcendents.android-maven' +group = 'com.github.Omega-R.OmegaBase' dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" From 57d1f17c3bf268187e93dca7592ecaea78cf89b3 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Mon, 9 Dec 2019 12:08:09 +0300 Subject: [PATCH 19/54] Fix Android logger --- lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt | 2 +- lib/src/main/java/com/omega_r/base/logs/LogManager.kt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt index 394327e..ea3f020 100644 --- a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt +++ b/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt @@ -6,7 +6,7 @@ import com.omega_r.base.logs.Logger.Level.* /** * Created by Anton Knyazev on 03.12.2019. */ -class AndroidLogger: Logger { +object AndroidLogger: Logger { override fun log( level: Logger.Level, diff --git a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt index e2f41f6..6cb3ca2 100644 --- a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt +++ b/lib/src/main/java/com/omega_r/base/logs/LogManager.kt @@ -11,6 +11,10 @@ object LogManager { private val loggersMap: MutableMap> = ConcurrentHashMap() + init { + this += AndroidLogger + } + fun isEmpty(level: Level) = loggersMap[level].isNullOrEmpty() fun addLogger(logger: Logger, levels: Array = Level.values()) = apply { @@ -21,6 +25,10 @@ object LogManager { } } + operator fun plusAssign(logger: Logger) { + addLogger(logger) + } + fun log( level: Level = Level.DEBUG, tag: String, From 2dbcb38bea2566d6951c518f713b6b2add404b5d Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Mon, 9 Dec 2019 12:25:50 +0300 Subject: [PATCH 20/54] Processor updated. Lib module renamed to core --- .idea/gradle.xml | 2 +- .idea/modules.xml | 2 +- app/build.gradle | 2 +- {lib => core}/.gitignore | 0 {lib => core}/build.gradle | 0 {lib => core}/proguard-rules.pro | 0 .../java/com/omega_r/base/ExampleInstrumentedTest.java | 0 {lib => core}/src/main/AndroidManifest.xml | 0 .../src/main/java/com/omega_r/base/OmegaContext.kt | 0 .../src/main/java/com/omega_r/base/OmegaViewFindable.kt | 0 .../main/java/com/omega_r/base/adapters/ListableAdapter.kt | 0 .../main/java/com/omega_r/base/adapters/OmegaAdapter.kt | 0 .../java/com/omega_r/base/adapters/OmegaAutoAdapter.kt | 0 .../java/com/omega_r/base/adapters/OmegaListAdapter.kt | 0 .../java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt | 0 .../com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt | 0 .../com/omega_r/base/adapters/OmegaViewPagerAdapter.kt | 0 .../java/com/omega_r/base/adapters/model/AutoBindModel.kt | 0 .../java/com/omega_r/base/annotations/OmegaClickViews.kt | 0 .../java/com/omega_r/base/annotations/OmegaContentView.kt | 0 .../com/omega_r/base/annotations/OmegaHomeIndicator.kt | 0 .../main/java/com/omega_r/base/annotations/OmegaMenu.kt | 0 .../main/java/com/omega_r/base/annotations/OmegaTheme.kt | 0 .../main/java/com/omega_r/base/annotations/OmegaTitle.kt | 0 .../com/omega_r/base/annotations/OmegaWindowBackground.kt | 0 .../java/com/omega_r/base/annotations/OmegaWindowFlags.kt | 0 .../src/main/java/com/omega_r/base/binders/IdHolder.kt | 0 .../main/java/com/omega_r/base/binders/OmegaBindable.kt | 0 .../com/omega_r/base/binders/managers/BindersManager.kt | 0 .../base/binders/managers/ResettableBindersManager.kt | 0 .../main/java/com/omega_r/base/clickers/ClickManager.kt | 0 .../main/java/com/omega_r/base/clickers/OmegaClickable.kt | 0 .../main/java/com/omega_r/base/components/OmegaActivity.kt | 0 .../base/components/OmegaBottomSheetDialogFragment.kt | 0 .../java/com/omega_r/base/components/OmegaComponent.kt | 0 .../main/java/com/omega_r/base/components/OmegaDialog.kt | 0 .../com/omega_r/base/components/OmegaDialogFragment.kt | 0 .../main/java/com/omega_r/base/components/OmegaFragment.kt | 0 .../src/main/java/com/omega_r/base/data/OmegaRepository.kt | 0 .../main/java/com/omega_r/base/data/sources/CacheSource.kt | 0 .../com/omega_r/base/data/sources/OmegaDefaultSource.kt | 0 .../com/omega_r/base/data/sources/OmegaFileCacheSource.kt | 0 .../omega_r/base/data/sources/OmegaMemoryCacheSource.kt | 0 .../com/omega_r/base/data/sources/OmegaRemoteSource.kt | 0 .../src/main/java/com/omega_r/base/data/sources/Source.kt | 0 .../src/main/java/com/omega_r/base/enitity/Identifiable.kt | 0 .../src/main/java/com/omega_r/base/enitity/Imageable.kt | 0 .../src/main/java/com/omega_r/base/errors/AppException.kt | 0 .../src/main/java/com/omega_r/base/errors/ErrorHandler.kt | 0 .../src/main/java/com/omega_r/base/logs/AndroidLogger.kt | 0 .../src/main/java/com/omega_r/base/logs/LogManager.kt | 0 .../src/main/java/com/omega_r/base/logs/Logger.kt | 0 .../src/main/java/com/omega_r/base/mvp/model/Action.kt | 0 .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 0 .../base/mvp/strategies/AddToEndSingleTagStrategy.kt | 0 .../omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt | 0 .../src/main/java/com/omega_r/base/mvp/views/OmegaView.kt | 0 .../com/omega_r/base/remote/CoroutineCallAdapterFactory.kt | 0 .../java/com/omega_r/base/remote/adapters/ImageAdapter.kt | 0 .../java/com/omega_r/base/remote/adapters/TextAdapter.kt | 0 .../src/main/java/com/omega_r/base/tools/DialogManager.kt | 0 .../main/java/com/omega_r/base/tools/LockScreenDialog.kt | 0 .../main/java/com/omega_r/base/tools/StringExtensions.kt | 0 .../src/main/java/com/omega_r/base/tools/WaitingDialog.kt | 0 {lib => core}/src/main/res/layout/dialog_waiting.xml | 0 {lib => core}/src/main/res/values/ids.xml | 0 {lib => core}/src/main/res/values/strings.xml | 0 .../src/test/java/com/omega_r/base/ExampleUnitTest.java | 0 processor/build.gradle | 4 +++- .../com/omega_r/base/processor/OmegaRepositoryProcessor.kt | 7 +++---- settings.gradle | 2 +- 71 files changed, 10 insertions(+), 9 deletions(-) rename {lib => core}/.gitignore (100%) rename {lib => core}/build.gradle (100%) rename {lib => core}/proguard-rules.pro (100%) rename {lib => core}/src/androidTest/java/com/omega_r/base/ExampleInstrumentedTest.java (100%) rename {lib => core}/src/main/AndroidManifest.xml (100%) rename {lib => core}/src/main/java/com/omega_r/base/OmegaContext.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/OmegaViewFindable.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/ListableAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaAutoAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/OmegaViewPagerAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/adapters/model/AutoBindModel.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaClickViews.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaContentView.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaHomeIndicator.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaMenu.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaTheme.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaTitle.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaWindowBackground.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/annotations/OmegaWindowFlags.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/binders/IdHolder.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/binders/OmegaBindable.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/binders/managers/BindersManager.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/binders/managers/ResettableBindersManager.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/clickers/ClickManager.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/clickers/OmegaClickable.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaActivity.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaComponent.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaDialog.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/components/OmegaFragment.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/OmegaRepository.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/CacheSource.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/OmegaDefaultSource.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/OmegaFileCacheSource.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/OmegaMemoryCacheSource.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/OmegaRemoteSource.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/data/sources/Source.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/enitity/Identifiable.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/enitity/Imageable.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/errors/AppException.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/errors/ErrorHandler.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/logs/AndroidLogger.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/logs/LogManager.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/logs/Logger.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/mvp/model/Action.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/mvp/strategies/AddToEndSingleTagStrategy.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/remote/adapters/ImageAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/remote/adapters/TextAdapter.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/tools/DialogManager.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/tools/LockScreenDialog.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/tools/StringExtensions.kt (100%) rename {lib => core}/src/main/java/com/omega_r/base/tools/WaitingDialog.kt (100%) rename {lib => core}/src/main/res/layout/dialog_waiting.xml (100%) rename {lib => core}/src/main/res/values/ids.xml (100%) rename {lib => core}/src/main/res/values/strings.xml (100%) rename {lib => core}/src/test/java/com/omega_r/base/ExampleUnitTest.java (100%) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index e4806de..d476705 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -10,7 +10,7 @@ diff --git a/.idea/modules.xml b/.idea/modules.xml index c9f54a7..9cbd4a7 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -5,7 +5,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 6642016..3895aa3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,7 +47,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3' implementation 'androidx.recyclerview:recyclerview:1.1.0' - implementation project(':lib') + implementation project(':core') kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.7.0' kapt project(':processor') diff --git a/lib/.gitignore b/core/.gitignore similarity index 100% rename from lib/.gitignore rename to core/.gitignore diff --git a/lib/build.gradle b/core/build.gradle similarity index 100% rename from lib/build.gradle rename to core/build.gradle diff --git a/lib/proguard-rules.pro b/core/proguard-rules.pro similarity index 100% rename from lib/proguard-rules.pro rename to core/proguard-rules.pro diff --git a/lib/src/androidTest/java/com/omega_r/base/ExampleInstrumentedTest.java b/core/src/androidTest/java/com/omega_r/base/ExampleInstrumentedTest.java similarity index 100% rename from lib/src/androidTest/java/com/omega_r/base/ExampleInstrumentedTest.java rename to core/src/androidTest/java/com/omega_r/base/ExampleInstrumentedTest.java diff --git a/lib/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml similarity index 100% rename from lib/src/main/AndroidManifest.xml rename to core/src/main/AndroidManifest.xml diff --git a/lib/src/main/java/com/omega_r/base/OmegaContext.kt b/core/src/main/java/com/omega_r/base/OmegaContext.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/OmegaContext.kt rename to core/src/main/java/com/omega_r/base/OmegaContext.kt diff --git a/lib/src/main/java/com/omega_r/base/OmegaViewFindable.kt b/core/src/main/java/com/omega_r/base/OmegaViewFindable.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/OmegaViewFindable.kt rename to core/src/main/java/com/omega_r/base/OmegaViewFindable.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/ListableAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/ListableAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/ListableAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/ListableAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaAutoAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaAutoAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaAutoAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaAutoAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaSpinnerAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaStickyAutoAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaViewPagerAdapter.kt b/core/src/main/java/com/omega_r/base/adapters/OmegaViewPagerAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/OmegaViewPagerAdapter.kt rename to core/src/main/java/com/omega_r/base/adapters/OmegaViewPagerAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/adapters/model/AutoBindModel.kt b/core/src/main/java/com/omega_r/base/adapters/model/AutoBindModel.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/adapters/model/AutoBindModel.kt rename to core/src/main/java/com/omega_r/base/adapters/model/AutoBindModel.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaClickViews.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaClickViews.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaClickViews.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaClickViews.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaContentView.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaContentView.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaContentView.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaContentView.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaHomeIndicator.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaHomeIndicator.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaHomeIndicator.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaHomeIndicator.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaMenu.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaMenu.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaMenu.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaMenu.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaTheme.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaTheme.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaTheme.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaTheme.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaTitle.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaTitle.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaTitle.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaTitle.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaWindowBackground.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaWindowBackground.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaWindowBackground.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaWindowBackground.kt diff --git a/lib/src/main/java/com/omega_r/base/annotations/OmegaWindowFlags.kt b/core/src/main/java/com/omega_r/base/annotations/OmegaWindowFlags.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/annotations/OmegaWindowFlags.kt rename to core/src/main/java/com/omega_r/base/annotations/OmegaWindowFlags.kt diff --git a/lib/src/main/java/com/omega_r/base/binders/IdHolder.kt b/core/src/main/java/com/omega_r/base/binders/IdHolder.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/binders/IdHolder.kt rename to core/src/main/java/com/omega_r/base/binders/IdHolder.kt diff --git a/lib/src/main/java/com/omega_r/base/binders/OmegaBindable.kt b/core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/binders/OmegaBindable.kt rename to core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt diff --git a/lib/src/main/java/com/omega_r/base/binders/managers/BindersManager.kt b/core/src/main/java/com/omega_r/base/binders/managers/BindersManager.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/binders/managers/BindersManager.kt rename to core/src/main/java/com/omega_r/base/binders/managers/BindersManager.kt diff --git a/lib/src/main/java/com/omega_r/base/binders/managers/ResettableBindersManager.kt b/core/src/main/java/com/omega_r/base/binders/managers/ResettableBindersManager.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/binders/managers/ResettableBindersManager.kt rename to core/src/main/java/com/omega_r/base/binders/managers/ResettableBindersManager.kt diff --git a/lib/src/main/java/com/omega_r/base/clickers/ClickManager.kt b/core/src/main/java/com/omega_r/base/clickers/ClickManager.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/clickers/ClickManager.kt rename to core/src/main/java/com/omega_r/base/clickers/ClickManager.kt diff --git a/lib/src/main/java/com/omega_r/base/clickers/OmegaClickable.kt b/core/src/main/java/com/omega_r/base/clickers/OmegaClickable.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/clickers/OmegaClickable.kt rename to core/src/main/java/com/omega_r/base/clickers/OmegaClickable.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt rename to core/src/main/java/com/omega_r/base/components/OmegaActivity.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt rename to core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt b/core/src/main/java/com/omega_r/base/components/OmegaComponent.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaComponent.kt rename to core/src/main/java/com/omega_r/base/components/OmegaComponent.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaDialog.kt b/core/src/main/java/com/omega_r/base/components/OmegaDialog.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaDialog.kt rename to core/src/main/java/com/omega_r/base/components/OmegaDialog.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt rename to core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaFragment.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/components/OmegaFragment.kt rename to core/src/main/java/com/omega_r/base/components/OmegaFragment.kt diff --git a/lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/OmegaRepository.kt rename to core/src/main/java/com/omega_r/base/data/OmegaRepository.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt b/core/src/main/java/com/omega_r/base/data/sources/CacheSource.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/CacheSource.kt rename to core/src/main/java/com/omega_r/base/data/sources/CacheSource.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/OmegaDefaultSource.kt b/core/src/main/java/com/omega_r/base/data/sources/OmegaDefaultSource.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/OmegaDefaultSource.kt rename to core/src/main/java/com/omega_r/base/data/sources/OmegaDefaultSource.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/OmegaFileCacheSource.kt b/core/src/main/java/com/omega_r/base/data/sources/OmegaFileCacheSource.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/OmegaFileCacheSource.kt rename to core/src/main/java/com/omega_r/base/data/sources/OmegaFileCacheSource.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/OmegaMemoryCacheSource.kt b/core/src/main/java/com/omega_r/base/data/sources/OmegaMemoryCacheSource.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/OmegaMemoryCacheSource.kt rename to core/src/main/java/com/omega_r/base/data/sources/OmegaMemoryCacheSource.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/OmegaRemoteSource.kt b/core/src/main/java/com/omega_r/base/data/sources/OmegaRemoteSource.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/OmegaRemoteSource.kt rename to core/src/main/java/com/omega_r/base/data/sources/OmegaRemoteSource.kt diff --git a/lib/src/main/java/com/omega_r/base/data/sources/Source.kt b/core/src/main/java/com/omega_r/base/data/sources/Source.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/data/sources/Source.kt rename to core/src/main/java/com/omega_r/base/data/sources/Source.kt diff --git a/lib/src/main/java/com/omega_r/base/enitity/Identifiable.kt b/core/src/main/java/com/omega_r/base/enitity/Identifiable.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/enitity/Identifiable.kt rename to core/src/main/java/com/omega_r/base/enitity/Identifiable.kt diff --git a/lib/src/main/java/com/omega_r/base/enitity/Imageable.kt b/core/src/main/java/com/omega_r/base/enitity/Imageable.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/enitity/Imageable.kt rename to core/src/main/java/com/omega_r/base/enitity/Imageable.kt diff --git a/lib/src/main/java/com/omega_r/base/errors/AppException.kt b/core/src/main/java/com/omega_r/base/errors/AppException.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/errors/AppException.kt rename to core/src/main/java/com/omega_r/base/errors/AppException.kt diff --git a/lib/src/main/java/com/omega_r/base/errors/ErrorHandler.kt b/core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/errors/ErrorHandler.kt rename to core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt diff --git a/lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt b/core/src/main/java/com/omega_r/base/logs/AndroidLogger.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/logs/AndroidLogger.kt rename to core/src/main/java/com/omega_r/base/logs/AndroidLogger.kt diff --git a/lib/src/main/java/com/omega_r/base/logs/LogManager.kt b/core/src/main/java/com/omega_r/base/logs/LogManager.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/logs/LogManager.kt rename to core/src/main/java/com/omega_r/base/logs/LogManager.kt diff --git a/lib/src/main/java/com/omega_r/base/logs/Logger.kt b/core/src/main/java/com/omega_r/base/logs/Logger.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/logs/Logger.kt rename to core/src/main/java/com/omega_r/base/logs/Logger.kt diff --git a/lib/src/main/java/com/omega_r/base/mvp/model/Action.kt b/core/src/main/java/com/omega_r/base/mvp/model/Action.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/mvp/model/Action.kt rename to core/src/main/java/com/omega_r/base/mvp/model/Action.kt diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt rename to core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt diff --git a/lib/src/main/java/com/omega_r/base/mvp/strategies/AddToEndSingleTagStrategy.kt b/core/src/main/java/com/omega_r/base/mvp/strategies/AddToEndSingleTagStrategy.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/mvp/strategies/AddToEndSingleTagStrategy.kt rename to core/src/main/java/com/omega_r/base/mvp/strategies/AddToEndSingleTagStrategy.kt diff --git a/lib/src/main/java/com/omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt b/core/src/main/java/com/omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt rename to core/src/main/java/com/omega_r/base/mvp/strategies/RemoveEndTagStrategy.kt diff --git a/lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt b/core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt rename to core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt diff --git a/lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt b/core/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt rename to core/src/main/java/com/omega_r/base/remote/CoroutineCallAdapterFactory.kt diff --git a/lib/src/main/java/com/omega_r/base/remote/adapters/ImageAdapter.kt b/core/src/main/java/com/omega_r/base/remote/adapters/ImageAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/remote/adapters/ImageAdapter.kt rename to core/src/main/java/com/omega_r/base/remote/adapters/ImageAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/remote/adapters/TextAdapter.kt b/core/src/main/java/com/omega_r/base/remote/adapters/TextAdapter.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/remote/adapters/TextAdapter.kt rename to core/src/main/java/com/omega_r/base/remote/adapters/TextAdapter.kt diff --git a/lib/src/main/java/com/omega_r/base/tools/DialogManager.kt b/core/src/main/java/com/omega_r/base/tools/DialogManager.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/tools/DialogManager.kt rename to core/src/main/java/com/omega_r/base/tools/DialogManager.kt diff --git a/lib/src/main/java/com/omega_r/base/tools/LockScreenDialog.kt b/core/src/main/java/com/omega_r/base/tools/LockScreenDialog.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/tools/LockScreenDialog.kt rename to core/src/main/java/com/omega_r/base/tools/LockScreenDialog.kt diff --git a/lib/src/main/java/com/omega_r/base/tools/StringExtensions.kt b/core/src/main/java/com/omega_r/base/tools/StringExtensions.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/tools/StringExtensions.kt rename to core/src/main/java/com/omega_r/base/tools/StringExtensions.kt diff --git a/lib/src/main/java/com/omega_r/base/tools/WaitingDialog.kt b/core/src/main/java/com/omega_r/base/tools/WaitingDialog.kt similarity index 100% rename from lib/src/main/java/com/omega_r/base/tools/WaitingDialog.kt rename to core/src/main/java/com/omega_r/base/tools/WaitingDialog.kt diff --git a/lib/src/main/res/layout/dialog_waiting.xml b/core/src/main/res/layout/dialog_waiting.xml similarity index 100% rename from lib/src/main/res/layout/dialog_waiting.xml rename to core/src/main/res/layout/dialog_waiting.xml diff --git a/lib/src/main/res/values/ids.xml b/core/src/main/res/values/ids.xml similarity index 100% rename from lib/src/main/res/values/ids.xml rename to core/src/main/res/values/ids.xml diff --git a/lib/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml similarity index 100% rename from lib/src/main/res/values/strings.xml rename to core/src/main/res/values/strings.xml diff --git a/lib/src/test/java/com/omega_r/base/ExampleUnitTest.java b/core/src/test/java/com/omega_r/base/ExampleUnitTest.java similarity index 100% rename from lib/src/test/java/com/omega_r/base/ExampleUnitTest.java rename to core/src/test/java/com/omega_r/base/ExampleUnitTest.java diff --git a/processor/build.gradle b/processor/build.gradle index 8b92480..9a0b9ff 100644 --- a/processor/build.gradle +++ b/processor/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'kotlin' +apply plugin: 'kotlin-kapt' apply plugin: 'com.github.dcendents.android-maven' group = 'com.github.Omega-R.OmegaBase' @@ -7,7 +8,8 @@ dependencies { implementation project(':annotations') implementation 'com.squareup:kotlinpoet:1.4.4' implementation 'com.google.auto.service:auto-service:1.0-rc6' + implementation 'com.google.auto.service:auto-service-annotations:1.0-rc6' implementation 'net.ltgt.gradle.incap:incap:0.2' - implementation 'net.ltgt.gradle.incap:incap-processor:0.2' + kapt 'net.ltgt.gradle.incap:incap-processor:0.2' implementation("me.eugeniomarletti.kotlin.metadata:kotlin-metadata:1.4.0") } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index 0e58c6c..f6b0a8d 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -19,7 +19,6 @@ import javax.lang.model.SourceVersion import javax.lang.model.element.Element import javax.lang.model.element.TypeElement import javax.lang.model.util.Elements -import javax.lang.model.util.Types import javax.tools.Diagnostic.Kind.ERROR private const val UNIT = "kotlin.Unit" @@ -82,7 +81,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { return this.toString() .removePrefix("$elementPackage.") .removeSuffix("Source") - .plus("OmegaGeneratedRepository") + .plus("OmegaRepository") } private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { @@ -107,7 +106,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { } private fun TypeSpec.Builder.addFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { - val funcName = resolver.getName(function) + var funcName = resolver.getName(function) val parameterSpecs = generateParameters(resolver, function) val arguments = parameterSpecs.subList(1, parameterSpecs.size).joinToString { it.name } val isUnitFunction = function.isUnitFunction(resolver) @@ -121,7 +120,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { }.build() val modifiers: MutableList = mutableListOf(KModifier.OPEN) - if (isUnitFunction) modifiers.add(KModifier.SUSPEND) + if (isUnitFunction) modifiers.add(KModifier.SUSPEND) else funcName += "Channel" return addFunction( FunSpec.builder(funcName) diff --git a/settings.gradle b/settings.gradle index e114a06..1f56102 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':lib', ':processor', ':annotations' +include ':app', ':core', ':processor', ':annotations' From fd8f24f44188d2d4a4c61e7701d4c77d6e80ed3d Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 11 Dec 2019 11:45:57 +0300 Subject: [PATCH 21/54] Upgrade OmegaMoxy --- app/build.gradle | 3 +-- lib/build.gradle | 4 ++-- .../main/java/com/omega_r/base/components/OmegaActivity.kt | 7 +++++++ .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 1 - 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c426979..0484d79 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,9 +48,8 @@ dependencies { androidTestImplementation 'androidx.test:runner:1.2.0-beta01' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01' implementation project(':lib') - kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.7.0' + kapt 'com.github.Omega-R.OmegaMoxy:moxy-compiler:1.7.1' implementation 'com.github.bumptech.glide:glide:4.9.0' - } diff --git a/lib/build.gradle b/lib/build.gradle index b25c753..a303417 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -53,8 +53,8 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${kotlinCorutines_version}" implementation "org.jetbrains.kotlin:kotlin-android-extensions-runtime:${kotlin_version}" - api 'com.github.Omega-R.OmegaMoxy:moxy:1.7.0' - api 'com.github.Omega-R.OmegaMoxy:moxy-androidx:1.7.0' + api 'com.github.Omega-R.OmegaMoxy:moxy:1.7.1' + api 'com.github.Omega-R.OmegaMoxy:moxy-androidx:1.7.1' api "com.github.Omega-R:OmegaRecyclerView:${omegaRecyclerView}@aar" api 'com.github.Omega-R.OmegaTypes:glide:2.0.1' diff --git a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 7752f20..c5ba301 100644 --- a/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/lib/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -8,6 +8,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup +import android.widget.Button import androidx.annotation.* import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat @@ -289,6 +290,12 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { finish() } + protected fun bindAndSetClick(@IdRes res: Int, block: () -> Unit): Lazy { + return bind(res) { + setOnClickListener(this, block) + } + } + final override fun bind(init: () -> T) = super.bind(init) final override fun bind(vararg idsPair: Pair) = super.bind(*idsPair) diff --git a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 1883353..a1c2254 100644 --- a/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/lib/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -55,7 +55,6 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco is AppException.NotFound, is AppException.ServerProblem -> Text.from(R.string.error_server_problem) is AppException.AccessDenied -> Text.from(R.string.error_access_denied) - else -> { getUnknownErrorMessage() } From 732474329ad6274118462ad220039b939b24b0b6 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 11 Dec 2019 12:33:17 +0300 Subject: [PATCH 22/54] Fix review --- .gitignore | 2 + ...pository.kt => GenerateOmegaRepository.kt} | 2 +- .../com/omega_r/base/simple/MainSource.kt | 4 +- .../processor/OmegaRepositoryProcessor.kt | 56 ++++++++++--------- 4 files changed, 36 insertions(+), 28 deletions(-) rename annotations/src/main/java/com/omega_r/base/annotations/{OmegaRepository.kt => GenerateOmegaRepository.kt} (76%) diff --git a/.gitignore b/.gitignore index 2b75303..503d55c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ /build /captures .externalNativeBuild +lib/build/generated +lib/build diff --git a/annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt b/annotations/src/main/java/com/omega_r/base/annotations/GenerateOmegaRepository.kt similarity index 76% rename from annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt rename to annotations/src/main/java/com/omega_r/base/annotations/GenerateOmegaRepository.kt index 90b6800..5ec2118 100644 --- a/annotations/src/main/java/com/omega_r/base/annotations/OmegaRepository.kt +++ b/annotations/src/main/java/com/omega_r/base/annotations/GenerateOmegaRepository.kt @@ -2,4 +2,4 @@ package com.omega_r.base.annotations @Retention(AnnotationRetention.SOURCE) @Target(allowedTargets = [AnnotationTarget.CLASS]) -annotation class OmegaRepository \ No newline at end of file +annotation class GenerateOmegaRepository \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/MainSource.kt b/app/src/main/java/com/omega_r/base/simple/MainSource.kt index 32c8d18..18a3137 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainSource.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainSource.kt @@ -1,9 +1,9 @@ package com.omega_r.base.simple -import com.omega_r.base.annotations.OmegaRepository +import com.omega_r.base.annotations.GenerateOmegaRepository import com.omega_r.base.data.sources.Source -@OmegaRepository +@GenerateOmegaRepository interface MainSource : Source { val per: String diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index f6b0a8d..9dda07e 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -1,7 +1,7 @@ package com.omega_r.base.processor import com.google.auto.service.AutoService -import com.omega_r.base.annotations.OmegaRepository +import com.omega_r.base.annotations.GenerateOmegaRepository import com.squareup.kotlinpoet.* import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata @@ -27,10 +27,14 @@ private const val UNIT = "kotlin.Unit" @IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING) class OmegaRepositoryProcessor : AbstractProcessor() { - private val OMEGA_REPOSITORY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") - private val STRATEGY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") - private val STRATEGY_PARAMETER_SPEC = ParameterSpec("strategy", STRATEGY_CLASS_NAME) - private val CONSUME_EACH_MEMBER_NAME = MemberName("kotlinx.coroutines.channels", "consumeEach") + companion object { + private val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") + private val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") + private val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") + private val PARAMETER_SPEC_STRATEGY = ParameterSpec("strategy", CLASS_NAME_STRATEGY) + private val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") + + } private val messager: Messager get() = processingEnv.messager @@ -38,19 +42,18 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private val elements: Elements get() = processingEnv.elementUtils - override fun getSupportedAnnotationTypes() = setOf(OmegaRepository::class.java.canonicalName) + override fun getSupportedAnnotationTypes() = setOf(GenerateOmegaRepository::class.java.canonicalName) - override fun getSupportedSourceVersion() = SourceVersion.latest() + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest() override fun process(elements: Set, environment: RoundEnvironment): Boolean { - val repositoryElements = environment.getElementsAnnotatedWith(OmegaRepository::class.java) - repositoryElements.forEach { - generateRepository(it) - } + environment + .getElementsAnnotatedWith(GenerateOmegaRepository::class.java) + .forEach(::generateOmegaRepository) return true } - private fun generateRepository(element: Element) { + private fun generateOmegaRepository(element: Element) { val typeMetadata = element.kotlinMetadata if (element !is TypeElement || typeMetadata !is KotlinClassMetadata) { messager.printMessage(ERROR, "@AppOmegaRepository can't be applied to $element: must be a Kotlin interface") @@ -64,7 +67,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { } val elementPackage = elements.getPackageOf(element).toString() - val fileName = element.getFileName(elementPackage) + val fileName = element.getFileName() val typeSpec = TypeSpec.classBuilder(fileName) .addConstructor(element) @@ -77,32 +80,35 @@ class OmegaRepositoryProcessor : AbstractProcessor() { .writeTo(processingEnv.filer) } - private fun Element.getFileName(elementPackage: String): String { - return this.toString() - .removePrefix("$elementPackage.") - .removeSuffix("Source") - .plus("OmegaRepository") + private fun Element.getFileName(): String { + val sourcePrefix = simpleName + .toString() + .removeSuffix(CLASS_NAME_SOURCE.simpleName) + + val repositoryClassName = CLASS_NAME_OMEGA_REPOSITORY.simpleName + + return sourcePrefix + repositoryClassName } + private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { - val className = ClassName.bestGuess(element.toString()) - return superclass(OMEGA_REPOSITORY_CLASS_NAME.parameterizedBy(className)) + val sourceTypeName = element.asType().asTypeName() + return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(sourceTypeName)) .addModifiers(KModifier.OPEN) .addSuperclassConstructorParameter("*sources") .primaryConstructor( FunSpec.constructorBuilder() - .addParameter("sources", ClassName.bestGuess(element.toString()), KModifier.VARARG) + .addParameter("sources", sourceTypeName, KModifier.VARARG) .build() ) } - private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata): TypeSpec.Builder { + private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata) = apply { val nameResolver = kotlinMetadata.data.nameResolver val classData = kotlinMetadata.data.classProto classData.functionList.forEach { addFunction(nameResolver, it) } - return this } private fun TypeSpec.Builder.addFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { @@ -113,7 +119,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { val codeBlockBuilder = CodeBlock.builder().apply { if (isUnitFunction) { - addStatement("createChannel(strategy) { $funcName($arguments) }.%M{}", CONSUME_EACH_MEMBER_NAME) + addStatement("createChannel(strategy) { $funcName($arguments) }.%M{}", MEMBER_NAME_CONSUME_EACH) } else { add("return createChannel(strategy) { $funcName($arguments) }\n\n") } @@ -132,7 +138,7 @@ class OmegaRepositoryProcessor : AbstractProcessor() { } private fun generateParameters(resolver: NameResolver, function: Function): List { - val list = mutableListOf(STRATEGY_PARAMETER_SPEC) + val list = mutableListOf(PARAMETER_SPEC_STRATEGY) list += function.valueParameterList.map { parameter -> val name = resolver.getString(parameter.name) val className = ClassName.bestGuess(resolver.getString(parameter.type.className).formatType()) From 06998926fe6c94fe4a42ff6b97736930e9396538 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 11 Dec 2019 12:43:09 +0300 Subject: [PATCH 23/54] Remove unnecessary pagkage in OmegaWindowFlags --- core/src/main/java/com/omega_r/base/components/OmegaActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt index 6907699..c5ba301 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -47,7 +47,7 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { override fun getContext(): Context = this override fun onCreate(savedInstanceState: Bundle?) { - this::class.findAnnotation()?.let { + this::class.findAnnotation()?.let { window?.apply { addFlags(it.addFlags) clearFlags(it.clearFlags) From 7028c1bcee0b886f91af228007972529adec6790 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 11 Dec 2019 13:54:50 +0300 Subject: [PATCH 24/54] Fix processors and remove request method from OmegaPresenter --- build.gradle | 4 +- core/build.gradle | 4 +- .../com/omega_r/base/data/OmegaRepository.kt | 28 +++++----- .../base/mvp/presenters/OmegaPresenter.kt | 55 ------------------- .../processor/OmegaRepositoryProcessor.kt | 4 +- 5 files changed, 20 insertions(+), 75 deletions(-) diff --git a/build.gradle b/build.gradle index a30d680..4f1352b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ ext { omegaRecyclerView = '1.9.8' - kotlinCorutines_version = '1.2.1' + kotlinCorutines_version = '1.3.2' }// Top-level build file where you can add configuration options common to all sub-projects/modules. @@ -12,7 +12,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' } diff --git a/core/build.gradle b/core/build.gradle index b1ff437..7748101 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -46,8 +46,8 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' testImplementation 'junit:junit:4.13-beta-3' - androidTestImplementation 'androidx.test:runner:1.3.0-alpha02' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha02' + androidTestImplementation 'androidx.test:runner:1.3.0-alpha03' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha03' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinCorutines_version}" diff --git a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt index 132456f..df8ca53 100644 --- a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -41,31 +41,19 @@ open class OmegaRepository(vararg sources: SOURCE) { return result } - fun createChannel( - strategy: Strategy = CACHE_AND_REMOTE, - block: suspend SOURCE.() -> R - ): ReceiveChannel { + protected fun createChannel(strategy: Strategy, block: suspend SOURCE.() -> R): ReceiveChannel { return coroutineScope.produce { when (strategy) { + CACHE_AND_REMOTE -> applyCacheAndRemote(block) ONLY_REMOTE -> applyOnlyRemote(block) ONLY_CACHE -> applyOnlyCache(block) REMOTE_ELSE_CACHE -> applyRemoteElseCache(block) CACHE_ELSE_REMOTE -> applyCacheElseRemote(block) - CACHE_AND_REMOTE -> applyCacheAndRemote(block) - MEMORY_ELSE_CACHE_AND_REMOTE -> { - if (memoryCacheSource != null) { - ignoreException { - send(block(memoryCacheSource as SOURCE)) - return@produce - } - } - applyCacheAndRemote(block) - } + MEMORY_ELSE_CACHE_AND_REMOTE -> applyMemoryElseCacheAndRemote(block) } } } - private suspend fun ProducerScope.applyOnlyRemote(block: suspend SOURCE.() -> R) { var remoteException: Exception? = null @@ -271,6 +259,16 @@ open class OmegaRepository(vararg sources: SOURCE) { } + private suspend fun ProducerScope.applyMemoryElseCacheAndRemote(block: suspend SOURCE.() -> R) { + if (memoryCacheSource != null) { + ignoreException { + send(block(memoryCacheSource as SOURCE)) + return + } + } + applyCacheAndRemote(block) + } + fun clearCache() { memoryCacheSource?.clear() fileCacheSource?.clear() diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index a1c2254..1193e07 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -103,61 +103,6 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } } - protected fun ReceiveChannel.request( - waiting: Boolean = true, - errorHandler: ((Throwable) -> Boolean)? = null, - block: (suspend View.(R) -> Unit)? = null - ) { - if (waiting) viewState.setWaiting(true) - val channel = this - launch { - var hideWaiting = waiting - try { - for (item in channel) { - block?.invoke(viewState, item) - - if (hideWaiting) { - hideWaiting = false - viewState.setWaiting(false) - } - } - } catch (e: Throwable) { - val handle = errorHandler?.invoke(e) - if (handle != true) { - handleErrors(e) - } - } finally { - if (hideWaiting) { - viewState.setWaiting(false) - } - } - } - } - - protected fun OmegaRepository.request( - sourceBlock: suspend S.() -> R, - strategy: OmegaRepository.Strategy = OmegaRepository.Strategy.CACHE_AND_REMOTE, - waiting: Boolean = true, - errorHandler: ((Throwable) -> Boolean)? = null, - viewStateBlock: suspend View.(R) -> Unit - ) { - createChannel(strategy, sourceBlock).request( - waiting = waiting, - errorHandler = errorHandler, - block = viewStateBlock - ) - } - - protected fun OmegaRepository.request( - strategy: OmegaRepository.Strategy = OmegaRepository.Strategy.CACHE_AND_REMOTE, - waiting: Boolean = true, - errorHandler: ((Throwable) -> Boolean)? = null, - sourceBlock: suspend S.() -> Unit - ) { - createChannel(strategy, sourceBlock) - .request(waiting = waiting, errorHandler = errorHandler) - } - fun hideQueryOrMessage() = viewState.hideQueryOrMessage() protected open fun Launcher.launch() { diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index 9dda07e..8f38274 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -31,7 +31,9 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") private val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") private val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") - private val PARAMETER_SPEC_STRATEGY = ParameterSpec("strategy", CLASS_NAME_STRATEGY) + private val PARAMETER_SPEC_STRATEGY = ParameterSpec.builder("strategy", CLASS_NAME_STRATEGY) + .defaultValue("Strategy.CACHE_AND_REMOTE") + .build() private val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") } From c6b48b83fcf04b31dc878003f6a0dd0b2308c928 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Thu, 12 Dec 2019 17:57:05 +0300 Subject: [PATCH 25/54] Refactoring OmegaRepository --- .idea/dictionaries/antonknyazev.xml | 1 + .../com/omega_r/base/simple/TestRepository.kt | 3 +- .../com/omega_r/base/data/OmegaRepository.kt | 153 +++++++++++------- .../processor/OmegaRepositoryProcessor.kt | 14 +- 4 files changed, 108 insertions(+), 63 deletions(-) diff --git a/.idea/dictionaries/antonknyazev.xml b/.idea/dictionaries/antonknyazev.xml index 13fb0ca..cc29f73 100644 --- a/.idea/dictionaries/antonknyazev.xml +++ b/.idea/dictionaries/antonknyazev.xml @@ -2,6 +2,7 @@ knyazev + messager \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/TestRepository.kt b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt index debf6a9..20e49dd 100644 --- a/app/src/main/java/com/omega_r/base/simple/TestRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt @@ -1,9 +1,10 @@ package com.omega_r.base.simple import com.omega_r.base.data.OmegaRepository +import com.omega_r.base.errors.ErrorHandler import kotlinx.coroutines.channels.ReceiveChannel -class TestRepository(vararg sources: MainSource) : OmegaRepository() { +class TestRepository(errorHandler: ErrorHandler, vararg sources: MainSource) : OmegaRepository(errorHandler) { fun testMethodReturn(strategy: OmegaRepository.Strategy, kek: String): ReceiveChannel { return createChannel(strategy) { testMethodReturn(kek) } diff --git a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt index df8ca53..c04f5ef 100644 --- a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -4,6 +4,7 @@ import com.omega_r.base.data.OmegaRepository.Strategy.* import com.omega_r.base.data.sources.CacheSource import com.omega_r.base.data.sources.Source import com.omega_r.base.errors.AppException +import com.omega_r.base.errors.ErrorHandler import com.omega_r.base.errors.throwNoData import kotlinx.coroutines.* import kotlinx.coroutines.channels.ProducerScope @@ -15,7 +16,7 @@ import kotlinx.coroutines.channels.produce */ @Suppress("UNCHECKED_CAST") @UseExperimental(ExperimentalCoroutinesApi::class) -open class OmegaRepository(vararg sources: SOURCE) { +open class OmegaRepository(private val errorHandler: ErrorHandler, vararg sources: SOURCE) { private val job = SupervisorJob() @@ -43,13 +44,17 @@ open class OmegaRepository(vararg sources: SOURCE) { protected fun createChannel(strategy: Strategy, block: suspend SOURCE.() -> R): ReceiveChannel { return coroutineScope.produce { - when (strategy) { - CACHE_AND_REMOTE -> applyCacheAndRemote(block) - ONLY_REMOTE -> applyOnlyRemote(block) - ONLY_CACHE -> applyOnlyCache(block) - REMOTE_ELSE_CACHE -> applyRemoteElseCache(block) - CACHE_ELSE_REMOTE -> applyCacheElseRemote(block) - MEMORY_ELSE_CACHE_AND_REMOTE -> applyMemoryElseCacheAndRemote(block) + try { + when (strategy) { + CACHE_AND_REMOTE -> applyCacheAndRemote(block) + ONLY_REMOTE -> applyOnlyRemote(block) + ONLY_CACHE -> applyOnlyCache(block) + REMOTE_ELSE_CACHE -> applyRemoteElseCache(block) + CACHE_ELSE_REMOTE -> applyCacheElseRemote(block) + MEMORY_ELSE_CACHE_AND_REMOTE -> applyMemoryElseCacheAndRemote(block) + } + } catch (e: Throwable) { + throw errorHandler.handleThrowable(e) } } } @@ -58,7 +63,7 @@ open class OmegaRepository(vararg sources: SOURCE) { var remoteException: Exception? = null if (remoteSource != null) { - remoteException = ignoreException { + remoteException = getException { val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) @@ -67,10 +72,12 @@ open class OmegaRepository(vararg sources: SOURCE) { } } + if (defaultSource != null) { - ignoreException { + val cacheException: Exception? = getException { return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } + cacheException?.printStackTraceIfNeeded() } if (remoteException != null) { @@ -81,15 +88,18 @@ open class OmegaRepository(vararg sources: SOURCE) { } private suspend fun ProducerScope.applyOnlyCache(block: suspend SOURCE.() -> R) { + var cacheException: Exception? = null + if (memoryCacheSource != null) { - ignoreException { + cacheException = getException { send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { - ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) @@ -98,9 +108,11 @@ open class OmegaRepository(vararg sources: SOURCE) { } if (defaultSource != null) { - ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } + cacheException?.printStackTraceIfNeeded() } throwNoData("Cache sources is null") @@ -109,7 +121,7 @@ open class OmegaRepository(vararg sources: SOURCE) { private suspend fun ProducerScope.applyRemoteElseCache(block: suspend SOURCE.() -> R) { var remoteException: Exception? = null if (remoteSource != null) { - remoteException = ignoreException { + remoteException = getException { val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) @@ -121,14 +133,16 @@ open class OmegaRepository(vararg sources: SOURCE) { var cacheException: Exception? = null if (memoryCacheSource != null) { - cacheException = ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { - cacheException = ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) @@ -137,13 +151,15 @@ open class OmegaRepository(vararg sources: SOURCE) { } if (defaultSource != null) { - cacheException = ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } if (remoteSource == null) { cacheException?.let { throw it } } else { + cacheException?.printStackTraceIfNeeded() remoteException?.let { throw it } } } @@ -153,13 +169,14 @@ open class OmegaRepository(vararg sources: SOURCE) { var cacheException: Exception? = null if (memoryCacheSource != null) { - cacheException = ignoreException { + cacheException = getException { send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) return } } if (fileCacheSource != null) { - cacheException = ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) send(result) memoryCacheSource?.update(result) @@ -170,7 +187,7 @@ open class OmegaRepository(vararg sources: SOURCE) { var remoteException: Exception? = null if (remoteSource != null) { - remoteException = ignoreException { + remoteException = getException { val result = processResult(block(remoteSource), Source.Type.REMOTE) send(result) memoryCacheSource?.update(result) @@ -180,60 +197,71 @@ open class OmegaRepository(vararg sources: SOURCE) { } if (defaultSource != null) { - cacheException = ignoreException { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { return send(processResult(block(defaultSource), Source.Type.DEFAULT)) } } - if (remoteException != null) { - throw remoteException - } else if (cacheException != null) { - throw cacheException - } else { - throwNoData("Cache sources is null") + when { + remoteException != null -> { + cacheException?.printStackTraceIfNeeded() + throw remoteException + } + cacheException != null -> { + throw cacheException + } + else -> { + throwNoData("Cache sources is null") + } } } private suspend fun ProducerScope.applyCacheAndRemote(block: suspend SOURCE.() -> R) { - val cacheReturnDeferred = async { - var cacheException: Exception? = null - if (memoryCacheSource != null) { - cacheException = ignoreException { - val result = - processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) - - if (isActive && !isClosedForSend) { - send(result) + val cacheReturnDeferred = coroutineScope { + async { + var cacheException: Exception? = null + if (memoryCacheSource != null) { + cacheException = getException { + val result = + processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) + + if (isActive && !isClosedForSend) { + send(result) + } + return@async null } - return@async null } - } - if (fileCacheSource != null) { - cacheException = ignoreException { - val result = - processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) - if (isActive && !isClosedForSend) { - send(result) - memoryCacheSource?.update(result) + if (fileCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + val result = + processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + if (isActive && !isClosedForSend) { + send(result) + memoryCacheSource?.update(result) + } + return@async null } - return@async null } - } - if (defaultSource != null) { - cacheException = ignoreException { - if (isActive && !isClosedForSend) { - send(processResult(block(defaultSource), Source.Type.DEFAULT)) + + if (defaultSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + if (isActive && !isClosedForSend) { + send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + return@async null } - return@async null } - } - return@async cacheException + return@async cacheException + } } - val remoteException = if (remoteSource != null) { - ignoreException { + val remoteException = remoteSource?.let { + getException { val result = processResult(block(remoteSource), Source.Type.REMOTE) cacheReturnDeferred.cancel() send(result) @@ -242,8 +270,6 @@ open class OmegaRepository(vararg sources: SOURCE) { fileCacheSource?.update(result) return } - } else { - null } val cacheException = cacheReturnDeferred.await() @@ -253,6 +279,7 @@ open class OmegaRepository(vararg sources: SOURCE) { throw cacheException } } else { + cacheException?.printStackTraceIfNeeded() if (remoteException != null && (cacheException != null || remoteException !is AppException.NoData)) throw remoteException } @@ -261,7 +288,7 @@ open class OmegaRepository(vararg sources: SOURCE) { private suspend fun ProducerScope.applyMemoryElseCacheAndRemote(block: suspend SOURCE.() -> R) { if (memoryCacheSource != null) { - ignoreException { + getException { send(block(memoryCacheSource as SOURCE)) return } @@ -284,7 +311,7 @@ open class OmegaRepository(vararg sources: SOURCE) { } - private inline fun ignoreException(block: () -> Unit): Exception? { + private inline fun getException(block: () -> Unit): Exception? { return try { block() null @@ -293,4 +320,10 @@ open class OmegaRepository(vararg sources: SOURCE) { } } + private fun Exception.printStackTraceIfNeeded() { + if (this is AppException.NoData) { + printStackTrace() + } + } + } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index 8f38274..52c80a3 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -10,8 +10,11 @@ import me.eugeniomarletti.kotlin.metadata.kotlinMetadata import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver +import me.eugeniomarletti.kotlin.metadata.shadow.util.capitalizeDecapitalize.decapitalizeAsciiOnly +import me.eugeniomarletti.kotlin.metadata.shadow.util.capitalizeDecapitalize.decapitalizeSmart import net.ltgt.gradle.incap.IncrementalAnnotationProcessor import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType +import java.util.* import javax.annotation.processing.AbstractProcessor import javax.annotation.processing.Messager import javax.annotation.processing.RoundEnvironment @@ -28,6 +31,8 @@ private const val UNIT = "kotlin.Unit" class OmegaRepositoryProcessor : AbstractProcessor() { companion object { + private val CLASS_NAME_ERROR_HANDLER = ClassName.bestGuess("com.omega_r.base.errors.ErrorHandler") + private val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") private val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") private val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") @@ -94,13 +99,18 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { + val errorHandlerName = CLASS_NAME_ERROR_HANDLER.simpleName.decapitalizeAsciiOnly() + val sourcesName = element.simpleName.toString().decapitalizeAsciiOnly() + val sourceTypeName = element.asType().asTypeName() + return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(sourceTypeName)) .addModifiers(KModifier.OPEN) - .addSuperclassConstructorParameter("*sources") + .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") .primaryConstructor( FunSpec.constructorBuilder() - .addParameter("sources", sourceTypeName, KModifier.VARARG) + .addParameter(errorHandlerName, CLASS_NAME_ERROR_HANDLER) + .addParameter(sourcesName, sourceTypeName, KModifier.VARARG) .build() ) } From 990330a579411ad9280e6f48a3e1b892fe54e973 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Sat, 28 Dec 2019 13:06:59 +0300 Subject: [PATCH 26/54] Fix crash when throw exception in non main thread --- .../java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 1193e07..c71d324 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -30,7 +30,11 @@ private const val REQUEST_PERMISSION_BASE = 10000 open class OmegaPresenter : MvpPresenter(), CoroutineScope { - private val handler = CoroutineExceptionHandler { _, throwable -> handleErrors(throwable) } + private val handler = CoroutineExceptionHandler { _, throwable -> + this@OmegaPresenter.launch { + handleErrors(throwable) + } + } private val job = SupervisorJob() From 89839b588477502b2acbeafa19e76bcc55194eb5 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Mon, 13 Jan 2020 13:59:08 +0300 Subject: [PATCH 27/54] Source code generation added --- .../base/simple/InspectionRepository.kt | 47 ++++ .../com/omega_r/base/simple/MainSource.kt | 23 +- .../com/omega_r/base/simple/TestRepository.kt | 15 +- .../com/omega_r/base/processor/Constants.kt | 24 ++ .../processor/OmegaRepositoryProcessor.kt | 232 +++++++++++------- .../base/processor/OmegaSourceGenerator.kt | 146 +++++++++++ .../processor/extensions/ElementExtensions.kt | 22 ++ .../extensions/FunctionExtensions.kt | 13 + .../processor/extensions/ListExtensions.kt | 5 + .../extensions/NameResolverExtentions.kt | 5 + .../processor/extensions/StringExtensions.kt | 11 + .../processor/factories/RepositoryFactory.kt | 107 ++++++++ .../base/processor/factories/SourceFactory.kt | 49 ++++ .../omega_r/base/processor/models/Function.kt | 25 ++ .../base/processor/models/Parameter.kt | 12 + .../base/processor/models/Repository.kt | 43 ++++ .../omega_r/base/processor/models/Source.kt | 47 ++++ .../com/omega_r/base/processor/models/Type.kt | 14 ++ 18 files changed, 726 insertions(+), 114 deletions(-) create mode 100644 app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/Constants.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/OmegaSourceGenerator.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/extensions/FunctionExtensions.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/extensions/ListExtensions.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/extensions/NameResolverExtentions.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/extensions/StringExtensions.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/models/Function.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/models/Repository.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/models/Source.kt create mode 100644 processor/src/main/java/com/omega_r/base/processor/models/Type.kt diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt new file mode 100644 index 0000000..980cb38 --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -0,0 +1,47 @@ +package com.omega_r.base.simple + + +import com.omega_r.base.annotations.OmegaRepository +import com.omega_r.base.data.OmegaRepository.Strategy +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ReceiveChannel + +@OmegaRepository +interface InspectionRepository { + + fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel + + fun getInspections(strategy: Strategy, index: Int): String + +// fun getInspectionsPair(strategy: Strategy, index: Int): Channel> + + suspend fun getInspections(pair: Pair, second: Boolean) + + fun clear() + + fun pair(): Pair + + fun kek(): Int + +} + + +//interface InspectionSource: Source { +// +// suspend fun getInspections(index: Int): String +// +// suspend fun getInspections(): String +// +//} +// +//class OmegaInspectionRepository(errorHandler: ErrorHandler, vararg sources: InspectionSource) : OmegaRepository(errorHandler, *sources), InspectionRepository { +// +// override fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel { +// return createChannel(strategy) { getInspections(index) } +// } +// +// override suspend fun getInspections(): String { +// return createChannel(Strategy.REMOTE_ELSE_CACHE) { getInspections() }.receive() +// } +// +//} \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/MainSource.kt b/app/src/main/java/com/omega_r/base/simple/MainSource.kt index 32c8d18..7e3cf69 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainSource.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainSource.kt @@ -1,15 +1,12 @@ package com.omega_r.base.simple -import com.omega_r.base.annotations.OmegaRepository -import com.omega_r.base.data.sources.Source - -@OmegaRepository -interface MainSource : Source { - - val per: String - - fun testMethod() - - fun testMethodReturn(kek: String?): String - -} \ No newline at end of file +//@GenerateOmegaRepository +//interface MainSource : Source { +// +// val per: String +// +// fun testMethod() +// +// fun testMethodReturn(kek: String?): String +// +//} \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/TestRepository.kt b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt index debf6a9..fb15e30 100644 --- a/app/src/main/java/com/omega_r/base/simple/TestRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/TestRepository.kt @@ -1,12 +1,13 @@ package com.omega_r.base.simple import com.omega_r.base.data.OmegaRepository +import com.omega_r.base.errors.ErrorHandler import kotlinx.coroutines.channels.ReceiveChannel -class TestRepository(vararg sources: MainSource) : OmegaRepository() { - - fun testMethodReturn(strategy: OmegaRepository.Strategy, kek: String): ReceiveChannel { - return createChannel(strategy) { testMethodReturn(kek) } - } - -} \ No newline at end of file +//class TestRepository(errorHandler: ErrorHandler, vararg sources: MainSource) : OmegaRepository(errorHandler) { +// +// fun testMethodReturn(strategy: OmegaRepository.Strategy, kek: String): ReceiveChannel { +// return createChannel(strategy) { testMethodReturn(kek) } +// } +// +//} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/Constants.kt b/processor/src/main/java/com/omega_r/base/processor/Constants.kt new file mode 100644 index 0000000..4554a05 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/Constants.kt @@ -0,0 +1,24 @@ +package com.omega_r.base.processor + +import com.squareup.kotlinpoet.ClassName + +class Constants { + + companion object { + + internal const val UNIT = "kotlin.Unit" + internal val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") + internal val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") + + internal val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") + + internal val UNIT_CLASS_NAME = ClassName.bestGuess(UNIT) + internal val CHANNEL_CLASS_NAME = ClassName.bestGuess("kotlinx.coroutines.channels.Channel") + internal val SEND_CHANNEL_CLASS_NAME = ClassName.bestGuess("kotlinx.coroutines.channels.SendChannel") + internal val RECEIVE_CHANNEL_CLASS_NAME = ClassName.bestGuess("kotlinx.coroutines.channels.ReceiveChannel") + + internal val CLASS_NAME_ERROR_HANDLER = ClassName.bestGuess("com.omega_r.base.errors.ErrorHandler") + + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt index f6b0a8d..78008f6 100644 --- a/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaRepositoryProcessor.kt @@ -2,18 +2,20 @@ package com.omega_r.base.processor import com.google.auto.service.AutoService import com.omega_r.base.annotations.OmegaRepository -import com.squareup.kotlinpoet.* -import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.omega_r.base.processor.factories.RepositoryFactory +import com.omega_r.base.processor.factories.SourceFactory +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.MemberName +import com.squareup.kotlinpoet.ParameterSpec import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata import me.eugeniomarletti.kotlin.metadata.classKind import me.eugeniomarletti.kotlin.metadata.kotlinMetadata import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf -import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function -import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver import net.ltgt.gradle.incap.IncrementalAnnotationProcessor import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType import javax.annotation.processing.AbstractProcessor import javax.annotation.processing.Messager +import javax.annotation.processing.ProcessingEnvironment import javax.annotation.processing.RoundEnvironment import javax.lang.model.SourceVersion import javax.lang.model.element.Element @@ -27,10 +29,18 @@ private const val UNIT = "kotlin.Unit" @IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.AGGREGATING) class OmegaRepositoryProcessor : AbstractProcessor() { - private val OMEGA_REPOSITORY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") - private val STRATEGY_CLASS_NAME = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") - private val STRATEGY_PARAMETER_SPEC = ParameterSpec("strategy", STRATEGY_CLASS_NAME) - private val CONSUME_EACH_MEMBER_NAME = MemberName("kotlinx.coroutines.channels", "consumeEach") + companion object { + private val CLASS_NAME_ERROR_HANDLER = ClassName.bestGuess("com.omega_r.base.errors.ErrorHandler") + + private val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") + private val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") + private val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") + private val PARAMETER_SPEC_STRATEGY = ParameterSpec.builder("strategy", CLASS_NAME_STRATEGY) + .defaultValue("Strategy.CACHE_AND_REMOTE") + .build() + private val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") + + } private val messager: Messager get() = processingEnv.messager @@ -38,19 +48,44 @@ class OmegaRepositoryProcessor : AbstractProcessor() { private val elements: Elements get() = processingEnv.elementUtils + private lateinit var sourceGenerator: OmegaSourceGenerator + + private lateinit var repositoryFactory: RepositoryFactory + private val sourceFactory: SourceFactory = SourceFactory() + + override fun init(environment: ProcessingEnvironment?) { + super.init(environment) + repositoryFactory = RepositoryFactory(messager, elements) + } + override fun getSupportedAnnotationTypes() = setOf(OmegaRepository::class.java.canonicalName) - override fun getSupportedSourceVersion() = SourceVersion.latest() + override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest() override fun process(elements: Set, environment: RoundEnvironment): Boolean { - val repositoryElements = environment.getElementsAnnotatedWith(OmegaRepository::class.java) - repositoryElements.forEach { - generateRepository(it) - } + sourceGenerator = OmegaSourceGenerator(processingEnv.filer, messager, this@OmegaRepositoryProcessor.elements) + +// val repositoryFactory = RepositoryFactory( +// messager, +// this@OmegaRepositoryProcessor.elements +// ) + + repositoryFactory.create(environment.getElementsAnnotatedWith(OmegaRepository::class.java)) + .forEach { repository -> + val source = sourceFactory.create(repository) + + source.toFileSpec() + .writeTo(processingEnv.filer) + + repository.toFileSpec(source) + .writeTo(processingEnv.filer) + + + } return true } - private fun generateRepository(element: Element) { + private fun generateOmegaRepository(element: Element) { val typeMetadata = element.kotlinMetadata if (element !is TypeElement || typeMetadata !is KotlinClassMetadata) { messager.printMessage(ERROR, "@AppOmegaRepository can't be applied to $element: must be a Kotlin interface") @@ -63,90 +98,99 @@ class OmegaRepositoryProcessor : AbstractProcessor() { return } - val elementPackage = elements.getPackageOf(element).toString() - val fileName = element.getFileName(elementPackage) +// sourceGenerator.generateSource(element) - val typeSpec = TypeSpec.classBuilder(fileName) - .addConstructor(element) - .addFunctions(typeMetadata) - .build() +// val elementPackage = elements.getPackageOf(element).toString() +// val fileName = element.getFileName() - FileSpec.builder(elementPackage, fileName) - .addType(typeSpec) - .build() - .writeTo(processingEnv.filer) - } - - private fun Element.getFileName(elementPackage: String): String { - return this.toString() - .removePrefix("$elementPackage.") - .removeSuffix("Source") - .plus("OmegaRepository") - } - - private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { - val className = ClassName.bestGuess(element.toString()) - return superclass(OMEGA_REPOSITORY_CLASS_NAME.parameterizedBy(className)) - .addModifiers(KModifier.OPEN) - .addSuperclassConstructorParameter("*sources") - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("sources", ClassName.bestGuess(element.toString()), KModifier.VARARG) - .build() - ) - } - - private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata): TypeSpec.Builder { - val nameResolver = kotlinMetadata.data.nameResolver - val classData = kotlinMetadata.data.classProto - classData.functionList.forEach { - addFunction(nameResolver, it) - } - return this - } - - private fun TypeSpec.Builder.addFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { - var funcName = resolver.getName(function) - val parameterSpecs = generateParameters(resolver, function) - val arguments = parameterSpecs.subList(1, parameterSpecs.size).joinToString { it.name } - val isUnitFunction = function.isUnitFunction(resolver) - - val codeBlockBuilder = CodeBlock.builder().apply { - if (isUnitFunction) { - addStatement("createChannel(strategy) { $funcName($arguments) }.%M{}", CONSUME_EACH_MEMBER_NAME) - } else { - add("return createChannel(strategy) { $funcName($arguments) }\n\n") - } - }.build() - - val modifiers: MutableList = mutableListOf(KModifier.OPEN) - if (isUnitFunction) modifiers.add(KModifier.SUSPEND) else funcName += "Channel" - - return addFunction( - FunSpec.builder(funcName) - .addModifiers(modifiers) - .addParameters(parameterSpecs) - .addCode(codeBlockBuilder) - .build() - ) - } +// val typeSpec = TypeSpec.classBuilder(fileName) +// .addConstructor(element) +// .addFunctions(typeMetadata) +// .build() - private fun generateParameters(resolver: NameResolver, function: Function): List { - val list = mutableListOf(STRATEGY_PARAMETER_SPEC) - list += function.valueParameterList.map { parameter -> - val name = resolver.getString(parameter.name) - val className = ClassName.bestGuess(resolver.getString(parameter.type.className).formatType()) - ParameterSpec(name, className.copy(nullable = parameter.type.nullable)) - - } - return list +// FileSpec.builder(elementPackage, fileName) +// .addType(typeSpec) +// .build() +// .writeTo(processingEnv.filer) } - private fun Function.isUnitFunction(resolver: NameResolver) = - resolver.getString(returnType.className).formatType() == UNIT - - private fun NameResolver.getName(function: Function): String = getString(function.name) - - private fun String.formatType(): String = replace("/", ".") +// private fun Element.getFileName(): String { +// val sourcePrefix = simpleName +// .toString() +// .removeSuffix(CLASS_NAME_SOURCE.simpleName) +// +// val repositoryClassName = CLASS_NAME_OMEGA_REPOSITORY.simpleName +// +// return sourcePrefix + repositoryClassName +// } + + +// private fun TypeSpec.Builder.addConstructor(element: Element): TypeSpec.Builder { +// val errorHandlerName = CLASS_NAME_ERROR_HANDLER.simpleName.decapitalizeAsciiOnly() +// val sourcesName = element.simpleName.toString().decapitalizeAsciiOnly() +// +// val sourceTypeName = element.asType().asTypeName() +// +// return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(sourceTypeName)) +// .addModifiers(KModifier.OPEN) +// .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") +// .primaryConstructor( +// FunSpec.constructorBuilder() +// .addParameter(errorHandlerName, CLASS_NAME_ERROR_HANDLER) +// .addParameter(sourcesName, sourceTypeName, KModifier.VARARG) +// .build() +// ) +// } + +// private fun TypeSpec.Builder.addFunctions(kotlinMetadata: KotlinClassMetadata) = apply { +// val nameResolver = kotlinMetadata.data.nameResolver +// val classData = kotlinMetadata.data.classProto +// classData.functionList.forEach { +// addFunction(nameResolver, it) +// } +// } + +// private fun TypeSpec.Builder.addFunction(resolver: NameResolver, function: Function): TypeSpec.Builder { +// var funcName = resolver.getName(function) +// val parameterSpecs = generateParameters(resolver, function) +// val arguments = parameterSpecs.subList(1, parameterSpecs.size).joinToString { it.name } +// val isUnitFunction = function.isUnitFunction(resolver) +// +// val codeBlockBuilder = CodeBlock.builder().apply { +// if (isUnitFunction) { +// addStatement("createChannel(strategy) { $funcName($arguments) }.%M{}", MEMBER_NAME_CONSUME_EACH) +// } else { +// add("return createChannel(strategy) { $funcName($arguments) }\n\n") +// } +// }.build() +// +// val modifiers: MutableList = mutableListOf(KModifier.OPEN) +// if (isUnitFunction) modifiers.add(KModifier.SUSPEND) else funcName += "Channel" +// +// return addFunction( +// FunSpec.builder(funcName) +// .addModifiers(modifiers) +// .addParameters(parameterSpecs) +// .addCode(codeBlockBuilder) +// .build() +// ) +// } + +// private fun generateParameters(resolver: NameResolver, function: Function): List { +// val list = mutableListOf(PARAMETER_SPEC_STRATEGY) +// list += function.valueParameterList.map { parameter -> +// val name = resolver.getString(parameter.name) +// val className = ClassName.bestGuess(resolver.getString(parameter.type.className).formatType()) +// ParameterSpec(name, className.copy(nullable = parameter.type.nullable)) +// } +// return list +// } +// +// private fun Function.isUnitFunction(resolver: NameResolver) = +// resolver.getString(returnType.className).formatType() == UNIT +// +// private fun NameResolver.getName(function: Function): String = getString(function.name) +// +// private fun String.formatType(): String = replace("/", ".") } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/OmegaSourceGenerator.kt b/processor/src/main/java/com/omega_r/base/processor/OmegaSourceGenerator.kt new file mode 100644 index 0000000..bebcc02 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/OmegaSourceGenerator.kt @@ -0,0 +1,146 @@ +package com.omega_r.base.processor + +import com.omega_r.base.processor.Constants.Companion.CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_STRATEGY +import com.omega_r.base.processor.Constants.Companion.SEND_CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.UNIT_CLASS_NAME +import com.omega_r.base.processor.extensions.formatType +import com.omega_r.base.processor.extensions.getName +import com.omega_r.base.processor.extensions.isUnitFunction +import com.omega_r.base.processor.extensions.sourceName +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata +import me.eugeniomarletti.kotlin.metadata.isSuspend +import me.eugeniomarletti.kotlin.metadata.kotlinMetadata +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver +import me.eugeniomarletti.kotlin.metadata.shadow.serialization.deserialization.getName +import javax.annotation.processing.Filer +import javax.annotation.processing.Messager +import javax.lang.model.element.Element +import javax.lang.model.util.Elements +import javax.tools.Diagnostic + +private const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" + +internal class OmegaSourceGenerator( + private val filer: Filer, + private val messager: Messager, + private val elements: Elements +) { + + fun generateSource(element: Element) { + val elementPackage = elements.getPackageOf(element).toString() + val sourceName = element.sourceName + + val typeSpec = TypeSpec.interfaceBuilder(sourceName) + .addSuperinterface(Constants.CLASS_NAME_SOURCE) + .addFunctions(element.generateFunctions()) + .build() + + FileSpec.builder(elementPackage, element.sourceName) + .addType(typeSpec) + .build() + .writeTo(filer) + } + + private fun Element.generateFunctions(): List { + val kotlinMetadata = kotlinMetadata as KotlinClassMetadata + + val classData = kotlinMetadata.data.classProto + val nameResolver = kotlinMetadata.data.nameResolver + + return classData.functionList.map { function -> +// function.toFunSpec(nameResolver) + val functionName = nameResolver.getName(function) + val functionBuilder = FunSpec.builder(functionName) + .addParameters(function.generateParameters(nameResolver)) + + if (function.isSuspend) functionBuilder.addModifiers(KModifier.SUSPEND) + + val codeBlock = CodeBlock.builder() + if (function.isUnitFunction(nameResolver)) { + codeBlock.addStatement("com.omega_r.base.errors.throwNoData()") + } else { + val returnType = function.returnType + val list = returnType.argumentList + + + + val returnName = nameResolver.getString(returnType.className).formatType() + val returnClassName = ClassName.bestGuess(returnName) + + + if (list.isEmpty()) { + functionBuilder.returns(returnClassName) + codeBlock.addStatement("return com.omega_r.base.errors.throwNoData()") + } else { + + + val map = list.map { + ClassName.bestGuess(nameResolver.getName(it.type.className).toString().formatType()) + } + + val parameterizedTypeName = returnClassName.parameterizedBy(map) + functionBuilder.returns(parameterizedTypeName) + codeBlock.addStatement("return com.omega_r.base.errors.throwNoData()") + } + + returnType.argumentList.forEach { argument -> + val argumentType = nameResolver.getName(argument.type.className) + messager.printMessage(Diagnostic.Kind.WARNING, "argumentType $argumentType") + } + + } + + functionBuilder + .addCode(codeBlock.build()) + .build() + } + } + + private fun Function.toFunSpec(element: Element, nameResolver: NameResolver): FunSpec { + val functionName = nameResolver.getName(this) + + val builder = FunSpec.builder(functionName) + .addParameters(generateParameters(nameResolver)) + .addSuspendIfNeeded(this) + + val codeBlockBuilder = CodeBlock.builder() + when(returnType.getClassName(nameResolver)) { + UNIT_CLASS_NAME -> codeBlockBuilder.addStatement(THROW_NO_DATA) + CHANNEL_CLASS_NAME, SEND_CHANNEL_CLASS_NAME -> { + messager.printMessage(Diagnostic.Kind.ERROR, "${element.simpleName} contains function " + + "$functionName with forbidden return type $returnType") + } + else -> { + + } + } + + return builder + .addCode(codeBlockBuilder.build()) + .build() + } + + private fun ProtoBuf.Type.getClassName(nameResolver: NameResolver): ClassName = + ClassName.bestGuess(nameResolver.getString(className).formatType()) + + private fun Function.generateParameters(nameResolver: NameResolver): List { + return valueParameterList.mapNotNull { parameter -> + val name = nameResolver.getString(parameter.name) + val className = ClassName.bestGuess(nameResolver.getString(parameter.type.className).formatType()) + + if (className == CLASS_NAME_STRATEGY) return@mapNotNull null + ParameterSpec(name, className.copy(nullable = parameter.type.nullable)) + } + } + + private fun FunSpec.Builder.addSuspendIfNeeded(function: Function): FunSpec.Builder { + if (function.isSuspend) addModifiers(KModifier.SUSPEND) + return this + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt new file mode 100644 index 0000000..83a8184 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt @@ -0,0 +1,22 @@ +package com.omega_r.base.processor.extensions + +import com.omega_r.base.processor.Constants +import javax.lang.model.element.Element +import javax.lang.model.util.Elements + +val Element.pureName: String + get() { + return simpleName + .toString() + .removeSuffix(Constants.CLASS_NAME_SOURCE.simpleName) + .removeSuffix(Constants.CLASS_NAME_OMEGA_REPOSITORY.simpleName) + .removeSuffix("Repository") + } + +val Element.sourceName: String + get() = pureName + Constants.CLASS_NAME_SOURCE.simpleName + +val Element.repositoryName: String + get() = pureName + Constants.CLASS_NAME_OMEGA_REPOSITORY.simpleName + +fun Elements.packageOf(element: Element) = getPackageOf(element).toString() \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/FunctionExtensions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/FunctionExtensions.kt new file mode 100644 index 0000000..7158d2d --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/FunctionExtensions.kt @@ -0,0 +1,13 @@ +package com.omega_r.base.processor.extensions + + +import com.omega_r.base.processor.Constants.Companion.UNIT +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Function +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver + +fun NameResolver.getName(function: Function): String = getString(function.name) + +fun Function.isUnitFunction(resolver: NameResolver) = + resolver.getString(returnType.className).formatType() == UNIT + +fun String.formatType(): String = replace("/", ".") \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/ListExtensions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/ListExtensions.kt new file mode 100644 index 0000000..fccde27 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/ListExtensions.kt @@ -0,0 +1,5 @@ +package com.omega_r.base.processor.extensions + +fun Collection.toLinkedHashSet(): LinkedHashSet { + return if (this is LinkedHashSet) this else LinkedHashSet(this) +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/NameResolverExtentions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/NameResolverExtentions.kt new file mode 100644 index 0000000..df8e42e --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/NameResolverExtentions.kt @@ -0,0 +1,5 @@ +package com.omega_r.base.processor.extensions + +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver + +fun NameResolver.getClassName(index: Int): String = getString(index).formatType() \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/StringExtensions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/StringExtensions.kt new file mode 100644 index 0000000..b9463a7 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/StringExtensions.kt @@ -0,0 +1,11 @@ +package com.omega_r.base.processor.extensions + +import com.omega_r.base.processor.Constants.Companion.CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.RECEIVE_CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.SEND_CHANNEL_CLASS_NAME + +fun String.removeChannelSuffix(): String { + return removeSuffix(SEND_CHANNEL_CLASS_NAME.simpleName) + .removeSuffix(RECEIVE_CHANNEL_CLASS_NAME.simpleName) + .removeSuffix(CHANNEL_CLASS_NAME.simpleName) +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt new file mode 100644 index 0000000..fe1913f --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt @@ -0,0 +1,107 @@ +package com.omega_r.base.processor.factories + +import com.omega_r.base.processor.Constants.Companion.CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.SEND_CHANNEL_CLASS_NAME +import com.omega_r.base.processor.Constants.Companion.UNIT_CLASS_NAME +import com.omega_r.base.processor.extensions.* +import com.omega_r.base.processor.models.Function +import com.omega_r.base.processor.models.Parameter +import com.omega_r.base.processor.models.Repository +import com.omega_r.base.processor.models.Type +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.KModifier +import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata +import me.eugeniomarletti.kotlin.metadata.classKind +import me.eugeniomarletti.kotlin.metadata.isSuspend +import me.eugeniomarletti.kotlin.metadata.kotlinMetadata +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Class.Kind.INTERFACE +import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver +import javax.annotation.processing.Messager +import javax.lang.model.element.Element +import javax.lang.model.element.TypeElement +import javax.lang.model.util.Elements +import javax.tools.Diagnostic.Kind.ERROR + +class RepositoryFactory(private val messager: Messager, private val elements: Elements) { + + fun create(elements: Set): List = elements.mapNotNull { create(it) } + + fun create(element: Element): Repository? { + val kotlinMetadata = element.kotlinMetadata + + if (element !is TypeElement || kotlinMetadata !is KotlinClassMetadata) { + messager.printMessage(ERROR, "@OmegaRepository can't be applied to $element: must be a Kotlin interface") + return null + } + + val proto = kotlinMetadata.data.classProto + if (proto.classKind != INTERFACE) { + messager.printMessage(ERROR, "@OmegaRepository can't be applied to $element: must be a Kotlin interface") + return null + } + + val repositoryPackage = elements.packageOf(element) + val repositoryName = element.repositoryName + + val classProto = kotlinMetadata.data.classProto + val nameResolver = kotlinMetadata.data.nameResolver + val functions = classProto.functionList.mapNotNull { + it.toFunction(element, nameResolver) + } + + return Repository(repositoryPackage, repositoryName, functions) + } + + private fun ProtoBuf.Function.toFunction(element: Element, nameResolver: NameResolver): Function? { + val functionName = nameResolver.getName(this) + val parameters = valueParameterList.map { + it.toParameter(nameResolver) + }.toLinkedHashSet() + val modifiers = if (isSuspend) listOf(KModifier.SUSPEND) else emptyList() + + when (returnType.getClassName(nameResolver)) { + CHANNEL_CLASS_NAME, SEND_CHANNEL_CLASS_NAME -> { + messager.printMessage( + ERROR, "${element.simpleName} contains function $functionName with forbidden return type $returnType" + ) + return null + } + } + val returnType = getReturnType(nameResolver) + + return Function(functionName, parameters, modifiers.toLinkedHashSet(), returnType) + } + + private fun ProtoBuf.ValueParameter.toParameter(nameResolver: NameResolver): Parameter { + val parameterName = nameResolver.getString(name) + val className = ClassName.bestGuess(nameResolver.getClassName(type.className)) + val parameterizedBy = getParameterTypes(type, nameResolver) + + return Parameter(parameterName, Type(className, parameterizedBy)) + } + + private fun ProtoBuf.Type.getClassName(nameResolver: NameResolver): ClassName = + ClassName.bestGuess(nameResolver.getClassName(className)) + + private fun getParameterTypes(type: ProtoBuf.Type, nameResolver: NameResolver): List { + val arguments = type.argumentList + + return if (arguments.isEmpty()) { + emptyList() + } else { + arguments.flatMap { + val list = getParameterTypes(it.type, nameResolver) + if (list.isEmpty()) listOf(Type(it.type.getClassName(nameResolver), emptyList())) else list + } + } + } + + private fun ProtoBuf.Function.getReturnType(nameResolver: NameResolver): Type? { + return when (val className = returnType.getClassName(nameResolver)) { + UNIT_CLASS_NAME -> null + else -> Type(className, getParameterTypes(returnType, nameResolver)) + } + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt new file mode 100644 index 0000000..9431eff --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt @@ -0,0 +1,49 @@ +package com.omega_r.base.processor.factories + +import com.omega_r.base.processor.Constants +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_OMEGA_REPOSITORY +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_SOURCE +import com.omega_r.base.processor.Constants.Companion.RECEIVE_CHANNEL_CLASS_NAME +import com.omega_r.base.processor.extensions.removeChannelSuffix +import com.omega_r.base.processor.extensions.toLinkedHashSet +import com.omega_r.base.processor.models.* +import com.omega_r.base.processor.models.Function + +class SourceFactory { + + fun create(repository: Repository): Source { + val sourcePackage = repository.repositoryPackage + val sourceName = repository.name.removeSuffix(CLASS_NAME_OMEGA_REPOSITORY.simpleName) + .plus(CLASS_NAME_SOURCE.simpleName) + val functions = repository.functions.filterFunctions() + + return Source(sourcePackage, sourceName, functions) + } + + private fun List.filterFunctions(): List { + return map { function -> + Function( + function.name.removeChannelSuffix(), + function.parameters.filterArguments(), + function.modifiers, + function.returnType.replaceReceiveChannel() + ) + } + .toLinkedHashSet() // Remove duplicate functions, after removing channel + .toList() + } + + private fun Set.filterArguments(): Set { + return filter { parameter -> + parameter.type.className != Constants.CLASS_NAME_STRATEGY + }.toLinkedHashSet() + } + + private fun Type?.replaceReceiveChannel(): Type? { + return when (this?.className) { + RECEIVE_CHANNEL_CLASS_NAME -> parameterizedBy.firstOrNull() + else -> this + } + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Function.kt b/processor/src/main/java/com/omega_r/base/processor/models/Function.kt new file mode 100644 index 0000000..771dbc8 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/models/Function.kt @@ -0,0 +1,25 @@ +package com.omega_r.base.processor.models + +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier + +data class Function ( + val name: String, + val parameters: Set, + val modifiers: Set, + val returnType: Type? = null +) { + + fun toFunSpec(): FunSpec { + val builder = FunSpec.builder(name) + .addParameters(parameters.map { it.toParameterSpec() }) + .addModifiers(modifiers) + + returnType?.let { + builder.returns(it.typeName) + } + + return builder.build() + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt new file mode 100644 index 0000000..4677b10 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt @@ -0,0 +1,12 @@ +package com.omega_r.base.processor.models + +import com.squareup.kotlinpoet.ParameterSpec + +data class Parameter( + val name: String, + val type: Type +) { + + fun toParameterSpec(): ParameterSpec = ParameterSpec(name, type.typeName) + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt new file mode 100644 index 0000000..5d03eff --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt @@ -0,0 +1,43 @@ +package com.omega_r.base.processor.models + +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_ERROR_HANDLER +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_OMEGA_REPOSITORY +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.TypeSpec +import me.eugeniomarletti.kotlin.metadata.shadow.util.capitalizeDecapitalize.decapitalizeAsciiOnly +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy + +class Repository( + val repositoryPackage: String, + val name: String, + val functions: List +) { + + fun toFileSpec(source: Source): FileSpec { + val typeSpec = TypeSpec.classBuilder(name) + .addConstructor(source) + .build() + + return FileSpec.builder(repositoryPackage, name) + .addType(typeSpec) + .build() + } + + private fun TypeSpec.Builder.addConstructor(source: Source): TypeSpec.Builder { + val errorHandlerName = CLASS_NAME_ERROR_HANDLER.simpleName.decapitalizeAsciiOnly() + val sourcesName = source.name.decapitalizeAsciiOnly() + + return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(source.className)) + .addModifiers(KModifier.OPEN) + .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") + .primaryConstructor( + FunSpec.constructorBuilder() + .addParameter(errorHandlerName, CLASS_NAME_ERROR_HANDLER) + .addParameter(sourcesName, source.className, KModifier.VARARG) + .build() + ) + } + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt new file mode 100644 index 0000000..2277056 --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt @@ -0,0 +1,47 @@ +package com.omega_r.base.processor.models + +import com.omega_r.base.processor.Constants +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.TypeSpec + +private const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" + +class Source( + val sourcePackage: String, + val name: String, + val functions: List +) { + + val className: ClassName = ClassName.bestGuess("$sourcePackage.$name") + + fun toFileSpec(): FileSpec { + val funcSpecs = functions.map { function -> + val codeBlock = CodeBlock.builder() + + codeBlock.addStatement( + when (function.returnType?.className) { + null, Constants.UNIT_CLASS_NAME -> THROW_NO_DATA + else -> "return $THROW_NO_DATA" + } + ) + + function.toFunSpec() + .toBuilder() + .addCode(codeBlock.build()) + .build() + } + + val typeSpec = TypeSpec.interfaceBuilder(name) + .addSuperinterface(Constants.CLASS_NAME_SOURCE) + .addFunctions(funcSpecs) + .build() + + return FileSpec.builder(sourcePackage, name) + .addType(typeSpec) + .build() + } + +} + diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Type.kt b/processor/src/main/java/com/omega_r/base/processor/models/Type.kt new file mode 100644 index 0000000..42b836c --- /dev/null +++ b/processor/src/main/java/com/omega_r/base/processor/models/Type.kt @@ -0,0 +1,14 @@ +package com.omega_r.base.processor.models + +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.TypeName +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy + +data class Type( + val className: ClassName, + val parameterizedBy: List +) { + + val typeName: TypeName = if (parameterizedBy.isEmpty()) className else className.parameterizedBy(parameterizedBy.map { it.typeName }) + +} \ No newline at end of file From 6622e95f01fbebb2c256f109934572d9b54171b0 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Tue, 14 Jan 2020 10:58:34 +0300 Subject: [PATCH 28/54] Properties for repository added. Nullable but fixed --- .../base/simple/InspectionRepository.kt | 38 ++++--------------- .../processor/factories/RepositoryFactory.kt | 28 +++++++++++--- .../base/processor/factories/SourceFactory.kt | 2 +- .../base/processor/models/Parameter.kt | 3 ++ .../base/processor/models/Repository.kt | 3 +- .../omega_r/base/processor/models/Source.kt | 2 + .../com/omega_r/base/processor/models/Type.kt | 14 +++++-- 7 files changed, 49 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index 2b178fc..a6c33bf 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -8,39 +8,17 @@ import kotlinx.coroutines.channels.ReceiveChannel @AppOmegaRepository interface InspectionRepository { + val isAuth: Boolean? + var age: Int + suspend fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel suspend fun getInspections(strategy: Strategy, index: Int): String -// fun getInspectionsPair(strategy: Strategy, index: Int): Channel> - suspend fun getInspections(pair: Pair, second: Boolean) - suspend fun pair(): Pair - - suspend fun kek(): Int - - fun kek2(): Int - -} - - -//interface InspectionSource: Source { -// -// suspend fun getInspections(index: Int): String -// -// suspend fun getInspections(): String -// -//} -// -//class OmegaInspectionRepository(errorHandler: ErrorHandler, vararg sources: InspectionSource) : OmegaRepository(errorHandler, *sources), InspectionRepository { -// -// override fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel { -// return createChannel(strategy) { getInspections(index) } -// } -// -// override suspend fun getInspections(): String { -// return createChannel(Strategy.REMOTE_ELSE_CACHE) { getInspections() }.receive() -// } -// -//} \ No newline at end of file + suspend fun pair(): Pair? + + suspend fun returnInt(): Int? + +} \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt index 704e290..2f3f96d 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt @@ -46,12 +46,24 @@ class RepositoryFactory(private val messager: Messager, private val elements: El val classProto = kotlinMetadata.data.classProto val nameResolver = kotlinMetadata.data.nameResolver + val superInterfaceClassName = ClassName.bestGuess("${elements.packageOf(element)}.${element.simpleName}") + + val properties = classProto.propertyList.map { property -> + property.toParameter(nameResolver) + } val functions = classProto.functionList.mapNotNull { it.toFunction(element, nameResolver) } - val superInterfaceClassName = ClassName.bestGuess("${elements.packageOf(element)}.${element.simpleName}") - return Repository(repositoryPackage, repositoryName, superInterfaceClassName, functions) + return Repository(repositoryPackage, repositoryName, superInterfaceClassName, properties, functions) + } + + private fun ProtoBuf.Property.toParameter(nameResolver: NameResolver): Parameter { + val parameterName = nameResolver.getString(name) + val className = returnType.getClassName(nameResolver) + val parameterizedBy = getParameterTypes(returnType, nameResolver) + + return Parameter(parameterName, Type(className, parameterizedBy, returnType.nullable)) } private fun ProtoBuf.Function.toFunction(element: Element, nameResolver: NameResolver): Function? { @@ -76,10 +88,10 @@ class RepositoryFactory(private val messager: Messager, private val elements: El private fun ProtoBuf.ValueParameter.toParameter(nameResolver: NameResolver): Parameter { val parameterName = nameResolver.getString(name) - val className = ClassName.bestGuess(nameResolver.getClassName(type.className)) + val className = type.getClassName(nameResolver) val parameterizedBy = getParameterTypes(type, nameResolver) - return Parameter(parameterName, Type(className, parameterizedBy)) + return Parameter(parameterName, Type(className, parameterizedBy, type.nullable)) } private fun ProtoBuf.Type.getClassName(nameResolver: NameResolver): ClassName = @@ -93,7 +105,11 @@ class RepositoryFactory(private val messager: Messager, private val elements: El } else { arguments.flatMap { val list = getParameterTypes(it.type, nameResolver) - if (list.isEmpty()) listOf(Type(it.type.getClassName(nameResolver), emptyList())) else list + if (list.isEmpty()) { + listOf(Type(it.type.getClassName(nameResolver), emptyList(), it.type.nullable)) + } else { + list + } } } } @@ -101,7 +117,7 @@ class RepositoryFactory(private val messager: Messager, private val elements: El private fun ProtoBuf.Function.getReturnType(nameResolver: NameResolver): Type? { return when (val className = returnType.getClassName(nameResolver)) { UNIT_CLASS_NAME -> null - else -> Type(className, getParameterTypes(returnType, nameResolver)) + else -> Type(className, getParameterTypes(returnType, nameResolver), returnType.nullable) } } diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt index 9431eff..713aba8 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt @@ -17,7 +17,7 @@ class SourceFactory { .plus(CLASS_NAME_SOURCE.simpleName) val functions = repository.functions.filterFunctions() - return Source(sourcePackage, sourceName, functions) + return Source(sourcePackage, sourceName, repository.properties, functions) } private fun List.filterFunctions(): List { diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt index 4677b10..01eb08f 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt @@ -1,6 +1,7 @@ package com.omega_r.base.processor.models import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.PropertySpec data class Parameter( val name: String, @@ -9,4 +10,6 @@ data class Parameter( fun toParameterSpec(): ParameterSpec = ParameterSpec(name, type.typeName) + fun toPropertySpec(): PropertySpec = PropertySpec.builder(name, type.typeName).build() + } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt index 86b4fa7..61b3244 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt @@ -17,6 +17,7 @@ class Repository( val repositoryPackage: String, val name: String, val superInterfaceClassName: ClassName, + val properties: List, val functions: List ) { @@ -36,7 +37,7 @@ class Repository( val sourcesName = source.name.decapitalizeAsciiOnly() return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(source.className)) - .addModifiers(KModifier.OPEN) + .addModifiers(if (properties.isEmpty()) KModifier.OPEN else KModifier.ABSTRACT) .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") .addSuperinterface(superInterfaceClassName) .primaryConstructor( diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt index f827265..ffc1a3e 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt @@ -11,6 +11,7 @@ private const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" class Source( val sourcePackage: String, val name: String, + val properties: List, val functions: List ) { @@ -36,6 +37,7 @@ class Source( val typeSpec = TypeSpec.interfaceBuilder(name) .addSuperinterface(Constants.CLASS_NAME_SOURCE) .addFunctions(funcSpecs) + .addProperties(properties.map { it.toPropertySpec() }) .build() return FileSpec.builder(sourcePackage, name) diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Type.kt b/processor/src/main/java/com/omega_r/base/processor/models/Type.kt index 42b836c..12a208e 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Type.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Type.kt @@ -1,14 +1,22 @@ package com.omega_r.base.processor.models import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.TypeName data class Type( val className: ClassName, - val parameterizedBy: List + val parameterizedBy: List, + val isNullable: Boolean ) { - val typeName: TypeName = if (parameterizedBy.isEmpty()) className else className.parameterizedBy(parameterizedBy.map { it.typeName }) + val typeName: TypeName + get() { + return if (parameterizedBy.isEmpty()) { + className.copy(isNullable) + } else { + className.parameterizedBy(parameterizedBy.map { it.typeName }).copy(isNullable) + } + } } \ No newline at end of file From a2e15fdb58d43d47aab91fa5381f645b0283f049 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Thu, 16 Jan 2020 13:17:45 +0300 Subject: [PATCH 29/54] RunBlocking logic removed. Repository with not suspend returns will be abstract. --- .../base/simple/InspectionRepository.kt | 2 + .../base/processor/models/Repository.kt | 42 ++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index a6c33bf..2ee1199 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -21,4 +21,6 @@ interface InspectionRepository { suspend fun returnInt(): Int? + fun returnBoolean(): Boolean + } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt index 61b3244..8f5e986 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt @@ -4,7 +4,6 @@ import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_ERROR_HANDLER import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_OMEGA_REPOSITORY import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_STRATEGY import com.omega_r.base.processor.Constants.Companion.MEMBER_NAME_CONSUME_EACH -import com.omega_r.base.processor.Constants.Companion.MEMBER_RUN_BLOCKING import com.omega_r.base.processor.Constants.Companion.RECEIVE_CHANNEL_CLASS_NAME import com.omega_r.base.processor.Constants.Companion.REMOTE_ELSE_CACHE import com.omega_r.base.processor.Constants.Companion.UNIT_CLASS_NAME @@ -24,7 +23,7 @@ class Repository( fun toFileSpec(source: Source): FileSpec { val typeSpec = TypeSpec.classBuilder(name) .addConstructor(source) - .addFunctions(functions.map { it.withImplementation() }) + .addFunctions(functions.mapNotNull { it.withImplementation() }) .build() return FileSpec.builder(repositoryPackage, name) @@ -37,7 +36,7 @@ class Repository( val sourcesName = source.name.decapitalizeAsciiOnly() return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(source.className)) - .addModifiers(if (properties.isEmpty()) KModifier.OPEN else KModifier.ABSTRACT) + .addModifiers(generateModifier()) .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") .addSuperinterface(superInterfaceClassName) .primaryConstructor( @@ -48,7 +47,19 @@ class Repository( ) } - private fun Function.withImplementation(): FunSpec { + private fun generateModifier(): KModifier { + return functions.firstOrNull { + !it.modifiers.contains(KModifier.SUSPEND) && it.returnType?.className != RECEIVE_CHANNEL_CLASS_NAME + }?.let { + KModifier.ABSTRACT + } ?: if (properties.isEmpty()) KModifier.OPEN else KModifier.ABSTRACT + } + + private fun Function.withImplementation(): FunSpec? { + if (!modifiers.contains(KModifier.SUSPEND) && returnType?.className != RECEIVE_CHANNEL_CLASS_NAME) { + return null + } + return toFunSpec().toBuilder() .addModifiers(KModifier.OVERRIDE) .addCode(getCodeBody()) @@ -59,24 +70,15 @@ class Repository( val funcWithArguments = name.removeChannelSuffix() + getArguments() val strategy = getStrategy() - val codeBlockBuilder = CodeBlock.builder() - when (this.returnType?.className) { - null, UNIT_CLASS_NAME -> { - codeBlockBuilder.addStatement("createChannel($strategy) { $funcWithArguments }.%M{}", MEMBER_NAME_CONSUME_EACH) - } - RECEIVE_CHANNEL_CLASS_NAME -> codeBlockBuilder.add("return createChannel($strategy) { $funcWithArguments } \n") - else -> { - if (modifiers.contains(KModifier.SUSPEND)) { - codeBlockBuilder.add("return createChannel($strategy) { $funcWithArguments }.receive()\n") - } else { - codeBlockBuilder.addStatement( - "return %M { createChannel($strategy) { $funcWithArguments }.receive() }", - MEMBER_RUN_BLOCKING - ) + return CodeBlock.builder().apply { + when (returnType?.className) { + null, UNIT_CLASS_NAME -> { + addStatement("createChannel($strategy) { $funcWithArguments }.%M{}", MEMBER_NAME_CONSUME_EACH) } + RECEIVE_CHANNEL_CLASS_NAME -> add("return createChannel($strategy) { $funcWithArguments } \n") + else -> add("return createChannel($strategy) { $funcWithArguments }.receive()\n") } - } - return codeBlockBuilder.build() + }.build() } private fun Function.getStrategy(): String = From 2db59a17102a9432af539ffcbdfd4a20abd5ef04 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Thu, 16 Jan 2020 13:48:08 +0300 Subject: [PATCH 30/54] Var, val get method added. --- .../main/java/com/omega_r/base/processor/Constants.kt | 3 ++- .../com/omega_r/base/processor/models/Parameter.kt | 10 +++++++++- .../java/com/omega_r/base/processor/models/Source.kt | 3 +-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/processor/src/main/java/com/omega_r/base/processor/Constants.kt b/processor/src/main/java/com/omega_r/base/processor/Constants.kt index 903ea91..0cd3be7 100644 --- a/processor/src/main/java/com/omega_r/base/processor/Constants.kt +++ b/processor/src/main/java/com/omega_r/base/processor/Constants.kt @@ -23,7 +23,8 @@ class Constants { internal val REMOTE_ELSE_CACHE = "Strategy.REMOTE_ELSE_CACHE" internal val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") - internal val MEMBER_RUN_BLOCKING = MemberName("kotlinx.coroutines", "runBlocking") + + internal const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" } diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt index 01eb08f..e78c5e9 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt @@ -1,5 +1,7 @@ package com.omega_r.base.processor.models +import com.omega_r.base.processor.Constants.Companion.THROW_NO_DATA +import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.ParameterSpec import com.squareup.kotlinpoet.PropertySpec @@ -10,6 +12,12 @@ data class Parameter( fun toParameterSpec(): ParameterSpec = ParameterSpec(name, type.typeName) - fun toPropertySpec(): PropertySpec = PropertySpec.builder(name, type.typeName).build() + fun toPropertySpec(): PropertySpec = PropertySpec.builder(name, type.typeName) + .getter( + FunSpec.getterBuilder() + .addStatement("return $THROW_NO_DATA") + .build() + ) + .build() } \ No newline at end of file diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt index ffc1a3e..ccc362c 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt @@ -1,13 +1,12 @@ package com.omega_r.base.processor.models import com.omega_r.base.processor.Constants +import com.omega_r.base.processor.Constants.Companion.THROW_NO_DATA import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.TypeSpec -private const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" - class Source( val sourcePackage: String, val name: String, From 0475ac2ba29c03ff1e9abe4bdb14495788b82776 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Thu, 16 Jan 2020 16:07:27 +0300 Subject: [PATCH 31/54] Not abstract functions and parameters removed from repo --- .../com/omega_r/base/simple/InspectionRepository.kt | 8 +++++++- .../java/com/omega_r/base/errors/AppException.kt | 3 --- .../java/com/omega_r/base/processor/Constants.kt | 2 +- .../base/processor/factories/RepositoryFactory.kt | 13 +++++++------ .../com/omega_r/base/processor/models/Parameter.kt | 4 ++-- .../com/omega_r/base/processor/models/Source.kt | 8 ++++---- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index 2ee1199..1fe0766 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.channels.ReceiveChannel interface InspectionRepository { val isAuth: Boolean? + get() = true var age: Int suspend fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel @@ -21,6 +22,11 @@ interface InspectionRepository { suspend fun returnInt(): Int? - fun returnBoolean(): Boolean + suspend fun returnBoolean(): Boolean { + return true + } + + // TODO future code generation +// suspend fun lambda(func: (String) -> Boolean): Int } \ No newline at end of file diff --git a/core/src/main/java/com/omega_r/base/errors/AppException.kt b/core/src/main/java/com/omega_r/base/errors/AppException.kt index dcb6084..4c96d28 100644 --- a/core/src/main/java/com/omega_r/base/errors/AppException.kt +++ b/core/src/main/java/com/omega_r/base/errors/AppException.kt @@ -1,8 +1,5 @@ package com.omega_r.base.errors -import com.omega_r.base.data.sources.Source -import com.omegar.mvp.MvpFacade.init - /** * Created by Anton Knyazev on 2019-05-28. */ diff --git a/processor/src/main/java/com/omega_r/base/processor/Constants.kt b/processor/src/main/java/com/omega_r/base/processor/Constants.kt index 0cd3be7..fff4ed9 100644 --- a/processor/src/main/java/com/omega_r/base/processor/Constants.kt +++ b/processor/src/main/java/com/omega_r/base/processor/Constants.kt @@ -24,7 +24,7 @@ class Constants { internal val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") - internal const val THROW_NO_DATA = "com.omega_r.base.errors.throwNoData()" + internal val MEMBER_NAME_THROW_NO_DATA = MemberName("com.omega_r.base.errors", "throwNoData") } diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt index 2f3f96d..d99d2ea 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt @@ -10,10 +10,7 @@ import com.omega_r.base.processor.models.Repository import com.omega_r.base.processor.models.Type import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.KModifier -import me.eugeniomarletti.kotlin.metadata.KotlinClassMetadata -import me.eugeniomarletti.kotlin.metadata.classKind -import me.eugeniomarletti.kotlin.metadata.isSuspend -import me.eugeniomarletti.kotlin.metadata.kotlinMetadata +import me.eugeniomarletti.kotlin.metadata.* import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf import me.eugeniomarletti.kotlin.metadata.shadow.metadata.ProtoBuf.Class.Kind.INTERFACE import me.eugeniomarletti.kotlin.metadata.shadow.metadata.deserialization.NameResolver @@ -22,6 +19,7 @@ import javax.lang.model.element.Element import javax.lang.model.element.TypeElement import javax.lang.model.util.Elements import javax.tools.Diagnostic.Kind.ERROR +import javax.tools.Diagnostic.Kind.WARNING class RepositoryFactory(private val messager: Messager, private val elements: Elements) { @@ -48,7 +46,7 @@ class RepositoryFactory(private val messager: Messager, private val elements: El val nameResolver = kotlinMetadata.data.nameResolver val superInterfaceClassName = ClassName.bestGuess("${elements.packageOf(element)}.${element.simpleName}") - val properties = classProto.propertyList.map { property -> + val properties = classProto.propertyList.mapNotNull { property -> property.toParameter(nameResolver) } val functions = classProto.functionList.mapNotNull { @@ -58,7 +56,8 @@ class RepositoryFactory(private val messager: Messager, private val elements: El return Repository(repositoryPackage, repositoryName, superInterfaceClassName, properties, functions) } - private fun ProtoBuf.Property.toParameter(nameResolver: NameResolver): Parameter { + private fun ProtoBuf.Property.toParameter(nameResolver: NameResolver): Parameter? { + if (modality != ProtoBuf.Modality.ABSTRACT) return null val parameterName = nameResolver.getString(name) val className = returnType.getClassName(nameResolver) val parameterizedBy = getParameterTypes(returnType, nameResolver) @@ -67,6 +66,8 @@ class RepositoryFactory(private val messager: Messager, private val elements: El } private fun ProtoBuf.Function.toFunction(element: Element, nameResolver: NameResolver): Function? { + if (modality != ProtoBuf.Modality.ABSTRACT) return null + val functionName = nameResolver.getName(this) val parameters = valueParameterList.map { it.toParameter(nameResolver) diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt index e78c5e9..9559721 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Parameter.kt @@ -1,6 +1,6 @@ package com.omega_r.base.processor.models -import com.omega_r.base.processor.Constants.Companion.THROW_NO_DATA +import com.omega_r.base.processor.Constants.Companion.MEMBER_NAME_THROW_NO_DATA import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.ParameterSpec import com.squareup.kotlinpoet.PropertySpec @@ -15,7 +15,7 @@ data class Parameter( fun toPropertySpec(): PropertySpec = PropertySpec.builder(name, type.typeName) .getter( FunSpec.getterBuilder() - .addStatement("return $THROW_NO_DATA") + .addStatement("return %M()", MEMBER_NAME_THROW_NO_DATA) .build() ) .build() diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt index ccc362c..404810d 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Source.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Source.kt @@ -1,7 +1,7 @@ package com.omega_r.base.processor.models import com.omega_r.base.processor.Constants -import com.omega_r.base.processor.Constants.Companion.THROW_NO_DATA +import com.omega_r.base.processor.Constants.Companion.MEMBER_NAME_THROW_NO_DATA import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -22,10 +22,10 @@ class Source( codeBlock.addStatement( when (function.returnType?.className) { - null, Constants.UNIT_CLASS_NAME -> THROW_NO_DATA - else -> "return $THROW_NO_DATA" + null, Constants.UNIT_CLASS_NAME -> "%M()" + else -> "return %M()" } - ) + , MEMBER_NAME_THROW_NO_DATA) function.toFunSpec() .toBuilder() From 43c9c9e595a072cea902cd4fa41fe0c5d13f52d3 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Thu, 16 Jan 2020 16:47:45 +0300 Subject: [PATCH 32/54] OmegaRepository errorHandler modifier changed to protected --- .../main/java/com/omega_r/base/simple/InspectionRepository.kt | 2 +- core/build.gradle | 2 +- core/src/main/java/com/omega_r/base/data/OmegaRepository.kt | 4 ++-- core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index 1fe0766..072e048 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -9,7 +9,7 @@ import kotlinx.coroutines.channels.ReceiveChannel interface InspectionRepository { val isAuth: Boolean? - get() = true + get() = true var age: Int suspend fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel diff --git a/core/build.gradle b/core/build.gradle index 7748101..603f43d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -67,7 +67,7 @@ dependencies { api "com.squareup.retrofit2:retrofit:2.6.2" api "com.squareup.moshi:moshi-kotlin:1.8.0" - implementation 'com.google.android.material:material:1.2.0-alpha02' + implementation 'com.google.android.material:material:1.2.0-alpha03' } repositories { diff --git a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt index c04f5ef..2954020 100644 --- a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -14,9 +14,9 @@ import kotlinx.coroutines.channels.produce /** * Created by Anton Knyazev on 2019-05-28. */ -@Suppress("UNCHECKED_CAST") +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") @UseExperimental(ExperimentalCoroutinesApi::class) -open class OmegaRepository(private val errorHandler: ErrorHandler, vararg sources: SOURCE) { +open class OmegaRepository(protected val errorHandler: ErrorHandler, vararg sources: SOURCE) { private val job = SupervisorJob() diff --git a/core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt b/core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt index 44ecdaf..aac30d1 100644 --- a/core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt +++ b/core/src/main/java/com/omega_r/base/errors/ErrorHandler.kt @@ -40,8 +40,8 @@ open class ErrorHandler : (Throwable) -> Exception, CoroutineExceptionHandler { is ConnectException, is SocketTimeoutException -> AppException.ServerUnavailable(null, throwable) is HttpException -> handleHttpException(throwable) + is AppException -> throwable else -> AppException.UnknownError("Unknown error", throwable) - } } From d59322afd7e0db32b3964dfb69446f6bdd911317 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Thu, 16 Jan 2020 17:32:34 +0300 Subject: [PATCH 33/54] Var val generation bug fixed --- .../com/omega_r/base/simple/InspectionRepository.kt | 2 ++ .../base/processor/factories/RepositoryFactory.kt | 12 ++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index 072e048..7d78bd5 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -12,6 +12,8 @@ interface InspectionRepository { get() = true var age: Int + val inspectionUpdateChannel: ReceiveChannel> + suspend fun getInspectionsChannel(strategy: Strategy, index: Int): ReceiveChannel suspend fun getInspections(strategy: Strategy, index: Int): String diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt index d99d2ea..3d47d19 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt @@ -18,8 +18,7 @@ import javax.annotation.processing.Messager import javax.lang.model.element.Element import javax.lang.model.element.TypeElement import javax.lang.model.util.Elements -import javax.tools.Diagnostic.Kind.ERROR -import javax.tools.Diagnostic.Kind.WARNING +import javax.tools.Diagnostic.Kind.* class RepositoryFactory(private val messager: Messager, private val elements: Elements) { @@ -62,6 +61,8 @@ class RepositoryFactory(private val messager: Messager, private val elements: El val className = returnType.getClassName(nameResolver) val parameterizedBy = getParameterTypes(returnType, nameResolver) + messager.printMessage(WARNING, "parameterName $parameterName $parameterizedBy") + return Parameter(parameterName, Type(className, parameterizedBy, returnType.nullable)) } @@ -105,12 +106,7 @@ class RepositoryFactory(private val messager: Messager, private val elements: El emptyList() } else { arguments.flatMap { - val list = getParameterTypes(it.type, nameResolver) - if (list.isEmpty()) { - listOf(Type(it.type.getClassName(nameResolver), emptyList(), it.type.nullable)) - } else { - list - } + listOf(Type(it.type.getClassName(nameResolver), getParameterTypes(it.type, nameResolver), it.type.nullable)) } } } From bc592a54639340c91871d113799361e5cc3b545a Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 17 Jan 2020 14:25:49 +0300 Subject: [PATCH 34/54] Repository hierarchy updated --- .../base/simple/InspectionRepository.kt | 3 +- .../omega_r/base/data/OmegaBaseRepository.kt | 319 ++++++++++++++++++ .../com/omega_r/base/data/OmegaRepository.kt | 317 +---------------- .../base/mvp/presenters/OmegaPresenter.kt | 4 - .../com/omega_r/base/processor/Constants.kt | 3 +- .../processor/extensions/ElementExtensions.kt | 2 +- .../processor/factories/RepositoryFactory.kt | 4 + .../base/processor/factories/SourceFactory.kt | 1 + .../base/processor/models/Repository.kt | 4 +- 9 files changed, 334 insertions(+), 323 deletions(-) create mode 100644 core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt diff --git a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt index 7d78bd5..be95cd3 100644 --- a/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt +++ b/app/src/main/java/com/omega_r/base/simple/InspectionRepository.kt @@ -1,6 +1,5 @@ package com.omega_r.base.simple - import com.omega_r.base.annotations.AppOmegaRepository import com.omega_r.base.data.OmegaRepository.Strategy import kotlinx.coroutines.channels.ReceiveChannel @@ -28,6 +27,8 @@ interface InspectionRepository { return true } + fun clearCache() + // TODO future code generation // suspend fun lambda(func: (String) -> Boolean): Int diff --git a/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt new file mode 100644 index 0000000..80d839e --- /dev/null +++ b/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt @@ -0,0 +1,319 @@ +package com.omega_r.base.data + +import com.omega_r.base.data.Strategy.* +import com.omega_r.base.data.sources.CacheSource +import com.omega_r.base.data.sources.Source +import com.omega_r.base.errors.AppException +import com.omega_r.base.errors.ErrorHandler +import com.omega_r.base.errors.throwNoData +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.ProducerScope +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.produce + +/** + * Created by Anton Knyazev on 2019-05-28. + */ +@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") +@UseExperimental(ExperimentalCoroutinesApi::class) +open class OmegaRepository(protected val errorHandler: ErrorHandler, vararg sources: SOURCE) { + + private val job = SupervisorJob() + + protected val coroutineScope = CoroutineScope(Dispatchers.Default + job) + + protected val remoteSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.REMOTE } + + protected val memorySource: SOURCE? + get() = memoryCacheSource as SOURCE? + + protected val fileSource: SOURCE? + get() = fileCacheSource as SOURCE? + + protected val defaultSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.DEFAULT } + + private val memoryCacheSource = + sources.firstOrNull { it.type == Source.Type.MEMORY_CACHE } as? CacheSource + + private val fileCacheSource = + sources.firstOrNull { it.type == Source.Type.FILE_CACHE } as? CacheSource + + protected open suspend fun processResult(result: R, sourceType: Source.Type): R { + return result + } + + protected fun createChannel(strategy: Strategy, block: suspend SOURCE.() -> R): ReceiveChannel { + return coroutineScope.produce { + try { + when (strategy) { + CACHE_AND_REMOTE -> applyCacheAndRemote(block) + ONLY_REMOTE -> applyOnlyRemote(block) + ONLY_CACHE -> applyOnlyCache(block) + REMOTE_ELSE_CACHE -> applyRemoteElseCache(block) + CACHE_ELSE_REMOTE -> applyCacheElseRemote(block) + MEMORY_ELSE_CACHE_AND_REMOTE -> applyMemoryElseCacheAndRemote(block) + } + } catch (e: Throwable) { + throw errorHandler.handleThrowable(e) + } + } + } + + private suspend fun ProducerScope.applyOnlyRemote(block: suspend SOURCE.() -> R) { + var remoteException: Exception? = null + + if (remoteSource != null) { + remoteException = getException { + val result = processResult(block(remoteSource), Source.Type.REMOTE) + send(result) + memoryCacheSource?.update(result) + fileCacheSource?.update(result) + return + } + } + + + if (defaultSource != null) { + val cacheException: Exception? = getException { + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + cacheException?.printStackTraceIfNeeded() + } + + if (remoteException != null) { + throw remoteException + } else { + throwNoData("Remote sources is null") + } + } + + private suspend fun ProducerScope.applyOnlyCache(block: suspend SOURCE.() -> R) { + var cacheException: Exception? = null + + if (memoryCacheSource != null) { + cacheException = getException { + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) + return + } + } + + if (fileCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + send(result) + memoryCacheSource?.update(result) + return + } + } + + if (defaultSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + cacheException?.printStackTraceIfNeeded() + } + + throwNoData("Cache sources is null") + } + + private suspend fun ProducerScope.applyRemoteElseCache(block: suspend SOURCE.() -> R) { + var remoteException: Exception? = null + if (remoteSource != null) { + remoteException = getException { + val result = processResult(block(remoteSource), Source.Type.REMOTE) + send(result) + memoryCacheSource?.update(result) + fileCacheSource?.update(result) + return + } + } + + var cacheException: Exception? = null + + if (memoryCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) + return + } + } + + if (fileCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + send(result) + memoryCacheSource?.update(result) + return + } + } + + if (defaultSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + } + if (remoteSource == null) { + cacheException?.let { throw it } + } else { + cacheException?.printStackTraceIfNeeded() + remoteException?.let { throw it } + } + } + + private suspend fun ProducerScope.applyCacheElseRemote(block: suspend SOURCE.() -> R) { + + var cacheException: Exception? = null + + if (memoryCacheSource != null) { + cacheException = getException { + send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) + return + } + } + if (fileCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + send(result) + memoryCacheSource?.update(result) + return + } + } + + var remoteException: Exception? = null + + if (remoteSource != null) { + remoteException = getException { + val result = processResult(block(remoteSource), Source.Type.REMOTE) + send(result) + memoryCacheSource?.update(result) + fileCacheSource?.update(result) + return + } + } + + if (defaultSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + return send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + } + + when { + remoteException != null -> { + cacheException?.printStackTraceIfNeeded() + throw remoteException + } + cacheException != null -> { + throw cacheException + } + else -> { + throwNoData("Cache sources is null") + } + } + } + + private suspend fun ProducerScope.applyCacheAndRemote(block: suspend SOURCE.() -> R) { + val cacheReturnDeferred = coroutineScope { + async { + var cacheException: Exception? = null + if (memoryCacheSource != null) { + cacheException = getException { + val result = + processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) + + if (isActive && !isClosedForSend) { + send(result) + } + return@async null + } + } + if (fileCacheSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + val result = + processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) + if (isActive && !isClosedForSend) { + send(result) + memoryCacheSource?.update(result) + } + return@async null + } + } + + + if (defaultSource != null) { + cacheException?.printStackTraceIfNeeded() + cacheException = getException { + if (isActive && !isClosedForSend) { + send(processResult(block(defaultSource), Source.Type.DEFAULT)) + } + return@async null + } + } + + return@async cacheException + } + } + + val remoteException = remoteSource?.let { + getException { + val result = processResult(block(remoteSource), Source.Type.REMOTE) + cacheReturnDeferred.cancel() + send(result) + channel.close() + memoryCacheSource?.update(result) + fileCacheSource?.update(result) + return + } + } + + val cacheException = cacheReturnDeferred.await() + + if (remoteSource == null) { + if (cacheException != null) { + throw cacheException + } + } else { + cacheException?.printStackTraceIfNeeded() + if (remoteException != null && (cacheException != null || remoteException !is AppException.NoData)) + throw remoteException + } + + } + + private suspend fun ProducerScope.applyMemoryElseCacheAndRemote(block: suspend SOURCE.() -> R) { + if (memoryCacheSource != null) { + getException { + send(block(memoryCacheSource as SOURCE)) + return + } + } + applyCacheAndRemote(block) + } + + fun clearCache() { + memoryCacheSource?.clear() + fileCacheSource?.clear() + } + + private inline fun getException(block: () -> Unit): Exception? { + return try { + block() + null + } catch (exception: Exception) { + exception + } + } + + private fun Exception.printStackTraceIfNeeded() { + if (this is AppException.NoData) { + printStackTrace() + } + } + +} \ No newline at end of file diff --git a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt index 2954020..4f60170 100644 --- a/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt +++ b/core/src/main/java/com/omega_r/base/data/OmegaRepository.kt @@ -1,307 +1,11 @@ package com.omega_r.base.data -import com.omega_r.base.data.OmegaRepository.Strategy.* -import com.omega_r.base.data.sources.CacheSource -import com.omega_r.base.data.sources.Source -import com.omega_r.base.errors.AppException -import com.omega_r.base.errors.ErrorHandler -import com.omega_r.base.errors.throwNoData -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.ProducerScope -import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.coroutines.channels.produce +interface OmegaRepository { -/** - * Created by Anton Knyazev on 2019-05-28. - */ -@Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") -@UseExperimental(ExperimentalCoroutinesApi::class) -open class OmegaRepository(protected val errorHandler: ErrorHandler, vararg sources: SOURCE) { - - private val job = SupervisorJob() - - protected val coroutineScope = CoroutineScope(Dispatchers.Default + job) - - protected val remoteSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.REMOTE } - - protected val memorySource: SOURCE? - get() = memoryCacheSource as SOURCE? - - protected val fileSource: SOURCE? - get() = fileCacheSource as SOURCE? - - protected val defaultSource: SOURCE? = sources.firstOrNull { it.type == Source.Type.DEFAULT } - - private val memoryCacheSource = - sources.firstOrNull { it.type == Source.Type.MEMORY_CACHE } as? CacheSource - - private val fileCacheSource = - sources.firstOrNull { it.type == Source.Type.FILE_CACHE } as? CacheSource - - protected open suspend fun processResult(result: R, sourceType: Source.Type): R { - return result - } - - protected fun createChannel(strategy: Strategy, block: suspend SOURCE.() -> R): ReceiveChannel { - return coroutineScope.produce { - try { - when (strategy) { - CACHE_AND_REMOTE -> applyCacheAndRemote(block) - ONLY_REMOTE -> applyOnlyRemote(block) - ONLY_CACHE -> applyOnlyCache(block) - REMOTE_ELSE_CACHE -> applyRemoteElseCache(block) - CACHE_ELSE_REMOTE -> applyCacheElseRemote(block) - MEMORY_ELSE_CACHE_AND_REMOTE -> applyMemoryElseCacheAndRemote(block) - } - } catch (e: Throwable) { - throw errorHandler.handleThrowable(e) - } - } - } - - private suspend fun ProducerScope.applyOnlyRemote(block: suspend SOURCE.() -> R) { - var remoteException: Exception? = null - - if (remoteSource != null) { - remoteException = getException { - val result = processResult(block(remoteSource), Source.Type.REMOTE) - send(result) - memoryCacheSource?.update(result) - fileCacheSource?.update(result) - return - } - } - - - if (defaultSource != null) { - val cacheException: Exception? = getException { - return send(processResult(block(defaultSource), Source.Type.DEFAULT)) - } - cacheException?.printStackTraceIfNeeded() - } - - if (remoteException != null) { - throw remoteException - } else { - throwNoData("Remote sources is null") - } - } - - private suspend fun ProducerScope.applyOnlyCache(block: suspend SOURCE.() -> R) { - var cacheException: Exception? = null - - if (memoryCacheSource != null) { - cacheException = getException { - send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) - return - } - } - - if (fileCacheSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) - send(result) - memoryCacheSource?.update(result) - return - } - } - - if (defaultSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - return send(processResult(block(defaultSource), Source.Type.DEFAULT)) - } - cacheException?.printStackTraceIfNeeded() - } - - throwNoData("Cache sources is null") - } - - private suspend fun ProducerScope.applyRemoteElseCache(block: suspend SOURCE.() -> R) { - var remoteException: Exception? = null - if (remoteSource != null) { - remoteException = getException { - val result = processResult(block(remoteSource), Source.Type.REMOTE) - send(result) - memoryCacheSource?.update(result) - fileCacheSource?.update(result) - return - } - } - - var cacheException: Exception? = null - - if (memoryCacheSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) - return - } - } - - if (fileCacheSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) - send(result) - memoryCacheSource?.update(result) - return - } - } - - if (defaultSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - return send(processResult(block(defaultSource), Source.Type.DEFAULT)) - } - } - if (remoteSource == null) { - cacheException?.let { throw it } - } else { - cacheException?.printStackTraceIfNeeded() - remoteException?.let { throw it } - } - } - - private suspend fun ProducerScope.applyCacheElseRemote(block: suspend SOURCE.() -> R) { - - var cacheException: Exception? = null - - if (memoryCacheSource != null) { - cacheException = getException { - send(processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE)) - return - } - } - if (fileCacheSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - val result = processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) - send(result) - memoryCacheSource?.update(result) - return - } - } - - var remoteException: Exception? = null - - if (remoteSource != null) { - remoteException = getException { - val result = processResult(block(remoteSource), Source.Type.REMOTE) - send(result) - memoryCacheSource?.update(result) - fileCacheSource?.update(result) - return - } - } - - if (defaultSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - return send(processResult(block(defaultSource), Source.Type.DEFAULT)) - } - } - - when { - remoteException != null -> { - cacheException?.printStackTraceIfNeeded() - throw remoteException - } - cacheException != null -> { - throw cacheException - } - else -> { - throwNoData("Cache sources is null") - } - } - } - - private suspend fun ProducerScope.applyCacheAndRemote(block: suspend SOURCE.() -> R) { - val cacheReturnDeferred = coroutineScope { - async { - var cacheException: Exception? = null - if (memoryCacheSource != null) { - cacheException = getException { - val result = - processResult(block(memoryCacheSource as SOURCE), Source.Type.MEMORY_CACHE) - - if (isActive && !isClosedForSend) { - send(result) - } - return@async null - } - } - if (fileCacheSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - val result = - processResult(block(fileCacheSource as SOURCE), Source.Type.FILE_CACHE) - if (isActive && !isClosedForSend) { - send(result) - memoryCacheSource?.update(result) - } - return@async null - } - } - - - if (defaultSource != null) { - cacheException?.printStackTraceIfNeeded() - cacheException = getException { - if (isActive && !isClosedForSend) { - send(processResult(block(defaultSource), Source.Type.DEFAULT)) - } - return@async null - } - } - - return@async cacheException - } - } - - val remoteException = remoteSource?.let { - getException { - val result = processResult(block(remoteSource), Source.Type.REMOTE) - cacheReturnDeferred.cancel() - send(result) - channel.close() - memoryCacheSource?.update(result) - fileCacheSource?.update(result) - return - } - } - - val cacheException = cacheReturnDeferred.await() - - if (remoteSource == null) { - if (cacheException != null) { - throw cacheException - } - } else { - cacheException?.printStackTraceIfNeeded() - if (remoteException != null && (cacheException != null || remoteException !is AppException.NoData)) - throw remoteException - } - - } - - private suspend fun ProducerScope.applyMemoryElseCacheAndRemote(block: suspend SOURCE.() -> R) { - if (memoryCacheSource != null) { - getException { - send(block(memoryCacheSource as SOURCE)) - return - } - } - applyCacheAndRemote(block) - } - - fun clearCache() { - memoryCacheSource?.clear() - fileCacheSource?.clear() - } + fun clearCache() enum class Strategy { + ONLY_REMOTE, REMOTE_ELSE_CACHE, CACHE_ELSE_REMOTE, @@ -311,19 +15,4 @@ open class OmegaRepository(protected val errorHandler: ErrorHan } - private inline fun getException(block: () -> Unit): Exception? { - return try { - block() - null - } catch (exception: Exception) { - exception - } - } - - private fun Exception.printStackTraceIfNeeded() { - if (this is AppException.NoData) { - printStackTrace() - } - } - } \ No newline at end of file diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index c71d324..2956bd6 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -1,11 +1,8 @@ package com.omega_r.base.mvp.presenters -import android.content.pm.PackageManager import android.content.pm.PackageManager.PERMISSION_GRANTED import androidx.annotation.CallSuper import com.omega_r.base.R -import com.omega_r.base.data.OmegaRepository -import com.omega_r.base.data.sources.Source import com.omega_r.base.errors.AppException import com.omega_r.base.logs.log import com.omega_r.base.mvp.views.OmegaView @@ -17,7 +14,6 @@ import com.omegar.libs.omegalaunchers.BaseIntentLauncher import com.omegar.libs.omegalaunchers.Launcher import com.omegar.mvp.MvpPresenter import kotlinx.coroutines.* -import kotlinx.coroutines.channels.ReceiveChannel import java.io.Serializable import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext diff --git a/processor/src/main/java/com/omega_r/base/processor/Constants.kt b/processor/src/main/java/com/omega_r/base/processor/Constants.kt index fff4ed9..77c54ca 100644 --- a/processor/src/main/java/com/omega_r/base/processor/Constants.kt +++ b/processor/src/main/java/com/omega_r/base/processor/Constants.kt @@ -9,6 +9,7 @@ class Constants { internal const val UNIT = "kotlin.Unit" internal val CLASS_NAME_SOURCE = ClassName.bestGuess("com.omega_r.base.data.sources.Source") + internal val CLASS_NAME_BASE_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaBaseRepository") internal val CLASS_NAME_OMEGA_REPOSITORY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository") internal val CLASS_NAME_STRATEGY = ClassName.bestGuess("com.omega_r.base.data.OmegaRepository.Strategy") @@ -20,7 +21,7 @@ class Constants { internal val CLASS_NAME_ERROR_HANDLER = ClassName.bestGuess("com.omega_r.base.errors.ErrorHandler") - internal val REMOTE_ELSE_CACHE = "Strategy.REMOTE_ELSE_CACHE" + internal val REMOTE_ELSE_CACHE = "com.omega_r.base.data.OmegaRepository.Strategy.REMOTE_ELSE_CACHE" internal val MEMBER_NAME_CONSUME_EACH = MemberName("kotlinx.coroutines.channels", "consumeEach") diff --git a/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt b/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt index 0ff3c2e..6d712da 100644 --- a/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt +++ b/processor/src/main/java/com/omega_r/base/processor/extensions/ElementExtensions.kt @@ -1,7 +1,6 @@ package com.omega_r.base.processor.extensions import com.omega_r.base.processor.Constants -import com.squareup.kotlinpoet.ClassName import javax.lang.model.element.Element import javax.lang.model.util.Elements @@ -11,6 +10,7 @@ val Element.pureName: String .toString() .removeSuffix(Constants.CLASS_NAME_SOURCE.simpleName) .removeSuffix(Constants.CLASS_NAME_OMEGA_REPOSITORY.simpleName) + .removeSuffix(Constants.CLASS_NAME_BASE_OMEGA_REPOSITORY.simpleName) .removeSuffix("Repository") } diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt index 3d47d19..0296e1e 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/RepositoryFactory.kt @@ -20,6 +20,8 @@ import javax.lang.model.element.TypeElement import javax.lang.model.util.Elements import javax.tools.Diagnostic.Kind.* +private const val FUNC_CLEAR_CACHE = "clearCache" + class RepositoryFactory(private val messager: Messager, private val elements: Elements) { fun create(elements: Set): List = elements.mapNotNull { create(it) } @@ -70,6 +72,8 @@ class RepositoryFactory(private val messager: Messager, private val elements: El if (modality != ProtoBuf.Modality.ABSTRACT) return null val functionName = nameResolver.getName(this) + if(functionName == FUNC_CLEAR_CACHE) return null + val parameters = valueParameterList.map { it.toParameter(nameResolver) }.toLinkedHashSet() diff --git a/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt index 713aba8..291bf44 100644 --- a/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt +++ b/processor/src/main/java/com/omega_r/base/processor/factories/SourceFactory.kt @@ -1,6 +1,7 @@ package com.omega_r.base.processor.factories import com.omega_r.base.processor.Constants +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_BASE_OMEGA_REPOSITORY import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_OMEGA_REPOSITORY import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_SOURCE import com.omega_r.base.processor.Constants.Companion.RECEIVE_CHANNEL_CLASS_NAME diff --git a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt index 8f5e986..ce45ef7 100644 --- a/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt +++ b/processor/src/main/java/com/omega_r/base/processor/models/Repository.kt @@ -1,7 +1,7 @@ package com.omega_r.base.processor.models import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_ERROR_HANDLER -import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_OMEGA_REPOSITORY +import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_BASE_OMEGA_REPOSITORY import com.omega_r.base.processor.Constants.Companion.CLASS_NAME_STRATEGY import com.omega_r.base.processor.Constants.Companion.MEMBER_NAME_CONSUME_EACH import com.omega_r.base.processor.Constants.Companion.RECEIVE_CHANNEL_CLASS_NAME @@ -35,7 +35,7 @@ class Repository( val errorHandlerName = CLASS_NAME_ERROR_HANDLER.simpleName.decapitalizeAsciiOnly() val sourcesName = source.name.decapitalizeAsciiOnly() - return superclass(CLASS_NAME_OMEGA_REPOSITORY.parameterizedBy(source.className)) + return superclass(CLASS_NAME_BASE_OMEGA_REPOSITORY.parameterizedBy(source.className)) .addModifiers(generateModifier()) .addSuperclassConstructorParameter("$errorHandlerName, *$sourcesName") .addSuperinterface(superInterfaceClassName) From 2dcb2926ed7fc17a38077953cbeadefb5af856cf Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Fri, 17 Jan 2020 14:26:10 +0300 Subject: [PATCH 35/54] clear cache function added --- .../java/com/omega_r/base/data/OmegaBaseRepository.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt b/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt index 80d839e..2af6198 100644 --- a/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt +++ b/core/src/main/java/com/omega_r/base/data/OmegaBaseRepository.kt @@ -1,6 +1,7 @@ package com.omega_r.base.data -import com.omega_r.base.data.Strategy.* +import com.omega_r.base.data.OmegaRepository.Strategy +import com.omega_r.base.data.OmegaRepository.Strategy.* import com.omega_r.base.data.sources.CacheSource import com.omega_r.base.data.sources.Source import com.omega_r.base.errors.AppException @@ -16,7 +17,10 @@ import kotlinx.coroutines.channels.produce */ @Suppress("UNCHECKED_CAST", "MemberVisibilityCanBePrivate") @UseExperimental(ExperimentalCoroutinesApi::class) -open class OmegaRepository(protected val errorHandler: ErrorHandler, vararg sources: SOURCE) { +open class OmegaBaseRepository( + protected val errorHandler: ErrorHandler, + vararg sources: SOURCE +) : OmegaRepository { private val job = SupervisorJob() @@ -296,7 +300,7 @@ open class OmegaRepository(protected val errorHandler: ErrorHan applyCacheAndRemote(block) } - fun clearCache() { + override fun clearCache() { memoryCacheSource?.clear() fileCacheSource?.clear() } From 9346bde1bc14a72f78ae556865658c69f0be03de Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Fri, 14 Feb 2020 12:33:01 +0300 Subject: [PATCH 36/54] Fix crash: attachChildPresenter --- .../omega_r/base/components/OmegaActivity.kt | 11 ----- .../OmegaBottomSheetDialogFragment.kt | 36 ++++++++++++++++ .../base/components/OmegaDialogFragment.kt | 36 ++++++++++++++++ .../omega_r/base/components/OmegaFragment.kt | 43 ++++++++++++++++--- .../base/mvp/presenters/OmegaPresenter.kt | 8 ++++ 5 files changed, 117 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt b/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt index c5ba301..ccc1db3 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaActivity.kt @@ -8,7 +8,6 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.Button import androidx.annotation.* import androidx.appcompat.widget.Toolbar import androidx.core.app.ActivityCompat @@ -266,16 +265,6 @@ abstract class OmegaActivity : MvpAppCompatActivity(), OmegaComponent { } } - override fun onAttachFragment(fragment: Fragment) { - super.onAttachFragment(fragment) - when (fragment) { - is OmegaFragment -> presenter.attachChildPresenter(fragment.presenter) - is OmegaDialogFragment -> presenter.attachChildPresenter(fragment.presenter) - is OmegaBottomSheetDialogFragment -> presenter.attachChildPresenter(fragment.presenter) - } - } - - override fun onStart() { super.onStart() dialogManager.onStart() diff --git a/core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt index e40f0bb..1b903e7 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaBottomSheetDialogFragment.kt @@ -30,6 +30,8 @@ abstract class OmegaBottomSheetDialogFragment : MvpBottomSheetDialogFragment(), override val bindersManager = ResettableBindersManager() + private var childPresenterAttached = false + override fun findViewById(id: Int): T? = view?.findViewById(id) override fun onCreate(savedInstanceState: Bundle?) { @@ -37,6 +39,34 @@ abstract class OmegaBottomSheetDialogFragment : MvpBottomSheetDialogFragment(), setHasOptionsMenu(this::class.findAnnotation() != null) } + private fun attachChildPresenter() { + if (!childPresenterAttached) { + childPresenterAttached = true + (activity as? OmegaActivity)?.presenter?.attachChildPresenter(presenter) + } + } + + private fun detachChildPresenter() { + if (childPresenterAttached) { + (activity as? OmegaActivity)?.presenter?.detachChildPresenter(presenter) + } + } + + override fun onStart() { + super.onStart() + attachChildPresenter() + } + + override fun onResume() { + super.onResume() + attachChildPresenter() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + detachChildPresenter() + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { val annotation = this::class.findAnnotation() if (annotation != null) { @@ -80,6 +110,11 @@ abstract class OmegaBottomSheetDialogFragment : MvpBottomSheetDialogFragment(), bindersManager.doAutoInit() } + override fun onDestroyView() { + super.onDestroyView() + detachChildPresenter() + } + override fun getViewForSnackbar() = view!! override fun setWaiting(waiting: Boolean, text: Text?) { @@ -183,6 +218,7 @@ abstract class OmegaBottomSheetDialogFragment : MvpBottomSheetDialogFragment(), override fun onStop() { super.onStop() + detachChildPresenter() dialogList.forEach { it.setOnDismissListener(null) it.dismiss() diff --git a/core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt index 145dda3..3f62dee 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaDialogFragment.kt @@ -33,6 +33,8 @@ abstract class OmegaDialogFragment : MvpAppCompatDialogFragment(), OmegaComponen override val bindersManager = ResettableBindersManager() + private var childPresenterAttached = false + override fun findViewById(id: Int): T? = view?.findViewById(id) override fun onCreate(savedInstanceState: Bundle?) { @@ -40,6 +42,34 @@ abstract class OmegaDialogFragment : MvpAppCompatDialogFragment(), OmegaComponen setHasOptionsMenu(this::class.findAnnotation() != null) } + private fun attachChildPresenter() { + if (!childPresenterAttached) { + childPresenterAttached = true + (activity as? OmegaActivity)?.presenter?.attachChildPresenter(presenter) + } + } + + private fun detachChildPresenter() { + if (childPresenterAttached) { + (activity as? OmegaActivity)?.presenter?.detachChildPresenter(presenter) + } + } + + override fun onStart() { + super.onStart() + attachChildPresenter() + } + + override fun onResume() { + super.onResume() + attachChildPresenter() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + detachChildPresenter() + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { val annotation = this::class.findAnnotation() if (annotation != null) { @@ -83,6 +113,11 @@ abstract class OmegaDialogFragment : MvpAppCompatDialogFragment(), OmegaComponen bindersManager.doAutoInit() } + override fun onDestroyView() { + super.onDestroyView() + detachChildPresenter() + } + override fun getViewForSnackbar() = view!! override fun setWaiting(waiting: Boolean, text: Text?) { @@ -178,6 +213,7 @@ abstract class OmegaDialogFragment : MvpAppCompatDialogFragment(), OmegaComponen override fun onStop() { super.onStop() + detachChildPresenter() dialogList.forEach { it.setOnDismissListener(null) it.dismiss() diff --git a/core/src/main/java/com/omega_r/base/components/OmegaFragment.kt b/core/src/main/java/com/omega_r/base/components/OmegaFragment.kt index 60d899a..c960eb4 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaFragment.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaFragment.kt @@ -33,6 +33,8 @@ abstract class OmegaFragment : MvpAppCompatFragment(), OmegaComponent { override val bindersManager = ResettableBindersManager() + private var childPresenterAttached = false + open fun getTitle(): Text? = null override fun findViewById(id: Int) = view?.findViewById(id) @@ -42,6 +44,34 @@ abstract class OmegaFragment : MvpAppCompatFragment(), OmegaComponent { setHasOptionsMenu(this::class.findAnnotation() != null) } + private fun attachChildPresenter() { + if (!childPresenterAttached) { + childPresenterAttached = true + (activity as? OmegaActivity)?.presenter?.attachChildPresenter(presenter) + } + } + + private fun detachChildPresenter() { + if (childPresenterAttached) { + (activity as? OmegaActivity)?.presenter?.detachChildPresenter(presenter) + } + } + + override fun onStart() { + super.onStart() + attachChildPresenter() + } + + override fun onResume() { + super.onResume() + attachChildPresenter() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + detachChildPresenter() + } + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { val annotation = this::class.findAnnotation() if (annotation != null) { @@ -52,11 +82,7 @@ abstract class OmegaFragment : MvpAppCompatFragment(), OmegaComponent { } override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (clickManager.handleMenuClick(item.itemId)) { - return true - } else { - return super.onOptionsItemSelected(item) - } + return if (clickManager.handleMenuClick(item.itemId)) true else super.onOptionsItemSelected(item) } override fun onCreateView( @@ -91,6 +117,11 @@ abstract class OmegaFragment : MvpAppCompatFragment(), OmegaComponent { bindersManager.doAutoInit() } + override fun onDestroyView() { + super.onDestroyView() + detachChildPresenter() + } + override fun getViewForSnackbar() = view!! override fun setWaiting(waiting: Boolean, text: Text?) { @@ -198,13 +229,13 @@ abstract class OmegaFragment : MvpAppCompatFragment(), OmegaComponent { override fun onStop() { super.onStop() + detachChildPresenter() dialogList.forEach { it.setOnDismissListener(null) it.dismiss() } } - override fun exit() { activity!!.finish() } diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index c71d324..d2eea7f 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -77,6 +77,14 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco // nothing } + internal open fun detachChildPresenter(childPresenter: OmegaPresenter<*>) { + childPresenter.detachParentPresenter(this) + } + + internal open fun detachParentPresenter(parentPresenter: OmegaPresenter<*>) { + // nothing + } + protected suspend fun withWaiting(waitingText: Text? = null, block: suspend () -> T): T { withContext(Dispatchers.Main) { viewState.setWaiting(true, waitingText) From 26ea094c369987d59f478e8f8defccefbd8abcb6 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 19 Feb 2020 10:55:32 +0300 Subject: [PATCH 37/54] Change attachParentPresenter method visiblity and add bindAnimator --- .../main/java/com/omega_r/base/binders/OmegaBindable.kt | 5 +++++ .../com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt b/core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt index 1813ddd..2312bf7 100644 --- a/core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt +++ b/core/src/main/java/com/omega_r/base/binders/OmegaBindable.kt @@ -6,6 +6,7 @@ import android.view.animation.AnimationUtils import androidx.annotation.* import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView +import androidx.vectordrawable.graphics.drawable.AnimatorInflaterCompat import com.omega_r.base.OmegaContext import com.omega_r.base.OmegaViewFindable import com.omega_r.base.binders.managers.BindersManager @@ -125,4 +126,8 @@ interface OmegaBindable : OmegaContext, OmegaViewFindable { AnimationUtils.loadAnimation(getContext(), res) }) + fun bindAnimator(@AnimatorRes res: Int) = bindersManager.bind(findInit = { + AnimatorInflaterCompat.loadAnimator(getContext(), res) + }) + } \ No newline at end of file diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index d2eea7f..64f1d3d 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -69,19 +69,19 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return Text.from(R.string.error_unknown) } - internal open fun attachChildPresenter(childPresenter: OmegaPresenter<*>) { + protected open fun attachChildPresenter(childPresenter: OmegaPresenter<*>) { childPresenter.attachParentPresenter(this) } - internal open fun attachParentPresenter(parentPresenter: OmegaPresenter<*>) { + protected open fun attachParentPresenter(parentPresenter: OmegaPresenter<*>) { // nothing } - internal open fun detachChildPresenter(childPresenter: OmegaPresenter<*>) { + protected open fun detachChildPresenter(childPresenter: OmegaPresenter<*>) { childPresenter.detachParentPresenter(this) } - internal open fun detachParentPresenter(parentPresenter: OmegaPresenter<*>) { + protected open fun detachParentPresenter(parentPresenter: OmegaPresenter<*>) { // nothing } From 3f99cc3f20182065f1aa3aa1185dca35348bdf33 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 19 Feb 2020 11:06:07 +0300 Subject: [PATCH 38/54] Fix compliation --- .../base/mvp/presenters/OmegaPresenter.kt | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 64f1d3d..519dbf1 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -69,19 +69,29 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco return Text.from(R.string.error_unknown) } - protected open fun attachChildPresenter(childPresenter: OmegaPresenter<*>) { - childPresenter.attachParentPresenter(this) + internal fun attachChildPresenter(childPresenter: OmegaPresenter<*>) { + onAttachChildPresenter(childPresenter) + childPresenter.onAttachParentPresenter(this) } - protected open fun attachParentPresenter(parentPresenter: OmegaPresenter<*>) { + protected open fun onAttachChildPresenter(childPresenter: OmegaPresenter<*>) { + + } + + protected open fun onAttachParentPresenter(parentPresenter: OmegaPresenter<*>) { // nothing } - protected open fun detachChildPresenter(childPresenter: OmegaPresenter<*>) { - childPresenter.detachParentPresenter(this) + internal fun detachChildPresenter(childPresenter: OmegaPresenter<*>) { + onDetachChildPresenter(childPresenter) + childPresenter.onDetachParentPresenter(this) + } + + protected open fun onDetachChildPresenter(parentPresenter: OmegaPresenter<*>) { + // nothing } - protected open fun detachParentPresenter(parentPresenter: OmegaPresenter<*>) { + protected open fun onDetachParentPresenter(parentPresenter: OmegaPresenter<*>) { // nothing } From 1930fcc7c04d2b3a80398ae1ad07458755846f06 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Thu, 27 Feb 2020 10:36:53 +0300 Subject: [PATCH 39/54] Upgrade OmegaTypes to 2.0.2 --- core/build.gradle | 2 +- .../main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/build.gradle b/core/build.gradle index 7748101..763c1ca 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -58,7 +58,7 @@ dependencies { api 'com.github.Omega-R.OmegaMoxy:moxy-androidx:1.7.1' api "com.github.Omega-R:OmegaRecyclerView:${omegaRecyclerView}@aar" - api 'com.github.Omega-R.OmegaTypes:glide:2.0.1' + api 'com.github.Omega-R.OmegaTypes:glide:2.0.2' api 'com.github.Omega-R:OmegaIntentBuilder:1.2.0' api 'com.github.Omega-R:OmegaLaunchers:1.0.2' api 'com.github.Omega-R:OmegaExtensions:1.0.3' diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index 519dbf1..eefee23 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -75,7 +75,7 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } protected open fun onAttachChildPresenter(childPresenter: OmegaPresenter<*>) { - + // nothing } protected open fun onAttachParentPresenter(parentPresenter: OmegaPresenter<*>) { From cdfc69520ec49b5d055dc0b54b0f1645cb962f86 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Wed, 4 Mar 2020 16:57:11 +0300 Subject: [PATCH 40/54] Add parentLauncher extensions for OmegaPresenter --- .../omega_r/base/components/OmegaComponent.kt | 5 +++++ .../base/mvp/presenters/OmegaPresenter.kt | 16 ++++++++++++++++ .../java/com/omega_r/base/mvp/views/OmegaView.kt | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/core/src/main/java/com/omega_r/base/components/OmegaComponent.kt b/core/src/main/java/com/omega_r/base/components/OmegaComponent.kt index 08b00be..e52e4d0 100644 --- a/core/src/main/java/com/omega_r/base/components/OmegaComponent.kt +++ b/core/src/main/java/com/omega_r/base/components/OmegaComponent.kt @@ -18,6 +18,7 @@ import com.omega_r.base.mvp.model.setAction import com.omega_r.base.mvp.model.setButtons import com.omega_r.base.mvp.model.setPositiveButton import com.omega_r.libs.omegatypes.Text +import com.omegar.libs.omegalaunchers.ActivityLauncher import com.omegar.libs.omegalaunchers.Launcher import kotlinx.coroutines.CompletableDeferred import java.io.Serializable @@ -86,6 +87,10 @@ interface OmegaComponent : OmegaBindable, OmegaView, OmegaClickable { launcher.launch(getContext()!!) } + override fun launch(launcher: ActivityLauncher, vararg parentLaunchers: ActivityLauncher) { + launcher.launch(getContext()!!, *parentLaunchers) + } + fun onLaunchResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { return presenter.onLaunchResult( requestCode, resultCode == Activity.RESULT_OK, diff --git a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt index eefee23..5d32d76 100644 --- a/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt +++ b/core/src/main/java/com/omega_r/base/mvp/presenters/OmegaPresenter.kt @@ -135,6 +135,14 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } } + protected fun ActivityLauncher.launch(vararg launchers: ActivityLauncher) { + try { + viewState.launch(this, *launchers) + } catch (e: Throwable) { + handleErrors(e) + } + } + protected fun ActivityLauncher.DefaultCompanion.launch() { try { viewState.launch(createLauncher()) @@ -143,6 +151,14 @@ open class OmegaPresenter : MvpPresenter(), CoroutineSco } } + protected fun ActivityLauncher.DefaultCompanion.launch(vararg launchers: ActivityLauncher) { + try { + viewState.launch(createLauncher(), *launchers) + } catch (e: Throwable) { + handleErrors(e) + } + } + protected fun BaseIntentLauncher.launchForResult(requestCode: Int) { try { viewState.launchForResult(this, requestCode) diff --git a/core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt b/core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt index 0757a8e..de7871b 100644 --- a/core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt +++ b/core/src/main/java/com/omega_r/base/mvp/views/OmegaView.kt @@ -3,6 +3,7 @@ package com.omega_r.base.mvp.views import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.strategies.RemoveEndTagStrategy import com.omega_r.libs.omegatypes.Text +import com.omegar.libs.omegalaunchers.ActivityLauncher import com.omegar.libs.omegalaunchers.BaseIntentLauncher import com.omegar.libs.omegalaunchers.DialogFragmentLauncher import com.omegar.libs.omegalaunchers.Launcher @@ -45,6 +46,9 @@ interface OmegaView : MvpView { @StateStrategyType(OneExecutionStateStrategy::class) fun launch(launcher: Launcher) + @StateStrategyType(OneExecutionStateStrategy::class) + fun launch(launcher: ActivityLauncher, vararg parentLaunchers: ActivityLauncher) + @StateStrategyType(OneExecutionStateStrategy::class) fun launch(launcher: DialogFragmentLauncher) From 3cf5440bbfc9050848e8da8345d12e5b99719d42 Mon Sep 17 00:00:00 2001 From: Anton Knyazev Date: Tue, 10 Mar 2020 18:59:29 +0300 Subject: [PATCH 41/54] Fix #26: setOnClickListener method is independent of the lifecycle --- .idea/dictionaries/antonknyazev.xml | 1 + .idea/gradle.xml | 4 +- .idea/modules.xml | 5 + .../com/omega_r/base/simple/MainActivity.kt | 5 +- .../com/omega_r/base/simple/MainPresenter.kt | 15 +- .../dialog_fragment/DialogDialogFragment.kt | 31 ++++ .../simple/dialog_fragment/DialogPresenter.kt | 12 ++ .../base/simple/dialog_fragment/DialogView.kt | 8 + app/src/main/res/layout/activity_main.xml | 18 ++- core/build.gradle | 2 +- .../{OmegaContext.kt => OmegaContextable.kt} | 2 +- .../com/omega_r/base/adapters/OmegaAdapter.kt | 17 ++- .../com/omega_r/base/binders/OmegaBindable.kt | 9 +- .../com/omega_r/base/clickers/ClickManager.kt | 139 +++++++++++++++--- .../omega_r/base/clickers/OmegaClickable.kt | 22 +-- .../omega_r/base/components/OmegaActivity.kt | 2 + .../OmegaBottomSheetDialogFragment.kt | 12 +- .../omega_r/base/components/OmegaDialog.kt | 2 + .../base/components/OmegaDialogFragment.kt | 10 +- .../omega_r/base/components/OmegaFragment.kt | 31 ++-- 20 files changed, 255 insertions(+), 92 deletions(-) create mode 100644 app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt create mode 100644 app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt create mode 100644 app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt rename core/src/main/java/com/omega_r/base/{OmegaContext.kt => OmegaContextable.kt} (86%) diff --git a/.idea/dictionaries/antonknyazev.xml b/.idea/dictionaries/antonknyazev.xml index cc29f73..e4fac9f 100644 --- a/.idea/dictionaries/antonknyazev.xml +++ b/.idea/dictionaries/antonknyazev.xml @@ -1,6 +1,7 @@ + contextable knyazev messager diff --git a/.idea/gradle.xml b/.idea/gradle.xml index d476705..22fd758 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,8 +1,11 @@ + diff --git a/.idea/modules.xml b/.idea/modules.xml index 9cbd4a7..7306d0b 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,11 @@ + + + + + diff --git a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt index 7b14661..75c3527 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt @@ -75,6 +75,9 @@ class MainActivity : OmegaActivity(), MainView { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) title = intent.getStringExtra(EXTRA_TITLE) + setOnClickListener(R.id.button) { + showToast(Text.from("Test")) + } } private fun onClickItem(item: Image) { @@ -82,7 +85,7 @@ class MainActivity : OmegaActivity(), MainView { // ActivityLauncher.launch(this, null, createLauncher("1"), createLauncher("2")) - createLauncher("1").launch(this, createLauncher("2")) +// createLauncher("1").launch(this, createLauncher("2")) } data class Item( diff --git a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt index 2e06c1f..d991b7d 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainPresenter.kt @@ -5,6 +5,7 @@ import com.omega_r.base.enitity.contains import com.omega_r.base.logs.log import com.omega_r.base.mvp.model.Action import com.omega_r.base.mvp.presenters.OmegaPresenter +import com.omega_r.base.simple.dialog_fragment.DialogDialogFragment import com.omega_r.libs.omegatypes.Text import com.omegar.mvp.InjectViewState import kotlinx.coroutines.Dispatchers @@ -19,18 +20,8 @@ import java.io.Serializable class MainPresenter : OmegaPresenter() { init { - launch { - delay(5000) - viewState.showToast(Text.from("Go")) - viewState.setWaiting(true) - delay(5000) - viewState.setWaiting(false) - } - - launch { - viewState.showToast(Text.from(getPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE).toString())) - } - + DialogDialogFragment.createLauncher() + .launch() // viewState.showMe // log { // "Message" diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt new file mode 100644 index 0000000..66d8251 --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogDialogFragment.kt @@ -0,0 +1,31 @@ +package com.omega_r.base.simple.dialog_fragment + +import android.os.Bundle +import com.omega_r.base.annotations.OmegaContentView +import com.omega_r.base.components.OmegaDialogFragment +import com.omega_r.base.simple.R +import com.omega_r.libs.omegatypes.Text +import com.omegar.libs.omegalaunchers.createDialogFragmentLauncher +import com.omegar.mvp.presenter.InjectPresenter + +/** + * Created by Anton Knyazev on 10.03.2020. + */ +@OmegaContentView(R.layout.activity_main) +class DialogDialogFragment : OmegaDialogFragment(), DialogView { + + companion object { + fun createLauncher() = createDialogFragmentLauncher() + } + + @InjectPresenter + override lateinit var presenter: DialogPresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setOnClickListener(R.id.button) { + showToast(Text.from("Test from dialog")) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt new file mode 100644 index 0000000..37260b6 --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogPresenter.kt @@ -0,0 +1,12 @@ +package com.omega_r.base.simple.dialog_fragment + +import com.omega_r.base.mvp.presenters.OmegaPresenter +import com.omegar.mvp.InjectViewState + +/** + * Created by Anton Knyazev on 10.03.2020. + */ +@InjectViewState +class DialogPresenter : OmegaPresenter() { + +} \ No newline at end of file diff --git a/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt new file mode 100644 index 0000000..da2a40b --- /dev/null +++ b/app/src/main/java/com/omega_r/base/simple/dialog_fragment/DialogView.kt @@ -0,0 +1,8 @@ +package com.omega_r.base.simple.dialog_fragment + +import com.omega_r.base.mvp.views.OmegaView + +/** + * Created by Anton Knyazev on 10.03.2020. + */ +interface DialogView: OmegaView \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index ecb49be..0e5e488 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,20 +1,26 @@ - +