/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.fw.hl7.builder;

// Java classes
import javax.jms.JMSException;
import javax.jms.Message;

// Library classes
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.SimpleMessageConverter102;

/**
 * Provides convenient methods to access a JMS message and its body
 * 
 * @author DNS   LEV
 * @version 1.0
 */
public class JMSMetaData extends AbstractMetaData {

   /**
	 * An instance of serialVersionUID
	 */
	private static final long serialVersionUID = 6239636410042628897L;
	
	/**
	 * An instance of converter
	 */
	private MessageConverter converter = null;

	/**
	 * A default constructor
	 * @param data
	 */
	public JMSMetaData( Message data ) {
      //
      // 1. We are using BEA Weblogic 8.1.* that is bundled 
      // with JMS 1.0 version.  In this version of JMS,
      // a BytesMessage interface doesn't have a getBodyLength()
      // that returns a number of bytes in a body message so 
      // we use a SimpleMessageConverter102 here.  When we 
		// upgrade to BEA 9, we can switch this to SimpleMessageConverter
      //
      this( data, new SimpleMessageConverter102() );
   }
   
	/**
	 * A default constructor
	 * @param data
	 * @param converter
	 */
	public JMSMetaData( Message data, MessageConverter converter ) {
      super( data );
      this.converter = converter;
   }
   
	/**
	 * This implementation converts a TextMessage back to a String, a
	 * ByteMessage back to a byte array, a MapMessage back to a Map,
	 * and an ObjectMessage back to a Serializable object.
	 * 
	 * @return A converted object 
	 * @throws JMSException If failed to get a message body 
	 */
	public Object getJMSMessageBody() throws JMSException {
		return converter.fromMessage( this.getJMSMessage() );
	}
	
   /** 
    * Returns a JMS message as a generic message
    * @return JMS message  
    */
   public Message getJMSMessage() {
      return (Message)getData();
   }
   
   /** Returns a wrapped text message in a JMS Text Message
    * or a BytesArray. This method is implemented to provide
    * support for Vitria.  Vitria uses a message.getBytes to 
    * convert from a string into an array of bytes so we need 
    * to do the same to convert from array of bytes to a string
    * 
    * @return A text message
    * @throws JMSException Thrown in case of errors
    */
   public String getTextMessage() throws JMSException {
      return getMessageBody( getJMSMessage() );
   }
   
   /** Returns a message body as a string.
    * 
    * @param message A JMS message to unwrapp
    * @return A text message 
    * @throws JMSException Thrown in case of invalid type to convert to a string
    */
   protected String getMessageBody( Message message )  throws JMSException {
   	
   	String text = null;
   	
   	Object body = this.getJMSMessageBody();
   	if( body instanceof byte[] ) {
   		text = new String( (byte[])body );
   	}
   	else if( body instanceof String ) {
   		text = (String)body;
   	}
   	else {
   		throw new MessageConversionException("Invalid message body to convert to a string");
   	}
   	return text;
   }
}