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     */
017    package org.apache.activemq;
018    
019    import javax.jms.DeliveryMode;
020    import javax.jms.Destination;
021    import javax.jms.IllegalStateException;
022    import javax.jms.JMSException;
023    import javax.jms.Message;
024    import javax.jms.MessageProducer;
025    
026    /**
027     * A useful base class for implementing a {@link MessageProducer}
028     *
029     * @version $Revision: $
030     */
031    public 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("unkown 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    }