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