001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq;
018
019import javax.jms.DeliveryMode;
020import javax.jms.Destination;
021import javax.jms.IllegalStateException;
022import javax.jms.JMSException;
023import javax.jms.Message;
024import javax.jms.MessageProducer;
025
026/**
027 * A useful base class for implementing a {@link MessageProducer}
028 *
029 *
030 */
031public abstract class ActiveMQMessageProducerSupport implements MessageProducer, Closeable {
032    protected ActiveMQSession session;
033    protected boolean disableMessageID;
034    protected boolean disableMessageTimestamp;
035    protected int defaultDeliveryMode;
036    protected int defaultPriority;
037    protected long defaultTimeToLive;
038    protected int sendTimeout=0;
039
040    public ActiveMQMessageProducerSupport(ActiveMQSession session) {
041        this.session = session;
042        disableMessageTimestamp = session.connection.isDisableTimeStampsByDefault();
043    }
044
045    /**
046     * Sets whether message IDs are disabled.
047     * <P>
048     * Since message IDs take some effort to create and increase a message's
049     * size, some JMS providers may be able to optimize message overhead if
050     * they are given a hint that the message ID is not used by an application.
051     * By calling the <CODE>setDisableMessageID</CODE> method on this message
052     * producer, a JMS client enables this potential optimization for all
053     * messages sent by this message producer. If the JMS provider accepts this
054     * hint, these messages must have the message ID set to null; if the
055     * provider ignores the hint, the message ID must be set to its normal
056     * unique value.
057     * <P>
058     * Message IDs are enabled by default.
059     *
060     * @param value indicates if message IDs are disabled
061     * @throws javax.jms.JMSException if the JMS provider fails to close the producer due to
062     *                      some internal error.
063     */
064    public void setDisableMessageID(boolean value) throws JMSException {
065        checkClosed();
066        this.disableMessageID = value;
067    }
068
069    /**
070     * Gets an indication of whether message IDs are disabled.
071     *
072     * @return an indication of whether message IDs are disabled
073     * @throws javax.jms.JMSException if the JMS provider fails to determine if message IDs are
074     *                      disabled due to some internal error.
075     */
076    public boolean getDisableMessageID() throws JMSException {
077        checkClosed();
078        return this.disableMessageID;
079    }
080
081    /**
082     * Sets whether message timestamps are disabled.
083     * <P>
084     * Since timestamps take some effort to create and increase a message's
085     * size, some JMS providers may be able to optimize message overhead if
086     * they are given a hint that the timestamp is not used by an application.
087     * By calling the <CODE>setDisableMessageTimestamp</CODE> method on this
088     * message producer, a JMS client enables this potential optimization for
089     * all messages sent by this message producer. If the JMS provider accepts
090     * this hint, these messages must have the timestamp set to zero; if the
091     * provider ignores the hint, the timestamp must be set to its normal
092     * value.
093     * <P>
094     * Message timestamps are enabled by default.
095     *
096     * @param value indicates if message timestamps are disabled
097     * @throws javax.jms.JMSException if the JMS provider fails to close the producer due to
098     *                      some internal error.
099     */
100    public void setDisableMessageTimestamp(boolean value) throws JMSException {
101        checkClosed();
102        this.disableMessageTimestamp = value;
103    }
104
105    /**
106     * Gets an indication of whether message timestamps are disabled.
107     *
108     * @return an indication of whether message timestamps are disabled
109     * @throws javax.jms.JMSException if the JMS provider fails to close the producer due to
110     *                      some internal error.
111     */
112    public boolean getDisableMessageTimestamp() throws JMSException {
113        checkClosed();
114        return this.disableMessageTimestamp;
115    }
116
117    /**
118     * Sets the producer's default delivery mode.
119     * <P>
120     * Delivery mode is set to <CODE>PERSISTENT</CODE> by default.
121     *
122     * @param newDeliveryMode the message delivery mode for this message producer; legal
123     *                        values are <code>DeliveryMode.NON_PERSISTENT</code> and
124     *                        <code>DeliveryMode.PERSISTENT</code>
125     * @throws javax.jms.JMSException if the JMS provider fails to set the delivery mode due to
126     *                      some internal error.
127     * @see javax.jms.MessageProducer#getDeliveryMode
128     * @see javax.jms.DeliveryMode#NON_PERSISTENT
129     * @see javax.jms.DeliveryMode#PERSISTENT
130     * @see javax.jms.Message#DEFAULT_DELIVERY_MODE
131     */
132    public void setDeliveryMode(int newDeliveryMode) throws JMSException {
133        if (newDeliveryMode != DeliveryMode.PERSISTENT && newDeliveryMode != DeliveryMode.NON_PERSISTENT) {
134            throw new javax.jms.IllegalStateException("unknown delivery mode: " + newDeliveryMode);
135        }
136        checkClosed();
137        this.defaultDeliveryMode = newDeliveryMode;
138    }
139
140    /**
141     * Gets the producer's default delivery mode.
142     *
143     * @return the message delivery mode for this message producer
144     * @throws javax.jms.JMSException if the JMS provider fails to close the producer due to
145     *                      some internal error.
146     */
147    public int getDeliveryMode() throws JMSException {
148        checkClosed();
149        return this.defaultDeliveryMode;
150    }
151
152    /**
153     * Sets the producer's default priority.
154     * <P>
155     * The JMS API defines ten levels of priority value, with 0 as the lowest
156     * priority and 9 as the highest. Clients should consider priorities 0-4 as
157     * gradations of normal priority and priorities 5-9 as gradations of
158     * expedited priority. Priority is set to 4 by default.
159     *
160     * @param newDefaultPriority the message priority for this message producer; must be a
161     *                           value between 0 and 9
162     * @throws javax.jms.JMSException if the JMS provider fails to set the delivery mode due to
163     *                      some internal error.
164     * @see javax.jms.MessageProducer#getPriority
165     * @see javax.jms.Message#DEFAULT_PRIORITY
166     */
167    public void setPriority(int newDefaultPriority) throws JMSException {
168        if (newDefaultPriority < 0 || newDefaultPriority > 9) {
169            throw new IllegalStateException("default priority must be a value between 0 and 9");
170        }
171        checkClosed();
172        this.defaultPriority = newDefaultPriority;
173    }
174
175    /**
176     * Gets the producer's default priority.
177     *
178     * @return the message priority for this message producer
179     * @throws javax.jms.JMSException if the JMS provider fails to close the producer due to
180     *                      some internal error.
181     * @see javax.jms.MessageProducer#setPriority
182     */
183    public int getPriority() throws JMSException {
184        checkClosed();
185        return this.defaultPriority;
186    }
187
188    /**
189     * Sets the default length of time in milliseconds from its dispatch time
190     * that a produced message should be retained by the message system.
191     * <P>
192     * Time to live is set to zero by default.
193     *
194     * @param timeToLive the message time to live in milliseconds; zero is unlimited
195     * @throws javax.jms.JMSException if the JMS provider fails to set the time to live due to
196     *                      some internal error.
197     * @see javax.jms.MessageProducer#getTimeToLive
198     * @see javax.jms.Message#DEFAULT_TIME_TO_LIVE
199     */
200    public void setTimeToLive(long timeToLive) throws JMSException {
201        if (timeToLive < 0L) {
202            throw new IllegalStateException("cannot set a negative timeToLive");
203        }
204        checkClosed();
205        this.defaultTimeToLive = timeToLive;
206    }
207
208    /**
209     * Gets the default length of time in milliseconds from its dispatch time
210     * that a produced message should be retained by the message system.
211     *
212     * @return the message time to live in milliseconds; zero is unlimited
213     * @throws javax.jms.JMSException if the JMS provider fails to get the time to live due to
214     *                      some internal error.
215     * @see javax.jms.MessageProducer#setTimeToLive
216     */
217    public long getTimeToLive() throws JMSException {
218        checkClosed();
219        return this.defaultTimeToLive;
220    }
221
222    /**
223     * Sends a message using the <CODE>MessageProducer</CODE>'s default
224     * delivery mode, priority, and time to live.
225     *
226     * @param message the message to send
227     * @throws javax.jms.JMSException                if the JMS provider fails to send the message due to some
228     *                                     internal error.
229     * @throws javax.jms.MessageFormatException      if an invalid message is specified.
230     * @throws javax.jms.InvalidDestinationException if a client uses this method with a <CODE>
231     *                                     MessageProducer</CODE> with an invalid destination.
232     * @throws UnsupportedOperationException
233     *                                     if a client uses this method with a <CODE>
234     *                                     MessageProducer</CODE> that did not specify a
235     *                                     destination at creation time.
236     * @see javax.jms.Session#createProducer
237     * @see javax.jms.MessageProducer
238     * @since 1.1
239     */
240    public void send(Message message) throws JMSException {
241        this.send(this.getDestination(),
242                  message,
243                  this.defaultDeliveryMode,
244                  this.defaultPriority,
245                  this.defaultTimeToLive);
246    }
247
248    /**
249     * Sends a message to the destination, specifying delivery mode, priority,
250     * and time to live.
251     *
252     * @param message      the message to send
253     * @param deliveryMode the delivery mode to use
254     * @param priority     the priority for this message
255     * @param timeToLive   the message's lifetime (in milliseconds)
256     * @throws javax.jms.JMSException                if the JMS provider fails to send the message due to some
257     *                                     internal error.
258     * @throws javax.jms.MessageFormatException      if an invalid message is specified.
259     * @throws javax.jms.InvalidDestinationException if a client uses this method with a <CODE>
260     *                                     MessageProducer</CODE> with an invalid destination.
261     * @throws UnsupportedOperationException
262     *                                     if a client uses this method with a <CODE>
263     *                                     MessageProducer</CODE> that did not specify a
264     *                                     destination at creation time.
265     * @see javax.jms.Session#createProducer
266     * @since 1.1
267     */
268    public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
269        this.send(this.getDestination(),
270                  message,
271                  deliveryMode,
272                  priority,
273                  timeToLive);
274    }
275
276    /**
277     * Sends a message to a destination for an unidentified message producer.
278     * Uses the <CODE>MessageProducer</CODE>'s default delivery mode,
279     * priority, and time to live.
280     * <P>
281     * Typically, a message producer is assigned a destination at creation
282     * time; however, the JMS API also supports unidentified message producers,
283     * which require that the destination be supplied every time a message is
284     * sent.
285     *
286     * @param destination the destination to send this message to
287     * @param message     the message to send
288     * @throws javax.jms.JMSException                if the JMS provider fails to send the message due to some
289     *                                     internal error.
290     * @throws javax.jms.MessageFormatException      if an invalid message is specified.
291     * @throws javax.jms.InvalidDestinationException if a client uses this method with an invalid destination.
292     * @throws UnsupportedOperationException
293     *                                     if a client uses this method with a <CODE>
294     *                                     MessageProducer</CODE> that specified a destination at
295     *                                     creation time.
296     * @see javax.jms.Session#createProducer
297     * @see javax.jms.MessageProducer
298     */
299    public void send(Destination destination, Message message) throws JMSException {
300        this.send(destination,
301                  message,
302                  this.defaultDeliveryMode,
303                  this.defaultPriority,
304                  this.defaultTimeToLive);
305    }
306
307
308    protected abstract void checkClosed() throws IllegalStateException;
309
310    /**
311     * @return the sendTimeout
312     */
313    public int getSendTimeout() {
314        return sendTimeout;
315    }
316
317    /**
318     * @param sendTimeout the sendTimeout to set
319     */
320    public void setSendTimeout(int sendTimeout) {
321        this.sendTimeout = sendTimeout;
322    }
323}