package org.wikipedia.wikidata;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import com.google.gson.JsonParseException;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.dataclient.retrofit.RetrofitFactory;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.GET;
import retrofit2.http.Query;
public final class EntityClient {
public static final String WIKIDATA_WIKI = "wikidatawiki";
@NonNull private final Service service;
public interface LabelCallback {
void success(@NonNull String label);
void failure(Throwable t);
}
private static final EntityClient INSTANCE = new EntityClient();
public static EntityClient instance() {
return INSTANCE;
}
private EntityClient() {
service = RetrofitFactory.newInstance(new WikiSite("www.wikidata.org", ""))
.create(Service.class);
}
@VisibleForTesting
static class LabelCallbackAdapter implements retrofit2.Callback<Entity.EntitiesResponse> {
@NonNull private final LabelCallback callback;
@NonNull private final String qNumber;
@NonNull private final String langCode;
LabelCallbackAdapter(@NonNull LabelCallback callback, @NonNull final String qNumber,
@NonNull final String langCode) {
this.callback = callback;
this.qNumber = qNumber;
this.langCode = langCode;
}
@Override public void onResponse(Call<Entity.EntitiesResponse> call,
Response<Entity.EntitiesResponse> response) {
if (response.body() != null && response.body().success()) {
for (Entity item : response.body().entities().values()) {
if (item.id().equals(qNumber)) {
for (Entity.Label label : item.labels().values()) {
if (label.language().equals(langCode)) {
callback.success(label.value());
return;
}
}
}
}
}
callback.failure(new JsonParseException("Failed to find label for " + qNumber + ":" + langCode));
}
@Override public void onFailure(Call<Entity.EntitiesResponse> call, Throwable caught) {
callback.failure(caught);
}
}
public void getLabelForLang(@NonNull final String qNumber, @NonNull final String langCode,
@NonNull final LabelCallback callback) {
requestLabels(service, qNumber, langCode)
.enqueue(new LabelCallbackAdapter(callback, qNumber, langCode));
}
@VisibleForTesting @NonNull
Call<Entity.EntitiesResponse> requestLabels(@NonNull Service service,
@NonNull final String qNumber,
@NonNull final String langCode) {
return service.getLabels(qNumber, langCode);
}
@VisibleForTesting interface Service {
String ACTION = "w/api.php?action=wbgetentities&format=json&formatversion=2";
@GET(ACTION + "&props=labels&languagefallback=1")
@NonNull Call<Entity.EntitiesResponse> getLabels(@Query("ids") @NonNull String idList,
@Query("languages") @NonNull String langList);
}
}