/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */


package javax.jms;

/** A client uses a <CODE>MessageProducer</CODE> object to send messages to a 
  * destination. A <CODE>MessageProducer</CODE> object is created by passing a 
  * <CODE>Destination</CODE> object to a message-producer creation method 
  * supplied by a session.
  *
  * <P><CODE>MessageProducer</CODE> is the parent interface for all message 
  * producers.
  *
  * <P>A client also has the option of creating a message producer without 
  * supplying a destination. In this case, a destination must be provided with 
  * every send operation. A typical use for this kind of message producer is
  * to send replies to requests using the request's <CODE>JMSReplyTo</CODE> 
  * destination.
  *
  * <P>A client can specify a default delivery mode, priority, and time to live 
  * for messages sent by a message producer. It can also specify the delivery 
  * mode, priority, and time to live for an individual message.
  *
  * <P>A client can specify a time-to-live value in milliseconds for each
  * message it sends. This value defines a message expiration time that
  * is the sum of the message's time-to-live and the GMT when it is sent (for
  * transacted sends, this is the time the client sends the message, not
  * the time the transaction is committed).
  *
  * <P>A JMS provider should do its best to expire messages accurately;
  * however, the JMS API does not define the accuracy provided.
  *
  * @version     1.1 - February 2, 2002
  * @author      Mark Hapner
  * @author      Rich Burridge
  * @author      Kate Stout
  *
  * @see         javax.jms.TopicPublisher
  * @see         javax.jms.QueueSender
  * @see         javax.jms.Session#createProducer
  */

public interface MessageProducer {

    /** Sets whether message IDs are disabled.
      *  
      * <P>Since message IDs take some effort to create and increase a
      * message's size, some JMS providers may be able to optimize message
      * overhead if they are given a hint that the message ID is not used by
      * an application. By calling the <CODE>setDisableMessageID</CODE>  
      * method on this message producer, a JMS client enables this potential 
      * optimization for all messages sent by this message producer. If the JMS 
      * provider accepts this hint, 
      * these messages must have the message ID set to null; if the provider 
      * ignores the hint, the message ID must be set to its normal unique value.
      *
      * <P>Message IDs are enabled by default.
      *
      * @param value indicates if message IDs are disabled
      *  
      * @exception JMSException if the JMS provider fails to set message ID to
      *                         disabled due to some internal error.
      */ 

    void
    setDisableMessageID(boolean value) throws JMSException;


    /** Gets an indication of whether message IDs are disabled.
      *  
      * @return an indication of whether message IDs are disabled
      *  
      * @exception JMSException if the JMS provider fails to determine if 
      *                         message IDs are disabled due to some internal 
      *                         error.
      */ 

    boolean 
    getDisableMessageID() throws JMSException;


    /** Sets whether message timestamps are disabled.
      *  
      * <P>Since timestamps take some effort to create and increase a 
      * message's size, some JMS providers may be able to optimize message 
      * overhead if they are given a hint that the timestamp is not used by an 
      * application. By calling the <CODE>setDisableMessageTimestamp</CODE> 
      * method on this message producer, a JMS client enables this potential 
      * optimization for all messages sent by this message producer.  If the 
      * JMS provider accepts this hint, 
      * these messages must have the timestamp set to zero; if the provider 
      * ignores the hint, the timestamp must be set to its normal value.
      *  
      * <P>Message timestamps are enabled by default.
      *
      * @param value indicates if message timestamps are disabled
      *  
      * @exception JMSException if the JMS provider fails to set timestamps to
      *                         disabled due to some internal error.
      */ 

    void
    setDisableMessageTimestamp(boolean value) throws JMSException;


    /** Gets an indication of whether message timestamps are disabled.
      *  
      * @return an indication of whether message timestamps are disabled
      *  
      * @exception JMSException if the JMS provider fails to determine if 
      *                         timestamps are disabled due to some internal 
      *                         error.
      */ 

