From b2859a891d8c2cd5076a4690064af2c9963dc51b Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 02:39:23 +0200 Subject: [PATCH 01/17] Enabled kotlin for the sdk module --- build.gradle | 2 ++ linkedinsdk/build.gradle | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/build.gradle b/build.gradle index 236a7f9..742f176 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.3.71' repositories { google() jcenter() @@ -12,6 +13,7 @@ buildscript { // Required plugins added to classpath to facilitate pushing to JCenter/Bintray classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' + 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 diff --git a/linkedinsdk/build.gradle b/linkedinsdk/build.gradle index 35271ca..50806e9 100644 --- a/linkedinsdk/build.gradle +++ b/linkedinsdk/build.gradle @@ -1,4 +1,10 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' + +repositories { + mavenCentral() +} android { @@ -29,8 +35,11 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "androidx.appcompat:appcompat:$rootProject.ext.androidxVersion" implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "androidx.core:core-ktx:1.2.0" + testImplementation "junit:junit:$rootProject.ext.junitVersion" androidTestImplementation "androidx.test:runner:$rootProject.ext.testRunnerVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.espressoCoreVersion" From 0441c1cc43f132abc8304fce1eb41e043ee54559 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 02:39:55 +0200 Subject: [PATCH 02/17] Added Executors to replace async tasks --- .../executors/Executors.kt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt new file mode 100644 index 0000000..503c630 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt @@ -0,0 +1,45 @@ +package com.AbdAllahAbdElFattah13.executors + +import android.os.Handler +import android.os.Looper + +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +/** + * Global executor pools for the sdk. + * + * Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind + * webservice requests). + */ +open class Executors( + private val diskIO: Executor, + private val networkIO: Executor, + private val mainThread: Executor +) { + + constructor() : this( + Executors.newSingleThreadExecutor(), + Executors.newFixedThreadPool(3), + MainThreadExecutor() + ) + + fun diskIO(): Executor { + return diskIO + } + + fun networkIO(): Executor { + return networkIO + } + + fun mainThread(): Executor { + return mainThread + } + + private class MainThreadExecutor : Executor { + private val mainThreadHandler = Handler(Looper.getMainLooper()) + override fun execute(command: Runnable) { + mainThreadHandler.post(command) + } + } +} \ No newline at end of file From 81aba0be253dc80d442f802d10936d493c92e69a Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 03:02:06 +0200 Subject: [PATCH 03/17] Added LinkedInConst and the abstract UseCase to be used with various use cases --- .../domain/usecases/UseCase.kt | 10 ++++++++++ .../domain/utils/LinkedInConst.kt | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt new file mode 100644 index 0000000..2b485cd --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt @@ -0,0 +1,10 @@ +package com.AbdAllahAbdElFattah13.domain.usecases + +import com.AbdAllahAbdElFattah13.domain.utils.Executors + +abstract class UseCase constructor( + private val executors: Executors +) { + + abstract fun run(input: Input?): Output +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt new file mode 100644 index 0000000..82d1107 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt @@ -0,0 +1,17 @@ +package com.AbdAllahAbdElFattah13.domain.utils + +object LinkedInConst { + const val AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/authorization" + const val ACCESS_TOKEN_URL = "https://www.linkedin.com/uas/oauth2/accessToken" + const val SECRET_KEY_PARAM = "client_secret" + const val RESPONSE_TYPE_PARAM = "response_type" + const val GRANT_TYPE_PARAM = "grant_type" + const val GRANT_TYPE = "authorization_code" + const val RESPONSE_TYPE_VALUE = "code" + const val CLIENT_ID_PARAM = "client_id" + const val STATE_PARAM = "state" + const val REDIRECT_URI_PARAM = "redirect_uri" + const val QUESTION_MARK = "?" + const val AMPERSAND = "&" + const val EQUALS = "=" +} \ No newline at end of file From c54b583d221daa44f371ba9807898909f671c06e Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 03:02:50 +0200 Subject: [PATCH 04/17] Moved Executors to the new utils package --- .../{executors => domain/utils}/Executors.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{executors => domain/utils}/Executors.kt (95%) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt similarity index 95% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt index 503c630..9791f31 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/executors/Executors.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.executors +package com.AbdAllahAbdElFattah13.domain.utils import android.os.Handler import android.os.Looper From 415b91f384f5e54d80730ba69e42616633d632f1 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 03:03:49 +0200 Subject: [PATCH 05/17] Created RetrieveAccessTokenFromUriUseCase --- .../usecases/RetrieveAccessTokenFromUriUseCase.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt new file mode 100644 index 0000000..73b1782 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt @@ -0,0 +1,11 @@ +package com.AbdAllahAbdElFattah13.domain.usecases + +import android.net.Uri +import com.AbdAllahAbdElFattah13.domain.utils.Executors +import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst + +class RetrieveAccessTokenFromUriUseCase(executors: Executors) : UseCase(executors) { + override fun run(input: Uri?): String? { + return input?.getQueryParameter(LinkedInConst.RESPONSE_TYPE_VALUE) + } +} \ No newline at end of file From cf36570799c9e7a0a00700c9436966f86e122d3a Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 03:04:38 +0200 Subject: [PATCH 06/17] Miner refactor to LinkedInAuthenticationActivity Replacing show/hideProgressDialog with setProgressDialogVisibility --- .../LinkedInAuthenticationActivity.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java index 962be7d..8cf5277 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java @@ -74,19 +74,19 @@ protected void onCreate(Bundle savedInstanceState) { webView.clearHistory(); webView.clearCache(true); - showProgressDialog(); + setProgressDialogVisibility(true); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { - hideProgressDialog(); + setProgressDialogVisibility(false); } //to support below Android N we need to use the deprecated method only @Override public boolean shouldOverrideUrlLoading(WebView view, String authorizationUrl) { - showProgressDialog(); + setProgressDialogVisibility(true); if (authorizationUrl.startsWith(REDIRECT_URI)) { @@ -130,7 +130,7 @@ private class RetrieveDataAsyncTask extends AsyncTask { @Override protected void onPreExecute() { super.onPreExecute(); - showProgressDialog(); + setProgressDialogVisibility(true); } @Override @@ -169,7 +169,7 @@ public void onDataRetrievalStart() { @Override public void onDataSuccess(LinkedInUser linkedInUser) { - hideProgressDialog(); + setProgressDialogVisibility(false); Intent intent = new Intent(); intent.putExtra("social_login", linkedInUser); setResult(Activity.RESULT_OK, intent); @@ -178,7 +178,7 @@ public void onDataSuccess(LinkedInUser linkedInUser) { @Override public void onDataFailed(int errCode, String errMessage) { - hideProgressDialog(); + setProgressDialogVisibility(false); Intent intent = new Intent(); intent.putExtra("err_code", errCode); intent.putExtra("err_message", errMessage); @@ -189,7 +189,7 @@ public void onDataFailed(int errCode, String errMessage) { } else { - hideProgressDialog(); + setProgressDialogVisibility(false); Intent intent = new Intent(); intent.putExtra("err_code", LinkedInFromActivityBuilder.ERROR_FAILED); intent.putExtra("err_message", "AUTHORIZATION FAILED"); @@ -263,21 +263,21 @@ private static String getAuthorizationUrl() { + AMPERSAND + "scope=r_liteprofile%20r_emailaddress"; } - private void showProgressDialog() { + private void setProgressDialogVisibility(boolean show) { if (!LinkedInAuthenticationActivity.this.isFinishing()) { - if (progressDialog == null) { - AlertDialog.Builder builder = new AlertDialog.Builder(LinkedInAuthenticationActivity.this); - builder.setCancelable(false); // if you want user to wait for some process to finish, - builder.setView(R.layout.linkedin_layout_progress_dialog); - progressDialog = builder.create(); + if (show) { + if (progressDialog == null) { + AlertDialog.Builder builder = new AlertDialog.Builder(LinkedInAuthenticationActivity.this); + builder.setCancelable(false); // if you want user to wait for some process to finish, + builder.setView(R.layout.linkedin_layout_progress_dialog); + progressDialog = builder.create(); + } + progressDialog.show(); + } else { + if (progressDialog != null) { + progressDialog.dismiss(); + } } - progressDialog.show(); - } - } - - private void hideProgressDialog() { - if (!LinkedInAuthenticationActivity.this.isFinishing() && progressDialog != null) { - progressDialog.dismiss(); } } } From e8f29cf27198bd8b6d2d40c645cdfb8d59112a50 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 03:12:15 +0200 Subject: [PATCH 07/17] Renamed RetrieveAccessTokenFromUriUseCase -> RetrieveAuthorizationTokenFromUriUseCase for more accurate naming. --- ...riUseCase.kt => RetrieveAuthorizationTokenFromUriUseCase.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/{RetrieveAccessTokenFromUriUseCase.kt => RetrieveAuthorizationTokenFromUriUseCase.kt} (75%) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt similarity index 75% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt index 73b1782..1c6e05f 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAccessTokenFromUriUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt @@ -4,7 +4,7 @@ import android.net.Uri import com.AbdAllahAbdElFattah13.domain.utils.Executors import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst -class RetrieveAccessTokenFromUriUseCase(executors: Executors) : UseCase(executors) { +class RetrieveAuthorizationTokenFromUriUseCase(executors: Executors) : UseCase(executors) { override fun run(input: Uri?): String? { return input?.getQueryParameter(LinkedInConst.RESPONSE_TYPE_VALUE) } From 742af33d2ddbca3f32525aa532d8faba27379314 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Wed, 6 May 2020 11:59:17 +0200 Subject: [PATCH 08/17] Created RetrieveAccessTokenUseCase --- .../domain/abstracts/UseCase.kt | 6 +++ ...etrieveAuthorizationTokenFromUriUseCase.kt | 4 +- .../domain/usecases/UseCase.kt | 10 ---- .../models/LinkedInAccessTokenInfo.kt | 3 ++ .../models/errors/RetrieveAccessTokenError.kt | 8 +++ .../usecases/RetrieveAccessTokenUseCase.kt | 54 +++++++++++++++++++ .../utils}/RequestHandler.java | 2 +- .../LinkedInAuthenticationActivity.java | 3 +- .../RetrieveBasicProfileAsyncTask.java | 2 +- 9 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{linkedinsdk/helpers => domain/utils}/RequestHandler.java (98%) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt new file mode 100644 index 0000000..4069a77 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt @@ -0,0 +1,6 @@ +package com.AbdAllahAbdElFattah13.domain.abstracts + +abstract class UseCase { + + abstract fun run(input: Input?): Output +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt index 1c6e05f..01670cf 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt @@ -1,10 +1,10 @@ package com.AbdAllahAbdElFattah13.domain.usecases import android.net.Uri -import com.AbdAllahAbdElFattah13.domain.utils.Executors +import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst -class RetrieveAuthorizationTokenFromUriUseCase(executors: Executors) : UseCase(executors) { +class RetrieveAuthorizationTokenFromUriUseCase : UseCase() { override fun run(input: Uri?): String? { return input?.getQueryParameter(LinkedInConst.RESPONSE_TYPE_VALUE) } diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt deleted file mode 100644 index 2b485cd..0000000 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/UseCase.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.AbdAllahAbdElFattah13.domain.usecases - -import com.AbdAllahAbdElFattah13.domain.utils.Executors - -abstract class UseCase constructor( - private val executors: Executors -) { - - abstract fun run(input: Input?): Output -} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt new file mode 100644 index 0000000..11a58e9 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt @@ -0,0 +1,3 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models + +data class LinkedInAccessTokenInfo(private val accessToken: String, private val accessTokenExpiry: Long) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt new file mode 100644 index 0000000..d0d4fef --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt @@ -0,0 +1,8 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.errors + +sealed class RetrieveAccessTokenError(msg: String) : RuntimeException("RetrieveAccessTokenError: $msg") { + + class NullInput(msg: String) : RetrieveAccessTokenError(msg) + class AccessTokenRequestFailed(msg: String) : RetrieveAccessTokenError(msg) + +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt new file mode 100644 index 0000000..73f28b0 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt @@ -0,0 +1,54 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.usecases + +import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase +import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo +import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError +import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst +import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler +import org.json.JSONObject +import java.util.* + +class RetrieveAccessTokenUseCase : UseCase() { + + private fun getAccessTokenEndpoint(inputs: RetrieveAccessTokenInputs): String { + return (LinkedInConst.ACCESS_TOKEN_URL + + LinkedInConst.QUESTION_MARK + + LinkedInConst.GRANT_TYPE_PARAM + LinkedInConst.EQUALS + LinkedInConst.GRANT_TYPE + + LinkedInConst.AMPERSAND + + LinkedInConst.RESPONSE_TYPE_VALUE + LinkedInConst.EQUALS + inputs.authorizationToken + + LinkedInConst.AMPERSAND + + LinkedInConst.CLIENT_ID_PARAM + LinkedInConst.EQUALS + inputs.clientId + + LinkedInConst.AMPERSAND + + LinkedInConst.REDIRECT_URI_PARAM + LinkedInConst.EQUALS + inputs.redirectUri + + LinkedInConst.AMPERSAND + + LinkedInConst.SECRET_KEY_PARAM + LinkedInConst.EQUALS + inputs.clientSecretKey) + } + + override fun run(input: RetrieveAccessTokenInputs?): LinkedInAccessTokenInfo { + if (input == null) throw RetrieveAccessTokenError.NullInput("RetrieveAccessTokenUseCase inputs can't be null!") + + val accessTokenEndpoint = getAccessTokenEndpoint(input) + //RequestHandler should be injected to ease testability! + val resultString = RequestHandler.sendPost(accessTokenEndpoint, JSONObject()) + if (resultString != null) { + val resultJson = JSONObject(resultString) + val expiresIn = if (resultJson.has("expires_in")) resultJson.getInt("expires_in") else 0 + val accessToken = if (resultJson.has("access_token")) resultJson.getString("access_token") else null + + if (expiresIn > 0 && accessToken != null) { + val calendar = Calendar.getInstance() + calendar.add(Calendar.SECOND, expiresIn) + val expireDate = calendar.timeInMillis + + val linkedInAccessTokenInfo = LinkedInAccessTokenInfo(accessToken, expireDate) + return linkedInAccessTokenInfo + } else { + throw RetrieveAccessTokenError.AccessTokenRequestFailed("API call returned null access token!") + } + } else { + throw RetrieveAccessTokenError.AccessTokenRequestFailed("Access token API failed!") + } + } + + data class RetrieveAccessTokenInputs(val authorizationToken: String, val clientId: String, val redirectUri: String, val clientSecretKey: String) +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.java similarity index 98% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.java index e264605..b2e8f86 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.java @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.helpers; +package com.AbdAllahAbdElFattah13.domain.utils; import android.util.Log; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java index 8cf5277..5f19d9d 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java @@ -17,7 +17,7 @@ import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.RequestHandler; +import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler; import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; @@ -91,6 +91,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String authorizationUrl) { if (authorizationUrl.startsWith(REDIRECT_URI)) { Uri uri = Uri.parse(authorizationUrl); + //vm.onRedirect(uri); String stateToken = uri.getQueryParameter(STATE_PARAM); if (stateToken == null || !stateToken.equals(STATE)) { Log.e(LinkedInFromActivityBuilder.TAG, "State token doesn't match"); diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java index cef8c5a..25d2346 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java @@ -5,7 +5,7 @@ import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.RequestHandler; +import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler; import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; From 619e5484ecd28efe6e29d648bfae649e743c0c42 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 00:54:28 +0200 Subject: [PATCH 09/17] Converted RequestHandler to Kotlin object and injected it into use cases Closes: #1 --- .../usecases/RetrieveAccessTokenUseCase.kt | 5 +- .../domain/utils/RequestHandler.java | 142 ------------------ .../domain/utils/RequestHandler.kt | 122 +++++++++++++++ 3 files changed, 124 insertions(+), 145 deletions(-) delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.java create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt index 73f28b0..0b0f82b 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt @@ -8,7 +8,7 @@ import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler import org.json.JSONObject import java.util.* -class RetrieveAccessTokenUseCase : UseCase() { +class RetrieveAccessTokenUseCase(private val requestHandler: RequestHandler) : UseCase() { private fun getAccessTokenEndpoint(inputs: RetrieveAccessTokenInputs): String { return (LinkedInConst.ACCESS_TOKEN_URL @@ -28,8 +28,7 @@ class RetrieveAccessTokenUseCase : UseCase itr = params.keys(); - while(itr.hasNext()){ - String key= itr.next(); - Object value = params.get(key); - if (first) - first = false; - else - result.append("&"); - - result.append(URLEncoder.encode(key, "UTF-8")); - result.append("="); - result.append(URLEncoder.encode(value.toString(), "UTF-8")); - } - return result.toString(); - } -} diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt new file mode 100644 index 0000000..0266391 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt @@ -0,0 +1,122 @@ +package com.AbdAllahAbdElFattah13.domain.utils + +import android.util.Log +import org.json.JSONException +import org.json.JSONObject +import java.io.* +import java.net.HttpURLConnection +import java.net.URL +import java.net.URLEncoder +import javax.net.ssl.HttpsURLConnection + +object RequestHandler { + private const val TAG = "RequestHandler" + + /** + * Method that handles Post request + * + * @return String - response from API, null if failed + */ + @JvmStatic + @Throws(IOException::class, JSONException::class) + fun sendPost(urlStr: String, postDataParams: JSONObject): String? { + val url = URL(urlStr) + val conn = url.openConnection() as HttpURLConnection + conn.readTimeout = 20000 + conn.connectTimeout = 20000 + conn.requestMethod = "POST" + conn.doInput = true + conn.doOutput = true + val os = conn.outputStream + val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8")) + writer.write(encodeParams(postDataParams)) + writer.flush() + writer.close() + os.close() + val responseCode = conn.responseCode // To Check for 200 + if (responseCode == HttpsURLConnection.HTTP_OK) { + val bufferedReader = BufferedReader(InputStreamReader(conn.inputStream)) + val sb = StringBuilder() + var line: String + while (bufferedReader.readLine().also { line = it } != null) { + sb.append(line) + break + } + bufferedReader.close() + return sb.toString() + } else { + val err = BufferedReader(InputStreamReader(conn.errorStream)) + val sb = StringBuilder() + var line: String + while (err.readLine().also { line = it } != null) { + sb.append(line) + break + } + err.close() + Log.e(TAG, "Error Code " + conn.responseCode) + Log.e(TAG, "Error Message $sb") + } + return null + } + + /** + * Method that handles Get request + * + * @return String - response from API, null if failed + */ + @JvmStatic + @Throws(IOException::class) + fun sendGet(url: String?, accessToken: String): String? { + val obj = URL(url) + val con = obj.openConnection() as HttpURLConnection + con.requestMethod = "GET" + con.setRequestProperty("Authorization", "Bearer $accessToken") + con.setRequestProperty("cache-control", "no-cache") + con.setRequestProperty("X-Restli-Protocol-Version", "2.0.0") + val responseCode = con.responseCode + Log.d(TAG, "Response Code :: $responseCode") + return if (responseCode == HttpURLConnection.HTTP_OK) { // connection ok + val bufferedReader = BufferedReader(InputStreamReader(con.inputStream)) + var inputLine: String? + val response = StringBuilder() + while (bufferedReader.readLine().also { inputLine = it } != null) { + response.append(inputLine) + } + bufferedReader.close() + response.toString() + } else { + val err = BufferedReader(InputStreamReader(con.errorStream)) + val sb = StringBuilder() + var line: String + while (err.readLine().also { line = it } != null) { + sb.append(line) + break + } + err.close() + Log.e(TAG, "Error Code " + con.responseCode) + Log.e(TAG, "Error Message $sb") + null + } + } + + /** + * Method that encodes parameters + * + * @return String - url encoded string + */ + @Throws(UnsupportedEncodingException::class, JSONException::class) + private fun encodeParams(params: JSONObject): String { + val result = StringBuilder() + var first = true + val itr = params.keys() + while (itr.hasNext()) { + val key = itr.next() + val value = params[key] + if (first) first = false else result.append("&") + result.append(URLEncoder.encode(key, "UTF-8")) + result.append("=") + result.append(URLEncoder.encode(value.toString(), "UTF-8")) + } + return result.toString() + } +} \ No newline at end of file From abe3aa3760f6caa1dc68a21fc8dd4c589fa5bb34 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 01:34:08 +0200 Subject: [PATCH 10/17] created retrieve_basic_profile use case/models/errors close #3 --- .../models/LinkedInAccessTokenInfo.kt | 2 +- .../models/LinkedInBasicProfileInfo.kt | 3 + .../error/RetrieveBasicProfileInfoError.kt | 6 ++ .../usecase/RetrieveBasicProfileInfo.kt | 98 +++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt index 11a58e9..2ca49f2 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt @@ -1,3 +1,3 @@ package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models -data class LinkedInAccessTokenInfo(private val accessToken: String, private val accessTokenExpiry: Long) \ No newline at end of file +data class LinkedInAccessTokenInfo(val accessToken: String, val accessTokenExpiry: Long) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt new file mode 100644 index 0000000..5ce8a21 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt @@ -0,0 +1,3 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models + +data class LinkedInBasicProfileInfo(val id: String, val email: String, val firstName: String, val lastName: String, val profilePictureUrl: String?) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt new file mode 100644 index 0000000..8656b79 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt @@ -0,0 +1,6 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.error + +sealed class RetrieveBasicProfileInfoError(msg: String) : RuntimeException(msg) { + class NullInput(msg: String) : RetrieveBasicProfileInfoError(msg) + class FailedToRetrieveBasicProfileInfo(msg: String) : RetrieveBasicProfileInfoError(msg) +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt new file mode 100644 index 0000000..09f39ca --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt @@ -0,0 +1,98 @@ +package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.usecase + +import android.util.Log +import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase +import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo +import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo +import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError +import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler +import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler.sendGet +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException + +class RetrieveBasicProfileInfo(private val requestHandler: RequestHandler) : UseCase() { + + private val TAG = "RetrieveBasicProfileInf" + + override fun run(input: LinkedInAccessTokenInfo?): LinkedInBasicProfileInfo { + if (input == null) throw RetrieveBasicProfileInfoError.NullInput("Input can't be null for RetrieveBasicProfileInfo") + + try { + val email = retrieveEmailFromAPI(input) + val profileInfo = retrieveBasicProfile(input, email) + + return profileInfo + } catch (e: Exception) { + throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo(e.localizedMessage) + } + } + + /** + * Method that retrieves user email from LinkedIn emailAddress API + */ + @Throws(IOException::class, JSONException::class) + private fun retrieveEmailFromAPI(accessTokenInfo: LinkedInAccessTokenInfo): String { + val emailUrl = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" + val result = sendGet(emailUrl, accessTokenInfo.accessToken) + if (result != null) { + val jsonObject = JSONObject(result) + val email = jsonObject.getJSONArray("elements").getJSONObject(0).getJSONObject("handle~").getString("emailAddress") + return email + } else { + Log.e(TAG, "Failed To Retrieve Email from LinkedIn API") + throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo("Failed To Retrieve Basic Profile") + } + } + + /** + * Method that retrieves user basic info from LinkedIn API + */ + @Throws(IOException::class, JSONException::class) + private fun retrieveBasicProfile(accessTokenInfo: LinkedInAccessTokenInfo, email: String): LinkedInBasicProfileInfo { + val profileEndpoint = "https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))" + val result = requestHandler.sendGet(profileEndpoint, accessTokenInfo.accessToken) + if (result != null) { + val jsonObject = JSONObject(result) + val linkedInUserId = jsonObject.getString("id") + + val country = jsonObject + .getJSONObject("firstName") + .getJSONObject("preferredLocale") + .getString("country") + val language = jsonObject + .getJSONObject("firstName") + .getJSONObject("preferredLocale") + .getString("language") + val firstNameKey = language + "_" + country + val linkedInUserFirstName = jsonObject.getJSONObject("firstName") + .getJSONObject("localized") + .getString(firstNameKey) + + val linkedInUserLastName = jsonObject.getJSONObject("lastName") + .getJSONObject("localized") + .getString(firstNameKey) + + //to take care of users without pp + val linkedInUserProfile = try { + jsonObject + .getJSONObject("profilePicture") + .getJSONObject("displayImage~") + .getJSONArray("elements") + .getJSONObject(0) + .getJSONArray("identifiers") + .getJSONObject(0) + .getString("identifier") + } catch (e: Exception) { + null + } + + return LinkedInBasicProfileInfo(linkedInUserId, email, linkedInUserFirstName, linkedInUserLastName, linkedInUserProfile) + + } else { + Log.e(TAG, "Failed To Retrieve Basic Profile") + throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo("Failed To Retrieve Basic Profile") + } + } + +} \ No newline at end of file From 1671aea3621cc929623188726d4beb2f633f7a33 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 01:35:54 +0200 Subject: [PATCH 11/17] quick refactor: moving domain package inside linkedinsdk package as it should be --- .../models/LinkedInAccessTokenInfo.kt | 3 --- .../LinkedInAuthenticationActivity.java | 2 +- .../linkedinsdk/RetrieveBasicProfileAsyncTask.java | 2 +- .../{ => linkedinsdk}/domain/abstracts/UseCase.kt | 2 +- .../RetrieveAuthorizationTokenFromUriUseCase.kt | 6 +++--- .../models/LinkedInAccessTokenInfo.kt | 3 +++ .../models/errors/RetrieveAccessTokenError.kt | 2 +- .../usecases/RetrieveAccessTokenUseCase.kt | 12 ++++++------ .../models/LinkedInBasicProfileInfo.kt | 2 +- .../models/error/RetrieveBasicProfileInfoError.kt | 2 +- .../usecase/RetrieveBasicProfileInfo.kt | 14 +++++++------- .../{ => linkedinsdk}/domain/utils/Executors.kt | 2 +- .../domain/utils/LinkedInConst.kt | 2 +- .../domain/utils/RequestHandler.kt | 2 +- 14 files changed, 28 insertions(+), 28 deletions(-) delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/abstracts/UseCase.kt (58%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt (52%) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt (72%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt (82%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt (61%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt (71%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt (85%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/utils/Executors.kt (94%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/utils/LinkedInConst.kt (91%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/{ => linkedinsdk}/domain/utils/RequestHandler.kt (98%) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt deleted file mode 100644 index 2ca49f2..0000000 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models - -data class LinkedInAccessTokenInfo(val accessToken: String, val accessTokenExpiry: Long) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java index 5f19d9d..620ddb6 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java @@ -17,7 +17,7 @@ import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; -import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler; +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler; import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java index 25d2346..f6cc1a5 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java @@ -5,7 +5,7 @@ import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; -import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler; +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler; import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt similarity index 58% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt index 4069a77..618b4ad 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/abstracts/UseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.abstracts +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts abstract class UseCase { diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt similarity index 52% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt index 01670cf..6ee9441 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt @@ -1,8 +1,8 @@ -package com.AbdAllahAbdElFattah13.domain.usecases +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases import android.net.Uri -import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase -import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst class RetrieveAuthorizationTokenFromUriUseCase : UseCase() { override fun run(input: Uri?): String? { diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt new file mode 100644 index 0000000..253c4b7 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt @@ -0,0 +1,3 @@ +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models + +data class LinkedInAccessTokenInfo(val accessToken: String, val accessTokenExpiry: Long) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt similarity index 72% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt index d0d4fef..10df57b 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.errors +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors sealed class RetrieveAccessTokenError(msg: String) : RuntimeException("RetrieveAccessTokenError: $msg") { diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt similarity index 82% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt index 0b0f82b..dde586e 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt @@ -1,10 +1,10 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.usecases +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases -import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase -import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo -import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError -import com.AbdAllahAbdElFattah13.domain.utils.LinkedInConst -import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler import org.json.JSONObject import java.util.* diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt similarity index 61% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt index 5ce8a21..d5d9f4d 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt @@ -1,3 +1,3 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models data class LinkedInBasicProfileInfo(val id: String, val email: String, val firstName: String, val lastName: String, val profilePictureUrl: String?) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt similarity index 71% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt index 8656b79..74a0ee1 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.error +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error sealed class RetrieveBasicProfileInfoError(msg: String) : RuntimeException(msg) { class NullInput(msg: String) : RetrieveBasicProfileInfoError(msg) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt similarity index 85% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt index 09f39ca..5a99326 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt @@ -1,12 +1,12 @@ -package com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.usecase +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase import android.util.Log -import com.AbdAllahAbdElFattah13.domain.abstracts.UseCase -import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo -import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo -import com.AbdAllahAbdElFattah13.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError -import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler -import com.AbdAllahAbdElFattah13.domain.utils.RequestHandler.sendGet +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler.sendGet import org.json.JSONException import org.json.JSONObject import java.io.IOException diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt similarity index 94% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt index 9791f31..1b46e21 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/Executors.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.utils +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils import android.os.Handler import android.os.Looper diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt similarity index 91% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt index 82d1107..1302425 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/LinkedInConst.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.utils +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils object LinkedInConst { const val AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/authorization" diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt similarity index 98% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt index 0266391..2a136b6 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/domain/utils/RequestHandler.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.domain.utils +package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils import android.util.Log import org.json.JSONException From 1bd07deac639fc843a52518c7c59afd58dd8ced6 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 01:40:51 +0200 Subject: [PATCH 12/17] added livedata and viewmodel gradle dependencies see #4 --- build.gradle | 4 ++++ linkedinsdk/build.gradle | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/build.gradle b/build.gradle index 742f176..36e6ea2 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,10 @@ ext { testRunnerVersion = "1.2.0" espressoCoreVersion = "3.2.0" + //arch components + lifecycle_version = "2.2.0" + arch_version = "2.1.0" + // LinkedIn SDK Library Info libVersionCode = 1 libVersionName = '1.0.0' diff --git a/linkedinsdk/build.gradle b/linkedinsdk/build.gradle index 50806e9..bfe05ea 100644 --- a/linkedinsdk/build.gradle +++ b/linkedinsdk/build.gradle @@ -40,7 +40,12 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation "androidx.core:core-ktx:1.2.0" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.ext.lifecycle_version" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.ext.lifecycle_version" + testImplementation "junit:junit:$rootProject.ext.junitVersion" + testImplementation "androidx.arch.core:core-testing:$rootProject.ext.arch_version" + androidTestImplementation "androidx.test:runner:$rootProject.ext.testRunnerVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.espressoCoreVersion" } From afd2fb6f3ec58f0cb43a9027edf36f6f58071aca Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 02:06:18 +0200 Subject: [PATCH 13/17] created 1st draft of LinkedInAuthenticationViewModel see #4 --- .../usecases/RetrieveAccessTokenUseCase.kt | 1 + ....kt => RetrieveBasicProfileInfoUseCase.kt} | 2 +- .../models/LinkedInAuthenticationState.kt | 14 +++++ .../models/LinkedInInitializationInfo.kt | 3 + .../LinkedInAuthenticationViewModel.kt | 59 +++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/{RetrieveBasicProfileInfo.kt => RetrieveBasicProfileInfoUseCase.kt} (96%) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt index dde586e..f8ae3d6 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt @@ -24,6 +24,7 @@ class RetrieveAccessTokenUseCase(private val requestHandler: RequestHandler) : U + LinkedInConst.SECRET_KEY_PARAM + LinkedInConst.EQUALS + inputs.clientSecretKey) } + @Throws(RetrieveAccessTokenError::class) override fun run(input: RetrieveAccessTokenInputs?): LinkedInAccessTokenInfo { if (input == null) throw RetrieveAccessTokenError.NullInput("RetrieveAccessTokenUseCase inputs can't be null!") diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt similarity index 96% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt index 5a99326..b171919 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfo.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt @@ -11,7 +11,7 @@ import org.json.JSONException import org.json.JSONObject import java.io.IOException -class RetrieveBasicProfileInfo(private val requestHandler: RequestHandler) : UseCase() { +class RetrieveBasicProfileInfoUseCase(private val requestHandler: RequestHandler) : UseCase() { private val TAG = "RetrieveBasicProfileInf" diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt new file mode 100644 index 0000000..4c9499c --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt @@ -0,0 +1,14 @@ +package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models + +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError + +sealed class LinkedInAuthenticationState { + object Loading : LinkedInAuthenticationState() + class AccessTokenRetrievedSuccessfully(val accessTokenInfo: LinkedInAccessTokenInfo) : LinkedInAuthenticationState() + class FailedToRetrieveAccessToken(val accessTokenRetrievalError: RetrieveAccessTokenError) : LinkedInAuthenticationState() + class BasicProfileRetrievedSuccessfully(val profileInfo: LinkedInBasicProfileInfo) : LinkedInAuthenticationState() + class FailedToRetrieveProfile(val accessTokenRetrievalError: RetrieveBasicProfileInfoError) : LinkedInAuthenticationState() +} \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt new file mode 100644 index 0000000..d430945 --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt @@ -0,0 +1,3 @@ +package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models + +data class LinkedInInitializationInfo(val clientId: String, val redirectUri: String, val clientSecretKey: String) \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt new file mode 100644 index 0000000..d884ecc --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt @@ -0,0 +1,59 @@ +package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases.RetrieveAccessTokenUseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase.RetrieveBasicProfileInfoUseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.Executors +import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInAuthenticationState +import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInInitializationInfo + +class LinkedInAuthenticationViewModel( + private val initializationInfo: LinkedInInitializationInfo, + private val retrieveAccessTokenUseCase: RetrieveAccessTokenUseCase, + private val retrieveBasicProfileInfoUseCase: RetrieveBasicProfileInfoUseCase, + private val executors: Executors +) : ViewModel() { + + private val _state = MutableLiveData() + val state: LiveData = _state + + fun onAuthorizationTokenGranted(authorizationToken: String) { + _state.value = LinkedInAuthenticationState.Loading + + executors.networkIO().execute { + val accessTokenInfo = try { + retrieveAccessTokenUseCase.run(RetrieveAccessTokenUseCase.RetrieveAccessTokenInputs( + authorizationToken = authorizationToken, + clientId = initializationInfo.clientId, + clientSecretKey = initializationInfo.clientSecretKey, + redirectUri = initializationInfo.redirectUri + )) + } catch (e: RetrieveAccessTokenError) { + executors.mainThread().execute { + _state.value = LinkedInAuthenticationState.FailedToRetrieveAccessToken(e) + } + return@execute + } + executors.mainThread().execute { + _state.value = LinkedInAuthenticationState.AccessTokenRetrievedSuccessfully(accessTokenInfo) + } + + val profileInfo = try { + retrieveBasicProfileInfoUseCase.run(accessTokenInfo) + } catch (e: RetrieveBasicProfileInfoError) { + executors.mainThread().execute { + _state.value = LinkedInAuthenticationState.FailedToRetrieveProfile(e) + } + return@execute + } + executors.mainThread().execute { + _state.value = LinkedInAuthenticationState.BasicProfileRetrievedSuccessfully(profileInfo) + } + } + } + +} \ No newline at end of file From 023c3ad46817ed6e0c36c34f04f7ff5bfad67f60 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 02:25:45 +0200 Subject: [PATCH 14/17] created ui package and moved builders/activity to it --- .../linkedin/login/MainActivity.java | 7 +++---- linkedinsdk/src/main/AndroidManifest.xml | 2 +- .../{ => ui}/LinkedInAuthenticationActivity.java | 7 +++---- .../linkedinsdk/{helpers => ui}/LinkedInUser.java | 2 +- .../{helpers => ui}/OnBasicProfileListener.java | 4 +++- .../{ => ui}/RetrieveBasicProfileAsyncTask.java | 6 ++---- .../{ => ui}/linkedin_builder/LinkedInBuilder.java | 8 ++++---- .../linkedin_builder/LinkedInFromActivityBuilder.java | 3 +-- .../linkedin_builder/LinkedInFromFragmentBuilder.java | 2 +- 9 files changed, 19 insertions(+), 22 deletions(-) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{ => ui}/LinkedInAuthenticationActivity.java (97%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{helpers => ui}/LinkedInUser.java (97%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{helpers => ui}/OnBasicProfileListener.java (62%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{ => ui}/RetrieveBasicProfileAsyncTask.java (93%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{ => ui}/linkedin_builder/LinkedInBuilder.java (91%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{ => ui}/linkedin_builder/LinkedInFromActivityBuilder.java (86%) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/{ => ui}/linkedin_builder/LinkedInFromFragmentBuilder.java (91%) diff --git a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java index 9618e11..a24fd13 100644 --- a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java +++ b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java @@ -15,10 +15,9 @@ import android.widget.TextView; import android.widget.Toast; -import com.AbdAllahAbdElFattah13.linkedin.login.R; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; -import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInUser; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.OnBasicProfileListener; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; import org.json.JSONObject; diff --git a/linkedinsdk/src/main/AndroidManifest.xml b/linkedinsdk/src/main/AndroidManifest.xml index edf24ee..e9511ae 100644 --- a/linkedinsdk/src/main/AndroidManifest.xml +++ b/linkedinsdk/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ package="com.AbdAllahAbdElFattah13.linkedinsdk"> - + \ No newline at end of file diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.java similarity index 97% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.java index 620ddb6..37fe32c 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.java @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui; import android.annotation.SuppressLint; import android.app.Activity; @@ -15,10 +15,9 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; +import com.AbdAllahAbdElFattah13.linkedinsdk.R; import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler; -import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; import org.json.JSONObject; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java similarity index 97% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java index 9010ab9..c33c38a 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.helpers; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui; import android.os.Parcel; import android.os.Parcelable; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/OnBasicProfileListener.java similarity index 62% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/OnBasicProfileListener.java index 0d11cce..d7d37be 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/OnBasicProfileListener.java @@ -1,4 +1,6 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.helpers; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui; + +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInUser; public interface OnBasicProfileListener { void onDataRetrievalStart(); diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/RetrieveBasicProfileAsyncTask.java similarity index 93% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/RetrieveBasicProfileAsyncTask.java index f6cc1a5..0523ddf 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/RetrieveBasicProfileAsyncTask.java @@ -1,12 +1,10 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui; import android.os.AsyncTask; import android.util.Log; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler; -import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder; import org.json.JSONException; import org.json.JSONObject; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java similarity index 91% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java index dcea7f8..c94d5d8 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder; import android.content.Context; import android.content.Intent; @@ -6,9 +6,9 @@ import androidx.annotation.NonNull; -import com.AbdAllahAbdElFattah13.linkedinsdk.LinkedInAuthenticationActivity; -import com.AbdAllahAbdElFattah13.linkedinsdk.RetrieveBasicProfileAsyncTask; -import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInAuthenticationActivity; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.RetrieveBasicProfileAsyncTask; +import com.AbdAllahAbdElFattah13.linkedinsdk.ui.OnBasicProfileListener; import java.util.Random; diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java similarity index 86% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java index 06ed007..cf27718 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java @@ -1,7 +1,6 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder; import android.app.Activity; -import android.content.Context; import android.content.Intent; public final class LinkedInFromActivityBuilder extends LinkedInBuilder { diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java similarity index 91% rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java index 556943b..6375cc7 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java @@ -1,4 +1,4 @@ -package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder; +package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder; import android.content.Intent; From 037d70256bf8a3594f5617d29ecb3fc6dadd5ca9 Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 02:26:34 +0200 Subject: [PATCH 15/17] added LinkedInAuthenticationViewModelFactory see #4 --- .../LinkedInAuthenticationViewModel.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt index d884ecc..bd0f29a 100644 --- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt @@ -3,6 +3,7 @@ package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authenticati import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases.RetrieveAccessTokenUseCase import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError @@ -55,5 +56,24 @@ class LinkedInAuthenticationViewModel( } } } +} +@Suppress("UNCHECKED_CAST") +class LinkedInAuthenticationViewModelFactory constructor( + private val initializationInfo: LinkedInInitializationInfo, + private val retrieveAccessTokenUseCase: RetrieveAccessTokenUseCase, + private val retrieveBasicProfileInfoUseCase: RetrieveBasicProfileInfoUseCase, + private val executors: Executors +) : ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(LinkedInAuthenticationViewModel::class.java)) { + return (LinkedInAuthenticationViewModel( + initializationInfo, + retrieveAccessTokenUseCase, + retrieveBasicProfileInfoUseCase, + executors + )) as T + } + throw IllegalArgumentException("Unknown ViewModel class!") + } } \ No newline at end of file From d2d5a95a88d8bf56ca134d3d4a2025432db7baac Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 02:27:33 +0200 Subject: [PATCH 16/17] created quick manual di to connect usecases/viewmodel together closes #6 --- .../linkedinsdk/di/DI.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DI.kt diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DI.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DI.kt new file mode 100644 index 0000000..0c699bf --- /dev/null +++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DI.kt @@ -0,0 +1,23 @@ +package com.AbdAllahAbdElFattah13.linkedinsdk.di + +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases.RetrieveAccessTokenUseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase.RetrieveBasicProfileInfoUseCase +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.Executors +import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler +import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInInitializationInfo +import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.viewmodel.LinkedInAuthenticationViewModelFactory + +class DI( + private val initializationInfo: LinkedInInitializationInfo, + private val requestHandler: RequestHandler, + private val executors: Executors +) { + fun providesRetrieveAccessTokenUseCase() = RetrieveAccessTokenUseCase(requestHandler) + fun providesRetrieveBasicProfileInfoUseCase() = RetrieveBasicProfileInfoUseCase(requestHandler) + fun providesLinkedInAuthenticationViewModelFactory() = LinkedInAuthenticationViewModelFactory( + initializationInfo, + providesRetrieveAccessTokenUseCase(), + providesRetrieveBasicProfileInfoUseCase(), + executors + ) +} \ No newline at end of file From 54e66c665cddc507ea59e1443741e8c7d6493b0b Mon Sep 17 00:00:00 2001 From: AbdAllah Date: Thu, 7 May 2020 11:41:10 +0200 Subject: [PATCH 17/17] closes milestone #1 * Removing all un-used Async tasks since they have been replaced by vm + usecases + executors. * Rewrote LinkedInAuthenticationActivity in Kotlin, removing old java file. --- .../linkedin/login/MainActivity.java | 113 +++---- app/src/main/res/layout/activity_main.xml | 17 -- .../di/{DI.kt => DependencyGraph.kt} | 2 +- .../models/LinkedInBasicProfileInfo.kt | 2 +- .../RetrieveBasicProfileInfoUseCase.kt | 2 +- .../linkedinsdk/domain/utils/LinkedInConst.kt | 7 + .../models/LinkedInInitializationInfo.kt | 2 +- .../ui/LinkedInAuthenticationActivity.java | 283 ------------------ .../ui/LinkedInAuthenticationActivity.kt | 173 +++++++++++ .../linkedinsdk/ui/LinkedInUser.java | 14 +- .../ui/OnBasicProfileListener.java | 12 - .../ui/RetrieveBasicProfileAsyncTask.java | 115 ------- .../ui/linkedin_builder/LinkedInBuilder.java | 9 - 13 files changed, 229 insertions(+), 522 deletions(-) rename linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/{DI.kt => DependencyGraph.kt} (98%) delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.java create mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.kt delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/OnBasicProfileListener.java delete mode 100644 linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/RetrieveBasicProfileAsyncTask.java diff --git a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java index a24fd13..ebcfdda 100644 --- a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java +++ b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java @@ -1,8 +1,5 @@ package com.AbdAllahAbdElFattah13.linkedin.login; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -15,16 +12,13 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInUser; -import com.AbdAllahAbdElFattah13.linkedinsdk.ui.OnBasicProfileListener; import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; @@ -37,12 +31,8 @@ public class MainActivity extends AppCompatActivity { private ImageView ivUserPic; private Button btnLogin; - private Button btnGetUpdatedInfo; private TextView tvFName, tvLName, tvEmail; - private String accessToken; - private long accessTokenExpiry; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -50,7 +40,6 @@ protected void onCreate(Bundle savedInstanceState) { getCredentials(); - ivUserPic = findViewById(R.id.iv_user_pic); btnLogin = findViewById(R.id.btn_login); tvFName = findViewById(R.id.tv_first_name); @@ -69,41 +58,12 @@ public void onClick(View v) { } }); - - btnGetUpdatedInfo = findViewById(R.id.btn_get_update); - btnGetUpdatedInfo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - LinkedInFromActivityBuilder.retrieveBasicProfile(accessToken, accessTokenExpiry, new OnBasicProfileListener() { - @Override - public void onDataRetrievalStart() { - - } - - @Override - public void onDataSuccess(LinkedInUser user) { - setUserData(user); - } - - @Override - public void onDataFailed(int errCode, String errMessage) { - - Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_SHORT).show(); - } - }); - - } - }); - } /** * Sets data to UI */ private void setUserData(LinkedInUser user) { - accessToken = user.getAccessToken(); - accessTokenExpiry = user.getAccessTokenExpiry(); Log.wtf("LINKEDIN ID", user.getId()); @@ -111,18 +71,14 @@ private void setUserData(LinkedInUser user) { tvLName.setText(user.getLastName()); tvEmail.setText(user.getEmail()); - btnGetUpdatedInfo.setVisibility(View.VISIBLE); - - if(user.getProfileUrl()!= null && !user.getProfileUrl().isEmpty()){ - new ImageLoadTask(user.getProfileUrl(), ivUserPic).execute(); + if (user.getProfilePictureUrl() != null && !user.getProfilePictureUrl().isEmpty()) { + new ImageLoadTask(user.getProfilePictureUrl(), ivUserPic).execute(); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - - super.onActivityResult(requestCode, resultCode, data); if (requestCode == LINKEDIN_REQUEST && data != null) { @@ -133,8 +89,6 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten setUserData(user); } else { - - //print the error Log.wtf("LINKEDIN ERR", data.getStringExtra("err_message")); @@ -145,11 +99,8 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten //some error occured Toast.makeText(this, "Failed", Toast.LENGTH_SHORT).show(); } - - } } - } @@ -187,7 +138,6 @@ protected void onPostExecute(Bitmap result) { super.onPostExecute(result); imageView.setImageBitmap(result); } - } @@ -198,25 +148,38 @@ protected void onPostExecute(Bitmap result) { * Make sure to update your linkedin credentials in the said file */ private void getCredentials() { - try { - - InputStream is = getAssets().open("linkedin-credentials.json"); - int size = is.available(); - byte[] buffer = new byte[size]; - is.read(buffer); - is.close(); - String json = new String(buffer, "UTF-8"); - JSONObject linkedinCred = new JSONObject(json); - clientID = linkedinCred.getString("client_id"); - clientSecret = linkedinCred.getString("client_secret"); - redirectUrl = linkedinCred.getString("redirect_url"); - - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (JSONException e) { - e.printStackTrace(); - } + + // 77uzd83rv05qdd +// 11jwfr3Jh1g6Vldb +// private const val REDIRECT_URI = "https://www.cuju.io/android" + + clientID = "77uzd83rv05qdd"; + clientSecret = "11jwfr3Jh1g6Vldb"; + redirectUrl = "https://www.cuju.io/android"; + +// try { +// +// InputStream is = getAssets().open("linkedin-credentials.json"); +// int size = is.available(); +// byte[] buffer = new byte[size]; +// is.read(buffer); +// is.close(); +// String json = new String(buffer, "UTF-8"); +// JSONObject linkedinCred = new JSONObject(json); +//// 77uzd83rv05qdd +//// 11jwfr3Jh1g6Vldb +//// private const val REDIRECT_URI = "https://www.cuju.io/android" +// +// clientID = "77uzd83rv05qdd"; +// clientSecret = "11jwfr3Jh1g6Vldb"; +// redirectUrl = "https://www.cuju.io/android"; +// +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (JSONException e) { +// e.printStackTrace(); +// } } } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 04a989b..d659d34 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -37,8 +37,6 @@ android:layout_height="wrap_content" /> - -