/*
* 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.repository.report;
import android.support.annotation.NonNull;
import com.jaspersoft.android.jaspermobile.data.JasperRestClient;
import com.jaspersoft.android.jaspermobile.data.cache.report.ControlsCache;
import com.jaspersoft.android.jaspermobile.data.cache.report.ReportParamsCache;
import com.jaspersoft.android.jaspermobile.data.entity.mapper.InputControlsMapper;
import com.jaspersoft.android.jaspermobile.data.entity.mapper.ReportParamsMapper;
import com.jaspersoft.android.jaspermobile.domain.repository.report.ControlsRepository;
import com.jaspersoft.android.jaspermobile.internal.di.PerProfile;
import com.jaspersoft.android.sdk.client.oxm.control.InputControlState;
import com.jaspersoft.android.sdk.client.oxm.report.ReportParameter;
import com.jaspersoft.android.sdk.network.entity.control.InputControl;
import com.jaspersoft.android.sdk.service.data.dashboard.DashboardControlComponent;
import com.jaspersoft.android.sdk.service.exception.ServiceException;
import com.jaspersoft.android.sdk.service.filter.FiltersService;
import com.jaspersoft.android.sdk.service.rx.filter.RxFiltersService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
/**
* @author Tom Koptel
* @since 2.3
*/
@PerProfile
public final class InMemoryControlsRepository implements ControlsRepository {
private final ControlsCache mControlsCache;
private final ReportParamsCache mReportParamsCache;
private final InputControlsMapper mControlsMapper;
private final ReportParamsMapper mReportParamsMapper;
private final JasperRestClient mRestClient;
@Inject
public InMemoryControlsRepository(JasperRestClient restClient,
ControlsCache controlsCache,
ReportParamsCache reportParamsCache, InputControlsMapper controlsMapper,
ReportParamsMapper reportParamsMapper) {
mRestClient = restClient;
mControlsCache = controlsCache;
mReportParamsCache = reportParamsCache;
mControlsMapper = controlsMapper;
mReportParamsMapper = reportParamsMapper;
}
@NonNull
@Override
public Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> listReportControls(@NonNull final String reportUri) {
Observable<List<InputControl>> listObservable = mRestClient.filtersService().flatMap(new Func1<RxFiltersService, Observable<List<InputControl>>>() {
@Override
public Observable<List<InputControl>> call(RxFiltersService service) {
return service.listReportControls(reportUri);
}
});
return createListControls(reportUri, listObservable);
}
@NonNull
@Override
public Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> listDashboardControls(@NonNull final String dashboardUri) {
Observable<List<InputControl>> listObservable = mRestClient.filtersService().flatMap(new Func1<RxFiltersService, Observable<List<InputControl>>>() {
@Override
public Observable<List<InputControl>> call(RxFiltersService service) {
return service.listDashboardControls(dashboardUri);
}
});
return createListControls(dashboardUri, listObservable);
}
@NonNull
private Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> createListControls(final String reportUri, final Observable<List<InputControl>> networkCall) {
Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> memorySource = Observable.defer(
new Func0<Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> call() {
List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> inputControls = mControlsCache.get(reportUri);
if (inputControls == null) {
return Observable.empty();
}
return Observable.just(inputControls);
}
});
Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> networkSource = Observable.defer(
new Func0<Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>> call() {
return networkCall
.map(new Func1<List<InputControl>, List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>>() {
@Override
public List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> call(List<InputControl> inputControls) {
return mControlsMapper.retrofittedControlsToLegacy(inputControls);
}
})
.doOnNext(new Action1<List<com.jaspersoft.android.sdk.client.oxm.control.InputControl>>() {
@Override
public void call(List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> inputControls) {
mControlsCache.put(reportUri, inputControls);
boolean containsParams = mReportParamsCache.contains(reportUri);
if (!containsParams) {
List<ReportParameter> parameters = mReportParamsMapper.legacyControlsToParams(inputControls);
mReportParamsCache.put(reportUri, parameters);
}
}
});
}
});
return Observable.concat(memorySource, networkSource).first();
}
@NonNull
@Override
public Observable<List<InputControlState>> validateReportControls(@NonNull final String reportUri) {
return Observable.defer(
new Func0<Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>> call() {
List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> controls =
mControlsCache.get(reportUri);
List<ReportParameter> parameters = mReportParamsMapper.legacyControlsToParams(controls);
if (parameters == null) {
return Observable.just(Collections.<com.jaspersoft.android.sdk.network.entity.control.InputControlState>emptyList());
}
final List<com.jaspersoft.android.sdk.network.entity.report.ReportParameter> params =
mReportParamsMapper.legacyParamsToRetrofitted(parameters);
return mRestClient.filtersService()
.flatMap(new Func1<RxFiltersService, Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>> call(RxFiltersService service) {
return service.validateControls(reportUri, params, true);
}
});
}
}).map(new Func1<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>, List<InputControlState>>() {
@Override
public List<InputControlState> call(List<com.jaspersoft.android.sdk.network.entity.control.InputControlState> inputControlStates) {
return mControlsMapper.retrofittedStatesToLegacy(inputControlStates);
}
});
}
@NonNull
@Override
public Observable<List<InputControlState>> validateDashboardControls(@NonNull final String dashboardUri) {
return Observable.defer(
new Func0<Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>> call() {
List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> controls =
mControlsCache.get(dashboardUri);
FiltersService filtersService = mRestClient.syncFilterService();
List<com.jaspersoft.android.sdk.network.entity.control.InputControlState> states =
new ArrayList<>();
for (com.jaspersoft.android.sdk.client.oxm.control.InputControl control : controls) {
try {
String controlUri = control.getUri().replace("repo:", "");
com.jaspersoft.android.sdk.network.entity.report.ReportParameter parameter =
mReportParamsMapper.legacyControlToRetrofittedParam(control);
List<com.jaspersoft.android.sdk.network.entity.control.InputControlState> inputControlStates =
filtersService.validateControls(controlUri, Collections.singletonList(parameter), false);
states.addAll(inputControlStates);
} catch (ServiceException e) {
return Observable.error(e);
}
}
return Observable.just(states);
}
}).map(new Func1<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>, List<InputControlState>>() {
@Override
public List<InputControlState> call(List<com.jaspersoft.android.sdk.network.entity.control.InputControlState> inputControlStates) {
return mControlsMapper.retrofittedStatesToLegacy(inputControlStates);
}
});
}
@NonNull
@Override
public Observable<List<InputControlState>> listControlValues(@NonNull final String reportUri) {
return Observable.defer(new Func0<Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>> call() {
List<com.jaspersoft.android.sdk.client.oxm.control.InputControl> inputControls = mControlsCache.get(reportUri);
List<ReportParameter> parameters = mReportParamsMapper.legacyControlsToParams(inputControls);
if (parameters == null) {
return Observable.just(Collections.<com.jaspersoft.android.sdk.network.entity.control.InputControlState>emptyList());
}
final List<com.jaspersoft.android.sdk.network.entity.report.ReportParameter> params =
mReportParamsMapper.legacyParamsToRetrofitted(parameters);
return mRestClient.filtersService()
.flatMap(new Func1<RxFiltersService, Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>>>() {
@Override
public Observable<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>> call(RxFiltersService service) {
return service.listControlsStates(reportUri, params, true);
}
});
}
}).map(new Func1<List<com.jaspersoft.android.sdk.network.entity.control.InputControlState>, List<InputControlState>>() {
@Override
public List<InputControlState> call(List<com.jaspersoft.android.sdk.network.entity.control.InputControlState> inputControlStates) {
return mControlsMapper.retrofittedStatesToLegacy(inputControlStates);
}
});
}
@NonNull
@Override
public Observable<List<DashboardControlComponent>> listDashboardControlComponents(@NonNull final String dashboardUri) {
return mRestClient.filtersService()
.flatMap(new Func1<RxFiltersService, Observable<List<DashboardControlComponent>>>() {
@Override
public Observable<List<DashboardControlComponent>> call(RxFiltersService service) {
return service.listDashboardControlComponents(dashboardUri);
}
});
}
@Override
public void flushControls(@NonNull String reportUri) {
mControlsCache.evict(reportUri);
}
}