Cleaning up suggestions model code
This commit is contained in:
parent
2723abcfd0
commit
e7c5819a89
@ -30,20 +30,18 @@ import okhttp3.OkHttpClient;
|
|||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
abstract class BaseSuggestionsTask {
|
abstract class BaseSuggestionsModel {
|
||||||
|
|
||||||
private static final String TAG = BaseSuggestionsTask.class.getSimpleName();
|
private static final String TAG = BaseSuggestionsModel.class.getSimpleName();
|
||||||
|
|
||||||
static final int MAX_RESULTS = 5;
|
static final int MAX_RESULTS = 5;
|
||||||
private static final long INTERVAL_DAY = TimeUnit.DAYS.toMillis(1);
|
private static final long INTERVAL_DAY = TimeUnit.DAYS.toMillis(1);
|
||||||
@NonNull private static final String DEFAULT_LANGUAGE = "en";
|
@NonNull private static final String DEFAULT_LANGUAGE = "en";
|
||||||
@Nullable private static String sLanguage;
|
@Nullable private static String sLanguage;
|
||||||
@NonNull private final SuggestionsResult mResultCallback;
|
|
||||||
@NonNull private final Application mApplication;
|
@NonNull private final Application mApplication;
|
||||||
@NonNull private final OkHttpClient mHttpClient = new OkHttpClient();
|
@NonNull private final OkHttpClient mHttpClient = new OkHttpClient();
|
||||||
@NonNull private final CacheControl mCacheControl;
|
@NonNull private final CacheControl mCacheControl;
|
||||||
@NonNull private final ConnectivityManager mConnectivityManager;
|
@NonNull private final ConnectivityManager mConnectivityManager;
|
||||||
@NonNull private String mQuery;
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
protected abstract String createQueryUrl(@NonNull String query, @NonNull String language);
|
protected abstract String createQueryUrl(@NonNull String query, @NonNull String language);
|
||||||
@ -53,11 +51,7 @@ abstract class BaseSuggestionsTask {
|
|||||||
@NonNull
|
@NonNull
|
||||||
protected abstract String getEncoding();
|
protected abstract String getEncoding();
|
||||||
|
|
||||||
BaseSuggestionsTask(@NonNull String query,
|
BaseSuggestionsModel(@NonNull Application application) {
|
||||||
@NonNull Application application,
|
|
||||||
@NonNull SuggestionsResult callback) {
|
|
||||||
mQuery = query;
|
|
||||||
mResultCallback = callback;
|
|
||||||
mApplication = application;
|
mApplication = application;
|
||||||
mCacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
|
mCacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
|
||||||
mConnectivityManager = getConnectivityManager(mApplication);
|
mConnectivityManager = getConnectivityManager(mApplication);
|
||||||
@ -74,39 +68,36 @@ abstract class BaseSuggestionsTask {
|
|||||||
return sLanguage;
|
return sLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() {
|
@NonNull
|
||||||
|
List<HistoryItem> getResults(@NonNull String query) {
|
||||||
List<HistoryItem> filter = new ArrayList<>(5);
|
List<HistoryItem> filter = new ArrayList<>(5);
|
||||||
try {
|
try {
|
||||||
mQuery = URLEncoder.encode(mQuery, getEncoding());
|
query = URLEncoder.encode(query, getEncoding());
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
Log.e(TAG, "Unable to encode the URL", e);
|
Log.e(TAG, "Unable to encode the URL", e);
|
||||||
}
|
}
|
||||||
File cache = downloadSuggestionsForQuery(mQuery, getLanguage(), mApplication);
|
File cache = downloadSuggestionsForQuery(query, getLanguage(), mApplication);
|
||||||
if (!cache.exists()) {
|
if (!cache.exists()) {
|
||||||
post(filter);
|
// There are no suggestions for this query, return an empty list.
|
||||||
return;
|
return filter;
|
||||||
}
|
}
|
||||||
FileInputStream fileInput = null;
|
FileInputStream fileInput = null;
|
||||||
try {
|
try {
|
||||||
fileInput = new FileInputStream(cache);
|
fileInput = new FileInputStream(cache);
|
||||||
parseResults(fileInput, filter);
|
parseResults(fileInput, filter);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
post(filter);
|
|
||||||
Log.e(TAG, "Unable to parse results", e);
|
Log.e(TAG, "Unable to parse results", e);
|
||||||
return;
|
return filter;
|
||||||
} finally {
|
} finally {
|
||||||
Utils.close(fileInput);
|
Utils.close(fileInput);
|
||||||
}
|
}
|
||||||
post(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void post(@NonNull List<HistoryItem> result) {
|
return filter;
|
||||||
mResultCallback.resultReceived(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method downloads the search suggestions for the specific query.
|
* This method downloads the search suggestions for the specific query.
|
||||||
* NOTE: This is a blocking operation, do not run on the UI thread.
|
* NOTE: This is a blocking operation, do not getResults on the UI thread.
|
||||||
*
|
*
|
||||||
* @param query the query to get suggestions for
|
* @param query the query to get suggestions for
|
||||||
* @return the cache file containing the suggestions
|
* @return the cache file containing the suggestions
|
@ -13,15 +13,13 @@ import acr.browser.lightning.R;
|
|||||||
import acr.browser.lightning.database.HistoryItem;
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
import acr.browser.lightning.utils.FileUtils;
|
import acr.browser.lightning.utils.FileUtils;
|
||||||
|
|
||||||
final class DuckSuggestionsTask extends BaseSuggestionsTask {
|
final class DuckSuggestionsModel extends BaseSuggestionsModel {
|
||||||
|
|
||||||
@NonNull private static final String ENCODING = "UTF-8";
|
@NonNull private static final String ENCODING = "UTF-8";
|
||||||
@NonNull private final String mSearchSubtitle;
|
@NonNull private final String mSearchSubtitle;
|
||||||
|
|
||||||
DuckSuggestionsTask(@NonNull String query,
|
DuckSuggestionsModel(@NonNull Application application) {
|
||||||
@NonNull Application application,
|
super(application);
|
||||||
@NonNull SuggestionsResult callback) {
|
|
||||||
super(query, application, callback);
|
|
||||||
mSearchSubtitle = application.getString(R.string.suggestion);
|
mSearchSubtitle = application.getString(R.string.suggestion);
|
||||||
}
|
}
|
||||||
|
|
@ -15,16 +15,14 @@ import java.util.List;
|
|||||||
import acr.browser.lightning.R;
|
import acr.browser.lightning.R;
|
||||||
import acr.browser.lightning.database.HistoryItem;
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
|
|
||||||
class GoogleSuggestionsTask extends BaseSuggestionsTask {
|
class GoogleSuggestionsModel extends BaseSuggestionsModel {
|
||||||
|
|
||||||
@NonNull private static final String ENCODING = "ISO-8859-1";
|
@NonNull private static final String ENCODING = "ISO-8859-1";
|
||||||
@Nullable private static XmlPullParser sXpp;
|
@Nullable private static XmlPullParser sXpp;
|
||||||
@NonNull private final String mSearchSubtitle;
|
@NonNull private final String mSearchSubtitle;
|
||||||
|
|
||||||
GoogleSuggestionsTask(@NonNull String query,
|
GoogleSuggestionsModel(@NonNull Application application) {
|
||||||
@NonNull Application application,
|
super(application);
|
||||||
@NonNull SuggestionsResult callback) {
|
|
||||||
super(query, application, callback);
|
|
||||||
mSearchSubtitle = application.getString(R.string.suggestion);
|
mSearchSubtitle = application.getString(R.string.suggestion);
|
||||||
}
|
}
|
||||||
|
|
@ -210,8 +210,8 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
|||||||
subscriber.onComplete();
|
subscriber.onComplete();
|
||||||
}
|
}
|
||||||
}).subscribeOn(FILTER_SCHEDULER)
|
}).subscribeOn(FILTER_SCHEDULER)
|
||||||
.observeOn(Schedulers.main())
|
.observeOn(Schedulers.main())
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void combineResults(final @Nullable List<HistoryItem> bookmarkList,
|
private void combineResults(final @Nullable List<HistoryItem> bookmarkList,
|
||||||
@ -256,13 +256,13 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
|||||||
subscriber.onComplete();
|
subscriber.onComplete();
|
||||||
}
|
}
|
||||||
}).subscribeOn(FILTER_SCHEDULER)
|
}).subscribeOn(FILTER_SCHEDULER)
|
||||||
.observeOn(Schedulers.main())
|
.observeOn(Schedulers.main())
|
||||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onItem(@Nullable List<HistoryItem> item) {
|
public void onItem(@Nullable List<HistoryItem> item) {
|
||||||
publishResults(item);
|
publishResults(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -277,7 +277,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault())
|
if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault())
|
||||||
.startsWith(query)) {
|
.startsWith(query)) {
|
||||||
bookmarks.add(mAllBookmarks.get(n));
|
bookmarks.add(mAllBookmarks.get(n));
|
||||||
counter++;
|
counter++;
|
||||||
} else if (mAllBookmarks.get(n).getUrl().contains(query)) {
|
} else if (mAllBookmarks.get(n).getUrl().contains(query)) {
|
||||||
@ -294,9 +294,9 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Single<List<HistoryItem>> getSuggestionsForQuery(@NonNull final String query) {
|
private Single<List<HistoryItem>> getSuggestionsForQuery(@NonNull final String query) {
|
||||||
if (mSuggestionChoice == PreferenceManager.Suggestion.SUGGESTION_GOOGLE) {
|
if (mSuggestionChoice == PreferenceManager.Suggestion.SUGGESTION_GOOGLE) {
|
||||||
return SuggestionsManager.getObservable(query, mContext, SuggestionsManager.Source.GOOGLE);
|
return SuggestionsManager.createGoogleQueryObservable(query, mContext);
|
||||||
} else if (mSuggestionChoice == PreferenceManager.Suggestion.SUGGESTION_DUCK) {
|
} else if (mSuggestionChoice == PreferenceManager.Suggestion.SUGGESTION_DUCK) {
|
||||||
return SuggestionsManager.getObservable(query, mContext, SuggestionsManager.Source.DUCK);
|
return SuggestionsManager.createDuckQueryObservable(query, mContext);
|
||||||
} else {
|
} else {
|
||||||
return Single.empty();
|
return Single.empty();
|
||||||
}
|
}
|
||||||
@ -325,35 +325,35 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
|||||||
|
|
||||||
if (mSuggestionsAdapter.shouldRequestNetwork() && !SuggestionsManager.isRequestInProgress()) {
|
if (mSuggestionsAdapter.shouldRequestNetwork() && !SuggestionsManager.isRequestInProgress()) {
|
||||||
mSuggestionsAdapter.getSuggestionsForQuery(query)
|
mSuggestionsAdapter.getSuggestionsForQuery(query)
|
||||||
.subscribeOn(Schedulers.worker())
|
.subscribeOn(Schedulers.worker())
|
||||||
.observeOn(Schedulers.main())
|
.observeOn(Schedulers.main())
|
||||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onItem(@Nullable List<HistoryItem> item) {
|
public void onItem(@Nullable List<HistoryItem> item) {
|
||||||
mSuggestionsAdapter.combineResults(null, null, item);
|
mSuggestionsAdapter.combineResults(null, null, item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mSuggestionsAdapter.getBookmarksForQuery(query)
|
mSuggestionsAdapter.getBookmarksForQuery(query)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(Schedulers.main())
|
.observeOn(Schedulers.main())
|
||||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onItem(@Nullable List<HistoryItem> item) {
|
public void onItem(@Nullable List<HistoryItem> item) {
|
||||||
mSuggestionsAdapter.combineResults(item, null, null);
|
mSuggestionsAdapter.combineResults(item, null, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
HistoryModel.findHistoryItemsContaining(query)
|
HistoryModel.findHistoryItemsContaining(query)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(Schedulers.main())
|
.observeOn(Schedulers.main())
|
||||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onItem(@Nullable List<HistoryItem> item) {
|
public void onItem(@Nullable List<HistoryItem> item) {
|
||||||
mSuggestionsAdapter.combineResults(null, item, null);
|
mSuggestionsAdapter.combineResults(null, item, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
results.count = 1;
|
results.count = 1;
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -15,42 +15,39 @@ import acr.browser.lightning.database.HistoryItem;
|
|||||||
|
|
||||||
class SuggestionsManager {
|
class SuggestionsManager {
|
||||||
|
|
||||||
public enum Source {
|
|
||||||
GOOGLE,
|
|
||||||
DUCK
|
|
||||||
}
|
|
||||||
|
|
||||||
private static volatile boolean sIsTaskExecuting;
|
private static volatile boolean sIsTaskExecuting;
|
||||||
|
|
||||||
static boolean isRequestInProgress() {
|
static boolean isRequestInProgress() {
|
||||||
return sIsTaskExecuting;
|
return sIsTaskExecuting;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Single<List<HistoryItem>> getObservable(@NonNull final String query, @NonNull final Context context, @NonNull final Source source) {
|
@NonNull
|
||||||
|
static Single<List<HistoryItem>> createGoogleQueryObservable(@NonNull final String query,
|
||||||
|
@NonNull final Context context) {
|
||||||
final Application application = BrowserApp.get(context);
|
final Application application = BrowserApp.get(context);
|
||||||
return Single.create(new SingleAction<List<HistoryItem>>() {
|
return Single.create(new SingleAction<List<HistoryItem>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(@NonNull final SingleSubscriber<List<HistoryItem>> subscriber) {
|
public void onSubscribe(@NonNull final SingleSubscriber<List<HistoryItem>> subscriber) {
|
||||||
sIsTaskExecuting = true;
|
sIsTaskExecuting = true;
|
||||||
switch (source) {
|
List<HistoryItem> results = new GoogleSuggestionsModel(application).getResults(query);
|
||||||
case GOOGLE:
|
subscriber.onItem(results);
|
||||||
new GoogleSuggestionsTask(query, application, new SuggestionsResult() {
|
subscriber.onComplete();
|
||||||
@Override
|
sIsTaskExecuting = false;
|
||||||
public void resultReceived(@NonNull List<HistoryItem> searchResults) {
|
}
|
||||||
subscriber.onItem(searchResults);
|
});
|
||||||
subscriber.onComplete();
|
}
|
||||||
}
|
|
||||||
}).run();
|
@NonNull
|
||||||
break;
|
static Single<List<HistoryItem>> createDuckQueryObservable(@NonNull final String query,
|
||||||
case DUCK:
|
@NonNull final Context context) {
|
||||||
new DuckSuggestionsTask(query, application, new SuggestionsResult() {
|
final Application application = BrowserApp.get(context);
|
||||||
@Override
|
return Single.create(new SingleAction<List<HistoryItem>>() {
|
||||||
public void resultReceived(@NonNull List<HistoryItem> searchResults) {
|
@Override
|
||||||
subscriber.onItem(searchResults);
|
public void onSubscribe(@NonNull final SingleSubscriber<List<HistoryItem>> subscriber) {
|
||||||
subscriber.onComplete();
|
sIsTaskExecuting = true;
|
||||||
}
|
List<HistoryItem> results = new DuckSuggestionsModel(application).getResults(query);
|
||||||
}).run();
|
subscriber.onItem(results);
|
||||||
}
|
subscriber.onComplete();
|
||||||
sIsTaskExecuting = false;
|
sIsTaskExecuting = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package acr.browser.lightning.search;
|
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import acr.browser.lightning.database.HistoryItem;
|
|
||||||
|
|
||||||
interface SuggestionsResult {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the search suggestions have
|
|
||||||
* been retrieved from the server.
|
|
||||||
*
|
|
||||||
* @param searchResults the results, a valid
|
|
||||||
* list of results. May
|
|
||||||
* be empty.
|
|
||||||
*/
|
|
||||||
void resultReceived(@NonNull List<HistoryItem> searchResults);
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user