package glaze.client.async;
import glaze.client.Response;
import glaze.client.handlers.CroakErrorHandler;
import glaze.client.handlers.ErrorHandler;
import glaze.mime.MimeResolver;
import glaze.spi.Registry;
import java.io.IOException;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.ContentInputStream;
import org.apache.http.nio.util.SimpleInputBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
public class MapperConsumer<T> extends AbstractContentConsumer<T>
{
private static final Logger LOGGER = LoggerFactory.getLogger(MapperConsumer.class);
private final Class<T> type;
private final ErrorHandler errorHandler;
private volatile ObjectMapper mapper;
private final String namespace;
private ContentType overrideType;
public MapperConsumer(Class<T> type)
{
this(Registry.NS_DEFAULT, type, CroakErrorHandler.instance());
}
public MapperConsumer(Class<T> type, ErrorHandler errorHandler)
{
this(Registry.NS_DEFAULT, type, errorHandler);
}
public MapperConsumer(String namespace, Class<T> type, ErrorHandler errorHandler)
{
this(namespace, type, errorHandler, null);
}
public MapperConsumer(String namespace, Class<T> type, ErrorHandler errorHandler, ContentType overrideType)
{
Preconditions.checkNotNull(type, "Type must not be null");
this.type = type;
this.overrideType = overrideType;
this.errorHandler = errorHandler == null ? CroakErrorHandler.instance() : errorHandler;
this.namespace = Optional.fromNullable(namespace).or(Registry.NS_DEFAULT);
}
@Override
protected T onBufferCompleted(SimpleInputBuffer buffer) throws IOException
{
if (mapper == null) {
buffer.shutdown();
return null;
}
return mapper.readValue(new ContentInputStream(buffer), type);
}
@Override
protected void onResponseReceived(HttpResponse httpResponse) throws HttpException, IOException
{
Response response = new Response(httpResponse);
if (response.isError()) {
errorHandler.onError(response);
return;
}
String mime = overrideType == null ? MimeResolver.resolve(httpResponse) : overrideType.getMimeType();
this.mapper = Registry.lookupMapper(namespace, mime);
if (mapper == null) {
LOGGER.warn("Mapper not found for response {}. Consuming quietly.", httpResponse);
}
}
@Override
protected void releaseResources()
{
this.mapper = null;
}
}