KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > walend > somnifugi > SomniSession


1 package net.walend.somnifugi;
2
3 import java.util.Set JavaDoc;
4 import java.util.HashSet JavaDoc;
5 import java.util.Map JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.LinkedList JavaDoc;
10
11 import java.io.Serializable JavaDoc;
12
13 import javax.naming.Context JavaDoc;
14
15 import javax.jms.Session JavaDoc;
16 import javax.jms.BytesMessage JavaDoc;
17 import javax.jms.JMSException JavaDoc;
18 import javax.jms.MapMessage JavaDoc;
19 import javax.jms.Message JavaDoc;
20 import javax.jms.ObjectMessage JavaDoc;
21 import javax.jms.StreamMessage JavaDoc;
22 import javax.jms.TextMessage JavaDoc;
23 //import javax.jms.ServerSessionPool;
24
//import javax.jms.ServerSession;
25
import javax.jms.MessageListener JavaDoc;
26 import javax.jms.Destination JavaDoc;
27 import javax.jms.MessageProducer JavaDoc;
28 import javax.jms.MessageConsumer JavaDoc;
29 import javax.jms.Queue JavaDoc;
30 import javax.jms.Topic JavaDoc;
31 import javax.jms.TopicSubscriber JavaDoc;
32 import javax.jms.QueueBrowser JavaDoc;
33 import javax.jms.TemporaryQueue JavaDoc;
34 import javax.jms.TemporaryTopic JavaDoc;
35
36
37
38 /**
39 A SomniSession contains a collection of its producers and consumers, used to start, stop and close the Session. Also use the Session to create instances of Messages to send.
40
41 @author <a HREF="http://walend.net">David Walend</a> <a HREF="mailto:david@walend.net">david@walend.net</a>
42 @author @pwang@ added support for client acknowledgement.
43  */

