/*
* Copyright � 2016 TIBCO Software,Inc.All rights reserved.
* http://community.jaspersoft.com/project/jaspermobile-android
*
* Unless you have purchased a commercial license agreement from TIBCO Jaspersoft,
* the following license terms apply:
*
* This program is part of TIBCO Jaspersoft Mobile for Android.
*
* TIBCO Jaspersoft Mobile is free software:you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation,either version 3of the License,or
* (at your option)any later version.
*
* TIBCO Jaspersoft Mobile is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY;without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TIBCO Jaspersoft Mobile for Android.If not,see
* <http://www.gnu.org/licenses/lgpl>.
*/
package com.jaspersoft.android.jaspermobile.data.fetchers;
import com.jaspersoft.android.jaspermobile.domain.SimpleSubscriber;
import com.jaspersoft.android.jaspermobile.domain.entity.Resource;
import com.jaspersoft.android.jaspermobile.domain.fetchers.CatalogFetcher;
import com.jaspersoft.android.jaspermobile.util.rx.RxTransformer;
import com.jaspersoft.android.sdk.service.exception.ServiceException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;
/**
* @author Andrew Tivodar
* @since 2.5
*/
public abstract class CatalogFetcherImpl<SearchType, ResourceType extends Resource> implements CatalogFetcher {
private List<Resource> mResourceList;
private LoaderCallback mLoaderCallback;
private Subscription mSearchSubscription;
private CompositeSubscription mSubscriptionsList;
private boolean mPreviousWasEmpty;
private boolean mDelivered;
public CatalogFetcherImpl() {
this.mSubscriptionsList = new CompositeSubscription();
this.mResourceList = new ArrayList<>();
this.mLoaderCallback = EMPTY;
this.mPreviousWasEmpty = true;
this.mDelivered = true;
}
public LoaderCallback getLoaderCallback() {
return mLoaderCallback;
}
public List<Resource> getResourceList() {
return mResourceList;
}
@Override
public void subscribe(LoaderCallback loaderCallback) {
mLoaderCallback = loaderCallback;
if (!mDelivered) {
mLoaderCallback.onLoaded(mResourceList);
mDelivered = true;
}
}
@Override
public void unsubscribe() {
mLoaderCallback = EMPTY;
}
@Override
public void reset() {
if (mSearchSubscription != null) {
mSearchSubscription.unsubscribe();
mSearchSubscription = null;
}
mResourceList = new ArrayList<>();
search();
}
@Override
public void search() {
if (!searchTaskInitialized()) {
createSearchTask();
searchNext();
return;
}
if (hasNext()) {
searchNext();
}
}
private void searchNext() {
if (mSearchSubscription != null) return;
int delay = mPreviousWasEmpty ? 0 : 750;
mSearchSubscription = getNextTask()
.delay(delay, TimeUnit.MILLISECONDS)
.compose(RxTransformer.<List<SearchType>>applySchedulers())
.subscribe(new SimpleSubscriber<List<SearchType>>() {
@Override
public void onStart() {
mLoaderCallback.onLoadStarted(mResourceList.isEmpty());
}
@Override
public void onNext(List<SearchType> items) {
mPreviousWasEmpty = items.isEmpty();
mResourceList.addAll(map(items));
mLoaderCallback.onLoaded(mResourceList);
}
@Override
public void onError(Throwable e) {
mPreviousWasEmpty = true;
mLoaderCallback.onError((ServiceException) e, mResourceList.isEmpty());
}
@Override
public void onCompleted() {
mSearchSubscription = null;
}
});
}
protected void observe(Observable<Void> observable) {
mSubscriptionsList.add(observable.subscribe(new ResourcesObserver()));
}
protected abstract boolean searchTaskInitialized();
protected abstract void createSearchTask();
protected abstract boolean hasNext();
protected abstract Observable<List<SearchType>> getNextTask();
protected abstract List<ResourceType> map(List<SearchType> items);
protected class ResourcesObserver extends SimpleSubscriber<Void> {
@Override
public void onNext(Void item) {
reset();
}
}
LoaderCallback EMPTY = new LoaderCallback() {
@Override
public void onLoadStarted(boolean first) {
}
@Override
public void onLoaded(List<Resource> resources) {
mDelivered = false;
}
@Override
public void onError(ServiceException ex, boolean first) {
}
};
}