/* * Copyright 2003,2004 Colin Crist * * 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 hermes.impl; import hermes.Domain; import hermes.HermesException; import hermes.HermesMessageListener; import hermes.HermesRuntimeException; import hermes.config.DestinationConfig; import java.util.ArrayList; import java.util.List; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.Session; import javax.jms.Topic; import javax.jms.TopicSession; import org.apache.log4j.Logger; /** * A queue browser that actually works on a topic, the browse will never stop. * * @author colincrist@hermesjms.com * @version $Id: TopicBrowser.java,v 1.15 2007/01/10 15:59:54 colincrist Exp $ */ public class TopicBrowser implements javax.jms.QueueBrowser { private class Enumeration implements java.util.Enumeration { private List messages = new ArrayList(); private int maxSize = 1000; private int receiveTimeout = 1000; private boolean keepRunning = true; private JMSException ex; private Enumeration() throws JMSException { init(); } private void stop() { log.debug("stopping iteration for " + dConfig.getName()); synchronized (messages) { keepRunning = false; messages.notify(); messages.clear(); } } public Object nextElement() { synchronized (messages) { if (keepRunning) { while (keepRunning && messages.size() == 0) { try { messages.wait(1000); } catch (InterruptedException ex) { } } if (keepRunning && messages.size() > 0) { return messages.remove(0); } } if (ex != null) { throw new RuntimeException(ex); } else { return null; } } } private void init() throws JMSException { log.debug("itereration running for " + dConfig.getName()); MessageListener listener = new HermesMessageListener() { public void onMessage(Message m) { synchronized (messages) { if (m != null) { messages.add(m); if (messages.size() == 1) { messages.notify(); } } } } public void onException(JMSException ex) { keepRunning = false; Enumeration.this.ex = ex; } }; try { if (keepRunning) { consumer.setMessageListener(listener); } } catch (JMSException ex) { log.error("in browse thread: " + ex.getMessage()); stop(); } // cat.debug("itereration stopped for " + subscriber) ; } /** * Returns true of the itereration is still running, else returns false */ public boolean hasMoreElements() { synchronized (messages) { return keepRunning; } } } private static final Logger log = Logger.getLogger(TopicBrowser.class); private Session session; private Enumeration iter; private DestinationConfig dConfig; private DestinationManager destinationManager; private MessageConsumer consumer = null; /** * TopicBrowser constructor comment. */ public TopicBrowser(Session session, DestinationManager destinationManager, DestinationConfig dConfig) { this.session = session; this.dConfig = dConfig; this.destinationManager = destinationManager; } /** * Stop the browser, this will stop any itereration running and unsubscribe. */ public void close() throws JMSException { if (iter != null) { iter.stop(); iter = null; } if (consumer != null) { consumer.close(); consumer = null; } } /** * Get the itereraiton for this browser. */ public synchronized java.util.Enumeration getEnumeration() throws JMSException { if (iter == null) { final Topic topic = (Topic) destinationManager.getDestination(session, dConfig.getName(), Domain.TOPIC); if (dConfig.isDurable()) { log.debug("creating DuableSubscriber for topic=" + dConfig.getName() + ", ClientID=" + dConfig.getClientID() + ", selector=" + dConfig.getSelector()); try { consumer = session.createDurableSubscriber(topic, dConfig.getClientID(), dConfig.getSelector(), false); } catch (NoSuchMethodError ex) { // NOP } catch (AbstractMethodError ex) { // NOP } if (consumer == null) { if (session instanceof TopicSession) { final TopicSession topicSession = (TopicSession) session; consumer = session.createDurableSubscriber(topic, dConfig.getClientID(), dConfig.getSelector(), false); } else { throw new HermesException("Session is 1.0.2 and not in the topic domain"); } } } else { try { if (dConfig.getSelector() == null) { consumer = session.createConsumer(topic); } else { consumer = session.createConsumer(topic, dConfig.getSelector(), false); } } catch (NoSuchMethodError ex) { // NOP } catch (AbstractMethodError ex) { // NOP } if (consumer == null) { if (session instanceof TopicSession) { final TopicSession topicSession = (TopicSession) session; if (dConfig.getSelector() == null) { consumer = topicSession.createSubscriber(topic); } else { consumer = topicSession.createSubscriber(topic, dConfig.getSelector(), false); } } else { throw new HermesRuntimeException("The session is JMS 1.0.2b and not in the topic domain."); } } } iter = new Enumeration(); } return iter; } /** * Get the message selector */ public String getMessageSelector() throws JMSException { return dConfig.getSelector(); } /** * Get the queue. There isn't one so this will return null */ public Queue getQueue() throws JMSException { return null; } }