//
// JmsaMessageProducer.java - JMS Adapter MessageProducer
//
// When this implementation is asked to send a message, it converts it to
// JmsaMessage form (if not already) and transforms it (using whatever flow is
// applicable), and then asks the underlying MessageProducer to send it.
// Afterwards it copies back JMS headers to the original message.
//

package nyangau.jmsadapter;

import javax.jms.*;

public class JmsaMessageProducer implements MessageProducer
  {
  protected MessageProducer mp;
  protected Destination d;
  protected FlowProcessor fp;
//...sJmsaMessageProducer:2:
public JmsaMessageProducer(
  MessageProducer producer,
  Destination destination,
  FlowProcessor flowproc
  )
  {
  mp = producer;
  d  = destination;
  fp = flowproc;
  }
//...e
//...sMessageID:2:
public void setDisableMessageID(boolean value)
  throws JMSException
  { mp.setDisableMessageID(value); }
public boolean getDisableMessageID()
  throws JMSException
  { return mp.getDisableMessageID(); }
//...e
//...sMessageTimestamp:2:
public void setDisableMessageTimestamp(boolean value)
  throws JMSException
  { mp.setDisableMessageTimestamp(value); }
public boolean getDisableMessageTimestamp()
  throws JMSException
  { return mp.getDisableMessageTimestamp(); }
//...e
//...sDeliveryMode:2:
public void setDeliveryMode(int deliveryMode)
  throws JMSException
  { mp.setDeliveryMode(deliveryMode); }
public int getDeliveryMode()
  throws JMSException
  { return mp.getDeliveryMode(); }
//...e
//...sPriority:2:
public void setPriority(int defaultPriority)
  throws JMSException
  { mp.setPriority(defaultPriority); }
public int getPriority()
  throws JMSException
  { return mp.getPriority(); }
//...e
//...sTimeToLive:2:
public void setTimeToLive(long timeToLive)
  throws JMSException
  { mp.setTimeToLive(timeToLive); }
public long getTimeToLive()
  throws JMSException
  { return mp.getTimeToLive(); }
//...e
//...sgetDestination:2:
public Destination getDestination()
  throws JMSException
  { return d; }
//...e
//...sclose:2:
public void close()
  throws JMSException
  { mp.close(); }
//...e
//...ssend:2:
// We must handle foreign Messages.
// The underlying JMS provider must handle our JmsaMessage (which is
// foreign from its point of view), although not necessarily optimally.

//...spreSend  \45\ convert to JmsaMessage\44\ invoke Flow Processor:2:
protected JmsaMessage preSend(Destination d, Message message)
  throws JMSException
  {
  JmsaMessage m;
  Destination dr = message.getJMSReplyTo();
  if ( message instanceof JmsaMessage )
    // We are being asked to send a JmsaMessage.
    // So we've no need to make a JmsaMessage from it, just use it as-is.
    {
    m = (JmsaMessage) message;
    if ( dr != null )
      {
      if ( ! ( dr instanceof JmsaD ) )
        throw new InvalidDestinationException("wrong type of JMSReplyTo");
      dr = ((JmsaD)dr).getDest();
      }
    }
  else
    // We are being asked to send a foreign Message.
    // So we'll make an equivelent JmsaMessage.
    // The JMSDestination and JMSReplyTo in the new JmsaMessage are null.
    // This is fine, as we are not obliged to honor (or preserve) a
    // foreign JMSReplyTo in a Message we are asked to send.
    {
    m = JmsaMessage.copyOfMessage(message);
    dr = null;
    }

  // Invoke the flow processor
  // If changes occur, m references a different JmsaMessage
  // The original m passed in is not modified
  m = fp.processOut(d, m);

  m.pushJMSReplyTo(dr);

  return m; // return the JmsaMessage to be sent
  }
//...e
//...spostSend \45\ copy back JMS headers:2:
protected static void postSend(Destination d, JmsaMessage m, Message message)
  throws JMSException
  {
  m.popJMSReplyTo();
  message.setJMSDestination(d);
  if ( m != message )
    {
    message.setJMSMessageID   (m.getJMSMessageID   ());
    message.setJMSDeliveryMode(m.getJMSDeliveryMode());
    message.setJMSPriority    (m.getJMSPriority    ());
    message.setJMSTimestamp   (m.getJMSTimestamp   ());
    message.setJMSExpiration  (m.getJMSExpiration  ());
    }
  }  
//...e

public void send(Message message)
  throws JMSException
  {
  if ( d == null )
    throw new UnsupportedOperationException("null Destination");
  JmsaMessage m = preSend(d, message);
  mp.send(m);
  postSend(d, m, message);
  }

public void send(Message message, int deliveryMode, int priority, long timeToLive)
  throws JMSException
  {
  if ( d == null )
    throw new UnsupportedOperationException("null Destination");
  JmsaMessage m = preSend(d, message);
  mp.send(m, deliveryMode, priority, timeToLive);
  postSend(d, m, message);
  }

public void send(Destination d, Message message)
  throws JMSException
  {
  if ( ! ( d instanceof JmsaD ) )
    throw new InvalidDestinationException("wrong type of Destination");
  JmsaMessage m = preSend(d, message);
  mp.send(((JmsaD)d).getDest(), m);
  postSend(d, m, message);
  }

public void send(Destination d, Message message, int deliveryMode, int priority, long timeToLive)
  throws JMSException
  {
  if ( ! ( d instanceof JmsaD ) )
    throw new InvalidDestinationException("wrong type of Destination");
  JmsaMessage m = preSend(d, message);
  mp.send(((JmsaD)d).getDest(), m, deliveryMode, priority, timeToLive);
  postSend(d, m, message);
  }
//...e
  }
