001    package com.mockrunner.mock.jms;
002    
003    import java.io.Serializable;
004    import java.util.ArrayList;
005    import java.util.Collections;
006    import java.util.HashSet;
007    import java.util.List;
008    import java.util.Set;
009    
010    import javax.jms.Destination;
011    import javax.jms.JMSException;
012    import javax.jms.Message;
013    import javax.jms.Session;
014    
015    import org.activemq.filter.mockrunner.Filter;
016    
017    import com.mockrunner.base.NestedApplicationException;
018    
019    /**
020     * Mock implementation of JMS <code>Destination</code>.
021     */
022    public abstract class MockDestination implements Destination, Serializable
023    {
024        private Set sessions;
025        private List currentMessages;
026        private List receivedMessages;
027    
028        public MockDestination()
029        {
030            sessions = new HashSet();
031            currentMessages = new ArrayList();
032            receivedMessages = new ArrayList();
033        }
034        
035        /**
036         * Adds a message and delivers it to the corresponding consumers. 
037         * Implemented by {@link MockQueue} and {@link MockTopic}.
038         * @param message the message
039         */
040        public abstract void addMessage(Message message) throws JMSException;
041     
042        /**
043         * Adds a message to the list of current messages in this
044         * destination. The message is not delivered to registered
045         * consumers. Can be used to preload destinations with
046         * test messages.
047         * @param message the message
048         */
049        public void loadMessage(Message message)
050        {
051            addCurrentMessage(message);
052        }
053        
054        /**
055         * Returns if this destination contains messages.
056         * @return <code>false</code> if there's at least one message,
057         *         <code>true</code> otherwise
058         */
059        public boolean isEmpty()
060        {
061            return currentMessages.size() <= 0;
062        }
063    
064        /**
065         * Clears all current messages.
066         */
067        public void clear()
068        {
069            currentMessages.clear();
070        }
071    
072        /**
073         * Clears all current messages and resets the list of received messages.
074         */
075        public void reset()
076        {
077            currentMessages.clear();
078            receivedMessages.clear();
079        }
080    
081        /**
082         * Returns the next message. The message will be removed from the list
083         * of current messages. 
084         * If there's no message, <code>null</code> will be returned.
085         * @return the <code>Message</code>
086         */
087        public Message getMessage()
088        {
089            if(currentMessages.size() <= 0) return null;
090            return (Message)currentMessages.remove(0);
091        }
092        
093        /**
094         * Returns the next message that matches the filter. 
095         * The message will be removed from the list of current messages. 
096         * If there's no matching message, <code>null</code> will be returned.
097         * @param filter the message filter
098         * @return the <code>Message</code>
099         */
100        public Message getMatchingMessage(Filter filter)
101        {
102            for(int ii = 0; ii < currentMessages.size(); ii++)
103            {
104                Message currentMessage = (Message)currentMessages.get(ii);
105                try
106                {
107                    if(filter.matches(currentMessage))
108                    {
109                        currentMessages.remove(ii);
110                        return currentMessage;
111                    }
112                }
113                catch(JMSException exc)
114                {
115                    throw new NestedApplicationException(exc);
116                }
117            }
118            return null;
119        }
120    
121        /**
122         * Returns a <code>List</code> of all current messages.
123         * @return the <code>List</code> of messages
124         */
125        public List getCurrentMessageList()
126        {
127            return Collections.unmodifiableList(currentMessages);
128        }
129    
130        /**
131         * Returns a <code>List</code> of all received messages.
132         * @return the <code>List</code> of messages
133         */
134        public List getReceivedMessageList()
135        {
136            return Collections.unmodifiableList(receivedMessages);
137        }
138    
139        /**
140         * Adds a <code>Session</code>.
141         * @param session the session
142         */
143        public void addSession(Session session)
144        {
145            sessions.add(session);
146        }
147        
148        /**
149         * Removes a <code>Session</code>.
150         * @param session the session
151         */
152        public void removeSession(Session session)
153        {
154            sessions.remove(session);
155        }
156        
157        /**
158         * Return a <code>Set</code> of all sessions.
159         * @return a <code>Set</code> of all sessions
160         */
161        public Set sessionSet()
162        {
163            return Collections.unmodifiableSet(sessions);
164        }
165        
166        protected void addReceivedMessage(Message message)
167        {
168            receivedMessages.add(message);
169        }
170        
171        protected void addCurrentMessage(Message message)
172        {
173            currentMessages.add(message);
174        }
175        
176        protected void acknowledgeMessage(Message message, MockSession session) throws JMSException
177        {
178            if(session.isAutoAcknowledge())
179            {
180                message.acknowledge();
181            }
182        }
183    }