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.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;
|
||||
private static final long INTERVAL_DAY = TimeUnit.DAYS.toMillis(1);
|
||||
@NonNull private static final String DEFAULT_LANGUAGE = "en";
|
||||
@Nullable private static String sLanguage;
|
||||
@NonNull private final SuggestionsResult mResultCallback;
|
||||
@NonNull private final Application mApplication;
|
||||
@NonNull private final OkHttpClient mHttpClient = new OkHttpClient();
|
||||
@NonNull private final CacheControl mCacheControl;
|
||||
@NonNull private final ConnectivityManager mConnectivityManager;
|
||||
@NonNull private String mQuery;
|
||||
|
||||
@NonNull
|
||||
protected abstract String createQueryUrl(@NonNull String query, @NonNull String language);
|
||||
@ -53,11 +51,7 @@ abstract class BaseSuggestionsTask {
|
||||
@NonNull
|
||||
protected abstract String getEncoding();
|
||||
|
||||
BaseSuggestionsTask(@NonNull String query,
|
||||
@NonNull Application application,
|
||||
@NonNull SuggestionsResult callback) {
|
||||
mQuery = query;
|
||||
mResultCallback = callback;
|
||||
BaseSuggestionsModel(@NonNull Application application) {
|
||||
mApplication = application;
|
||||
mCacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
|
||||
mConnectivityManager = getConnectivityManager(mApplication);
|
||||
@ -74,39 +68,36 @@ abstract class BaseSuggestionsTask {
|
||||
return sLanguage;
|
||||
}
|
||||
|
||||
void run() {
|
||||
@NonNull
|
||||
List<HistoryItem> getResults(@NonNull String query) {
|
||||
List<HistoryItem> filter = new ArrayList<>(5);
|
||||
try {
|
||||
mQuery = URLEncoder.encode(mQuery, getEncoding());
|
||||
query = URLEncoder.encode(query, getEncoding());
|
||||
} catch (UnsupportedEncodingException 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()) {
|
||||
post(filter);
|
||||
return;
|
||||
// There are no suggestions for this query, return an empty list.
|
||||
return filter;
|
||||
}
|
||||
FileInputStream fileInput = null;
|
||||
try {
|
||||
fileInput = new FileInputStream(cache);
|
||||
parseResults(fileInput, filter);
|
||||
} catch (Exception e) {
|
||||
post(filter);
|
||||
Log.e(TAG, "Unable to parse results", e);
|
||||
return;
|
||||
return filter;
|
||||
} finally {
|
||||
Utils.close(fileInput);
|
||||
}
|
||||
post(filter);
|
||||
}
|
||||
|
||||
private void post(@NonNull List<HistoryItem> result) {
|
||||
mResultCallback.resultReceived(result);
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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.utils.FileUtils;
|
||||
|
||||
final class DuckSuggestionsTask extends BaseSuggestionsTask {
|
||||
final class DuckSuggestionsModel extends BaseSuggestionsModel {
|
||||
|
||||
@NonNull private static final String ENCODING = "UTF-8";
|
||||
@NonNull private final String mSearchSubtitle;
|
||||
|
||||
DuckSuggestionsTask(@NonNull String query,
|
||||
@NonNull Application application,
|
||||
@NonNull SuggestionsResult callback) {
|
||||
super(query, application, callback);
|
||||
DuckSuggestionsModel(@NonNull Application application) {
|
||||
super(application);
|
||||
mSearchSubtitle = application.getString(R.string.suggestion);
|
||||
}
|
||||
|
@ -15,16 +15,14 @@ import java.util.List;
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.database.HistoryItem;
|
||||
|
||||
class GoogleSuggestionsTask extends BaseSuggestionsTask {
|
||||
class GoogleSuggestionsModel extends BaseSuggestionsModel {
|
||||
|
||||
@NonNull private static final String ENCODING = "ISO-8859-1";
|
||||
@Nullable private static XmlPullParser sXpp;
|
||||
@NonNull private final String mSearchSubtitle;
|
||||
|
||||
GoogleSuggestionsTask(@NonNull String query,
|
||||
@NonNull Application application,
|
||||
@NonNull SuggestionsResult callback) {
|
||||
super(query, application, callback);
|
||||
GoogleSuggestionsModel(@NonNull Application application) {
|
||||
super(application);
|
||||
mSearchSubtitle = application.getString(R.string.suggestion);
|
||||
}
|
||||
|
@ -210,8 +210,8 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
||||
subscriber.onComplete();
|
||||
}
|
||||
}).subscribeOn(FILTER_SCHEDULER)
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe();
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
private void combineResults(final @Nullable List<HistoryItem> bookmarkList,
|
||||
@ -256,13 +256,13 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
||||
subscriber.onComplete();
|
||||
}
|
||||
}).subscribeOn(FILTER_SCHEDULER)
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
publishResults(item);
|
||||
}
|
||||
});
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
publishResults(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -277,7 +277,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
||||
break;
|
||||
}
|
||||
if (mAllBookmarks.get(n).getTitle().toLowerCase(Locale.getDefault())
|
||||
.startsWith(query)) {
|
||||
.startsWith(query)) {
|
||||
bookmarks.add(mAllBookmarks.get(n));
|
||||
counter++;
|
||||
} else if (mAllBookmarks.get(n).getUrl().contains(query)) {
|
||||
@ -294,9 +294,9 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
||||
@NonNull
|
||||
private Single<List<HistoryItem>> getSuggestionsForQuery(@NonNull final String query) {
|
||||
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) {
|
||||
return SuggestionsManager.getObservable(query, mContext, SuggestionsManager.Source.DUCK);
|
||||
return SuggestionsManager.createDuckQueryObservable(query, mContext);
|
||||
} else {
|
||||
return Single.empty();
|
||||
}
|
||||
@ -325,35 +325,35 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
|
||||
|
||||
if (mSuggestionsAdapter.shouldRequestNetwork() && !SuggestionsManager.isRequestInProgress()) {
|
||||
mSuggestionsAdapter.getSuggestionsForQuery(query)
|
||||
.subscribeOn(Schedulers.worker())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(null, null, item);
|
||||
}
|
||||
});
|
||||
.subscribeOn(Schedulers.worker())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(null, null, item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mSuggestionsAdapter.getBookmarksForQuery(query)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(item, null, null);
|
||||
}
|
||||
});
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(item, null, null);
|
||||
}
|
||||
});
|
||||
|
||||
HistoryModel.findHistoryItemsContaining(query)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(null, item, null);
|
||||
}
|
||||
});
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.main())
|
||||
.subscribe(new SingleOnSubscribe<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onItem(@Nullable List<HistoryItem> item) {
|
||||
mSuggestionsAdapter.combineResults(null, item, null);
|
||||
}
|
||||
});
|
||||
results.count = 1;
|
||||
return results;
|
||||
}
|
||||
|
@ -15,42 +15,39 @@ import acr.browser.lightning.database.HistoryItem;
|
||||
|
||||
class SuggestionsManager {
|
||||
|
||||
public enum Source {
|
||||
GOOGLE,
|
||||
DUCK
|
||||
}
|
||||
|
||||
private static volatile boolean sIsTaskExecuting;
|
||||
|
||||
static boolean isRequestInProgress() {
|
||||
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);
|
||||
return Single.create(new SingleAction<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull final SingleSubscriber<List<HistoryItem>> subscriber) {
|
||||
sIsTaskExecuting = true;
|
||||
switch (source) {
|
||||
case GOOGLE:
|
||||
new GoogleSuggestionsTask(query, application, new SuggestionsResult() {
|
||||
@Override
|
||||
public void resultReceived(@NonNull List<HistoryItem> searchResults) {
|
||||
subscriber.onItem(searchResults);
|
||||
subscriber.onComplete();
|
||||
}
|
||||
}).run();
|
||||
break;
|
||||
case DUCK:
|
||||
new DuckSuggestionsTask(query, application, new SuggestionsResult() {
|
||||
@Override
|
||||
public void resultReceived(@NonNull List<HistoryItem> searchResults) {
|
||||
subscriber.onItem(searchResults);
|
||||
subscriber.onComplete();
|
||||
}
|
||||
}).run();
|
||||
}
|
||||
List<HistoryItem> results = new GoogleSuggestionsModel(application).getResults(query);
|
||||
subscriber.onItem(results);
|
||||
subscriber.onComplete();
|
||||
sIsTaskExecuting = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static Single<List<HistoryItem>> createDuckQueryObservable(@NonNull final String query,
|
||||
@NonNull final Context context) {
|
||||
final Application application = BrowserApp.get(context);
|
||||
return Single.create(new SingleAction<List<HistoryItem>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull final SingleSubscriber<List<HistoryItem>> subscriber) {
|
||||
sIsTaskExecuting = true;
|
||||
List<HistoryItem> results = new DuckSuggestionsModel(application).getResults(query);
|
||||
subscriber.onItem(results);
|
||||
subscriber.onComplete();
|
||||
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