/* * Copyright 2016 Dmitry Monakhov. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * 16.02.16 18:19 * */ package monakhv.samlib.service; import monakhv.samlib.data.AbstractSettings; import monakhv.samlib.db.entity.AuthorCard; import monakhv.samlib.db.entity.SamLibConfig; import monakhv.samlib.exception.SamlibSearchLimitExceeded; import monakhv.samlib.http.HttpClientController; import monakhv.samlib.log.Log; import rx.Observable; import java.text.Collator; import java.text.ParseException; import java.text.RuleBasedCollator; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Locale; /** * Observable to make Author search * * Created by monakhv on 16.02.16. */ public class AuthorSearchService { private static final String DEBUG_TAG = "AuthorSearchService"; final private HttpClientController mHttpClientController; final private AbstractSettings mSettings; public AuthorSearchService(HttpClientController httpClientController, AbstractSettings settings) { mHttpClientController = httpClientController; mSettings = settings; } public Observable<AuthorCard> makeSearch(String pattern){ return Observable.create(aSubscriber->{ int resNumber=0; int page = 1; HashMap<String, ArrayList<AuthorCard>> colAuthors = null; try { colAuthors = mHttpClientController.searchAuthors(pattern, page); } catch (Exception ex) { Log.e(DEBUG_TAG, "makeSearch: searchAuthors error", ex); aSubscriber.onError(ex); return; } RuleBasedCollator russianCollator = (RuleBasedCollator) Collator.getInstance(new Locale("ru", "RU")); try { russianCollator = new RuleBasedCollator(mSettings.getCollationRule()); } catch (ParseException ex) { Log.e(DEBUG_TAG, "makeSearch: Collator error", ex); aSubscriber.onError(ex); return; } russianCollator.setStrength(Collator.IDENTICAL); russianCollator.setDecomposition(Collator.NO_DECOMPOSITION); while (colAuthors != null) {//page cycle while we find anything String[] keys = colAuthors.keySet().toArray(new String[1]); Arrays.sort(keys, russianCollator); int ires = Arrays.binarySearch(keys, pattern, russianCollator); Log.d(DEBUG_TAG, "makeSearch: Page number:" + page + " search result " + ires + " length is " + keys.length); int iStart; if (ires < 0) { iStart = -ires - 1; } else { iStart = ires; } for (int i = iStart; i < keys.length; i++) { String sKey = keys[i]; if (sKey.toLowerCase().startsWith(pattern.toLowerCase())) { for (AuthorCard ac : colAuthors.get(sKey)) { aSubscriber.onNext(ac); ++resNumber; if (resNumber >= SamLibConfig.SEARCH_LIMIT) { aSubscriber.onError(new SamlibSearchLimitExceeded(resNumber+" - "+SamLibConfig.SEARCH_LIMIT)); return ; } } } else { Log.d(DEBUG_TAG, "makeSearch: Search for " + pattern + " stop by substring - " + sKey + " " + keys.length + " " + iStart + " - " + ires); aSubscriber.onCompleted(); return ; } } ++page; try { colAuthors = mHttpClientController.searchAuthors(pattern, page); } catch (Exception ex) { Log.e(DEBUG_TAG,"makeSearch: searchAuthors2 error: "+ex); aSubscriber.onError(ex); return; } } aSubscriber.onCompleted(); }); } }