Skip to content

Commit

Permalink
Deserialize LocatorList to SearchLocatorList
Browse files Browse the repository at this point in the history
  • Loading branch information
hrishikesh-kadam committed Nov 1, 2018
1 parent 1ffa8f6 commit 078ab70
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 52 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ ext {
constraintLayoutVersion = "1.1.3"

jacksonVersion = "2.9.7"
// When Kotlin Class doesn't contain default Constructor GSON can be used to deserialize
// See FolioReader-Android/folioreader/src/test/java/com/folioreader/android/LocatorUnitTest.kt
gsonVersion = "2.8.5"
}

task clean(type: Delete) {
Expand Down
3 changes: 3 additions & 0 deletions folioreader/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ dependencies {
implementation "com.android.support:recyclerview-v7:$androidSupportLibVersion"
implementation "com.android.support:support-v4:$androidSupportLibVersion"
implementation "com.android.support:design:$androidSupportLibVersion"
testImplementation 'junit:junit:4.12'

implementation 'org.slf4j:slf4j-android:1.7.25'
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
Expand All @@ -97,6 +98,8 @@ dependencies {
implementation "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
implementation "com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion"
implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion"
implementation "com.google.code.gson:gson:$gsonVersion"

// R2 modules
api("com.github.codetoart:r2-shared-kotlin:$r2SharedKotlinVersion") {
Expand Down
62 changes: 30 additions & 32 deletions folioreader/src/main/java/com/folioreader/loaders/SearchLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import android.net.Uri
import android.os.Bundle
import android.support.v4.content.AsyncTaskLoader
import android.util.Log
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.folioreader.model.search.SearchItem
import com.folioreader.model.search.SearchItemType
import com.folioreader.model.search.SearchLocator
import com.folioreader.ui.folio.activity.SearchActivity
import com.folioreader.ui.folio.adapter.ListViewType
import com.folioreader.ui.folio.adapter.SearchAdapter
import com.folioreader.util.AppUtil
import org.readium.r2.streamer.r2_streamer_java.SearchQueryResults
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import org.readium.r2.shared.Locator
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
Expand Down Expand Up @@ -66,7 +66,7 @@ class SearchLoader : AsyncTaskLoader<Any?> {
override fun loadInBackground(): Any? {
Log.v(LOG_TAG, "-> loadInBackground")

var searchQueryResults: SearchQueryResults? = null
var locatorList: MutableList<Locator>? = null

try {
val searchUri: Uri? = loaderBundle?.getParcelable(SearchActivity.BUNDLE_SEARCH_URI)
Expand All @@ -87,11 +87,12 @@ class SearchLoader : AsyncTaskLoader<Any?> {

//Thread.sleep(6000)

val objectMapper = ObjectMapper()
/*val objectMapper = ObjectMapper()
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
searchQueryResults = objectMapper.readValue(stringBuilder.toString(),
SearchQueryResults::class.java)
Log.v(LOG_TAG, "-> loadInBackground -> " + stringBuilder.toString())
locatorList = objectMapper.readValue(stringBuilder.toString())*/
val locatorType = object : TypeToken<MutableList<Locator>>() {}.type
locatorList = Gson().fromJson(stringBuilder.toString(), locatorType)
Log.d(LOG_TAG, "-> loadInBackground -> " + stringBuilder.toString())

inputStream.close()
urlConnection.disconnect()
Expand All @@ -101,17 +102,17 @@ class SearchLoader : AsyncTaskLoader<Any?> {
}

return when {
searchQueryResults == null -> {
locatorList == null -> {
val dataBundle = Bundle()
dataBundle.putString(ListViewType.KEY, ListViewType.FAILURE_VIEW.toString())
dataBundle
}
searchQueryResults.searchCount == 0 -> {
locatorList.size == 0 -> {
val dataBundle = Bundle()
dataBundle.putString(ListViewType.KEY, ListViewType.EMPTY_VIEW.toString())
dataBundle
}
else -> initSearchItemList(searchQueryResults)
else -> initSearchLocatorList(locatorList)
}
}

Expand All @@ -128,38 +129,35 @@ class SearchLoader : AsyncTaskLoader<Any?> {
return running
}

private fun initSearchItemList(searchQueryResults: SearchQueryResults): Bundle {
Log.v(LOG_TAG, "-> initSearchItemList")
private fun initSearchLocatorList(locatorList: MutableList<Locator>): Bundle {
Log.v(LOG_TAG, "-> initSearchLocatorList")

val searchItemList = ArrayList<SearchItem>()
val searchLocatorList: MutableList<SearchLocator> = mutableListOf()

val searchCountItem = SearchItem()
val searchCountItem = SearchLocator()
searchCountItem.searchItemType = SearchItemType.SEARCH_COUNT_ITEM
searchCountItem.primaryContents = searchQueryResults.searchCount.toString()
searchItemList.add(searchCountItem)
searchCountItem.primaryContents = locatorList.size.toString()
searchLocatorList.add(searchCountItem)

var title: String? = null
var resourceHref: String? = null

for (searchResult in searchQueryResults.searchResultList) {
for (locator in locatorList) {

if (title != searchResult.title) {
title = searchResult.title
val titleItem = SearchItem()
titleItem.searchItemType = SearchItemType.PAGE_TITLE_ITEM
titleItem.primaryContents = title
searchItemList.add(titleItem)
if (resourceHref != locator.href) {
resourceHref = locator.href
val titleLocator = SearchLocator()
titleLocator.searchItemType = SearchItemType.RESOURCE_TITLE_ITEM
titleLocator.primaryContents = locator.title
searchLocatorList.add(titleLocator)
}

val searchResultItem = SearchItem(searchResult)
searchResultItem.searchItemType = SearchItemType.SEARCH_RESULT_ITEM
searchResultItem.primaryContents = searchResultItem.sentence
searchItemList.add(searchResultItem)
val searchResultItem = SearchLocator(locator, SearchItemType.SEARCH_RESULT_ITEM)
searchLocatorList.add(searchResultItem)
}

val dataBundle = Bundle()
dataBundle.putString(ListViewType.KEY, ListViewType.NORMAL_VIEW.toString())
dataBundle.putParcelableArrayList("DATA", searchItemList)

dataBundle.putParcelableArrayList("DATA", ArrayList(searchLocatorList))
return dataBundle
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.folioreader.model.search

enum class SearchItemType {
UNKNOWN_ITEM,
SEARCH_COUNT_ITEM,
PAGE_TITLE_ITEM,
RESOURCE_TITLE_ITEM,
SEARCH_RESULT_ITEM
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.folioreader.model.search

import android.os.Parcel
import android.os.Parcelable
import org.readium.r2.shared.Locations
import org.readium.r2.shared.Locator
import org.readium.r2.shared.LocatorText

// TODO -> Move to locator package
class SearchLocator : Locator, Parcelable {

var primaryContents: String? = text?.before + text?.hightlight + text?.after
var searchItemType: SearchItemType

constructor() : this(Locator("", 0, "", Locations(), null), SearchItemType.UNKNOWN_ITEM)

constructor(locator: Locator, searchItemType: SearchItemType) :
super(locator.href, locator.created, locator.title, locator.locations, locator.text) {
this.searchItemType = searchItemType
}

constructor(parcel: Parcel) : this(
Locator(
parcel.readString()!!,
parcel.readLong(),
parcel.readString()!!,
parcel.readSerializable() as Locations,
parcel.readSerializable() as LocatorText?
), SearchItemType.valueOf(parcel.readString()!!))

override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(href)
parcel.writeLong(created)
parcel.writeString(title)
parcel.writeSerializable(locations)
parcel.writeSerializable(text)
parcel.writeString(searchItemType.name)
}

override fun describeContents(): Int {
return 0
}

companion object {

@JvmField
val CREATOR = object : Parcelable.Creator<SearchLocator> {
override fun createFromParcel(parcel: Parcel): SearchLocator {
return SearchLocator(parcel)
}

override fun newArray(size: Int): Array<SearchLocator?> {
return arrayOfNulls(size)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Intent
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v4.content.LocalBroadcastManager
Expand Down Expand Up @@ -345,13 +346,13 @@ class SearchActivity : AppCompatActivity(), LoaderManager.LoaderCallbacks<Any?>,

if (adapter is SearchAdapter) {
if (viewHolder is SearchAdapter.NormalViewHolder) {
Log.v(LOG_TAG, "-> onItemClick -> " + viewHolder.searchItem)
Log.v(LOG_TAG, "-> onItemClick -> " + viewHolder.searchLocator)

val intent = Intent()
searchAdapterDataBundle.putInt(BUNDLE_FIRST_VISIBLE_ITEM_INDEX,
linearLayoutManager.findFirstVisibleItemPosition())
intent.putExtra(SearchAdapter.DATA_BUNDLE, searchAdapterDataBundle)
intent.putExtra(FolioActivity.EXTRA_SEARCH_ITEM, viewHolder.searchItem)
intent.putExtra(FolioActivity.EXTRA_SEARCH_ITEM, viewHolder.searchLocator as Parcelable)
intent.putExtra(BUNDLE_SAVE_SEARCH_QUERY, searchView.query)
setResult(ResultCode.ITEM_SELECTED.value, intent)
finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.folioreader.R
import com.folioreader.model.search.SearchItem
import com.folioreader.model.search.SearchItemType
import com.folioreader.model.search.SearchLocator

class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

Expand All @@ -26,7 +26,7 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

private val context: Context
private var listViewType: ListViewType
var searchItemList: ArrayList<SearchItem>? = null
var searchLocatorList: MutableList<SearchLocator>? = null
private set
var onItemClickListener: OnItemClickListener? = null

Expand All @@ -35,22 +35,22 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

this.context = context
listViewType = ListViewType.fromString(dataBundle.getString("ListViewType"))
searchItemList = dataBundle.getParcelableArrayList("DATA")
searchLocatorList = dataBundle.getParcelableArrayList("DATA")
}

fun changeDataBundle(dataBundle: Bundle) {

listViewType = ListViewType.fromString(dataBundle.getString(ListViewType.KEY))
searchItemList = dataBundle.getParcelableArrayList("DATA")
searchLocatorList = dataBundle.getParcelableArrayList("DATA")
notifyDataSetChanged()
}

override fun getItemCount(): Int {

return if (searchItemList == null || searchItemList!!.size == 0) {
return if (searchLocatorList == null || searchLocatorList?.size == 0) {
1
} else {
searchItemList!!.size
searchLocatorList!!.size
}
}

Expand Down Expand Up @@ -147,7 +147,7 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
val textViewCount: TextView = itemView.findViewById(R.id.textViewCount)
val textViewTitle: TextView = itemView.findViewById(R.id.textViewTitle)
val textViewResult: TextView = itemView.findViewById(R.id.textViewResult)
lateinit var searchItem: SearchItem
lateinit var searchLocator: SearchLocator

init {
listViewType = ListViewType.NORMAL_VIEW
Expand All @@ -156,12 +156,12 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
override fun onBind(position: Int) {

itemPosition = position
searchItem = searchItemList!![position]
searchLocator = searchLocatorList!![position]

when (searchItem.searchItemType) {
when (searchLocator.searchItemType) {

SearchItemType.SEARCH_COUNT_ITEM -> {
val count: Int = searchItem.primaryContents?.toInt()!!
val count: Int = searchLocator.primaryContents?.toInt()!!
textViewCount.text = context.resources.getQuantityString(
R.plurals.numberOfSearchResults, count, count)
textViewCount.visibility = View.VISIBLE
Expand All @@ -171,8 +171,8 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {
itemView.setOnClickListener(null)
}

SearchItemType.PAGE_TITLE_ITEM -> {
textViewTitle.text = searchItem.primaryContents
SearchItemType.RESOURCE_TITLE_ITEM -> {
textViewTitle.text = searchLocator.primaryContents
textViewTitle.visibility = View.VISIBLE
textViewCount.visibility = View.GONE
textViewResult.visibility = View.GONE
Expand All @@ -182,11 +182,11 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

SearchItemType.SEARCH_RESULT_ITEM -> {

val spannableString = SpannableString(searchItem.textBefore
+ searchItem.matchQuery
+ searchItem.textAfter)
val from = searchItem.textBefore.length
val to = from + searchItem.matchQuery.length
val spannableString = SpannableString(searchLocator.text?.before
+ searchLocator.text?.hightlight
+ searchLocator.text?.after)
val from = searchLocator.text?.before?.length ?: 0
val to = from + (searchLocator.text?.hightlight?.length ?: 0)
spannableString.setSpan(StyleSpan(Typeface.BOLD), from, to, 0)
spannableString.setSpan(UnderlineSpan(), from, to, 0)
textViewResult.text = spannableString
Expand All @@ -197,6 +197,9 @@ class SearchAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder> {

itemView.setOnClickListener(this)
}

else -> {
}
}
}

Expand Down

0 comments on commit 078ab70

Please sign in to comment.