org.mule.transport.comm.protocols.AbstractByteProtocol.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.transport.comm.protocols.AbstractByteProtocol.java

Source

/*
 * 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()));
    }

}