//
// FlowStepBodyGet.java - Copy from message body to variable
//

package nyangau.jmsadapter;

//...simports:0:
import java.io.Serializable;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import javax.jms.JMSException;
import javax.jms.MessageEOFException;
//...e

public class FlowStepBodyGet extends FlowStep
  {
//...senum RT:2:
enum RT
  {
  RT_UTF,
  RT_Boolean,
  RT_Character,
  RT_Byte,
  RT_Short,
  RT_Integer,
  RT_Long,
  RT_Float,
  RT_Double,
  RT_Bytes
  }
//...e
  protected boolean reset;
  protected RT readtype;  // used if BytesMessage
  protected String item;  // used if MapMessage
  protected String var;
//...sFlowStepBodyGet:2:
public FlowStepBodyGet(Node eStep)
  throws FlowProcessorException
  {
  super(eStep);
  NamedNodeMap nnmStep = eStep.getAttributes();
  Node aReset = nnmStep.getNamedItem("reset");
  reset = ( aReset != null ) ? aReset.getNodeValue().equals("true") : true;
  Node aType = nnmStep.getNamedItem("type");
  String type = ( aType != null ) ? aType.getNodeValue() : null;

  if ( type == null || type.equals("UTF") )
    readtype = RT.RT_UTF;
  else if ( type.equals("Boolean") )
    readtype = RT.RT_Boolean;
  else if ( type.equals("Character") )
    readtype = RT.RT_Character;
  else if ( type.equals("Byte") )
    readtype = RT.RT_Byte;
  else if ( type.equals("Short") )
    readtype = RT.RT_Short;
  else if ( type.equals("Integer") )
    readtype = RT.RT_Integer;
  else if ( type.equals("Long") )
    readtype = RT.RT_Long;
  else if ( type.equals("Float") )
    readtype = RT.RT_Float;
  else if ( type.equals("Double") )
    readtype = RT.RT_Double;
  else if ( type.equals("byte[]") )
    readtype = RT.RT_Bytes;
  else
    throw new FlowProcessorException("unexpected type "+type+" in step "+name+", bad jmsadapter.xsd?");

  Node aItem = nnmStep.getNamedItem("item");
  item = ( aItem != null ) ? aItem.getNodeValue() : null;
  Node aVar = nnmStep.getNamedItem("var");
  var = ( aVar != null ) ? aVar.getNodeValue() : "v0";
  }
//...e
//...sprocess:2:
public void process(FlowContext c)
  throws FlowProcessorException, JMSException
  {
  JmsaMessage m = c.getMessage();
  if ( m instanceof JmsaBytesMessage )
//...shandle BytesMessage using readXxx\40\\41\:6:
{
if ( reset )
  ((JmsaBytesMessage)m).reset();
Object o = null;
switch ( readtype )
  {
  case RT_UTF:
    o = ((JmsaBytesMessage)m).readUTF();
    break;
  case RT_Boolean:
    o = new Boolean(((JmsaBytesMessage)m).readBoolean());
    break;
  case RT_Character:
    o = new Character(((JmsaBytesMessage)m).readChar());
    break;
  case RT_Byte:
    o = new Byte(((JmsaBytesMessage)m).readByte());
    break;
  case RT_Short:
    o = new Short(((JmsaBytesMessage)m).readByte());
    break;
  case RT_Integer:
    o = new Integer(((JmsaBytesMessage)m).readInt());
    break;
  case RT_Long:
    o = new Long(((JmsaBytesMessage)m).readLong());
    break;
  case RT_Float:
    o = new Float(((JmsaBytesMessage)m).readFloat());
    break;
  case RT_Double:
    o = new Double(((JmsaBytesMessage)m).readDouble());
    break;
  case RT_Bytes:
    {
    if ( ! reset )
      // A bit of an arbitrary limitation, perhaps I'll work out how to be more flexible
      throw new FlowProcessorException("reset must be true when type is byte[] and reading from a BytesMessage");
    int len = (int) ((JmsaBytesMessage)m).getBodyLength();
    byte[] b = new byte[len];
    ((JmsaBytesMessage)m).readBytes(b);
    o = b;
    }
    break;
  }
c.setVar(var, o);
}
//...e
  else if ( m instanceof JmsaTextMessage )
//...shandle TextMessage using getText\40\\41\:6:
{
String s = ((JmsaTextMessage)m).getText();
c.setVar(var, s != null ? s : new FlowNullValue());
}
//...e
  else if ( m instanceof JmsaMapMessage )
//...shandle MapMessage using getObject\40\\41\:6:
{
if ( item == null )
  throw new FlowProcessorException("item is null and we have a MapMessage");
Object o = ((JmsaMapMessage)m).getObject(item);
  // o is now one of
  //   Boolean
  //   Character
  //   Byte
  //   Short
  //   Integer
  //   Long
  //   Float
  //   Double
  //   String
  //   byte[]
  //   null
c.setVar(var, o != null ? o : new FlowNullValue());
}
//...e
  else if ( m instanceof JmsaStreamMessage )
//...shandle StreamMessage using readXxx\40\\41\:6:
{
if ( reset )
  ((JmsaStreamMessage)m).reset();
try
  {
  Object o = ((JmsaStreamMessage)m).readObject();
    // o is now one of
    //   byte[]
    //   Boolean
    //   Byte
    //   Character
    //   Short
    //   Integer
    //   Long
    //   Float
    //   Double
    //   String
  c.setVar(var, o);
  }
catch ( MessageEOFException e )
  {
  c.setVar(var, new FlowNullValue());
  }
}
//...e
  else if ( m instanceof JmsaObjectMessage )
//...shandle ObjectMessage using getObject\40\\41\:6:
{
Serializable o = ((JmsaObjectMessage)m).getObject();
c.setVar(var, o != null ? o : new FlowNullValue());
}
//...e
  else
    throw new FlowProcessorException("can't bodyget from plain old Message in step "+name);
  }
//...e
  }