    boolean
    getDisableMessageTimestamp() throws JMSException;


    /** Sets the producer's default delivery mode.
      *  
      * <P>Delivery mode is set to <CODE>PERSISTENT</CODE> by default.
      *
      * @param deliveryMode the message delivery mode for this message
      * producer; legal values are <code>DeliveryMode.NON_PERSISTENT</code>
      * and <code>DeliveryMode.PERSISTENT</code>
      *  
      * @exception JMSException if the JMS provider fails to set the delivery 
      *                         mode due to some internal error.          
      *
      * @see javax.jms.MessageProducer#getDeliveryMode
      * @see javax.jms.DeliveryMode#NON_PERSISTENT
      * @see javax.jms.DeliveryMode#PERSISTENT
      * @see javax.jms.Message#DEFAULT_DELIVERY_MODE
      */ 

    void
    setDeliveryMode(int deliveryMode) throws JMSException;


    /** Gets the producer's default delivery mode.
      *  
      * @return the message delivery mode for this message producer
      *  
      * @exception JMSException if the JMS provider fails to get the delivery 
      *                         mode due to some internal error.
      *
      * @see javax.jms.MessageProducer#setDeliveryMode
      */ 

    int 
    getDeliveryMode() throws JMSException;


    /** Sets the producer's default priority.
      *  
      * <P>The JMS API defines ten levels of priority value, with 0 as the 
      * lowest priority and 9 as the highest. Clients should consider priorities
      * 0-4 as gradations of normal priority and priorities 5-9 as gradations 
      * of expedited priority. Priority is set to 4 by default.
      *
      * @param defaultPriority the message priority for this message producer;
      *                        must be a value between 0 and 9
      * 
      *  
      * @exception JMSException if the JMS provider fails to set the priority
      *                         due to some internal error.
      *
      * @see javax.jms.MessageProducer#getPriority
      * @see javax.jms.Message#DEFAULT_PRIORITY
      */ 

    void
    setPriority(int defaultPriority) throws JMSException;


    /** Gets the producer's default priority.
      *  
      * @return the message priority for this message producer
      *  
      * @exception JMSException if the JMS provider fails to get the priority
      *                         due to some internal error.
      *
      * @see javax.jms.MessageProducer#setPriority
      */ 

    int 
    getPriority() throws JMSException;


    /** Sets the default length of time in milliseconds from its dispatch time
      * that a produced message should be retained by the message system.
      *
      * <P>Time to live is set to zero by default.
      *
      * @param timeToLive the message time to live in milliseconds; zero is
      * unlimited
      *
      * @exception JMSException if the JMS provider fails to set the time to 
      *                         live due to some internal error.
      *
      * @see javax.jms.MessageProducer#getTimeToLive
      * @see javax.jms.Message#DEFAULT_TIME_TO_LIVE
      */
   
    void
    setTimeToLive(long timeToLive) throws JMSException;
   
   
    /** Gets the default length of time in milliseconds from its dispatch time
      * that a produced message should be retained by the message system.
      *
      * @return the message time to live in milliseconds; zero is unlimited
      *
      * @exception JMSException if the JMS provider fails to get the time to 
      *                         live due to some internal error.
      *
      * @see javax.jms.MessageProducer#setTimeToLive
      */ 
 
    long
    getTimeToLive() throws JMSException;

    /** Gets the destination associated with this <CODE>MessageProducer</CODE>.
      *  
      * @return this producer's <CODE>Destination/<CODE>
      *  
      * @exception JMSException if the JMS provider fails to get the destination for
      *                         this <CODE>MessageProducer</CODE>
      *                         due to some internal error.
      *@since 1.1 
      */ 
    
    Destination 
    getDestination() throws JMSException;
    
    /** Closes the message producer.
      *
      * <P>Since a provider may allocate some resources on behalf of a
      * <CODE>MessageProducer</CODE> 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.
      *  
      * @exception JMSException if the JMS provider fails to close the producer
      *                         due to some internal error.
      */ 

