package org.wikipedia.dataclient.restbase.page;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.gson.JsonParseException;
import org.wikipedia.dataclient.page.PageClient;
import org.wikipedia.dataclient.page.PageLead;
import org.wikipedia.dataclient.page.PageRemaining;
import org.wikipedia.dataclient.page.PageSummary;
import org.wikipedia.dataclient.restbase.RbDefinition;
import java.util.Map;
import okhttp3.CacheControl;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
// todo: consolidate with MwPageClient or just use the Services directly!
/**
* Retrofit web service client for RESTBase Nodejs API.
*/
public class RbPageClient implements PageClient {
public interface DefinitionCallback {
void success(@NonNull RbDefinition definition);
void failure(@NonNull Throwable throwable);
}
// todo: why not hold a reference to a WikiCachedService and require clients to pass a WikiSite
// with each request?
@NonNull private final RbPageService service;
public RbPageClient(@NonNull RbPageService service) {
this.service = service;
}
// todo: RbPageSummary should specify an @Required annotation that throws a JsonParseException
// when the body is null rather than requiring all clients to check for a null body. There
// may be some abandoned demo patches that already have this functionality. It should be
// part of the Gson augmentation package and eventually cut into a separate lib. Repeat
// everywhere a Response.body() == null check occurs that throws
@SuppressWarnings("unchecked")
@NonNull @Override public Call<? extends PageSummary> summary(@NonNull String title) {
return service.summary(title);
}
@SuppressWarnings("unchecked")
@NonNull @Override public Call<? extends PageLead> lead(@Nullable CacheControl cacheControl,
@NonNull CacheOption cacheOption,
@NonNull String title,
int leadThumbnailWidth,
boolean noImages) {
return service.lead(cacheControl == null ? null : cacheControl.toString(),
optional(cacheOption.save()), title, optional(noImages));
}
@SuppressWarnings("unchecked")
@NonNull @Override public Call<? extends PageRemaining> sections(@Nullable CacheControl cacheControl,
@NonNull CacheOption cacheOption,
@NonNull String title,
boolean noImages) {
return service.sections(cacheControl == null ? null : cacheControl.toString(),
optional(cacheOption.save()), title, optional(noImages));
}
/* Not defined in the PageClient interface since the Wiktionary definition endpoint exists only
* in the mobile content service, and does not concern the wholesale retrieval of the contents
* of a wiki page.
*/
public void define(String title, final DefinitionCallback cb) {
Call<Map<String, RbDefinition.Usage[]>> call = service.define(title);
call.enqueue(new Callback<Map<String, RbDefinition.Usage[]>>() {
@Override
public void onResponse(@NonNull Call<Map<String, RbDefinition.Usage[]>> call,
@NonNull Response<Map<String, RbDefinition.Usage[]>> response) {
if (response.body() == null) {
cb.failure(new JsonParseException("Response missing required fields"));
return;
}
cb.success(new RbDefinition(response.body()));
}
@Override
public void onFailure(Call<Map<String, RbDefinition.Usage[]>> call, Throwable throwable) {
cb.failure(throwable);
}
});
}
// todo: consolidate MwPageClient and RbPageClient.optional() in util
/**
* Optional boolean Retrofit parameter.
* We don't want to send the query parameter at all when it's false since the presence of the
* parameter alone is enough to trigger the truthy behavior.
*/
private Boolean optional(boolean param) {
if (param) {
return true;
}
return null;
}
}