Package org.codehaus.activemq.message

Source Code of org.codehaus.activemq.message.WireFormat

/**
*
* Copyright 2004 Protique Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/

package org.codehaus.activemq.message;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.jms.JMSException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;

/**
* Represents a strategy of encoding packets on the wire or on disk
* using some kind of serialization or wire format.
* <p/>
* We use a default efficient format
* for Java to Java communication but other formats to other systems
* can be used, such as using simple text
* strings when talking to JavaScript or coming up with other formats for
* talking to C / C# languages or proprietary messaging systems
* we wish to interface with at the wire level etc.
*
* @version $Revision: 1.11 $
*/
public abstract class WireFormat {

    private static final Log log = LogFactory.getLog(WireFormat.class);

    /**
     * Reads a packet from the given input stream
     *
     * @param in
     * @return
     * @throws IOException
     */
    public abstract Packet readPacket(DataInput in) throws IOException;

    /**
     * A helper method for working with sockets where the first byte is read
     * first, then the rest of the message is read.
     * <p/>
     * Its common when dealing with sockets to have different timeout semantics
     * until the first non-zero byte is read of a message, after which
     * time a zero timeout is used.
     *
     * @param firstByte the first byte of the packet
     * @param in        the rest of the packet
     * @return
     * @throws IOException
     */
    public abstract Packet readPacket(int firstByte, DataInput in) throws IOException;


    /**
     * Read a packet from a Datagram packet from the given channelID. If the
     * packet is from the same channel ID as it was sent then we have a
     * loop-back so discard the packet
     *
     * @param channelID is the unique channel ID
     * @param dpacket
     * @return the packet read from the datagram or null if it should be
     *         discarded
     * @throws IOException
     */
    public Packet readPacket(String channelID, DatagramPacket dpacket) throws IOException {
        DataInput in = new DataInputStream(new ByteArrayInputStream(dpacket.getData(), dpacket.getOffset(), dpacket.getLength()));
        String id = in.readUTF();

        if (channelID == null) {
            log.trace("We do not have a channelID which is probably caused by a synchronization issue, we're receiving messages before we're fully initialised");
        }
        else if (channelID.equals(id)) {
            if (log.isTraceEnabled()) {
                log.trace("Discarding packet from id: " + id);
            }
            return null;
        }
        int type = in.readByte();
        Packet packet = readPacket(type, in);

//        if (packet instanceof ActiveMQMessage) {
//            System.out.println("#####  read packet from channel: " + id + " in channel: " + channelID + " message: " + packet);
//        }
//
        return packet;
    }

    /**
     * Writes the packet to the given output stream
     *
     * @param packet
     * @param out
     * @throws IOException
     * @throws JMSException
     */
    public abstract void writePacket(Packet packet, DataOutput out) throws IOException, JMSException;

    /**
     * Writes the given package to a new datagram
     *
     * @param channelID is the unique channel ID
     * @param packet    is the packet to write
     * @return
     * @throws IOException
     * @throws JMSException
     */
    public DatagramPacket writePacket(String channelID, Packet packet) throws IOException, JMSException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DataOutputStream dataOut = new DataOutputStream(out);
        channelID = channelID != null ? channelID : "";
        dataOut.writeUTF(channelID);

//        if (packet instanceof ActiveMQMessage) {
//            System.out.println("##### write packet from channel: " + channelID + " message: " + packet);
//        }

        writePacket(packet, dataOut);
        dataOut.close();
        byte[] data = out.toByteArray();
        return new DatagramPacket(data, data.length);
    }

    /**
     * Reads the packet from the given byte[]
     * @param bytes
     * @param offset
     * @param length
     * @return
     * @throws IOException
     */
    public Packet fromBytes(byte[] bytes, int offset, int length) throws IOException {
        DataInput in = new DataInputStream(new ByteArrayInputStream(bytes, offset, length));
        return readPacket(in);
    }

    /**
     * Reads the packet from the given byte[]
     * @param bytes
     * @return
     * @throws IOException
     */
    public Packet fromBytes(byte[] bytes) throws IOException {
        DataInput in = new DataInputStream(new ByteArrayInputStream(bytes));
        return readPacket(in);
    }

    /**
     * A helper method which converts a packet into a byte array
     *
     * @param packet
     * @return a byte array representing the packet using some wire protocol
     * @throws IOException
     * @throws JMSException
     */
    public byte[] toBytes(Packet packet) throws IOException, JMSException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DataOutputStream dataOut = new DataOutputStream(out);
        writePacket(packet, dataOut);
        dataOut.close();
        return out.toByteArray();
    }

    /**
     * Creates a new copy of this wire format so it can be used in another thread/context
     *
     * @return
     */
    public abstract WireFormat copy();
   
    /**
     * Can this wireformat process packets of this version
     * @param version the version number to test
     * @return true if can accept the version
     */
    public abstract boolean canProcessWireFormatVersion(int version);
   
    /**
     * @return the current version of this wire format
     */
    public abstract int getCurrentWireFormatVersion();
}
TOP

Related Classes of org.codehaus.activemq.message.WireFormat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.