1 /***
2 *
3 * Copyright 2005 LogicBlaze, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.jencks;
19
20 import javax.jms.Destination;
21 import javax.jms.JMSException;
22 import javax.jms.Message;
23 import javax.jms.MessageConsumer;
24 import javax.jms.MessageProducer;
25 import javax.jms.Session;
26 import javax.jms.TemporaryQueue;
27 import javax.jms.TemporaryTopic;
28
29 /***
30 * A helper class for performing remote method invocations over JMS.
31 * This class is a polymorphic version of the {@link javax.jms.QueueRequestor} and {@link javax.jms.TopicRequestor}
32 * that ship with the JMS API which take advantage of the polymorphism of JMS 1.1 and which also supports timeouts.
33 *
34 * @version $Revision: 1.1.1.1 $
35 */
36 public class Requestor {
37 private Session session;
38 private Destination temporaryDestination;
39 private MessageProducer sender;
40 private MessageConsumer receiver;
41 private long maximumTimeout = 20000L;
42
43
44 /***
45 * Constructor for the <CODE>Requestor</CODE> class.
46 * <p/>
47 * <P>This implementation assumes the session parameter to be non-transacted,
48 * with a delivery mode of either <CODE>AUTO_ACKNOWLEDGE</CODE> or
49 * <CODE>DUPS_OK_ACKNOWLEDGE</CODE>.
50 *
51 * @param session the <CODE>Session</CODE> the queue belongs to
52 * @param destination the destination to perform the request/reply call on
53 * @throws javax.jms.JMSException if the JMS provider fails to create the
54 * <CODE>Requestor</CODE> due to some internal
55 * error.
56 * @throws javax.jms.InvalidDestinationException
57 * if an invalid queue is specified.
58 */
59 public Requestor(Session session, Destination destination) throws JMSException {
60 this.session = session;
61 temporaryDestination = createTemporaryDestination(session);
62 sender = session.createProducer(destination);
63 receiver = session.createConsumer(temporaryDestination);
64 }
65
66
67 /***
68 * Sends a request and waits for a reply. The temporary queue is used for
69 * the <CODE>JMSReplyTo</CODE> destination, and only one reply per request
70 * is expected.
71 *
72 * @param message the message to send
73 * @return the reply message
74 * @throws javax.jms.JMSException if the JMS provider fails to complete the
75 * request due to some internal error.
76 */
77 public Message request(Message message) throws JMSException {
78 message.setJMSReplyTo(temporaryDestination);
79 sender.send(message);
80 long timeout = getMaximumTimeout();
81 if (timeout > 0) {
82 return receiver.receive(timeout);
83 }
84 else {
85 return receiver.receive();
86 }
87 }
88
89
90 /***
91 * Sends a request and waits for a reply up to a maximum timeout. The temporary queue is used for
92 * the <CODE>JMSReplyTo</CODE> destination, and only one reply per request
93 * is expected.
94 *
95 * @param message the message to send
96 * @return the reply message
97 * @throws javax.jms.JMSException if the JMS provider fails to complete the
98 * request due to some internal error.
99 */
100 public Message request(Message message, long timeout) throws JMSException {
101 message.setJMSReplyTo(temporaryDestination);
102 sender.send(message);
103 return receiver.receive(timeout);
104 }
105
106
107 /***
108 * Closes the <CODE>Requestor</CODE> and its session.
109 * <p/>
110 * <P>Since a provider may allocate some resources on behalf of a
111 * <CODE>Requestor</CODE> outside the Java virtual machine, clients
112 * should close them when they
113 * are not needed. Relying on garbage collection to eventually reclaim
114 * these resources may not be timely enough.
115 * <p/>
116 * <P>Note that this method closes the <CODE>Session</CODE> object
117 * passed to the <CODE>Requestor</CODE> constructor.
118 *
119 * @throws javax.jms.JMSException if the JMS provider fails to close the
120 * <CODE>Requestor</CODE> due to some internal
121 * error.
122 */
123 public void close() throws JMSException {
124
125 session.close();
126 if (temporaryDestination instanceof TemporaryQueue) {
127 ((TemporaryQueue) temporaryDestination).delete();
128 }
129 else if (temporaryDestination instanceof TemporaryTopic) {
130 ((TemporaryTopic) temporaryDestination).delete();
131 }
132 }
133
134 public long getMaximumTimeout() {
135 return maximumTimeout;
136 }
137
138 /***
139 * Sets the maximum default timeout used for remote requests. If set to <= 0 then
140 * the timeout is ignored.
141 *
142 * @param maximumTimeout
143 */
144 public void setMaximumTimeout(long maximumTimeout) {
145 this.maximumTimeout = maximumTimeout;
146 }
147
148 protected TemporaryQueue createTemporaryDestination(Session session) throws JMSException {
149 return session.createTemporaryQueue();
150 }
151 }