Java tutorial
/* * Generated by the Mule project wizard. http://mule.mulesource.org * * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.transport.comm.protocols; import org.mule.transport.comm.CommProtocol; import org.mule.transport.comm.ResponseOutputStream; import org.mule.api.transport.MessageAdapter; import org.mule.util.ClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.lang.SerializationUtils; import org.apache.commons.io.IOUtils; import javax.comm.CommPort; import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.net.SocketException; /** * Created by IntelliJ IDEA. * User: Christopher Cheng * Date: Mar 1, 2009 * Time: 3:12:43 PM * To change this template use File | Settings | File Templates. */ public abstract class AbstractByteProtocol implements CommProtocol { private static final Log logger = LogFactory.getLog(org.mule.transport.comm.protocols.DirectProtocol.class); private static final long PAUSE_PERIOD = 100; public static final int EOF = -1; // make this really clear in subclasses, because otherwise people will forget public static final boolean STREAM_OK = true; public static final boolean NO_STREAM = false; private boolean streamOk; public AbstractByteProtocol(boolean streamOk) { this.streamOk = streamOk; } public void write(OutputStream os, Object data) throws IOException { if (data instanceof InputStream) { if (streamOk) { InputStream is = (InputStream) data; IOUtils.copy(is, os); os.flush(); os.close(); is.close(); } else { throw new IOException( "Comm protocol " + ClassUtils.getSimpleName(getClass()) + " cannot handle streaming"); } } else if (data instanceof MessageAdapter) { write(os, ((MessageAdapter) data).getPayload()); } else if (data instanceof byte[]) { writeByteArray(os, (byte[]) data); } else if (data instanceof String) { // TODO SF: encoding is lost/ignored; it is probably a good idea to have // a separate "stringEncoding" property on the protocol writeByteArray(os, ((String) data).getBytes()); } else if (data instanceof Serializable) { writeByteArray(os, SerializationUtils.serialize((Serializable) data)); } else { throw new IllegalArgumentException("Cannot serialize data: " + data); } } protected void writeByteArray(OutputStream os, byte[] data) throws IOException { os.write(data); } /** * Manage non-blocking reads and handle errors * * @param is The input stream to read from * @param buffer The buffer to read into * @return The amount of data read (always non-zero, -1 on EOF or socket exception) * @throws IOException other than socket exceptions */ protected int safeRead(InputStream is, byte[] buffer) throws IOException { return safeRead(is, buffer, buffer.length); } /** * Manage non-blocking reads and handle errors * * @param is The input stream to read from * @param buffer The buffer to read into * @param size The amount of data (upper bound) to read * @return The amount of data read (always non-zero, -1 on EOF or socket exception) * @throws IOException other than socket exceptions */ protected int safeRead(InputStream is, byte[] buffer, int size) throws IOException { int len; try { do { len = is.read(buffer, 0, size); if (0 == len) { // wait for non-blocking input stream // use new lock since not expecting notification try { Thread.sleep(PAUSE_PERIOD); } catch (InterruptedException e) { // no-op } } } while (0 == len); return len; } catch (SocketException e) { // do not pollute the log with a stacktrace, log only the message logger.info("Port exception occured: " + e.getMessage()); return EOF; } // catch (PortInUseException e) // { // logger.debug("Port timeout."); // return EOF; // } } /** * Make a single transfer from source to dest via a byte array buffer * * @param source Source of data * @param buffer Buffer array for transfer * @param dest Destination of data * @return Amount of data transferred, or -1 on eof or socket error * @throws IOException On non-socket error */ protected int copy(InputStream source, byte[] buffer, OutputStream dest) throws IOException { return copy(source, buffer, dest, buffer.length); } /** * Make a single transfer from source to dest via a byte array buffer * * @param source Source of data * @param buffer Buffer array for transfer * @param dest Destination of data * @param size The amount of data (upper bound) to read * @return Amount of data transferred, or -1 on eof or socket error * @throws IOException On non-socket error */ protected int copy(InputStream source, byte[] buffer, OutputStream dest, int size) throws IOException { int len = safeRead(source, buffer, size); if (len > 0) { dest.write(buffer, 0, len); } return len; } protected byte[] nullEmptyArray(byte[] data) { if (0 == data.length) { return null; } else { return data; } } public ResponseOutputStream createResponse(CommPort commPort) throws IOException { return new ResponseOutputStream(commPort, new ProtocolStream(this, streamOk, commPort.getOutputStream())); } }