/**
*
* 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.activemq.io.impl;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.jms.JMSException;
import org.activemq.io.AbstractWireFormat;
import org.activemq.io.WireFormat;
import org.activemq.message.AbstractPacket;
import org.activemq.message.CachedValue;
import org.activemq.message.Packet;
import org.activemq.message.WireFormatInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Default implementation used for Java-Java protocols. When talking to non-Java nodes we may use a different wire
* format.
*
* @version $Revision: 1.1.1.1 $
*/
public abstract class AbstractDefaultWireFormat extends AbstractWireFormat implements Serializable {
/**
* Current wire format version for this implementation
*/
public static final int WIRE_FORMAT_VERSION = 3;
private static final Log log = LogFactory.getLog(AbstractDefaultWireFormat.class);
protected transient PacketReader messageReader;
protected transient PacketReader textMessageReader;
protected transient PacketReader objectMessageReader;
protected transient PacketReader bytesMessageReader;
protected transient PacketReader streamMessageReader;
protected transient PacketReader mapMessageReader;
protected transient PacketReader messageAckReader;
protected transient PacketReader receiptReader;
protected transient PacketReader consumerInfoReader;
protected transient PacketReader producerInfoReader;
protected transient PacketReader transactionInfoReader;
protected transient PacketReader xaTransactionInfoReader;
protected transient PacketReader brokerInfoReader;
protected transient PacketReader connectionInfoReader;
protected transient PacketReader sessionInfoReader;
protected transient PacketReader durableUnsubscribeReader;
protected transient PacketReader reponseReceiptReader;
protected transient PacketReader intReponseReceiptReader;
protected transient PacketReader capacityInfoReader;
protected transient PacketReader capacityInfoRequestReader;
protected transient PacketReader wireFormatInfoReader;
protected transient PacketReader keepAliveReader;
protected transient PacketReader brokerAdminCommandReader;
protected transient PacketReader cachedValueReader;
protected transient PacketReader cleanupConnectionAndSessionInfoReader;
protected transient PacketWriter messageWriter;
protected transient PacketWriter textMessageWriter;
protected transient PacketWriter objectMessageWriter;
protected transient PacketWriter bytesMessageWriter;
protected transient PacketWriter streamMessageWriter;
protected transient PacketWriter mapMessageWriter;
protected transient PacketWriter messageAckWriter;
protected transient PacketWriter receiptWriter;
protected transient PacketWriter consumerInfoWriter;
protected transient PacketWriter producerInfoWriter;
protected transient PacketWriter transactionInfoWriter;
protected transient PacketWriter xaTransactionInfoWriter;
protected transient PacketWriter brokerInfoWriter;
protected transient PacketWriter connectionInfoWriter;
protected transient PacketWriter sessionInfoWriter;
protected transient PacketWriter durableUnsubscribeWriter;
protected transient PacketWriter reponseReceiptWriter;
protected transient PacketWriter intReponseReceiptWriter;
protected transient PacketWriter capacityInfoWriter;
protected transient PacketWriter capacityInfoRequestWriter;
protected transient PacketWriter wireFormatInfoWriter;
protected transient PacketWriter keepAliveWriter;
protected transient PacketWriter brokerAdminCommandWriter;
protected transient PacketWriter cachedValueWriter;
protected transient PacketWriter cleanupConnectionAndSessionInfoWriter;
private List readers = new ArrayList();
private List writers = new ArrayList();
protected transient int currentWireFormatVersion;
/**
* Default Constructor
*/
public AbstractDefaultWireFormat() {
this.currentWireFormatVersion = WIRE_FORMAT_VERSION;
initializeReaders();
initializeWriters();
}
abstract public byte[] toBytes(Packet packet) throws IOException;
abstract public Packet writePacket(Packet packet, DataOutput dataOut) throws IOException;
abstract protected Packet readPacket(DataInput dataIn, PacketReader reader) throws IOException;
abstract protected void handleCachedValue(CachedValue cv);
abstract public Object getValueFromReadCache(short key);
abstract short getWriteCachedKey(Object value) throws IOException;
/**
* Some wire formats require a handshake at start-up
* @param dataOut
* @param dataIn
* @throws JMSException
*/
public void initiateClientSideProtocol(DataOutputStream dataOut,DataInputStream dataIn) throws JMSException{
WireFormatInfo info = new WireFormatInfo();
info.setVersion(getCurrentWireFormatVersion());
try {
writePacket(info, dataOut);
dataOut.flush();
}
catch (IOException e) {
throw new JMSException("Failed to intiate protocol");
}
}
/**
* Some wire formats require a handshake at start-up
* @param dataOut
* @param dataIn
* @throws JMSException
*/
public void initiateServerSideProtocol(DataOutputStream dataOut,DataInputStream dataIn) throws JMSException{
}
/**
* @return new WireFormat
*/
abstract public WireFormat copy();
/**
* @param firstByte
* @param dataIn
* @return
* @throws IOException
*
*/
public Packet readPacket(int firstByte, DataInput dataIn) throws IOException {
switch (firstByte) {
case Packet.ACTIVEMQ_MESSAGE :
return readPacket(dataIn, messageReader);
case Packet.ACTIVEMQ_TEXT_MESSAGE :
return readPacket(dataIn, textMessageReader);
case Packet.ACTIVEMQ_OBJECT_MESSAGE :
return readPacket(dataIn, objectMessageReader);
case Packet.ACTIVEMQ_BYTES_MESSAGE :
return readPacket(dataIn, bytesMessageReader);
case Packet.ACTIVEMQ_STREAM_MESSAGE :
return readPacket(dataIn, streamMessageReader);
case Packet.ACTIVEMQ_MAP_MESSAGE :
return readPacket(dataIn, mapMessageReader);
case Packet.ACTIVEMQ_MSG_ACK :
return readPacket(dataIn, messageAckReader);
case Packet.RECEIPT_INFO :
return readPacket(dataIn, receiptReader);
case Packet.CONSUMER_INFO :
return readPacket(dataIn, consumerInfoReader);
case Packet.PRODUCER_INFO :
return readPacket(dataIn, producerInfoReader);
case Packet.TRANSACTION_INFO :
return readPacket(dataIn, transactionInfoReader);
case Packet.XA_TRANSACTION_INFO :
return readPacket(dataIn, xaTransactionInfoReader);
case Packet.ACTIVEMQ_BROKER_INFO :
return readPacket(dataIn, brokerInfoReader);
case Packet.ACTIVEMQ_CONNECTION_INFO :
return readPacket(dataIn, connectionInfoReader);
case Packet.SESSION_INFO :
return readPacket(dataIn, sessionInfoReader);
case Packet.DURABLE_UNSUBSCRIBE :
return readPacket(dataIn, durableUnsubscribeReader);
case Packet.RESPONSE_RECEIPT_INFO :
return readPacket(dataIn, reponseReceiptReader);
case Packet.INT_RESPONSE_RECEIPT_INFO :
return readPacket(dataIn, intReponseReceiptReader);
case Packet.CAPACITY_INFO :
return readPacket(dataIn, capacityInfoReader);
case Packet.CAPACITY_INFO_REQUEST :
return readPacket(dataIn, capacityInfoRequestReader);
case Packet.WIRE_FORMAT_INFO :
WireFormatInfo info = (WireFormatInfo)readPacket(dataIn, wireFormatInfoReader);
if (info != null){
if (info.getVersion() < 3){
throw new IOException("Cannot support wire format version: " + info.getVersion());
}
}
return info;
case Packet.KEEP_ALIVE :
return readPacket(dataIn, keepAliveReader);
case Packet.BROKER_ADMIN_COMMAND :
return readPacket(dataIn, brokerAdminCommandReader);
case Packet.CACHED_VALUE_COMMAND :
CachedValue cv = (CachedValue)readPacket(dataIn,cachedValueReader);
handleCachedValue(cv);
return null;
case Packet.CLEANUP_CONNECTION_INFO :
return readPacket(dataIn, cleanupConnectionAndSessionInfoReader);
default :
log.error("Could not find PacketReader for packet type: "
+ AbstractPacket.getPacketTypeAsString(firstByte));
return null;
}
}
protected PacketWriter getWriter(Packet packet) throws IOException {
PacketWriter answer = null;
switch (packet.getPacketType()) {
case Packet.ACTIVEMQ_MESSAGE :
answer = messageWriter;
break;
case Packet.ACTIVEMQ_TEXT_MESSAGE :
answer = textMessageWriter;
break;
case Packet.ACTIVEMQ_OBJECT_MESSAGE :
answer = objectMessageWriter;
break;
case Packet.ACTIVEMQ_BYTES_MESSAGE :
answer = bytesMessageWriter;
break;
case Packet.ACTIVEMQ_STREAM_MESSAGE :
answer = streamMessageWriter;
break;
case Packet.ACTIVEMQ_MAP_MESSAGE :
answer = mapMessageWriter;
break;
case Packet.ACTIVEMQ_MSG_ACK :
answer = messageAckWriter;
break;
case Packet.RECEIPT_INFO :
answer = receiptWriter;
break;
case Packet.CONSUMER_INFO :
answer = consumerInfoWriter;
break;
case Packet.PRODUCER_INFO :
answer = producerInfoWriter;
break;
case Packet.TRANSACTION_INFO :
answer = transactionInfoWriter;
break;
case Packet.XA_TRANSACTION_INFO :
answer = xaTransactionInfoWriter;
break;
case Packet.ACTIVEMQ_BROKER_INFO :
answer = brokerInfoWriter;
break;
case Packet.ACTIVEMQ_CONNECTION_INFO :
answer = connectionInfoWriter;
break;
case Packet.SESSION_INFO :
answer = sessionInfoWriter;
break;
case Packet.DURABLE_UNSUBSCRIBE :
answer = durableUnsubscribeWriter;
break;
case Packet.RESPONSE_RECEIPT_INFO :
answer = reponseReceiptWriter;
break;
case Packet.INT_RESPONSE_RECEIPT_INFO :
answer = intReponseReceiptWriter;
break;
case Packet.CAPACITY_INFO :
answer = capacityInfoWriter;
break;
case Packet.CAPACITY_INFO_REQUEST :
answer = capacityInfoRequestWriter;
break;
case Packet.WIRE_FORMAT_INFO :
answer = wireFormatInfoWriter;
break;
case Packet.KEEP_ALIVE :
answer = keepAliveWriter;
break;
case Packet.BROKER_ADMIN_COMMAND :
answer = brokerAdminCommandWriter;
break;
case Packet.CACHED_VALUE_COMMAND:
answer = cachedValueWriter;
break;
case Packet.CLEANUP_CONNECTION_INFO:
answer = cleanupConnectionAndSessionInfoWriter;
break;
default :
log.error("no PacketWriter for packet: " + packet);
}
return answer;
}
/**
* Can this wireformat process packets of this version
* @param version the version number to test
* @return true if can accept the version
*/
public boolean canProcessWireFormatVersion(int version){
return version <= WIRE_FORMAT_VERSION;
}
/**
* @return the current version of this wire format
*/
public int getCurrentWireFormatVersion(){
return currentWireFormatVersion;
}
/**
* set the current version
* @param version
*/
public void setCurrentWireFormatVersion(int version){
this.currentWireFormatVersion = version;
for (int i =0; i < readers.size(); i++){
PacketReader reader = (PacketReader)readers.get(i);
reader.setWireFormatVersion(version);
}
for (int i =0; i < writers.size(); i++){
PacketWriter writer = (PacketWriter)writers.get(i);
writer.setWireFormatVersion(version);
}
}
private void initializeReaders() {
messageReader = new ActiveMQMessageReader(this);
readers.add(messageReader);
textMessageReader = new ActiveMQTextMessageReader(this);
readers.add(textMessageReader);
objectMessageReader = new ActiveMQObjectMessageReader(this);
readers.add(objectMessageReader);
bytesMessageReader = new ActiveMQBytesMessageReader(this);
readers.add(bytesMessageReader);
streamMessageReader = new ActiveMQStreamMessageReader(this);
readers.add(streamMessageReader);
mapMessageReader = new ActiveMQMapMessageReader(this);
readers.add(mapMessageReader);
messageAckReader = new MessageAckReader(this);
readers.add(messageAckReader);
receiptReader = new ReceiptReader();
readers.add(receiptReader);
consumerInfoReader = new ConsumerInfoReader();
readers.add(consumerInfoReader);
producerInfoReader = new ProducerInfoReader();
readers.add(producerInfoReader);
transactionInfoReader = new TransactionInfoReader();
readers.add(transactionInfoReader);
xaTransactionInfoReader = new XATransactionInfoReader();
readers.add(xaTransactionInfoReader);
brokerInfoReader = new BrokerInfoReader();
readers.add(brokerInfoReader);
connectionInfoReader = new ConnectionInfoReader();
readers.add(connectionInfoReader);
sessionInfoReader = new SessionInfoReader();
readers.add(sessionInfoReader);
durableUnsubscribeReader = new DurableUnsubscribeReader();
readers.add(durableUnsubscribeReader);
reponseReceiptReader = new ResponseReceiptReader();
readers.add(reponseReceiptReader);
intReponseReceiptReader = new IntResponseReceiptReader();
readers.add(intReponseReceiptReader);
capacityInfoReader = new CapacityInfoReader();
readers.add(capacityInfoReader);
capacityInfoRequestReader = new CapacityInfoRequestReader();
readers.add(capacityInfoReader);
wireFormatInfoReader = new WireFormatInfoReader(this);
readers.add(wireFormatInfoReader);
keepAliveReader = new KeepAliveReader();
readers.add(keepAliveReader);
brokerAdminCommandReader = new BrokerAdminCommandReader();
readers.add(brokerAdminCommandReader);
cachedValueReader = new CachedValueReader();
readers.add(cachedValueReader);
cleanupConnectionAndSessionInfoReader = new CleanupConnectionInfoReader();
readers.add(cleanupConnectionAndSessionInfoReader);
}
private void initializeWriters(){
messageWriter = new ActiveMQMessageWriter(this);
writers.add(messageWriter);
textMessageWriter = new ActiveMQTextMessageWriter(this);
writers.add(textMessageWriter);
objectMessageWriter = new ActiveMQObjectMessageWriter(this);
writers.add(objectMessageWriter);
bytesMessageWriter = new ActiveMQBytesMessageWriter(this);
writers.add(bytesMessageWriter);
streamMessageWriter = new ActiveMQStreamMessageWriter(this);
writers.add(streamMessageWriter);
mapMessageWriter = new ActiveMQMapMessageWriter(this);
writers.add(mapMessageWriter);
messageAckWriter = new MessageAckWriter(this);
writers.add(messageAckWriter);
receiptWriter = new ReceiptWriter();
writers.add(receiptWriter);
consumerInfoWriter = new ConsumerInfoWriter();
writers.add(consumerInfoWriter);
producerInfoWriter = new ProducerInfoWriter();
writers.add(producerInfoWriter);
transactionInfoWriter = new TransactionInfoWriter();
writers.add(transactionInfoWriter);
xaTransactionInfoWriter = new XATransactionInfoWriter();
writers.add(xaTransactionInfoWriter);
brokerInfoWriter = new BrokerInfoWriter();
writers.add(brokerInfoWriter);
connectionInfoWriter = new ConnectionInfoWriter();
writers.add(connectionInfoWriter);
sessionInfoWriter = new SessionInfoWriter();
writers.add(sessionInfoWriter);
durableUnsubscribeWriter = new DurableUnsubscribeWriter();
writers.add(durableUnsubscribeWriter);
reponseReceiptWriter = new ResponseReceiptWriter();
writers.add(reponseReceiptWriter);
intReponseReceiptWriter = new IntResponseReceiptWriter();
writers.add(intReponseReceiptWriter);
capacityInfoWriter = new CapacityInfoWriter();
writers.add(capacityInfoWriter);
capacityInfoRequestWriter = new CapacityInfoRequestWriter();
writers.add(capacityInfoWriter);
wireFormatInfoWriter = new WireFormatInfoWriter();
writers.add(wireFormatInfoWriter);
keepAliveWriter = new KeepAliveWriter();
writers.add(keepAliveWriter);
brokerAdminCommandWriter = new BrokerAdminCommandWriter();
writers.add(brokerAdminCommandWriter);
cachedValueWriter = new CachedValueWriter();
writers.add(cachedValueWriter);
cleanupConnectionAndSessionInfoWriter = new CleanupConnectionInfoWriter();
writers.add(cleanupConnectionAndSessionInfoWriter);
}
}