Skip to content

Commit

Permalink
Merge pull request #3 from bloomreach/dev
Browse files Browse the repository at this point in the history
Dev -> main for release v1
  • Loading branch information
prashant-br authored Sep 18, 2023
2 parents 59b1d4c + 70a7013 commit d00dc89
Show file tree
Hide file tree
Showing 81 changed files with 4,610 additions and 0 deletions.
53 changes: 53 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}

android {
compileSdk 32

defaultConfig {
minSdk 24
targetSdk 32
versionCode 1
versionName "1.0.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
debug {
buildConfigField "String", 'SDK_VERSION', '"1.0.5"'
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

release {
buildConfigField "String", 'SDK_VERSION', '"1.0.5"'
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
// implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.5'

testImplementation 'junit:junit:4.13.2'
testImplementation "org.robolectric:robolectric:4.+"
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.6.0'
}
Empty file added consumer-rules.pro
Empty file.
21 changes: 21 additions & 0 deletions proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.bloomreach.discovery.pixel

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.bloomreach.discovery.pixel.test", appContext.packageName)
}
}
6 changes: 6 additions & 0 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bloomreach.discovery">
<uses-permission android:name="android.permission.INTERNET"/>

</manifest>
58 changes: 58 additions & 0 deletions src/main/java/com/bloomreach/discovery/api/ApiConstants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2022 Bloomreach
*/

package com.bloomreach.discovery.api

/**
* API module constants including request parameters
*/
internal object ApiConstants {

const val REQUEST_TYPE = "request_type"
const val SEARCH_TYPE = "search_type"

const val REQUEST_TYPE_SEARCH = "search"
const val REQUEST_TYPE_SUGGEST = "suggest"

const val SEARCH_TYPE_KEYWORD = "keyword"
const val SEARCH_TYPE_CATEGORY = "category"
const val SEARCH_TYPE_BESTSELLER = "bestseller"

const val ROWS = "rows"
const val DEFAULT_ROWS = 10

const val START = "start"
const val DEFAULT_START = 0

const val SEARCH_TERM = "q"
const val FL = "fl"
const val FQ = "fq"
const val SORT = "sort"
const val STATS_FIELD = "stats.field"
const val EFQ = "efq"
const val LAT_LONG = "ll"
const val FACET_RANGE = "facet.range"

const val USER_ID = "user_id"
const val VIEW_ID = "view_id"
const val WIDGET_ID = "widget_id"

const val ITEM_IDS = "item_ids"
const val CAT_ID = "cat_id"
const val QUERY = "query"
const val CATALOG_NAME = "catalog_name"
const val TITLE = "title"
const val URL = "url"
const val CATALOG_VIEWS = "catalog_views"
const val USER_AGENT = "user_agent"
const val CONTEXT_ID = "context_id"
const val FIELDS = "fields"
const val FILTER_FACET = "filter_facet"
const val FACET = "facet"
const val FILTER = "filter"

const val DEFAULT_FACET_FLAG = false


}
176 changes: 176 additions & 0 deletions src/main/java/com/bloomreach/discovery/api/BrApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Copyright 2022 Bloomreach
*/

package com.bloomreach.discovery.api

import com.bloomreach.discovery.api.listener.BrApiCompletionListener
import com.bloomreach.discovery.api.network.ApiProcessor
import com.bloomreach.discovery.api.request.*

/**
* BrApi Singleton class holds method to initiate BrApiRequest object and API calls methods
*/
object BrApi {
private val TAG: String = BrApi.javaClass.simpleName
private val apiProcessor = ApiProcessor()
lateinit var brApiRequest: BrApiRequest

/**
* Initialise BrApi class with BrApiRequest object
* @param brApiRequest BrApiRequest object defined for initialisation
*/
public fun init(brApiRequest: BrApiRequest) {
BrApi.brApiRequest = brApiRequest
}

/**
* Method for calling Product Search API request
* @param productSearchRequest Request Object required for Product Search API
* @param brApiCompletionListener Callback listener
*/
fun productSearchApi(productSearchRequest: ProductSearchRequest, brApiCompletionListener: BrApiCompletionListener) {
apiProcessor.processCoreApi(productSearchRequest.getMap(), brApiCompletionListener)
}

/**
* Method for calling Category Search API request
* @param categorySearchRequest Request Object required for Category Search API
* @param brApiCompletionListener Callback listener
*/
fun categorySearchApi(categorySearchRequest: CategorySearchRequest, brApiCompletionListener: BrApiCompletionListener) {
apiProcessor.processCoreApi(categorySearchRequest.getMap(), brApiCompletionListener)
}

/**
* Method for calling Content API request
* @param contentSearchRequest Request Object required for Content Search API
* @param brApiCompletionListener Callback listener
*/
fun contentSearchApi(contentSearchRequest: ContentSearchRequest, brApiCompletionListener: BrApiCompletionListener) {
apiProcessor.processCoreApi(contentSearchRequest.getMap(), brApiCompletionListener)
}

/**
* Method for calling BestSeller API request
* @param bestSellerRequest Request Object required for Content Search API
* @param brApiCompletionListener Callback listener
*/
fun bestSellerApi(bestSellerRequest: BestSellerRequest, brApiCompletionListener: BrApiCompletionListener) {
apiProcessor.processCoreApi(bestSellerRequest.getMap(), brApiCompletionListener)
}

/**
* Method for calling Suggest API request
* @param autosuggestRequest Request Object required for Content Search API
* @param brApiCompletionListener Callback listener
*/
fun autoSuggestApi(autosuggestRequest: AutosuggestRequest, brApiCompletionListener: BrApiCompletionListener) {
apiProcessor.processSuggestApi(autosuggestRequest.getMap(), brApiCompletionListener)
}

/* ========= WIDGET API=== */

/**
* Method for calling Recommendation Widget API where apiType can be specified
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param apiType the type of Recommendation Widget API. This is the widgetType path parameter
* @param widgetRequest request Object required for Global Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/
fun recAndPathwaysWidgetApi(widgetId: String, apiType:WidgetApiType, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}

recAndPathwaysWidgetApi(widgetId, apiType.value, widgetRequest, brApiCompletionListener)
}

/**
* Method for calling Recommendation Widget API where apiType can be specified
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param apiType the type of Recommendation Widget API. This is the widgetType path parameter
* @param widgetRequest request Object required for Global Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/
fun recAndPathwaysWidgetApi(widgetId: String,
apiType:String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
apiProcessor.processRecsAndPathwaysApi(widgetId, apiType, widgetRequest.getMap(), brApiCompletionListener)
}

/**
* Method for calling Item-based Recommendation Widget API
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param widgetRequest request Object required for Item-based Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/
fun itemBasedRecommendationWidgetApi(widgetId: String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
recAndPathwaysWidgetApi(widgetId, WidgetApiType.ITEM.value, widgetRequest, brApiCompletionListener)
}

/**
* Method for calling Category-based Recommendation Widget API
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param widgetRequest request Object required for Category-based Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/
fun categoryBasedWidgetApi(widgetId: String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
recAndPathwaysWidgetApi(widgetId, WidgetApiType.CATEGORY.value, widgetRequest, brApiCompletionListener)
}

/**
* Method for calling Keyword-based Widget API
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param widgetRequest request Object required for Keyword-based Recommendation Widget API
* @param brApiCompletionListener Callback listener
*/
fun keywordBasedWidgetApi(widgetId: String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
recAndPathwaysWidgetApi(widgetId, WidgetApiType.KEYWORD.value, widgetRequest, brApiCompletionListener)
}


/**
* Method for calling Personalization-based Widget API
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param widgetRequest request Object required for Personalization-based Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/

fun personalizationBasedWidgetApi(widgetId: String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
recAndPathwaysWidgetApi(widgetId, WidgetApiType.PERSONALIZED.value, widgetRequest, brApiCompletionListener)
}

/**
* Method for calling Global Recommendation Widget API
* @param widgetId The ID of the widget, which can be found in the Widget Configurator in the Dashboard.
* @param widgetRequest request Object required for Global Recommendation Widget API
*
* @param brApiCompletionListener Callback listener
*/
fun globalRecommendationWidgetApi(widgetId: String, widgetRequest: WidgetRequest, brApiCompletionListener: BrApiCompletionListener) {
if(widgetId.isEmpty()) {
throw IllegalArgumentException("Widget Id is empty")
}
recAndPathwaysWidgetApi(widgetId, WidgetApiType.GLOBAL.value, widgetRequest, brApiCompletionListener)
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/bloomreach/discovery/api/BrApiRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2022 Bloomreach
*/

package com.bloomreach.discovery.api

import com.bloomreach.discovery.api.model.Env
import com.bloomreach.discovery.pixel.model.VisitorType

/**
* Class containing initialising parameters for the API SDK.
*
* @property accountId Account Id provided by Bloomreach
* @property uuid Android Advertising ID
* @property visitorType ENUM type for New User or returning user
* @property domainKey The Bloomreach-provided ID of the domain receiving the request.
* @property authKey This parameter is only required if you track users via a universal customer ID.
* @property userId This parameter is only required if you track users via a universal customer ID.
* @property environment ENUM for api to be pointed to which version., STAGE or PROD
*/
data class BrApiRequest(
val accountId: String,
val uuid: String,
val visitorType: VisitorType,
val domainKey: String,
var authKey: String? = null,
var userId: String? = null,
var environment: Env = Env.STAGE
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2022 Bloomreach
*/

package com.bloomreach.discovery.api.listener

import com.bloomreach.discovery.api.model.BrApiError

/**
* Interface to provide callback with response when API is success and Error when API fails
*/
interface BrApiCompletionListener {
fun onBrApiSuccess(response: Any)
fun onBrApiFailure(error: BrApiError)
}
Loading

0 comments on commit d00dc89

Please sign in to comment.