44
45 public abstract class SomniSession
46     implements Session JavaDoc
47 {
48     protected final Object JavaDoc guard = new Object JavaDoc();
49
50     private boolean closed = false;
51     private boolean started;
52     private Set JavaDoc<SomniMessageProducer> producers = new HashSet JavaDoc<SomniMessageProducer>();
53     private Set JavaDoc<SomniMessageConsumer> consumers = new HashSet JavaDoc<SomniMessageConsumer>();
54     private SomniExceptionListener exceptionListener;
55     private int acknowledgeMode;
56     private String JavaDoc connectionClientID;
57     
58     private final String JavaDoc name;
59
60     private Context JavaDoc context;
61
62     private List JavaDoc<Message JavaDoc> messagesWaitingForAck = new LinkedList JavaDoc<Message JavaDoc>();
63
64     private int consumerCounter = 0;
65
66     protected SomniSession(String JavaDoc name,SomniExceptionListener exceptionListener,boolean started,Context JavaDoc context,int acknowledgeMode,String JavaDoc connectionClientID)
67     {
68         this.exceptionListener = exceptionListener;
69         this.started = started;
70         this.name = name;
71         this.context = context;
72         this.acknowledgeMode = acknowledgeMode;
73         this.connectionClientID = connectionClientID;
74     }
75
76     /**
77     Creates a report of how many messages are pending in each message consumer. The result is a guess.
78     
79     This method synchronizes on the protected guard, so you won't be able to create or remove consumers while it runs.
80     
81     @return a Map of the consumer names to a guess at the number of pending messages and time stamp of the next message out.
82     */

83     public Map JavaDoc<String JavaDoc,SomniConsumerReport> createConsumerReports()
84     {
85         Map JavaDoc<String JavaDoc,SomniConsumerReport> report = new HashMap JavaDoc<String JavaDoc,SomniConsumerReport>(consumers.size());
86         synchronized(guard)
87         {
88             for(SomniMessageConsumer consumer : consumers)
89             {
90                 report.put(consumer.getName(),consumer.createSomniConsumerReport());
91             }
92         }
93         return report;
94     }
95     
96     
97     protected Context JavaDoc getContext()
98     {
99         return context;
100     }
101
102     protected String JavaDoc getConnectionClientID()
103     {
104         return connectionClientID;
105     }
106     
107     private int producerCounter = 0;
108
109     protected String JavaDoc createProducerName(String JavaDoc destName,String JavaDoc senderOrPublisher)
110     {
111         synchronized(guard)
112             {
113                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
114                 
115                 buffy.append(destName);
116                 buffy.append(":");
117                 buffy.append(name);
118                 buffy.append(senderOrPublisher);
119                 buffy.append(":"+producerCounter);
120
121                 producerCounter++;
122                 return buffy.toString();
123             }
124     }
125
126     protected String JavaDoc createConsumerName(String JavaDoc destName,String JavaDoc receiverOrSubscriber)
127     {
128         synchronized(guard)
129             {
130                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
131                 
132                 buffy.append(destName);
133                 buffy.append(":");
134                 buffy.append(name);
135                 buffy.append(receiverOrSubscriber);
136                 buffy.append(":"+consumerCounter);
137
138                 consumerCounter++;
139                 return buffy.toString();
140             }
141     }
142
143     protected SomniExceptionListener getExceptionListener()
144     {
145         return exceptionListener;
146     }
147
148     protected void addProducer(SomniMessageProducer producer)
149     {
150         synchronized(guard)
151             {
152                 producers.add(producer);
153
154                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
155                 buffy.append("Added ");
156                 buffy.append(producer.getName());
157                 buffy.append(" to ");
158                 buffy.append(getName());
159
160                 SomniLogger.IT.finer(buffy.toString());
161             }
162     }
163
164     protected void removeProducer(SomniMessageProducer producer)
165         throws JMSException JavaDoc
166     {
167         synchronized(guard)
168             {
169                 producers.remove(producer);
170
171                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
172                 buffy.append("Removed ");
173                 buffy.append(producer.getName());
174                 buffy.append(" from ");
175                 buffy.append(getName());
176
177                 SomniLogger.IT.finer(buffy.toString());
178
179                 producer.close();
180             }
181     }
182
183     protected void addConsumer(SomniMessageConsumer consumer)
184     {
185         synchronized(guard)
186             {
187                 consumers.add(consumer);
188
189                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
190                 buffy.append("Added ");
191                 buffy.append(consumer.getName());
192                 buffy.append(" to ");
193                 buffy.append(getName());
194
195                 SomniLogger.IT.finer(buffy.toString());
196
197                 if(started)
198                     {
199                         consumer.start();
200                     }
201             }
202     }
203
204     protected void removeConsumer(SomniMessageConsumer consumer)
205         throws JMSException JavaDoc
206     {
207         synchronized(guard)
208             {
209                 consumers.remove(consumer);
210
211                 StringBuffer JavaDoc buffy = new StringBuffer JavaDoc();
212                 buffy.append("Removed ");
213                 buffy.append(consumer.getName());
214                 buffy.append(" from ");
215                 buffy.append(getName());
216
217                 SomniLogger.IT.finer(buffy.toString());
218
219                 consumer.close();
220             }
221     }
222
223     protected void start()
224     {
225         synchronized(guard)
226             {
227                 checkClosed();
228                 started = true;
229
230                 Iterator JavaDoc it = consumers.iterator();
231                 while(it.hasNext())
232                     {
233                         SomniMessageConsumer consumer = (SomniMessageConsumer)it.next();
234                         consumer.start();
235                     }
236                 SomniLogger.IT.fine(getName()+" started.");
237             }
238     }
239
240     protected void stop()
241     {
242         synchronized(guard)
243             {
244                 started = false;
245
246                 Iterator JavaDoc it = consumers.iterator();
247                 while(it.hasNext())
248                     {
249                         SomniMessageConsumer consumer = (SomniMessageConsumer)it.next();
250                         consumer.stop();
251                     }
252                 SomniLogger.IT.fine(getName()+" stopped.");
253             }
254     }
255
256     protected void checkClosed()
257     {
258         synchronized(guard)
259             {
260                 if(closed)
261                     {
262                         throw new IllegalStateException JavaDoc("This Session is closed.");
263                     }
264             }
265     }
266
267     /**
268 Creates a <CODE>BytesMessage</CODE> object. A <CODE>BytesMessage</CODE>
269 object is used to send a message containing a stream of uninterpreted
270 bytes.
271  
272 @exception JMSException if the JMS provider fails to create this message
273                         due to some internal error.
274 @exception UnsupportedOperationException because it isn't implemented.
275       */

276     public BytesMessage JavaDoc createBytesMessage()
277         throws JMSException JavaDoc
278     {
279         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
280     }
281
282     /**
283 Creates a <CODE>MapMessage</CODE> object. A <CODE>MapMessage</CODE>
284 object is used to send a self-defining set of name-value pairs, where
285 names are <CODE>String</CODE> objects and values are primitive values
286 in the Java programming language.
287  
288 @exception JMSException if the JMS provider fails to create this message
289                         due to some internal error.
290 @exception UnsupportedOperationException because it isn't implemented.
291       */

292     public MapMessage JavaDoc createMapMessage()
293         throws JMSException JavaDoc
294     {
295         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
296     }
297
298     /**
299 Creates a <CODE>Message</CODE> object. The <CODE>Message</CODE>
300 interface is the root interface of all JMS messages. A
301 <CODE>Message</CODE> object holds all the
302 standard message header information. It can be sent when a message
303 containing only header information is sufficient.
304  
305 @exception JMSException if the JMS provider fails to create this message
306                         due to some internal error.
307       */

308     public Message JavaDoc createMessage()
309         throws JMSException JavaDoc
310     {
311         synchronized(guard)
312         {
313             checkClosed();
314             Message JavaDoc result = new SomniMessage();
315             return result;
316         }
317     }
318
319     /**
320 Creates an <CODE>ObjectMessage</CODE> object. An
321 <CODE>ObjectMessage</CODE> object is used to send a message
322 that contains a serializable Java object.
323  
324 @exception JMSException if the JMS provider fails to create this message
325                         due to some internal error.
326       */

327     public ObjectMessage JavaDoc createObjectMessage()
328         throws JMSException JavaDoc
329     {
330         synchronized(guard)
331         {
332             checkClosed();
333             ObjectMessage JavaDoc result = new SomniObjectMessage();
334
335             return result;
336         }
337     }
338
339     /**
340 Creates an initialized <CODE>ObjectMessage</CODE> object. An
341 <CODE>ObjectMessage</CODE> object is used
342 to send a message that contains a serializable Java object.
343  
344 @param object the object to use to initialize this message
345       *
346 @exception JMSException if the JMS provider fails to create this message
347                         due to some internal error.
348       */

349     public ObjectMessage JavaDoc createObjectMessage(Serializable JavaDoc object)
350         throws JMSException JavaDoc
351     {
352         synchronized(guard)
353             {
354                 checkClosed();
355                 ObjectMessage JavaDoc result = createObjectMessage();
356                 result.setObject(object);
357                 return result;
358             }
359     }
360
361     /**
362 Creates a <CODE>StreamMessage</CODE> object. A
363 <CODE>StreamMessage</CODE> object is used to send a
364 self-defining stream of primitive values in the Java programming
365 language.
366  
367 @exception JMSException if the JMS provider fails to create this message
368                         due to some internal error.
369 @exception UnsupportedOperationException because it isn't implemented.
370       */

371     public StreamMessage JavaDoc createStreamMessage()
372         throws JMSException JavaDoc
373     {
374         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
375         
376     }
377
378     /**
379 Creates a <CODE>TextMessage</CODE> object. A <CODE>TextMessage</CODE>
380 object is used to send a message containing a <CODE>String</CODE>
381 object.
382  
383 @exception JMSException if the JMS provider fails to create this message
384                         due to some internal error.
385 @exception UnsupportedOperationException because it isn't implemented.
386       */

387     public TextMessage JavaDoc createTextMessage()
388         throws JMSException JavaDoc
389     {
390         synchronized(guard)
391         {
392             checkClosed();
393             TextMessage JavaDoc result = new SomniTextMessage();
394
395             return result;
396         }
397     }
398
399     /**
400 Creates an initialized <CODE>TextMessage</CODE> object. A
401 <CODE>TextMessage</CODE> object is used to send
402 a message containing a <CODE>String</CODE>.
403       *
404 @param text the string used to initialize this message
405       *
406 @exception JMSException if the JMS provider fails to create this message
407                         due to some internal error.
408 @exception UnsupportedOperationException because it isn't implemented.
409       */

410     public TextMessage JavaDoc createTextMessage(String JavaDoc text)
411         throws JMSException JavaDoc
412     {
413         synchronized(guard)
414         {
415             checkClosed();
416             TextMessage JavaDoc result = createTextMessage();
417             result.setText(text);
418             return result;
419         }
420     }
421
422     /**
423 Indicates whether the session is in transacted mode.
424  
425 @return true if the session is in transacted mode
426  
427 @exception JMSException if the JMS provider fails to return the
428                         transaction mode due to some internal error.
429       */

430     public boolean getTransacted()
431         throws JMSException JavaDoc
432     {
433         return false;
434     }
435
436     /** Returns the acknowledgement mode of the session. The acknowledgement
437      * mode is set at the time that the session is created. If the session is
438      * transacted, the acknowledgement mode is ignored.
439      *
440      *@return If the session is not transacted, returns the
441      * current acknowledgement mode for the session.
442      * If the session
443      * is transacted, returns SESSION_TRANSACTED.
444      *
445      *@exception JMSException if the JMS provider fails to return the
446      * acknowledgment mode due to some internal error.
447      *
448      *@since 1.1
449      */

450     public int getAcknowledgeMode() throws JMSException JavaDoc
451     {
452         return acknowledgeMode;
453     }
454
455     /**
456 Commits all messages done in this transaction and releases any locks
457 currently held.
458       *
459 @exception JMSException if the JMS provider fails to commit the
460                         transaction due to some internal error.
461 @exception TransactionRolledBackException if the transaction
462                         is rolled back due to some internal error
463                         during commit.
464 @exception IllegalStateException if the method is not called by a
465                         transacted session.
466       */

467     public void commit()
468         throws JMSException JavaDoc
469     {
470         throw new IllegalStateException JavaDoc("somnifugi methods are never transactional.");
471     }
472
473     /**
474 Rolls back any messages done in this transaction and releases any locks
475 currently held.
476       *
477 @exception JMSException if the JMS provider fails to roll back the
478                         transaction due to some internal error.
479 @exception IllegalStateException if the method is not called by a
480                         transacted session.
481                                     
482       */

483     public void rollback()
484         throws JMSException JavaDoc
485     {
486         throw new IllegalStateException JavaDoc("somnifugi methods are never transactional.");
487     }
488
489     /** Closes the session.
490       *
491 <P>Since a provider may allocate some resources on behalf of a session
492 outside the JVM, clients should close the resources when they are not
493 needed.
494 Relying on garbage collection to eventually reclaim these resources
495 may not be timely enough.
496       *
497 <P>There is no need to close the producers and consumers
498 of a closed session.
499       *
500 <P> This call will block until a <CODE>receive</CODE> call or message
501 listener in progress has completed. A blocked message consumer
502 <CODE>receive</CODE> call returns <CODE>null</CODE> when this session
503 is closed.
504       *
505 <P>Closing a transacted session must roll back the transaction
506 in progress.
507
508 <P>This method is the only <CODE>Session</CODE> method that can
509 be called concurrently.
510       *
511 <P>Invoking any other <CODE>Session</CODE> method on a closed session
512 must throw a <CODE>JMSException.IllegalStateException</CODE>. Closing a
513 closed session must <I>not</I> throw an exception.
514
515 @exception JMSException if the JMS provider fails to close the
516                         session due to some internal error.
517       */

518     public void close()
519         throws JMSException JavaDoc
520     {
521         try
522             {
523                 synchronized(guard)
524                     {
525                         closed = true;
526                         stop();
527                         Iterator JavaDoc it = producers.iterator();
528                         while(it.hasNext())
529                         {
530                             SomniMessageProducer producer = (SomniMessageProducer)it.next();
531                             producer.close();
532                         }
533                         Iterator JavaDoc itt = consumers.iterator();
534                         while(itt.hasNext())
535                         {
536                             SomniMessageConsumer consumer = (SomniMessageConsumer)itt.next();
537                             consumer.close();
538                         }
539                         SomniLogger.IT.fine(getName()+" closed.");
540                     }
541             }
542         catch(RuntimeException JavaDoc re)
543             {
544                 throw new SomniCannotCloseException(re);
545             }
546     }
547
548     /**
549 Stops message delivery in this session, and restarts message delivery
550 with the oldest unacknowledged message.
551  
552 <P>All consumers deliver messages in a serial order.
553 Acknowledging a received message automatically acknowledges all
554 messages that have been delivered to the client.
555       *
556 <P>Restarting a session causes it to take the following actions:
557       *
558 <UL>
559   <LI>Stop message delivery
560   <LI>Mark all messages that might have been delivered but not
561       acknowledged as "redelivered"
562   <LI>Restart the delivery sequence including all unacknowledged
563       messages that had been previously delivered. Redelivered messages
564       do not have to be delivered in
565       exactly their original delivery order.
566 </UL>
567       *
568 @exception JMSException if the JMS provider fails to stop and restart
569                         message delivery due to some internal error.
570 @exception IllegalStateException if the method is called by a
571                         transacted session.
572 @exception UnsupportedOperationException because it isn't implemented.
573       */

574     public void recover()
575         throws JMSException JavaDoc
576     {
577         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
578     }
579
580     /**
581 Returns the session's distinguished message listener (optional).
582       *
583 @return the message listener associated with this session
584       *
585 @exception JMSException if the JMS provider fails to get the message
586                         listener due to an internal error.
587       *
588 @see javax.jms.Session#setMessageListener
589 @see <{ServerSessionPool}>
590 @see <{ServerSession}>
591 @exception UnsupportedOperationException because it isn't implemented.
592       */

593     public MessageListener JavaDoc getMessageListener()
594         throws JMSException JavaDoc
595     {
596         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
597     }
598
599     /**
600 Sets the session's distinguished message listener (optional).
601       *
602 <P>When the distinguished message listener is set, no other form of
603 message receipt in the session can
604 be used; however, all forms of sending messages are still supported.
605
606 <P>This is an expert facility not used by regular JMS clients.
607
608 @param listener the message listener to associate with this session
609
610 @exception JMSException if the JMS provider fails to set the message
611                         listener due to an internal error.
612
613 @see javax.jms.Session#getMessageListener
614 @see <{ServerSessionPool}>
615 @see <{ServerSession}>
616 @exception UnsupportedOperationException because it isn't implemented.
617       */

618     public void setMessageListener(MessageListener JavaDoc listener)
619         throws JMSException JavaDoc
620     {
621         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
622     }
623
624     /**
625 Optional operation, intended to be used only by Application Servers,
626 not by ordinary JMS clients.
627
628 @see <{ServerSession}>
629 @exception UnsupportedOperationException because it isn't implemented.
630      */

631     public void run()
632     {
633         throw new UnsupportedOperationException JavaDoc("I haven't done this yet.");
634     }
635
636     protected String JavaDoc getName()
637     {
638         return name;
639     }
640
641     //new Session methods from jms 1.1
642

643     /** Creates a <CODE>MessageProducer</CODE> to send messages to the specified
644       * destination.
645       *
646       * <P>A client uses a <CODE>MessageProducer</CODE> object to send
647       * messages to a destination. Since <CODE>Queue</CODE> and <CODE>Topic</CODE>
648       * both inherit from <CODE>Destination</CODE>, they can be used in
649       * the destination parameter to create a <CODE>MessageProducer</CODE> object.
650       *
651       * @param destination the <CODE>Destination</CODE> to send to,
652       * or null if this is a producer which does not have a specified
653       * destination.
654       *
655       * @exception JMSException if the session fails to create a MessageProducer
656       * due to some internal error.
657       * @exception InvalidDestinationException if an invalid destination
658       * is specified.
659       *
660       * @since 1.1
661       *
662      */

663
664     public abstract MessageProducer JavaDoc createProducer(Destination JavaDoc destination) throws JMSException JavaDoc;
665     
666     
667        /** Creates a <CODE>MessageConsumer</CODE> for the specified destination.
668       * Since <CODE>Queue</CODE> and <CODE>Topic</CODE>
669       * both inherit from <CODE>Destination</CODE>, they can be used in
670       * the destination parameter to create a <CODE>MessageConsumer</CODE>.
671       *
672       * @param destination the <CODE>Destination</CODE> to access.
673       *
674       * @exception JMSException if the session fails to create a consumer
675       * due to some internal error.
676       * @exception InvalidDestinationException if an invalid destination
677       * is specified.
678       *
679       * @since 1.1
680       */

681
682     public abstract MessageConsumer JavaDoc createConsumer(Destination JavaDoc destination) throws JMSException JavaDoc;
683
684        /** Creates a <CODE>MessageConsumer</CODE> for the specified destination,
685       * using a message selector.
686       * Since <CODE>Queue</CODE> and <CODE>Topic</CODE>
687       * both inherit from <CODE>Destination</CODE>, they can be used in
688       * the destination parameter to create a <CODE>MessageConsumer</CODE>.
689       *
690       * <P>A client uses a <CODE>MessageConsumer</CODE> object to receive
691       * messages that have been sent to a destination.
692       *
693       *
694       * @param destination the <CODE>Destination</CODE> to access
695       * @param messageSelector only messages with properties matching the
696       * message selector expression are delivered. A value of null or
697       * an empty string indicates that there is no message selector
698       * for the message consumer.
699       *
700       *
701       * @exception JMSException if the session fails to create a MessageConsumer
702       * due to some internal error.
703       * @exception InvalidDestinationException if an invalid destination
704        * is specified.
705      
706       * @exception InvalidSelectorException if the message selector is invalid.
707       *
708       * @since 1.1
709       */

710     public abstract MessageConsumer JavaDoc createConsumer(Destination JavaDoc destination, java.lang.String JavaDoc messageSelector)
711         throws JMSException JavaDoc;
712     
713     
714      /** Creates <CODE>MessageConsumer</CODE> for the specified destination, using a
715       * message selector. This method can specify whether messages published by
716       * its own connection should be delivered to it, if the destination is a
717       * topic.
718       *<P> Since <CODE>Queue</CODE> and <CODE>Topic</CODE>
719       * both inherit from <CODE>Destination</CODE>, they can be used in
720       * the destination parameter to create a <CODE>MessageConsumer</CODE>.
721       * <P>A client uses a <CODE>MessageConsumer</CODE> object to receive
722       * messages that have been published to a destination.
723       *
724       * <P>In some cases, a connection may both publish and subscribe to a
725       * topic. The consumer <CODE>NoLocal</CODE> attribute allows a consumer
726       * to inhibit the delivery of messages published by its own connection.
727       * The default value for this attribute is False. The <CODE>noLocal</CODE>
728       * value must be supported by destinations that are topics.
729       *
730       * @param destination the <CODE>Destination</CODE> to access
731       * @param messageSelector only messages with properties matching the
732       * message selector expression are delivered. A value of null or
733       * an empty string indicates that there is no message selector
734       * for the message consumer.
735       * @param NoLocal - if true, and the destination is a topic,
736       * inhibits the delivery of messages published
737       * by its own connection. The behavior for
738       * <CODE>NoLocal</CODE> is
739       * not specified if the destination is a queue.
740       *
741       * @exception JMSException if the session fails to create a MessageConsumer
742       * due to some internal error.
743       * @exception InvalidDestinationException if an invalid destination
744        * is specified.
745      
746       * @exception InvalidSelectorException if the message selector is invalid.
747       *
748       * @since 1.1
749       *
750       */

751     public abstract MessageConsumer JavaDoc createConsumer(Destination JavaDoc destination, java.lang.String JavaDoc messageSelector,boolean NoLocal)
752         throws JMSException JavaDoc;
753     
754     
755       /** Creates a queue identity given a <CODE>Queue</CODE> name.
756       *
757       * <P>This facility is provided for the rare cases where clients need to
758       * dynamically manipulate queue identity. It allows the creation of a
759       * queue identity with a provider-specific name. Clients that depend
760       * on this ability are not portable.
761       *
762       * <P>Note that this method is not for creating the physical queue.
763       * The physical creation of queues is an administrative task and is not
764       * to be initiated by the JMS API. The one exception is the
765       * creation of temporary queues, which is accomplished with the
766       * <CODE>createTemporaryQueue</CODE> method.
767       *
768       * @param queueName the name of this <CODE>Queue</CODE>
769       *
770       * @return a <CODE>Queue</CODE> with the given name
771       *
772       * @exception JMSException if the session fails to create a queue
773       * due to some internal error.
774       * @since 1.1
775       */

776  
777     public abstract Queue JavaDoc createQueue(String JavaDoc queueName) throws JMSException JavaDoc;
778     
779       /** Creates a topic identity given a <CODE>Topic</CODE> name.
780       *
781       * <P>This facility is provided for the rare cases where clients need to
782       * dynamically manipulate topic identity. This allows the creation of a
783       * topic identity with a provider-specific name. Clients that depend
784       * on this ability are not portable.
785       *
786       * <P>Note that this method is not for creating the physical topic.
787       * The physical creation of topics is an administrative task and is not
788       * to be initiated by the JMS API. The one exception is the
789       * creation of temporary topics, which is accomplished with the
790       * <CODE>createTemporaryTopic</CODE> method.
791       *
792       * @param topicName the name of this <CODE>Topic</CODE>
793       *
794       * @return a <CODE>Topic</CODE> with the given name
795       *
796       * @exception JMSException if the session fails to create a topic
797       * due to some internal error.
798       * @since 1.1
799       */

800
801     public abstract Topic JavaDoc createTopic(String JavaDoc topicName) throws JMSException JavaDoc;
802
803      /** Creates a <CODE>QueueBrowser</CODE> object to peek at the messages on
804       * the specified queue.
805       *
806       * @param queue the <CODE>queue</CODE> to access
807       *
808       * @exception InvalidDestinationException if an invalid destination
809       * is specified
810       *
811       * @since 1.1
812       */

813     //todo where is this method? It wasn't in Session.java
814

815       /** Creates a durable subscriber to the specified topic.
816       *
817       * <P>If a client needs to receive all the messages published on a
818       * topic, including the ones published while the subscriber is inactive,
819       * it uses a durable <CODE>TopicSubscriber</CODE>. The JMS provider
820       * retains a record of this
821       * durable subscription and insures that all messages from the topic's
822       * publishers are retained until they are acknowledged by this
823       * durable subscriber or they have expired.
824       *
825       * <P>Sessions with durable subscribers must always provide the same
826       * client identifier. In addition, each client must specify a name that
827       * uniquely identifies (within client identifier) each durable
828       * subscription it creates. Only one session at a time can have a
829       * <CODE>TopicSubscriber</CODE> for a particular durable subscription.
830       *
831       * <P>A client can change an existing durable subscription by creating
832       * a durable <CODE>TopicSubscriber</CODE> with the same name and a new
833       * topic and/or
834       * message selector. Changing a durable subscriber is equivalent to
835       * unsubscribing (deleting) the old one and creating a new one.
836       *
837       * <P>In some cases, a connection may both publish and subscribe to a
838       * topic. The subscriber <CODE>NoLocal</CODE> attribute allows a subscriber
839       * to inhibit the delivery of messages published by its own connection.
840       * The default value for this attribute is false.
841       *
842       * @param topic the non-temporary <CODE>Topic</CODE> to subscribe to
843       * @param name the name used to identify this subscription
844       *
845       * @exception JMSException if the session fails to create a subscriber
846       * due to some internal error.
847       * @exception InvalidDestinationException if an invalid topic is specified.
848       *
849       * @since 1.1
850       */

851
852     public abstract TopicSubscriber JavaDoc createDurableSubscriber(Topic JavaDoc topic,String JavaDoc name)
853         throws JMSException JavaDoc;
854
855
856     /** Creates a durable subscriber to the specified topic, using a
857       * message selector and specifying whether messages published by its
858       * own connection should be delivered to it.
859       *
860       * <P>If a client needs to receive all the messages published on a
861       * topic, including the ones published while the subscriber is inactive,
862       * it uses a durable <CODE>TopicSubscriber</CODE>. The JMS provider
863       * retains a record of this
864       * durable subscription and insures that all messages from the topic's
865       * publishers are retained until they are acknowledged by this
866       * durable subscriber or they have expired.
867       *
868       * <P>Sessions with durable subscribers must always provide the same
869       * client identifier. In addition, each client must specify a name which
870       * uniquely identifies (within client identifier) each durable
871       * subscription it creates. Only one session at a time can have a
872       * <CODE>TopicSubscriber</CODE> for a particular durable subscription.
873       * An inactive durable subscriber is one that exists but
874       * does not currently have a message consumer associated with it.
875       *
876       * <P>A client can change an existing durable subscription by creating
877       * a durable <CODE>TopicSubscriber</CODE> with the same name and a new
878       * topic and/or
879       * message selector. Changing a durable subscriber is equivalent to
880       * unsubscribing (deleting) the old one and creating a new one.
881       *
882       * @param topic the non-temporary <CODE>Topic</CODE> to subscribe to
883       * @param name the name used to identify this subscription
884       * @param messageSelector only messages with properties matching the
885       * message selector expression are delivered. A value of null or
886       * an empty string indicates that there is no message selector
887       * for the message consumer.
888       * @param noLocal if set, inhibits the delivery of messages published
889       * by its own connection
890       *
891       * @exception JMSException if the session fails to create a subscriber
892       * due to some internal error.
893       * @exception InvalidDestinationException if an invalid topic is specified.
894       * @exception InvalidSelectorException if the message selector is invalid.
895       *
896       * @since 1.1
897       */

898  
899     public abstract TopicSubscriber JavaDoc createDurableSubscriber(Topic JavaDoc topic,String JavaDoc name,String JavaDoc messageSelector,boolean noLocal)
900         throws JMSException JavaDoc;
901     
902   /** Creates a <CODE>QueueBrowser</CODE> object to peek at the messages on
903       * the specified queue.
904       *
905       * @param queue the <CODE>queue</CODE> to access
906       *
907       *
908       * @exception JMSException if the session fails to create a browser
909       * due to some internal error.
910       * @exception InvalidDestinationException if an invalid destination
911       * is specified
912       *
913       * @since 1.1
914       */

915     public abstract QueueBrowser JavaDoc createBrowser(Queue JavaDoc queue) throws JMSException JavaDoc;
916
917
918     /** Creates a <CODE>QueueBrowser</CODE> object to peek at the messages on
919       * the specified queue using a message selector.
920       *
921       * @param queue the <CODE>queue</CODE> to access
922       *
923       * @param messageSelector only messages with properties matching the
924       * message selector expression are delivered. A value of null or
925       * an empty string indicates that there is no message selector
926       * for the message consumer.
927       *
928       * @exception JMSException if the session fails to create a browser
929       * due to some internal error.
930       * @exception InvalidDestinationException if an invalid destination
931       * is specified
932       * @exception InvalidSelectorException if the message selector is invalid.
933       *
934       * @since 1.1
935       */

936
937     public abstract QueueBrowser JavaDoc createBrowser(Queue JavaDoc queue,String JavaDoc messageSelector)
938         throws JMSException JavaDoc;
939
940     
941      /** Creates a <CODE>TemporaryQueue</CODE> object. Its lifetime will be that
942       * of the <CODE>Connection</CODE> unless it is deleted earlier.
943       *
944       * @return a temporary queue identity
945       *
946       * @exception JMSException if the session fails to create a temporary queue
947       * due to some internal error.
948       *
949       *@since 1.1
950       */

951
952     public abstract TemporaryQueue JavaDoc createTemporaryQueue() throws JMSException JavaDoc;
953    
954
955      /** Creates a <CODE>TemporaryTopic</CODE> object. Its lifetime will be that
956       * of the <CODE>Connection</CODE> unless it is deleted earlier.
957       *
958       * @return a temporary topic identity
959       *
960       * @exception JMSException if the session fails to create a temporary
961       * topic due to some internal error.
962       *
963       * @since 1.1
964       */

965  
966     public abstract TemporaryTopic JavaDoc createTemporaryTopic() throws JMSException JavaDoc;
967
968
969     /** Unsubscribes a durable subscription that has been created by a client.
970       *
971       * <P>This method deletes the state being maintained on behalf of the
972       * subscriber by its provider.
973       *
974       * <P>It is erroneous for a client to delete a durable subscription
975       * while there is an active <CODE>MessageConsumer</CODE>
976       * or <CODE>TopicSubscriber</CODE> for the
977       * subscription, or while a consumed message is part of a pending
978       * transaction or has not been acknowledged in the session.
979       *
980       * @param name the name used to identify this subscription
981       *
982       * @exception JMSException if the session fails to unsubscribe to the
983       * durable subscription due to some internal error.
984       * @exception InvalidDestinationException if an invalid subscription name
985       * is specified.
986       *
987       * @since 1.1
988       */

989
990     public abstract void unsubscribe(String JavaDoc name) throws JMSException JavaDoc;
991
992
993     //methods for handling acknowledgement
994
void addMessageToAcknowledge(SomniMessage message)
995     {
996         synchronized(guard)
997         {
998             messagesWaitingForAck.add(message);
999         }
1000    }
1001
1002    void acknowledge()
1003    {
1004        synchronized(guard)
1005        {
1006            messagesWaitingForAck.clear();
1007        }
1008    }
1009}
1010
1011/* Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 David Walend
1012All rights reserved.
1013
1014Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1015
1016Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1017
1018Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1019
1020Neither the name of the SomnifugiJMS Project, walend.net, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission from David Walend.
1021
1022Credits in redistributions in source or binary forms must include a link to http://somnifugi.sourceforge.net .
1023
1024THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1025The net.walend.somnifugi.sql92 package is modified code from the openmq project, https://mq.dev.java.net/ , Copyright (c) of Sun, and carries the CDDL license, repeated here: You can obtain a copy of the license at https://glassfish.dev.java.net/public/CDDLv1.0.html. See the License for the specific language governing permissions and limitations under the License.
1026
1027=================================================================================
1028
1029For more information and the latest version of this software, please see http://somnifugi.sourceforge.net and http://walend.net or email <a HREF="mailto:david@walend.net">david@walend.net</a>.
1030 */

1031
Popular Tags