    void
    close() throws JMSException;
    
     
      /** Sends a message using the <CODE>MessageProducer</CODE>'s 
      * default delivery mode, priority, and time to live.
      *
      * @param message the message to send 
      *  
      * @exception JMSException if the JMS provider fails to send the message 
      *                         due to some internal error.
      * @exception MessageFormatException if an invalid message is specified.
      * @exception InvalidDestinationException if a client uses
      *                         this method with a <CODE>MessageProducer</CODE> with
      *                         an invalid destination.
      * @exception java.lang.UnsupportedOperationException if a client uses this
      *                         method with a <CODE>MessageProducer</CODE> that did
      *                         not specify a destination at creation time.
      * 
      * @see javax.jms.Session#createProducer 
      * @see javax.jms.MessageProducer 
      *
      * @since 1.1 
      */

    void 
    send(Message message) throws JMSException;
    
      /** Sends a message to the destination, specifying delivery mode, priority, and 
      * time to live.
      *
      * @param message the message to send
      * @param deliveryMode the delivery mode to use
      * @param priority the priority for this message
      * @param timeToLive the message's lifetime (in milliseconds)
      *  
      * @exception JMSException if the JMS provider fails to send the message 
      *                         due to some internal error.
      * @exception MessageFormatException if an invalid message is specified.
      * @exception InvalidDestinationException if a client uses
      *                         this method with a <CODE>MessageProducer</CODE> with
      *                         an invalid destination.
      * @exception java.lang.UnsupportedOperationException if a client uses this
      *                         method with a <CODE>MessageProducer</CODE> that did
      *                         not specify a destination at creation time.
      *
      * @see javax.jms.Session#createProducer
      * @since 1.1 
      */

    void 
    send(Message message, 
	 int deliveryMode, 
	 int priority,
	 long timeToLive) throws JMSException;
    
    
     /**Sends a message to a destination for an unidentified message producer.
      * Uses the <CODE>MessageProducer</CODE>'s default delivery mode, priority,
      * and time to live.
      *
      * <P>Typically, a message producer is assigned a destination at creation 
      * time; however, the JMS API also supports unidentified message producers,
      * which require that the destination be supplied every time a message is
      * sent. 
      *  
      * @param destination the destination to send this message to
      * @param message the message to send
      *  
      * @exception JMSException if the JMS provider fails to send the message 
      *                         due to some internal error.
      * @exception MessageFormatException if an invalid message is specified.
      * @exception InvalidDestinationException if a client uses
      *                         this method with an invalid destination.
      * @exception java.lang.UnsupportedOperationException if a client uses this
      *                         method with a <CODE>MessageProducer</CODE> that 
      *                         specified a destination at creation time.
      * 
      * @see javax.jms.Session#createProducer
      * @see javax.jms.MessageProducer
      * @since 1.1 
      */ 
 
    void
    send(Destination destination, Message message) throws JMSException;
 
 
    /** Sends a message to a destination for an unidentified message producer, 
      * specifying delivery mode, priority and time to live.
      *  
      * <P>Typically, a message producer is assigned a destination at creation 
      * time; however, the JMS API also supports unidentified message producers,
      * which require that the destination be supplied every time a message is
      * sent. 
      *  
      * @param destination the destination to send this message to
      * @param message the message to send
      * @param deliveryMode the delivery mode to use
      * @param priority the priority for this message
      * @param timeToLive the message's lifetime (in milliseconds)
      *  
      * @exception JMSException if the JMS provider fails to send the message 
      *                         due to some internal error.
      * @exception MessageFormatException if an invalid message is specified.
      * @exception InvalidDestinationException if a client uses
      *                         this method with an invalid destination.
      *
      * @see javax.jms.Session#createProducer
      * @since 1.1 
      */ 

    void
    send(Destination destination, 
	 Message message, 
	 int deliveryMode, 
	 int priority,
	 long timeToLive) throws JMSException;



}
