MTU-Dining/app/src/main/java/com/thebrokenrail/mtudining/api/Connection.java

131 lines
3.7 KiB
Java

package com.thebrokenrail.mtudining.api;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.thebrokenrail.mtudining.util.Constants;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class Connection {
/**
* HTTP Client
*/
private final OkHttpClient client;
public Connection() {
client = new OkHttpClient.Builder()
.connectTimeout(Constants.TIMEOUT, TimeUnit.SECONDS)
.readTimeout(Constants.TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(Constants.TIMEOUT, TimeUnit.SECONDS)
.build();
}
/**
* Link to main thread.
*/
private final Handler mainThread = new Handler(Looper.getMainLooper());
/**
* List of current HTTP calls.
*/
private final List<Call> calls = new ArrayList<>();
/**
* Send API method.
* @param method API method
* @param success Callback on success
* @param error Callback on error
* @param <T> Response type
*/
public <T> void send(Method<T> method, Consumer<T> success, Runnable error) {
// Build URL
String url = Constants.API_BASE + method.getPath();
// Build Request
Request request = new Request.Builder()
.url(url)
.build();
// Call
Call call = client.newCall(request);
synchronized (calls) {
calls.add(call);
}
call.enqueue(new Callback() {
private void error(Exception e) {
// Print Error
e.printStackTrace();
// Callback
mainThread.post(error);
}
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
synchronized (calls) {
calls.remove(call);
}
// Log Error
error(e);
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
synchronized (calls) {
calls.remove(call);
}
try {
// Read Response
try (ResponseBody responseBody = response.body()) {
// Check Response
if (!response.isSuccessful()) {
// Run Error Callback
mainThread.post(error);
return;
}
// Deserialize Body
Moshi moshi = new Moshi.Builder().build();
JsonAdapter<T> jsonAdapter = moshi.adapter(method.getResponseClass());
assert responseBody != null;
T obj = jsonAdapter.fromJson(responseBody.string());
// Run Callback
mainThread.post(() -> success.accept(obj));
}
} catch (Exception e) {
// Run Error Callback
error(e);
}
}
});
}
/**
* Cancel all current calls.
*/
public void cancelAll() {
synchronized (calls) {
for (Call call : calls) {
call.cancel();
}
calls.clear();
}
}
}