001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    
019    package org.activemq.io.impl;
020    import java.io.ByteArrayInputStream;
021    import java.io.DataInput;
022    import java.io.DataInputStream;
023    import java.io.IOException;
024    import org.activemq.message.AbstractPacket;
025    import org.activemq.message.Packet;
026    import org.activemq.util.BitArray;
027    import org.activemq.util.SerializationHelper;
028    
029    import javax.jms.JMSException;
030    
031    /**
032     * Allows instances implementing Packet interface to be deserailized
033     * 
034     * @version $Revision: 1.1.1.1 $
035     */
036    public abstract class AbstractPacketReader implements PacketReader {
037        protected int wireFormatVersion = DefaultWireFormat.WIRE_FORMAT_VERSION;
038      
039    
040        /**
041         * @param packetType
042         * @return true if this PacketReader can a Packet of this type
043         */
044        public boolean canRead(int packetType) {
045            return this.getPacketType() == packetType;
046        }
047    
048        /**
049         * pointless method - but mirrors writer
050         * 
051         * @param dataIn
052         * @return the String
053         * @throws IOException
054         */
055        protected String readUTF(DataInput dataIn) throws IOException {
056            return dataIn.readUTF();
057        }
058    
059        /**
060         * ;
061         * 
062         * @param dataIn
063         * @return object
064         * @throws IOException
065         */
066        protected Object readObject(DataInput dataIn) throws IOException {
067            int dataLength = dataIn.readInt();
068            if (dataLength > 0) {
069                byte[] data = new byte[dataLength];
070                dataIn.readFully(data);
071                
072                try {
073                    return SerializationHelper.readObject(data);
074                }
075                catch (ClassNotFoundException ex) {
076                    throw (IOException)new IOException("Class Not Found: "+ ex.getMessage()).initCause(ex);
077                }
078            }
079            return null;
080        }
081    
082        /**
083         * build a Packet instance from the data input stream
084         * 
085         * @param p A Packet object
086         * @param dataIn the data input stream to build the packet from
087         * @throws IOException
088         */
089        public void buildPacket(Packet p, DataInput dataIn) throws IOException {
090            AbstractPacket packet = (AbstractPacket) p;
091            packet.setId(dataIn.readShort());
092            BitArray ba = packet.getBitArray();
093            ba.readFromStream(dataIn);
094            packet.setReceiptRequired(ba.get(AbstractPacket.RECEIPT_REQUIRED_INDEX));
095            if (ba.get(AbstractPacket.BROKERS_VISITED_INDEX)) {
096                int visitedLen = dataIn.readShort();
097                for (int i = 0;i < visitedLen;i++) {
098                    packet.addBrokerVisited(dataIn.readUTF());
099                }
100            }
101        }
102    
103        /**
104         * Deserailizes a Packet from a byte array
105         * 
106         * @param data
107         * @return the deserialized Packet
108         * @throws IOException
109         */
110        public Packet readPacketFromByteArray(byte[] data) throws IOException {
111            ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
112            DataInputStream dataIn = new DataInputStream(bytesIn);
113            Packet packet = createPacket();
114            buildPacket(packet, dataIn);
115            return packet;
116        }
117    
118        /**
119         * Set the wire format version
120         * 
121         * @param version
122         */
123        public void setWireFormatVersion(int version) {
124            this.wireFormatVersion = version;
125        }
126    
127        /**
128         * @return the wire format version
129         */
130        public int getWireFormatVersion() {
131            return wireFormatVersion;
132        }
133    }