package cern.cmw.mom.pubsub.impl; import cern.cmw.mom.pubsub.MOMException; import cern.cmw.mom.pubsub.Publisher; import cern.cmw.mom.util.MomConfig; import cern.cmw.mom.util.TopicAdminHelper; import org.apache.log4j.Category; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.jms.BytesMessage; import javax.jms.DeliveryMode; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.JMSSecurityException; import javax.jms.MapMessage; import javax.jms.Message; import javax.jms.ObjectMessage; import javax.jms.StreamMessage; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicPublisher; import javax.jms.TopicSession; import javax.naming.NamingException; /** * Implementation class. * @version 1.0 23 Jan 2001 * @author Controls Middleware Project * @see Publisher */ public class DefaultPublisherImpl implements Publisher, ExceptionListener { static Category cat = Category.getInstance(DefaultPublisherImpl.class.getName()); private Boolean loadBalancing; private Boolean selectorAtBroker; private Boolean sequential; private cern.cmw.mom.pubsub.ExceptionListener listener = null; private JMSTopicConnection connection = null; private Map topicDirectory = null; private Properties momProperties = null; private String brokerList; private String password; private String username; private TopicPublisher publisher = null; private TopicSession session = null; private boolean closed = true; private int defaultPersistance; private int defaultPriority; private long defaultTimeToLive; /** * Constructor DefaultPublisherImpl * * @throws MOMException * */ public DefaultPublisherImpl() throws MOMException { this.username = null; this.password = null; this.brokerList = null; this.loadBalancing = null; this.sequential = null; this.selectorAtBroker = null; open(); } /** * Constructor DefaultPublisherImpl * * @param username the user name * @param password the password * @param brokerList the coma separated broker URLs list (in the form [protocol://]hostname[:port]) * @param loadBalancing if true, indicates that the client is willing to have a connect request re-directed to another broker within a cluster * @param sequential if true, the broker list will be scanned sequentially * @param selectorAtBroker if true, selectors will be evaluated on the broker side * @throws MOMException * */ public DefaultPublisherImpl(String username, String password, String brokerList, Boolean loadBalancing, Boolean sequential, Boolean selectorAtBroker) throws MOMException { this.username = username; this.password = password; this.brokerList = brokerList; this.loadBalancing = loadBalancing; this.sequential = sequential; this.selectorAtBroker = selectorAtBroker; open(); } /** * Method isClosed * * @return Topic */ public boolean isClosed() { return closed; } /** * Method setExceptionListener * * @param listener */ public void setExceptionListener(cern.cmw.mom.pubsub.ExceptionListener listener) { this.listener = listener; } /** * Method close * * */ public void close() { cat.debug("close()"); if (closed) { return; } try { if (publisher != null) { publisher.close(); publisher = null; } if (session != null) { session.close(); session = null; } if (connection != null) { try { connection.stop(); } catch (ConnectionException ce) { ce.printStackTrace(); } connection.close(); connection = null; } if (topicDirectory != null) { topicDirectory.clear(); topicDirectory = null; } closed = true; } catch (javax.jms.JMSException e) { cat.error("JMSException raised closing a Publisher : " + e.getMessage()); } } /** * Method createBytesMessage * * * @return BytesMessage * * @throws JMSException * */ public BytesMessage createBytesMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } BytesMessage message = null; message = session.createBytesMessage(); return message; } /** * Method createMapMessage * * * @return MapMessage * * @throws JMSException * */ public MapMessage createMapMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } MapMessage message = null; message = session.createMapMessage(); return message; } /** * Method createMessage * * * @return Message * * @throws JMSException * */ public Message createMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } Message message = null; message = session.createMessage(); return message; } /** * Method createObjectMessage * * * @return ObjectMessage * * @throws JMSException * */ public ObjectMessage createObjectMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } ObjectMessage message = null; message = session.createObjectMessage(); return message; } /** * Method createStreamMessage * * * @return StreamMessage * * @throws JMSException * */ public StreamMessage createStreamMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } StreamMessage message = null; message = session.createStreamMessage(); return message; } /** * Method createTextMessage * * * @return TextMessage * * @throws JMSException * */ public TextMessage createTextMessage() throws JMSException { if (closed) { throw (new JMSException("Publisher object has been closed")); } TextMessage message = null; message = session.createTextMessage(); return message; } /** * Method onException * * * @param ex * */ public void onException(JMSException ex) { cat.warn("onException()"); /*if (progress.message.jclient.ErrorCodes.testException(ex, progress.message.jclient.ErrorCodes.ERR_CONNECTION_DROPPED)) { cat.error("ERR_CONNECTION_DROPPED detected."); if (listener != null) { listener.onException(new MOMException("ERR_CONNECTION_DROPPED detected.", MOMException.CONNECTION_LOST_EXCEPTION)); } connection.disconnect(); try { initialize(true); if (listener != null) { listener.onException(new MOMException("Connection reestabilished", MOMException.CONNECTION_RECOVERED_EXCEPTION)); } } catch (MOMException e) { cat.error("unable to recover", e); } }*/ } /** * Method open * * @throws MOMException */ public void open() throws MOMException { cat.debug("open()"); initialize(false); } /** * Method publish * * * @param topic * @param message * * @throws JMSException * @throws NamingException * */ public void publish(String topic, Message message) throws JMSException, NamingException { publish(topic, message, defaultPersistance, defaultPriority, defaultTimeToLive); } /** * Publish a message to the given topic. * @param topic The String representation of the topic * @param message The Message object to publish * @param deliveryMode The Message persistence * @param priority The Message priority * @param timeToLive The Message time to live * @exception JMSException if JMS fails to publish the message due to some internal JMS error. * @exception NamingException if there is a violation in the namespace policy. */ public void publish(String topic, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException, NamingException { cat.debug("publish(" + topic + ", " + message + ")"); if (closed) { throw (new JMSException("Publisher object has been closed")); } Topic t = createTopic(topic); try { publisher.publish(t, message, deliveryMode, priority, timeToLive); } catch (JMSSecurityException jse) { cat.error("JMSSecurityException caught"); throw (new NamingException(jse.getMessage())); } } /** * Method finalize * * @throws Throwable */ protected void finalize() throws Throwable { cat.debug("finalize()"); close(); super.finalize(); } /** * Method createTopic * * @param topic * @return Topic * @throws JMSException * @throws NamingException */ private Topic createTopic(String topic) throws JMSException, NamingException { cat.debug("createTopic(" + topic + ")"); Topic the_topic = null; if (TopicAdminHelper.validateTopic(topic, connection.getUsername(), TopicAdminHelper.FOR_PUBLISHING)) { the_topic = (Topic) topicDirectory.get(topic); if (the_topic == null) { the_topic = session.createTopic(topic); topicDirectory.put(topic, the_topic); } } else { throw (new NamingException("[" + topic + "] is not a valid topic name")); } return the_topic; } /** * Method initialize. * * @param retry * @throws MOMException */ private void initialize(boolean retry) throws MOMException { momProperties = MomConfig.getProperties(this.getClass().getClassLoader()); defaultPersistance = (momProperties.getProperty(MomConfig.MSG_PERSISTANCE_PROPERTY).equals("true") ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT); defaultPriority = Integer.parseInt(momProperties.getProperty(MomConfig.MSG_PRIORITY_PROPERTY)); defaultTimeToLive = Long.parseLong(momProperties.getProperty(MomConfig.MSG_TIMETOLIVE_PROPERTY)); topicDirectory = new HashMap(); try { connection = JMSTopicConnectionFactory.createJMSTopicConnection(username, password, brokerList, loadBalancing, sequential, selectorAtBroker); connection.connect(retry); connection.setExceptionListener(this); session = connection.createTopicSession(); connection.start(); publisher = session.createPublisher(null); closed = false; } catch (ConnectionException e) { System.out.println("Exception caught: "+e.getMessage()); e.printStackTrace(System.err); throw new MOMException("Unable to estabilish a connection, cause is : " + e.getMessage()); } catch (JMSException e) { System.out.println("Exception caught: "+e.getMessage()); e.printStackTrace(System.err); throw (new MOMException(e.getMessage())); } } } /*--- Formatted in Sun Java Convention Style on Fri, Aug 3, '01 ---*/ /*------ Formatted by Jindent 3.23 Gold 1.02 --- http://www.jindent.de ------*/