package com.taskadapter.redmineapi.internal.comm; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import org.apache.http.HttpResponse; import com.taskadapter.redmineapi.RedmineException; import com.taskadapter.redmineapi.RedmineTransportException; /** * Communicator utilities. * * @author maxkar * */ public final class Communicators { private static final ContentHandler<Object, Object> IDENTITY_HANDLER = new ContentHandler<Object, Object>() { @Override public Object processContent(Object content) throws RedmineException { return content; } }; private static final ContentHandler<HttpResponse, BasicHttpResponse> TRANSPORT_DECODER = new TransportDecoder(); private static final ContentHandler<BasicHttpResponse, Reader> CHARACTER_DECODER = new ContentHandler<BasicHttpResponse, Reader>() { @Override public Reader processContent(BasicHttpResponse content) throws RedmineException { final String charset = content.getCharset(); try { return new InputStreamReader(content.getStream(), charset); } catch (UnsupportedEncodingException e) { throw new RedmineTransportException( "Unsupported response charset " + charset, e); } } }; private static final ContentHandler<HttpResponse, Integer> HTTP_RESPONSE_CODE = new ContentHandler<HttpResponse, Integer>() { @Override public Integer processContent(HttpResponse content) throws RedmineException { return content.getStatusLine().getStatusCode(); } }; private static final ContentHandler<Reader, String> READ_CHARS = new ContentHandler<Reader, String>() { @Override public String processContent(Reader content) throws RedmineException { return readAll(content); } }; private static final ContentHandler<BasicHttpResponse, String> CHAR_CONTENT_READER = compose( READ_CHARS, CHARACTER_DECODER); static String readAll(Reader r) throws RedmineException { final StringWriter writer = new StringWriter(); final char[] buffer = new char[4096]; int readed; try { while ((readed = r.read(buffer)) > 0) { writer.write(buffer, 0, readed); } r.close(); writer.close(); return writer.toString(); } catch (IOException e) { throw new RedmineTransportException(e); } } public static <K, V> SimpleCommunicator<V> simplify( Communicator<K> communicator, ContentHandler<K, V> handler) { return new BasicSimplifier<V, K>(handler, communicator); } @SuppressWarnings("unchecked") public static <K> ContentHandler<K, K> identityHandler() { return (ContentHandler<K, K>) IDENTITY_HANDLER; } public static ContentHandler<BasicHttpResponse, String> contentReader() { return CHAR_CONTENT_READER; } public static <K, I, R> ContentHandler<K, R> compose( ContentHandler<I, R> cont1, ContentHandler<K, I> cont2) { return new ComposingHandler<K, I, R>(cont1, cont2); } public static <K, R> Communicator<R> fmap(Communicator<K> comm, ContentHandler<K, R> handler) { return new FmapCommunicator<R, K>(handler, comm); } public static ContentHandler<HttpResponse, BasicHttpResponse> transportDecoder() { return TRANSPORT_DECODER; } public static ContentHandler<BasicHttpResponse, Reader> characterDecoder() { return CHARACTER_DECODER; } public static ContentHandler<Reader, String> readChars() { return READ_CHARS; } public static ContentHandler<HttpResponse, Integer> httpResponseCodeReader() { return HTTP_RESPONSE_CODE; } }