001/*
002 * #%L
003 * Netarchivesuite - common - test
004 * %%
005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library,
006 *             the National Library of France and the Austrian National Library.
007 * %%
008 * This program is free software: you can redistribute it and/or modify
009 * it under the terms of the GNU Lesser General Public License as
010 * published by the Free Software Foundation, either version 2.1 of the
011 * License, or (at your option) any later version.
012 * 
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Lesser Public License for more details.
017 * 
018 * You should have received a copy of the GNU General Lesser Public
019 * License along with this program.  If not, see
020 * <http://www.gnu.org/licenses/lgpl-2.1.html>.
021 * #L%
022 */
023
024package dk.netarkivet.common.distribute;
025
026import java.io.Serializable;
027import java.util.ArrayList;
028import java.util.Collections;
029import java.util.Enumeration;
030import java.util.HashMap;
031import java.util.HashSet;
032import java.util.List;
033import java.util.Map;
034import java.util.Random;
035import java.util.Set;
036import java.util.concurrent.atomic.AtomicInteger;
037
038import javax.jms.BytesMessage;
039import javax.jms.Connection;
040import javax.jms.ConnectionConsumer;
041import javax.jms.ConnectionFactory;
042import javax.jms.ConnectionMetaData;
043import javax.jms.Destination;
044import javax.jms.ExceptionListener;
045import javax.jms.JMSException;
046import javax.jms.MapMessage;
047import javax.jms.Message;
048import javax.jms.MessageConsumer;
049import javax.jms.MessageListener;
050import javax.jms.MessageProducer;
051import javax.jms.ObjectMessage;
052import javax.jms.Queue;
053import javax.jms.QueueBrowser;
054import javax.jms.QueueReceiver;
055import javax.jms.QueueSender;
056import javax.jms.QueueSession;
057import javax.jms.ServerSessionPool;
058import javax.jms.Session;
059import javax.jms.StreamMessage;
060import javax.jms.TemporaryQueue;
061import javax.jms.TemporaryTopic;
062import javax.jms.TextMessage;
063import javax.jms.Topic;
064import javax.jms.TopicSubscriber;
065
066import org.slf4j.Logger;
067import org.slf4j.LoggerFactory;
068
069import dk.netarkivet.common.CommonSettings;
070import dk.netarkivet.common.exceptions.NotImplementedException;
071import dk.netarkivet.common.utils.Settings;
072import dk.netarkivet.common.utils.batch.TestChecksumJob;
073
074/**
075 * A MockUp message queue, that generates a connection and destinations suitable for testing.
076 */
077@SuppressWarnings({"rawtypes", "unused", "serial"})
078public class JMSConnectionMockupMQ extends JMSConnection {
079    //private static final Log log = LogFactory.getLog(JMSConnectionMockupMQ.class);
080    private static final Logger log = LoggerFactory.getLogger(JMSConnectionMockupMQ.class);
081
082    /**
083     * A set of threads where onMessage has been called. This object is notified when all threads have finished
084     * executing.
085     */
086    protected final Set<Thread> concurrentTasksToComplete = Collections.synchronizedSet(new HashSet<Thread>());
087    /**
088     * A map from channelnames to destinations.
089     */
090    protected Map<String, TestDestination> destinations;
091
092    /** Constructor. Does nothing, initConnection is used for setup. */
093    protected JMSConnectionMockupMQ() {
094        super();
095        log.info("Creating instance of " + getClass().getName());
096    }
097
098    /**
099     * Get the singleton, and initialise it if it is new.
100     *
101     * @return A JMSConnection
102     */
103    public static synchronized JMSConnection getInstance() {
104        if (instance == null) {
105            instance = new JMSConnectionMockupMQ();
106            instance.initConnection();
107        }
108        return instance;
109    }
110
111    protected void initConnection() {
112        super.initConnection();
113        destinations = new HashMap<String, TestDestination>();
114    }
115
116    protected ConnectionFactory getConnectionFactory() throws JMSException {
117        return new JMSConnectionMockupMQ.TestConnectionFactory();
118    }
119
120    protected Destination getDestination(String channelName) throws JMSException {
121        if (destinations == null) {
122            destinations = new HashMap<String, TestDestination>();
123        }
124        TestDestination destination = destinations.get(channelName);
125        if (destination == null) {
126            if (Channels.isTopic(channelName)) {
127                destination = new TestTopic(channelName);
128            } else {
129                destination = new TestQueue(channelName);
130            }
131            destinations.put(channelName, destination);
132        }
133        return destination;
134    }
135
136    /**
137     * Does nothing.
138     *
139     * @param e The exception to ignore :-)
140     */
141    public void onException(JMSException e) {
142        // Ignore
143    }
144
145    /** Clean up singleton instance and internal state */
146    public void cleanup() {
147        super.cleanup();
148        instance = null;
149        concurrentTasksToComplete.clear();
150        destinations = null;
151    }
152
153    /**
154     * Waits until all threads where onMessage has been called have finished executing.
155     */
156    public void waitForConcurrentTasksToFinish() {
157        synchronized (concurrentTasksToComplete) {
158            while (!concurrentTasksToComplete.isEmpty()) {
159                try {
160                    concurrentTasksToComplete.wait();
161                } catch (InterruptedException e) {
162                    // Go on
163                }
164            }
165        }
166    }
167
168    /**
169     * Wrap a NetarkivetMessage into an ObjectMessage
170     *
171     * @param nMsg a NetarkivetMessage
172     * @return an ObjectMessage
173     */
174    public static ObjectMessage getObjectMessage(NetarkivetMessage nMsg) {
175        return new TestObjectMessage(nMsg);
176    }
177
178    public static void clearTestQueues() {
179        JMSConnectionMockupMQ.getInstance().initConnection();
180    }
181
182    /**
183     * For testing purposes: Set the ID of a message
184     *
185     * @param msg The message to set the id on
186     * @param id the new id
187     */
188    public static void updateMsgID(NetarkivetMessage msg, String id) {
189        msg.updateId(id);
190    }
191
192    public static void useJMSConnectionMockupMQ() {
193        // JMSConnectionFactory.getInstance().cleanup();
194        Settings.set(CommonSettings.JMS_BROKER_CLASS, "dk.netarkivet.common.distribute.JMSConnectionMockupMQ");
195        JMSConnectionMockupMQ.getInstance().cleanup();
196    }
197
198    /**
199     * Returns a list of all MessageListeners listening to a particular channel
200     *
201     * @param channel The channel
202     * @return list of listeners
203     */
204    public List<MessageListener> getListeners(ChannelID channel) {
205        TestDestination destination = destinations.get(channel.getName());
206        if (destination == null) {
207            return Collections.emptyList();
208        } else {
209            return new ArrayList<MessageListener>(destination.listeners);
210        }
211    }
212
213    public boolean isSentToChannel(TestChecksumJob job, ChannelID channelID) {
214        TestDestination destination = destinations.get(channelID.getName());
215        for (TestObjectMessage sentMessage : destination.sent) {
216            NetarkivetMessage message = unpack(sentMessage);
217        }
218        return false;
219    }
220
221    protected static class TestConnectionFactory implements ConnectionFactory {
222        public Connection createConnection() throws JMSException {
223            return new TestConnection();
224        }
225
226        public Connection createConnection(String string, String string1) throws JMSException {
227            return new TestConnection();
228        }
229    }
230
231    protected static class TestConnection implements Connection {
232        public boolean isStarted = false;
233        private ExceptionListener exceptionListener;
234
235        public Session createSession(boolean b, int i) throws JMSException {
236            return new TestSession();
237        }
238
239        public void start() throws JMSException {
240            if (isStarted) {
241                throw new IllegalStateException(this + " already started");
242            }
243            isStarted = true;
244        }
245
246        public void stop() throws JMSException {
247            isStarted = false;
248        }
249
250        public void close() throws JMSException {
251            isStarted = false;
252            // TODO: Methods should start throwing exceptions
253        }
254
255        public void setExceptionListener(ExceptionListener exceptionListener) throws JMSException {
256            this.exceptionListener = exceptionListener;
257        }
258
259        public ExceptionListener getExceptionListener() throws JMSException {
260            return this.exceptionListener;
261        }
262
263        public String getClientID() throws JMSException {
264            throw new NotImplementedException("Not implemented");
265        }
266
267        public void setClientID(String string) throws JMSException {
268            throw new NotImplementedException("Not implemented");
269        }
270
271        public ConnectionMetaData getMetaData() throws JMSException {
272            throw new NotImplementedException("Not implemented");
273        }
274
275        public ConnectionConsumer createConnectionConsumer(Destination destination, String string,
276                ServerSessionPool serverSessionPool, int i) throws JMSException {
277            throw new NotImplementedException("Not implemented");
278        }
279
280        public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String string, String string1,
281                ServerSessionPool serverSessionPool, int i) throws JMSException {
282            throw new NotImplementedException("Not implemented");
283        }
284    }
285
286    protected static class TestSession implements Session {
287        public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException {
288            return new TestObjectMessage(serializable);
289        }
290
291        public BytesMessage createBytesMessage() throws JMSException {
292            throw new NotImplementedException("Not implemented");
293        }
294
295        public MessageProducer createProducer(Destination destination) throws JMSException {
296            return new TestMessageProducer(destination);
297        }
298
299        public MessageConsumer createConsumer(Destination destination) throws JMSException {
300            return new TestMessageConsumer(destination);
301        }
302
303        public MapMessage createMapMessage() throws JMSException {
304            throw new NotImplementedException("Not implemented");
305        }
306
307        public Message createMessage() throws JMSException {
308            throw new NotImplementedException("Not implemented");
309        }
310
311        public ObjectMessage createObjectMessage() throws JMSException {
312            throw new NotImplementedException("Not implemented");
313        }
314
315        public StreamMessage createStreamMessage() throws JMSException {
316            throw new NotImplementedException("Not implemented");
317        }
318
319        public TextMessage createTextMessage() throws JMSException {
320            throw new NotImplementedException("Not implemented");
321        }
322
323        public TextMessage createTextMessage(String string) throws JMSException {
324            throw new NotImplementedException("Not implemented");
325        }
326
327        public boolean getTransacted() throws JMSException {
328            throw new NotImplementedException("Not implemented");
329        }
330
331        public int getAcknowledgeMode() throws JMSException {
332            throw new NotImplementedException("Not implemented");
333        }
334
335        public void commit() throws JMSException {
336            throw new NotImplementedException("Not implemented");
337        }
338
339        public void rollback() throws JMSException {
340            throw new NotImplementedException("Not implemented");
341        }
342
343        public void close() throws JMSException {
344            throw new NotImplementedException("Not implemented");
345        }
346
347        public void recover() throws JMSException {
348            throw new NotImplementedException("Not implemented");
349        }
350
351        public MessageListener getMessageListener() throws JMSException {
352            throw new NotImplementedException("Not implemented");
353        }
354
355        public void setMessageListener(MessageListener messageListener) throws JMSException {
356            throw new NotImplementedException("Not implemented");
357        }
358
359        public void run() {
360            throw new NotImplementedException("Not implemented");
361        }
362
363        public MessageConsumer createConsumer(Destination destination, String string) throws JMSException {
364            throw new NotImplementedException("Not implemented");
365        }
366
367        public MessageConsumer createConsumer(Destination destination, String string, boolean b) throws JMSException {
368            throw new NotImplementedException("Not implemented");
369        }
370
371        @Override
372        public Queue createQueue(String string) throws JMSException {
373            return new TestQueue(string);
374        }
375
376        public Topic createTopic(String string) throws JMSException {
377            throw new NotImplementedException("Not implemented");
378        }
379
380        public TopicSubscriber createDurableSubscriber(Topic topic, String string) throws JMSException {
381            throw new NotImplementedException("Not implemented");
382        }
383
384        public TopicSubscriber createDurableSubscriber(Topic topic, String string, String string1, boolean b)
385                throws JMSException {
386            throw new NotImplementedException("Not implemented");
387        }
388
389        public QueueBrowser createBrowser(Queue queue) throws JMSException {
390            throw new NotImplementedException("Not implemented");
391        }
392
393        public QueueBrowser createBrowser(Queue queue, String string) throws JMSException {
394            throw new NotImplementedException("Not implemented");
395        }
396
397        public TemporaryQueue createTemporaryQueue() throws JMSException {
398            throw new NotImplementedException("Not implemented");
399        }
400
401        public TemporaryTopic createTemporaryTopic() throws JMSException {
402            throw new NotImplementedException("Not implemented");
403        }
404
405        public void unsubscribe(String string) throws JMSException {
406            throw new NotImplementedException("Not implemented");
407        }
408    }
409
410    protected static class TestMessageConsumer implements MessageConsumer {
411        private MessageListener listener;
412        protected TestDestination destination;
413
414        public TestMessageConsumer(Destination destination) {
415            this.destination = (TestDestination) destination;
416        }
417
418        public MessageListener getMessageListener() throws JMSException {
419            return listener;
420        }
421
422        public void setMessageListener(MessageListener messageListener) throws JMSException {
423            listener = messageListener;
424            destination.listeners.add(listener);
425        }
426
427        public void close() throws JMSException {
428            // TODO: Methods should start throwing exceptions
429            destination.listeners.remove(listener);
430            listener = null;
431        }
432
433        @Override
434        public String getMessageSelector() throws JMSException {
435            throw new NotImplementedException("Not implemented");
436        }
437
438        @Override
439        public Message receive() throws JMSException {
440            throw new NotImplementedException("Not implemented");
441        }
442
443        @Override
444        public Message receive(long l) throws JMSException {
445            throw new NotImplementedException("Not implemented");
446        }
447
448        public Message receiveNoWait() throws JMSException {
449            throw new NotImplementedException("Not implemented");
450        }
451    }
452
453    public class TestQueueReceiver extends TestMessageConsumer implements QueueReceiver {
454        public TestQueueReceiver(Destination destination) {
455            super(destination);
456        }
457
458        public Queue getQueue() throws JMSException {
459            return (Queue) destination;
460        }
461
462        @Override
463        public Message receiveNoWait() throws JMSException {
464            List<TestObjectMessage> messageQueue = ((TestQueue) getQueue()).messageQueue;
465            if (messageQueue.isEmpty()) {
466                return null;
467            } else {
468                return ((TestQueue) getQueue()).messageQueue.remove(0);
469            }
470        }
471    }
472
473    protected static class TestMessageProducer implements MessageProducer {
474        TestDestination destination;
475        List<TestObjectMessage> messages = new ArrayList<TestObjectMessage>();
476        private static AtomicInteger id = new AtomicInteger(0);
477
478        public TestMessageProducer(Destination destination) {
479            this.destination = (TestDestination) destination;
480        }
481
482        public Destination getDestination() throws JMSException {
483            return destination;
484        }
485
486        public void close() throws JMSException {
487            // TODO: Methods should start throwing exceptions
488            destination = null;
489        }
490
491        public void send(Message message) throws JMSException {
492            TestObjectMessage testObjectMessage = (TestObjectMessage) message;
493            messages.add(testObjectMessage);
494            testObjectMessage.id = "msg" + id.incrementAndGet();
495            if (destination instanceof Topic) {
496                for (MessageListener ml : destination.listeners) {
497                    TestObjectMessage clone;
498                    try {
499                        // TODO: We really should copy the object, but the
500                        // tests do not expect it. :-(
501                        // clone = Serial.serial(testObjectMessage);
502                        clone = testObjectMessage;
503                    } catch (Exception e) {
504                        throw new JMSException("Serialization failed: " + e);
505                    }
506                    new CallOnMessageThread(ml, clone).start();
507                }
508            } else if (destination.listeners.size() > 0) {
509                MessageListener[] mls = destination.listeners
510                        .toArray(new MessageListener[destination.listeners.size()]);
511                MessageListener ml = mls[new Random().nextInt(mls.length)];
512                TestObjectMessage clone;
513                try {
514                    // TODO: We really should copy the object, but the
515                    // tests do not expect it. :-(
516                    // clone = Serial.serial(testObjectMessage);
517                    clone = testObjectMessage;
518                } catch (Exception e) {
519                    throw new JMSException("Serialization failed: " + e);
520                }
521                new CallOnMessageThread(ml, clone).start();
522            } else if (destination instanceof Queue) {
523                ((TestQueue) destination).messageQueue.add(testObjectMessage);
524            }
525            destination.sent.add(testObjectMessage);
526        }
527
528        private void checkForExceptionsToThrow() {
529            // TODO Auto-generated method stub
530
531        }
532
533        public void setDisableMessageID(boolean b) throws JMSException {
534            throw new NotImplementedException("Not implemented");
535        }
536
537        public boolean getDisableMessageID() throws JMSException {
538            throw new NotImplementedException("Not implemented");
539        }
540
541        public void setDisableMessageTimestamp(boolean b) throws JMSException {
542            throw new NotImplementedException("Not implemented");
543        }
544
545        public boolean getDisableMessageTimestamp() throws JMSException {
546            throw new NotImplementedException("Not implemented");
547        }
548
549        public void setDeliveryMode(int i) throws JMSException {
550            throw new NotImplementedException("Not implemented");
551        }
552
553        public int getDeliveryMode() throws JMSException {
554            throw new NotImplementedException("Not implemented");
555        }
556
557        public void setPriority(int i) throws JMSException {
558            throw new NotImplementedException("Not implemented");
559        }
560
561        public int getPriority() throws JMSException {
562            throw new NotImplementedException("Not implemented");
563        }
564
565        public void setTimeToLive(long l) throws JMSException {
566            throw new NotImplementedException("Not implemented");
567        }
568
569        public long getTimeToLive() throws JMSException {
570            throw new NotImplementedException("Not implemented");
571        }
572
573        public void send(Message message, int i, int i1, long l) throws JMSException {
574            throw new NotImplementedException("Not implemented");
575        }
576
577        public void send(Destination destination, Message message) throws JMSException {
578            throw new NotImplementedException("Not implemented");
579        }
580
581        public void send(Destination destination, Message message, int i, int i1, long l) throws JMSException {
582            throw new NotImplementedException("Not implemented");
583        }
584    }
585
586    protected static class TestDestination implements Destination {
587        protected String name;
588        protected Set<MessageListener> listeners = new HashSet<MessageListener>();
589        protected List<TestObjectMessage> sent = new ArrayList<TestObjectMessage>();
590    }
591
592    protected static class TestQueue extends TestDestination implements Queue {
593        protected List<TestObjectMessage> messageQueue = new ArrayList<TestObjectMessage>();
594
595        public TestQueue(String name) {
596            this.name = name;
597        }
598
599        public String getQueueName() throws JMSException {
600            return name;
601        }
602    }
603
604    protected static class TestTopic extends TestDestination implements Topic {
605        public TestTopic(String name) {
606            this.name = name;
607        }
608
609        public String getTopicName() throws JMSException {
610            return name;
611        }
612    }
613
614    public static class TestObjectMessage implements ObjectMessage, Serializable {
615        protected Serializable serializable;
616        public String id;
617
618        public TestObjectMessage(Serializable serializable) {
619            this.serializable = serializable;
620        }
621
622        public Serializable getObject() throws JMSException {
623            return serializable;
624        }
625
626        public String getJMSMessageID() throws JMSException {
627            return id;
628        }
629
630        // Empty implementation in methods - require to be implemented by the
631        // javax.jms.ObjectMessage interface
632
633        public void setObject(Serializable object) throws JMSException {
634            throw new NotImplementedException("Empty implementation - dummy method");
635        }
636
637        public void setJMSType(String s) throws JMSException {
638            throw new NotImplementedException("Empty implementation - dummy method");
639        }
640
641        public void setJMSMessageID(String s) throws JMSException {
642            throw new NotImplementedException("Empty implementation - dummy method");
643        }
644
645        public long getJMSTimestamp() throws JMSException {
646            throw new NotImplementedException("Empty implementation - dummy method");
647        }
648
649        public void setJMSTimestamp(long l) throws JMSException {
650            throw new NotImplementedException("Empty implementation - dummy method");
651        }
652
653        public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
654            throw new NotImplementedException("Empty implementation - dummy method");
655        }
656
657        public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException {
658            throw new NotImplementedException("Empty implementation - dummy method");
659        }
660
661        public void setJMSCorrelationID(String s) throws JMSException {
662            throw new NotImplementedException("Empty implementation - dummy method");
663        }
664
665        public String getJMSCorrelationID() throws JMSException {
666            throw new NotImplementedException("Empty implementation - dummy method");
667        }
668
669        public Destination getJMSReplyTo() throws JMSException {
670            throw new NotImplementedException("Empty implementation - dummy method");
671        }
672
673        public void setJMSReplyTo(Destination destination) throws JMSException {
674            throw new NotImplementedException("Empty implementation - dummy method");
675        }
676
677        public Destination getJMSDestination() throws JMSException {
678            throw new NotImplementedException("Empty implementation - dummy method");
679        }
680
681        public void setJMSDestination(Destination destination) throws JMSException {
682            throw new NotImplementedException("Empty implementation - dummy method");
683        }
684
685        public int getJMSDeliveryMode() throws JMSException {
686            throw new NotImplementedException("Empty implementation - dummy method");
687        }
688
689        public void setJMSDeliveryMode(int i) throws JMSException {
690            throw new NotImplementedException("Empty implementation - dummy method");
691        }
692
693        public boolean getJMSRedelivered() throws JMSException {
694            throw new NotImplementedException("Empty implementation - dummy method");
695        }
696
697        public void setJMSRedelivered(boolean b) throws JMSException {
698            throw new NotImplementedException("Empty implementation - dummy method");
699        }
700
701        public String getJMSType() throws JMSException {
702            throw new NotImplementedException("Empty implementation - dummy method");
703        }
704
705        public long getJMSExpiration() throws JMSException {
706            throw new NotImplementedException("Empty implementation - dummy method");
707        }
708
709        public void setJMSExpiration(long l) throws JMSException {
710            throw new NotImplementedException("Empty implementation - dummy method");
711        }
712
713        public int getJMSPriority() throws JMSException {
714            throw new NotImplementedException("Empty implementation - dummy method");
715        }
716
717        public void setJMSPriority(int i) throws JMSException {
718            throw new NotImplementedException("Empty implementation - dummy method");
719        }
720
721        public void clearProperties() throws JMSException {
722            throw new NotImplementedException("Empty implementation - dummy method");
723        }
724
725        public boolean propertyExists(String s) throws JMSException {
726            throw new NotImplementedException("Empty implementation - dummy method");
727        }
728
729        public boolean getBooleanProperty(String s) throws JMSException {
730            throw new NotImplementedException("Empty implementation - dummy method");
731        }
732
733        public byte getByteProperty(String s) throws JMSException {
734            throw new NotImplementedException("Empty implementation - dummy method");
735        }
736
737        public short getShortProperty(String s) throws JMSException {
738            throw new NotImplementedException("Empty implementation - dummy method");
739        }
740
741        public int getIntProperty(String s) throws JMSException {
742            throw new NotImplementedException("Empty implementation - dummy method");
743        }
744
745        public long getLongProperty(String s) throws JMSException {
746            throw new NotImplementedException("Empty implementation - dummy method");
747        }
748
749        public float getFloatProperty(String s) throws JMSException {
750            throw new NotImplementedException("Empty implementation - dummy method");
751        }
752
753        public double getDoubleProperty(String s) throws JMSException {
754            throw new NotImplementedException("Empty implementation - dummy method");
755        }
756
757        public String getStringProperty(String s) throws JMSException {
758            throw new NotImplementedException("Empty implementation - dummy method");
759        }
760
761        public Object getObjectProperty(String s) throws JMSException {
762            throw new NotImplementedException("Empty implementation - dummy method");
763        }
764
765        public Enumeration getPropertyNames() throws JMSException {
766            throw new NotImplementedException("Empty implementation - dummy method");
767        }
768
769        public void setBooleanProperty(String s, boolean b) throws JMSException {
770            throw new NotImplementedException("Empty implementation - dummy method");
771        }
772
773        public void setByteProperty(String s, byte b) throws JMSException {
774            throw new NotImplementedException("Empty implementation - dummy method");
775        }
776
777        public void setShortProperty(String s, short i) throws JMSException {
778            throw new NotImplementedException("Empty implementation - dummy method");
779        }
780
781        public void setIntProperty(String s, int i) throws JMSException {
782            throw new NotImplementedException("Empty implementation - dummy method");
783        }
784
785        public void setLongProperty(String s, long l) throws JMSException {
786            throw new NotImplementedException("Empty implementation - dummy method");
787        }
788
789        public void setFloatProperty(String s, float v) throws JMSException {
790            throw new NotImplementedException("Empty implementation - dummy method");
791        }
792
793        public void setDoubleProperty(String s, double v) throws JMSException {
794            throw new NotImplementedException("Empty implementation - dummy method");
795        }
796
797        public void setStringProperty(String s, String s1) throws JMSException {
798            throw new NotImplementedException("Empty implementation - dummy method");
799        }
800
801        public void setObjectProperty(String s, Object o) throws JMSException {
802            throw new NotImplementedException("Empty implementation - dummy method");
803        }
804
805        public void acknowledge() throws JMSException {
806            throw new NotImplementedException("Empty implementation - dummy method");
807        }
808
809        public void clearBody() throws JMSException {
810            throw new NotImplementedException("Empty implementation - dummy method");
811        }
812
813        public String toString() {
814            return "TestObjectMessage: " + (serializable == null ? "null" : serializable.toString());
815        }
816
817    } // end WrappedMessage
818
819    protected static class CallOnMessageThread extends Thread {
820        private final MessageListener listener;
821        private final TestObjectMessage msg;
822
823        public CallOnMessageThread(MessageListener listener, TestObjectMessage wMsg) {
824            this.listener = listener;
825            this.msg = wMsg;
826            ((JMSConnectionMockupMQ) JMSConnectionMockupMQ.getInstance()).concurrentTasksToComplete.add(this);
827        }
828
829        public void run() {
830            synchronized (listener) {
831                listener.onMessage(msg);
832            }
833
834            Set<Thread> concurrentTasksToComplete = ((JMSConnectionMockupMQ) JMSConnectionMockupMQ.getInstance()).concurrentTasksToComplete;
835            synchronized (concurrentTasksToComplete) {
836                concurrentTasksToComplete.remove(Thread.currentThread());
837                if (concurrentTasksToComplete.isEmpty()) {
838                    concurrentTasksToComplete.notifyAll();
839                }
840            }
841        }
842    }
843
844    public class TestQueueBrowser implements QueueBrowser {
845        private final TestQueue queue;
846
847        public TestQueueBrowser(TestQueue queue) {
848            this.queue = queue;
849        }
850
851        @Override
852        public void close() throws JMSException {
853        }
854
855        @Override
856        public Enumeration getEnumeration() throws JMSException {
857            return Collections.enumeration(queue.messageQueue);
858        }
859
860        @Override
861        public String getMessageSelector() throws JMSException {
862            return null;
863        }
864
865        @Override
866        public Queue getQueue() throws JMSException {
867            return queue;
868        }
869    }
870
871    public class TestQueueSession extends TestSession implements QueueSession {
872        @Override
873        public QueueBrowser createBrowser(Queue queue) throws JMSException {
874            return new TestQueueBrowser((TestQueue) getDestination(queue.getQueueName()));
875        }
876
877        @Override
878        public QueueReceiver createReceiver(Queue queue) throws JMSException {
879            return new TestQueueReceiver((TestQueue) getDestination(queue.getQueueName()));
880        }
881
882        @Override
883        public QueueReceiver createReceiver(Queue arg0, String arg1) throws JMSException {
884            return null;
885        }
886
887        @Override
888        public QueueSender createSender(Queue arg0) throws JMSException {
889            return null;
890        }
891    }
892
893    @Override
894    public QueueSession getQueueSession() throws JMSException {
895        return new TestQueueSession();
896    }
897}