org.jwebsocket.jms.endpoint.JMSEndPointSender.java Source code

Java tutorial

Introduction

Here is the source code for org.jwebsocket.jms.endpoint.JMSEndPointSender.java

Source

//   ---------------------------------------------------------------------------
//   jWebSocket - JMSEndPointSender (Community Edition, CE)
//   ---------------------------------------------------------------------------
//   Copyright 2010-2014 Innotrade GmbH (jWebSocket.org)
//   Alexander Schulze, Germany (NRW)
//
//   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.jwebsocket.jms.endpoint;

import java.util.Enumeration;
import java.util.Map;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javolution.util.FastMap;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.jwebsocket.packetProcessors.JSONProcessor;
import org.jwebsocket.token.Token;
import org.jwebsocket.util.JWSTimerTask;
import org.jwebsocket.util.Tools;
import org.springframework.util.Assert;

/**
 *
 * @author Alexander Schulze
 */
public class JMSEndPointSender {

    // TODO: Introduce timeout management
    private static final Logger mLog = Logger.getLogger(JMSEndPointSender.class);
    private final MessageProducer mProducer;
    private final Session mSession;
    private final String mEndPointId;
    private final Map<String, IJMSResponseListener> mResponseListeners = new FastMap<String, IJMSResponseListener>()
            .shared();
    private final JMSEndPoint mEndPoint;

    /**
     *
     * @param aEndPoint
     */
    public JMSEndPointSender(JMSEndPoint aEndPoint) {
        mEndPoint = aEndPoint;
        mSession = aEndPoint.getSession();
        mProducer = aEndPoint.getProducer();
        mEndPointId = aEndPoint.getEndPointId();

        mEndPoint.addListener(new IJMSMessageListener() {
            @Override
            public JMSEndPointSender getSender() {
                return null;
            }

            @Override
            public void setSender(JMSEndPointSender aSender) {
            }

            @Override

            public void onMessage(Message aMessage) {
                // mLog.debug("onMessage: " + aMessage);
            }

            @Override
            public void onBytesMessage(BytesMessage aMessage) {
                // mLog.debug("onBytesMessage: " + aMessage);
            }

            @Override
            public void onTextMessage(final TextMessage aMessage) {
                // mLog.debug("### onTextMessage: " + aMessage);
                try {
                    boolean lIsProgressEvent = false;
                    // try to get the correlation id (utid) directly from the message
                    String lKey = aMessage.getJMSCorrelationID();

                    // if no correllation id (utid) found try to get it from token
                    if (null == lKey) {
                        Token lToken = JSONProcessor.JSONStringToToken(aMessage.getText());
                        if (null != lToken) {
                            lKey = String.valueOf(lToken.getInteger("utid"));
                            lIsProgressEvent = "event".equals(lToken.getString("type"))
                                    && "progress".equals(lToken.getString("name"));
                        }
                    }

                    if (null != lKey) {
                        // trying to get available response listener
                        final IJMSResponseListener lRespListener;
                        if (lIsProgressEvent) {
                            lRespListener = mResponseListeners.get(lKey);
                        } else {
                            lRespListener = mResponseListeners.remove(lKey);
                        }

                        // if listener exists
                        if (null != lRespListener) {
                            // getting the response text
                            final String lResponse = aMessage.getText();
                            // invoke "onResponse" callback out of this thread 
                            Tools.getThreadPool().submit(new Runnable() {

                                @Override
                                public void run() {
                                    lRespListener.onResponse(lResponse, aMessage);
                                }
                            });
                        }
                    }

                } catch (JMSException lEx) {
                }

                //            try {
                //               boolean lIsProgressEvent = false;
                //               // getting the correlation ID
                //               String lKey = aMessage.getJMSCorrelationID();
                //
                //               // TODO: fix this temporary patch in the future, using only the JMSCorrelationID
                //               if (null == lKey) {
                //                  Token lToken = JSONProcessor.JSONStringToToken(aMessage.getText());
                //                  if (null != lToken && lToken.getMap().containsKey("utid")) {
                //                     lKey = String.valueOf(lToken.getInteger("utid"));
                //                  }
                //               }
                //
                //               // in case of progress events the utid is negative
                //               if (null != lKey && lKey.startsWith("-")) {
                //                  lIsProgressEvent = true;
                //                  // cut leading "-"
                //                  lKey = lKey.substring(1);
                //               }
                //
                //               if (null != lKey) {
                //                  // trying to get available response listener
                //                  final IJMSResponseListener lRespListener;
                //                  if (lIsProgressEvent) {
                //                     lRespListener = mResponseListeners.get(lKey);
                //                  } else {
                //                     lRespListener = mResponseListeners.remove(lKey);
                //                  }
                //                  mLog.warn("#### Message A: " + aMessage.getText());
                //
                //                  // if listener exists
                //                  if (null != lRespListener) {
                //                     // getting the response text
                //                     final String lResponse = aMessage.getText();
                //                     // invoke "onResponse" callback out of this thread 
                //                     Tools.getThreadPool().submit(new Runnable() {
                //                        @Override
                //                        public void run() {
                //                           mLog.warn("#### Message B: " + lResponse);
                //                           lRespListener.onResponse(lResponse, aMessage);
                //                        }
                //                     });
                //                  }
                //               }
                //
                //            } catch (JMSException lEx) {
                //            }
            }

            @Override
            public void onMapMessage(MapMessage aMessage) {
            }

            @Override
            public void onObjectMessage(ObjectMessage aMessage) {
            }
        });
    }

