package jade.imtp.leap.nio; //#J2ME_EXCLUDE_FILE import jade.imtp.leap.JICP.JICPPacket; import jade.imtp.leap.JICP.JICPProtocol; import jade.imtp.leap.http.HTTPHelper; import jade.imtp.leap.http.HTTPRequest; import jade.imtp.leap.http.HTTPResponse; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Eduard Drenth: Logica, 22-sep-2009 * */ public class NIOHTTPHelper extends HTTPHelper implements BufferTransformer { //private boolean needToRead = false; NIOJICPConnection connection; private static Logger log = Logger.getLogger(NIOHTTPHelper.class.getName()); public static ByteBuffer readByteBufferFromHttp(InputStream is) throws IOException { HTTPRequest request = new HTTPRequest(); request.readFrom(is); if (is.markSupported()) { is.mark(2); if (is.read() != -1) { is.reset(); throw new IOException("bytes left in stream after constructing HTTPRequest"); } } if (request.getMethod().equals("GET")) { String recipientID = request.getField(RECIPIENT_ID_FIELD); JICPPacket pkt = new JICPPacket(JICPProtocol.CONNECT_MEDIATOR_TYPE, JICPProtocol.DEFAULT_INFO, recipientID, null); ByteBuffer b = ByteBuffer.allocateDirect(pkt.getLength()); MyOut out = new MyOut(b); pkt.writeTo(out); b.flip(); return b; } else { // Read the JICPPacket from the HTTP request payload byte[] a = request.getPayload(); ByteBuffer b = ByteBuffer.allocateDirect(a.length); MyOut out = new MyOut(b); out.write(a, 0, a.length); b.flip(); return b; } } public NIOHTTPHelper(NIOJICPConnection connection) { this.connection = connection; } private static ByteBuffer wrapInHttpResponse(ByteBuffer pkt) throws IOException { byte[] b = new byte[pkt.remaining()]; pkt.get(b, 0, pkt.remaining()); HTTPResponse response = wrapInHttp(b); ByteArrayOutputStream out = new ByteArrayOutputStream(); response.writeTo(out); return ByteBuffer.wrap(out.toByteArray()); } private static ByteBuffer constructJICPPacket(ByteBuffer input) throws IOException { byte[] out = new byte[input.remaining()]; input.get(out, 0, input.remaining()); if (log.isLoggable(Level.FINE)) { log.fine("trying to read jicp packet from http: \n" + new String(out)); } return readByteBufferFromHttp(new ByteArrayInputStream(out)); } public synchronized ByteBuffer postprocessBufferRead(ByteBuffer data) throws IOException { //needToRead = false; data.mark(); try { return constructJICPPacket(data); } catch (EOFException ex) { if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "not enough data available, wait for more", ex); } //needToRead = true; // incomplete, wait for more data data.reset(); } return NIOHelper.EMPTY_BUFFER; } public synchronized ByteBuffer preprocessBufferToWrite(ByteBuffer dataToSend) throws IOException { return wrapInHttpResponse(dataToSend); } public boolean needSocketData() { //return needToRead; return false; } private static class MyOut extends ByteArrayOutputStream { private ByteBuffer buffer; public MyOut(ByteBuffer b) { this.buffer = b; } @Override public synchronized void write(int b) { buffer.put((byte) b); } @Override public synchronized void write(byte[] b, int off, int len) { buffer.put(b, off, len); } } }