package org.mom4j.jms;
import javax.jms.Connection;
import javax.jms.ConnectionConsumer;
import javax.jms.ConnectionMetaData;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.ServerSessionPool;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import org.mom4j.xcp.XcpResponse;
import org.mom4j.xcp.XcpSender;
import org.mom4j.messaging.XcpMessage;
import org.mom4j.messaging.XcpMessageHandler;
public class ConnectionImpl implements Connection, TopicConnection, QueueConnection {
private static ConnectionMetaData metaData = new ConnectionMetaDataImpl();
private static String ID_SUFFIX;
private static long connectionCount = 0;
private static java.util.Random random = new java.util.Random();
private ExceptionListener exceptionListener;
private String hostname;
private String clientId;
private boolean started;
private boolean closed;
private int port;
private long sessionCount;
private long msgCount;
private long pollSync;
private long pollAsync;
protected Map sessions;
protected XcpSender sender;
static {
try {
java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
java.util.StringTokenizer st =
new java.util.StringTokenizer(addr.getHostAddress(), ".");
StringBuffer sb = new StringBuffer();
while(st.hasMoreTokens()) {
sb.insert(0, st.nextToken());
}
ID_SUFFIX = sb.toString();
} catch(Exception ex) {
ex.printStackTrace();
throw new IllegalStateException(ex.getMessage());
}
}
public ConnectionImpl(String hostname,
int port,
String username,
String password,
long pollSync,
long pollAsync)
throws JMSException
{
if(hostname == null)
throw new IllegalArgumentException("hostname is null!");
long t = Math.abs(System.currentTimeMillis() ^ random.nextLong());
this.hostname = hostname;
this.port = port;
this.exceptionListener = null;
//this.clientId = new UID().toString() + "@" + ID_SUFFIX;
this.clientId = Long.toString(t) + (connectionCount++) + "@" + ID_SUFFIX;
this.started = false;
this.closed = false;
this.sessions = Collections.synchronizedMap(new HashMap());
this.sessionCount = 0;
this.msgCount = 1;
this.pollSync = pollSync;
this.pollAsync = pollAsync;
try {
this.sender =
new XcpSender(java.net.InetAddress.getByName(hostname), port);
} catch(java.net.UnknownHostException ex) {
throw new JMSException("unknown host:" + hostname);
}
}
//
// javax.jms.Connection - Interface
//
public String getClientID()
throws JMSException
{
return this.clientId;
}
public void start()
throws JMSException
{
if(this.closed) {
throw new javax.jms.IllegalStateException("connection is closed");
}
if(this.started) {
return;
}
this.started = true;
}
public void stop()
throws JMSException
{
if(this.closed) {
throw new javax.jms.IllegalStateException("connection is closed");
}
if(!this.started) {
return;
}
this.started = false;
}
public void setExceptionListener(ExceptionListener listener)
throws JMSException
{
if(listener == null)
throw new IllegalArgumentException("listener is null!");
this.exceptionListener = listener;
}
public void setClientID(String id)
throws JMSException
{
throw new javax.jms.IllegalStateException("id is set already.");
}
public void close()
throws JMSException
{
if(this.closed) {
return;
}
if(this.started) {
this.stop();
}
Iterator it = this.sessions.keySet().iterator();
while(it.hasNext()) {
String s = (String)it.next();
SessionImpl si = (SessionImpl)this.sessions.get(s);
si.close();
}
this.closed = true;
}
public ConnectionMetaData getMetaData()
throws JMSException
{
return ConnectionImpl.metaData;
}
public ExceptionListener getExceptionListener()
throws javax.jms.JMSException
{
return this.exceptionListener;
}
public ConnectionConsumer createConnectionConsumer(
Destination dest,
String messageSelector,
ServerSessionPool pool,
int maxMessages)
throws JMSException
{
throw new FeatureNotSupportedException();
}
public Session createSession(boolean transacted, int acknowledgeMode)
throws JMSException
{
return this.createSessionInternal(transacted, acknowledgeMode);
}
private SessionImpl createSessionInternal(boolean transacted, int acknowledgeMode)
throws JMSException
{
SessionImpl s = null;
String sid = (++this.sessionCount) + this.getClientID();
try {
s = new SessionImpl(sid, transacted, acknowledgeMode, this);
} catch(IllegalArgumentException ex) {
throw new JMSException(ex.getMessage());
}
this.sessions.put(sid, s);
return s;
}
//
// javax.jms.TopicConnection - Interface
//
public TopicSession createTopicSession(boolean transacted, int acknowledgeMode)
throws JMSException
{
return this.createSessionInternal(transacted, acknowledgeMode);
}
public ConnectionConsumer createConnectionConsumer(
Topic topic,
String messageSelector,
ServerSessionPool pool,
int maxMessages)
throws JMSException
{
throw new FeatureNotSupportedException();
}
public ConnectionConsumer createDurableConnectionConsumer(
Topic topic,
String messageSelector,
String subscriptionName,
ServerSessionPool pool,
int maxMessages)
throws JMSException
{
throw new FeatureNotSupportedException();
}
//
// javax.jms.QueueConnection - Interface
//
public QueueSession createQueueSession(boolean transacted, int acknowledgeMode)
throws JMSException
{
return this.createSessionInternal(transacted, acknowledgeMode);
}
public ConnectionConsumer createConnectionConsumer(
Queue queue,
String messageSelector,
ServerSessionPool pool,
int maxMessages)
throws JMSException
{
throw new FeatureNotSupportedException();
}
//
// Internal Methods
//
private synchronized String nextMsgId() {
return "ID:" + (msgCount++) + this.clientId;
}
long getPollSync() {
return this.pollSync;
}
long getPollAsync() {
return this.pollAsync;
}
void register(DestinationImpl dest, String consumerId, String messageSelector)
throws JMSException
{
int pos = consumerId.lastIndexOf("@");
XcpMessage message = new XcpMessage(consumerId.substring(0, pos),
XcpMessage.ACTION_REGISTER,
dest.getName(),
consumerId);
message.setMessageSelector(messageSelector);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
String registerDur(DestinationImpl dest,
String name,
String consumerId,
String messageSelector)
throws JMSException
{
int pos = consumerId.lastIndexOf("@");
XcpMessage message = new XcpMessage(consumerId.substring(0, pos),
XcpMessage.ACTION_REGISTER_DUR,
dest.getName(),
consumerId);
message.setMessageSelector(messageSelector);
message.setSubscriberName(name + "@" + ID_SUFFIX);
XcpResponse resp = null;
try {
resp = this.sender.send(message, new XcpMessageHandler());
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
XcpMessage msg = (XcpMessage)resp.getRootElement();
return msg.getConsumerId();
}
void unregister(DestinationImpl dest, String consumerId)
throws JMSException
{
int pos = consumerId.lastIndexOf("@");
XcpMessage message = new XcpMessage(consumerId.substring(0, pos),
XcpMessage.ACTION_UNREGISTER,
dest.getName(),
consumerId);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
void unregisterDur(String sessionId, String name)
throws JMSException
{
XcpMessage message = new XcpMessage(sessionId,
XcpMessage.ACTION_UNREGISTER_DUR);
message.setSubscriberName(name + "@" + ID_SUFFIX);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
void createDestination(SessionImpl session, boolean queue, String name)
throws JMSException
{
String sid = session.getSessionId();
if(this.sessions.get(sid) == null)
throw new javax.jms.IllegalStateException("session is closed");
String action = queue ? XcpMessage.ACTION_CREATE_QUEUE
: XcpMessage.ACTION_CREATE_TOPIC;
XcpMessage message = new XcpMessage(sid, action, name);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
void send(SessionImpl session, MessageImpl msg, boolean disableMessageId)
throws JMSException
{
if(!disableMessageId) {
msg.setJMSMessageID(this.nextMsgId());
}
String sid = session.getSessionId();
if(this.sessions.get(sid) == null)
throw new javax.jms.IllegalStateException("session is closed");
DestinationImpl d = (DestinationImpl)msg.getJMSDestination();
String action = session.isTransacted
? XcpMessage.ACTION_SEND_TX
: XcpMessage.ACTION_SEND;
XcpMessage message = new XcpMessage(sid, action, d.getName());
message.setMessage(msg);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
javax.jms.Message receive(SessionImpl session,
String destinationName,
String consumerId)
throws JMSException
{
String sid = session.getSessionId();
if(this.sessions.get(sid) == null)
throw new javax.jms.IllegalStateException("session is closed");
String action = null;
if(!session.isTransacted && session.ackMode != Session.CLIENT_ACKNOWLEDGE) {
action = XcpMessage.ACTION_RECEIVE;
} else {
action = XcpMessage.ACTION_RECEIVE_TX;
}
XcpMessage message = new XcpMessage(sid,
action,
destinationName,
consumerId);
XcpResponse resp = null;
try {
resp = this.sender.send(message, new XcpMessageHandler());
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
message = (XcpMessage)resp.getRootElement();
return message.getMessage();
}
void commit(SessionImpl session)
throws JMSException
{
String sid = session.getSessionId();
if(this.sessions.get(sid) == null)
throw new javax.jms.IllegalStateException("session is closed");
XcpMessage message = new XcpMessage(sid,
XcpMessage.ACTION_COMMIT,
null);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
void rollback(SessionImpl session)
throws JMSException
{
String sid = session.getSessionId();
if(this.sessions.get(sid) == null)
throw new javax.jms.IllegalStateException("session is closed");
XcpMessage message = new XcpMessage(sid,
XcpMessage.ACTION_ROLLBACK,
null);
try {
this.sender.send(message);
} catch(java.io.IOException ex) {
JMSException jmsx = new JMSException(ex.getMessage());
jmsx.setLinkedException(ex);
throw jmsx;
}
}
void closeSession(SessionImpl session)
throws JMSException
{
this.sessions.remove(session.getSessionId());
}
}