    /**
     *
     * @return
     */
    public JMSEndPoint getEndPoint() {
        return mEndPoint;
    }

    /**
     *
     * @param aTargetId
     * @param aCorrelationID
     * @param aText
     * @param aListener
     */
    public void sendText(String aTargetId, String aCorrelationID, final String aText,
            IJMSResponseListener aListener) {
        sendText(aTargetId, aCorrelationID, aText, aListener, 1000 * 10);
    }

    /**
     *
     * @param aTargetId
     * @param aCorrelationID
     * @param aText
     * @param aResponseListener
     * @param aTimeout
     */
    public synchronized void sendText(String aTargetId, final String aCorrelationID, final String aText,
            IJMSResponseListener aResponseListener, long aTimeout) {
        Message lMsg;
        try {
            lMsg = mSession.createTextMessage(aText);
            if (null != aCorrelationID) {
                lMsg.setJMSCorrelationID(aCorrelationID);
            }
            lMsg.setStringProperty("targetId", aTargetId);
            lMsg.setStringProperty("sourceId", mEndPointId);

            if (mLog.isDebugEnabled()) {
                StringBuilder lPropStr = new StringBuilder();
                Enumeration lPropNames = lMsg.getPropertyNames();
                while (lPropNames.hasMoreElements()) {
                    String lPropName = (String) lPropNames.nextElement();
                    Object lValue = lMsg.getObjectProperty(lPropName);
                    lPropStr.append(lPropName).append("=").append(lValue);
                    if (lPropNames.hasMoreElements()) {
                        lPropStr.append(", ");
                    }
                }
                mLog.debug("Sending text to '" + aTargetId + "': "
                        + (JMSLogging.isFullTextLogging() ? aText
                                : "[content suppressed, length: " + aText.length() + " bytes]")
                        + ", props: " + lPropStr + "...");
            }

            // processing callbacks
            if (null != aResponseListener) {
                Assert.notNull(aCorrelationID, "The 'correlationID' argument cannot be null!");
                Assert.isTrue(aTimeout > 0, "Invalid 'timeout' argument. Expecting 'timeout' > 0");
                // setting the expiration time
                lMsg.setJMSExpiration(aTimeout);

                // saving the callback 
                mResponseListeners.put(aCorrelationID, aResponseListener);

                // schedule the timer task
                Tools.getTimer().schedule(new JWSTimerTask() {
                    @Override
                    public void runTask() {
                        Thread lThread = new Thread() {
                            @Override
                            public void run() {
                                IJMSResponseListener lListener = mResponseListeners.remove(aCorrelationID);
                                if (null != lListener) {
                                    lListener.onTimeout();
                                }
                            }
                        };
                        lThread.setName("JMSEndPointSender Timeout Thread");
                        Tools.getThreadPool().submit(lThread);
                    }
                }, aTimeout);
            }

            mProducer.send(lMsg);

        } catch (JMSException lEx) {
            mLog.error(lEx.getClass().getSimpleName() + " sending message: " + lEx.getMessage() + " "
                    + ExceptionUtils.getStackTrace(lEx));
        }
    }

    /**
     *
     * @param aTargetId
     * @param aCorrelationID
     * @param aText
     */
    public void sendText(String aTargetId, String aCorrelationID, final String aText) {
        sendText(aTargetId, aCorrelationID, aText, null);
    }

    /**
     *
     * @param aTargetId
     * @param aText
     */
    public void sendText(String aTargetId, final String aText) {
        sendText(aTargetId, null, aText);
    }

    /**
     * @return the mJmsTemplate
     */
    public MessageProducer getProducer() {
        return mProducer;
    }

    /**
     * @return the EndPointId
     */
    public String getEndPointId() {
        return mEndPointId;
    }
}