package ru.semiot.commons.restapi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rx.Subscriber; import rx.functions.Action1; import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.core.Response; public class AsyncResponseHelper { private static final Logger logger = LoggerFactory.getLogger(AsyncResponseHelper.class); public static <T> Subscriber<T> resume(AsyncResponse response) { return new AsyncResponseHelper.Resume(response); } public static void resumeOnError(AsyncResponse response, Throwable e) { new AsyncResponseHelper.ActionOnError(response).call(e); } public static Action1<Throwable> resumeOnError(AsyncResponse response) { return new AsyncResponseHelper.ActionOnError(response); } public static void safeResume(AsyncResponse response, Throwable e) { if (!response.resume(e)) { logger.error("Response was not resumed!"); } } private static void safeResume(AsyncResponse response, Object object) { if (!response.resume(object)) { logger.error("Response was not resumed!"); } } private static class ActionOnError implements Action1<Throwable> { private final AsyncResponse response; public ActionOnError(AsyncResponse response) { this.response = response; } @Override public void call(Throwable e) { logger.warn(e.getMessage(), e); safeResume(response, e); } } private static class Resume<T> extends Subscriber<T> { private final AsyncResponse response; private final Response.Status fallbackStatus; private boolean calledOnNext = false; public Resume(AsyncResponse response) { this.response = response; this.fallbackStatus = null; } public Resume(AsyncResponse response, Response.Status fallbackStatus) { this.response = response; this.fallbackStatus = fallbackStatus; } @Override public void onCompleted() { if (!calledOnNext) { if (fallbackStatus != null) { safeResume(response, Response.status( fallbackStatus).build()); } else { safeResume(response, Response.status( Response.Status.NO_CONTENT).build()); } } } @Override public void onError(Throwable e) { logger.warn(e.getMessage(), e); safeResume(response, e); } @Override public void onNext(T t) { calledOnNext = true; safeResume(response, t); } } }