/** * * Copyright 2005 LogicBlaze, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ package org.jencks; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TemporaryQueue; import javax.jms.TemporaryTopic; /** * A helper class for performing remote method invocations over JMS. * This class is a polymorphic version of the {@link javax.jms.QueueRequestor} and {@link javax.jms.TopicRequestor} * that ship with the JMS API which take advantage of the polymorphism of JMS 1.1 and which also supports timeouts. * * @version $Revision$ */ public class Requestor { private Session session; private Destination temporaryDestination; private MessageProducer sender; private MessageConsumer receiver; private long maximumTimeout = 20000L; /** * Constructor for the Requestor class. *

*

This implementation assumes the session parameter to be non-transacted, * with a delivery mode of either AUTO_ACKNOWLEDGE or * DUPS_OK_ACKNOWLEDGE. * * @param session the Session the queue belongs to * @param destination the destination to perform the request/reply call on * @throws javax.jms.JMSException if the JMS provider fails to create the * Requestor due to some internal * error. * @throws javax.jms.InvalidDestinationException * if an invalid queue is specified. */ public Requestor(Session session, Destination destination) throws JMSException { this.session = session; temporaryDestination = createTemporaryDestination(session); sender = session.createProducer(destination); receiver = session.createConsumer(temporaryDestination); } /** * Sends a request and waits for a reply. The temporary queue is used for * the JMSReplyTo destination, and only one reply per request * is expected. * * @param message the message to send * @return the reply message * @throws javax.jms.JMSException if the JMS provider fails to complete the * request due to some internal error. */ public Message request(Message message) throws JMSException { message.setJMSReplyTo(temporaryDestination); sender.send(message); long timeout = getMaximumTimeout(); if (timeout > 0) { return receiver.receive(timeout); } else { return receiver.receive(); } } /** * Sends a request and waits for a reply up to a maximum timeout. The temporary queue is used for * the JMSReplyTo destination, and only one reply per request * is expected. * * @param message the message to send * @return the reply message * @throws javax.jms.JMSException if the JMS provider fails to complete the * request due to some internal error. */ public Message request(Message message, long timeout) throws JMSException { message.setJMSReplyTo(temporaryDestination); sender.send(message); return receiver.receive(timeout); } /** * Closes the Requestor and its session. *

*

Since a provider may allocate some resources on behalf of a * Requestor outside the Java virtual machine, clients * should close them when they * are not needed. Relying on garbage collection to eventually reclaim * these resources may not be timely enough. *

*

Note that this method closes the Session object * passed to the Requestor constructor. * * @throws javax.jms.JMSException if the JMS provider fails to close the * Requestor due to some internal * error. */ public void close() throws JMSException { // producer and consumer created by constructor are implicitly closed. session.close(); if (temporaryDestination instanceof TemporaryQueue) { ((TemporaryQueue) temporaryDestination).delete(); } else if (temporaryDestination instanceof TemporaryTopic) { ((TemporaryTopic) temporaryDestination).delete(); } } public long getMaximumTimeout() { return maximumTimeout; } /** * Sets the maximum default timeout used for remote requests. If set to <= 0 then * the timeout is ignored. * * @param maximumTimeout */ public void setMaximumTimeout(long maximumTimeout) { this.maximumTimeout = maximumTimeout; } protected TemporaryQueue createTemporaryDestination(Session session) throws JMSException { return session.createTemporaryQueue(); } }