/*
 * JBossMQ, the OpenSource JMS implementation
 * 
 * Distributable under LGPL license. See terms of license at gnu.org.
 */
package org.jboss.mq;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

import javax.transaction.xa.Xid;

/**
 * This class contians all the data needed to perform a JMS transaction
 * 
 * @author Hiram Chirino (Cojonudo14@hotmail.com)
 * @author David Maplesden (David.Maplesden@orion.co.nz)
 * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
 * @author Daniel Bloomfield Ramagem (daniel.ramagem@gmail.com) 
 * @version $Revision: 1.3.6.1 $
 */
public class TransactionRequest implements Externalizable
{
   // Constants -----------------------------------------------------

   /** The serialVersionUID */
   static final long serialVersionUID = 5368191944552650149L;
   
   /** One phase Commit request */
   public final static byte ONE_PHASE_COMMIT_REQUEST = 0;
   /** Two phase Prepare phase */
   public final static byte TWO_PHASE_COMMIT_PREPARE_REQUEST = 1;
   /** Two phase Commit phase */
   public final static byte TWO_PHASE_COMMIT_COMMIT_REQUEST = 2;
   /** Rollback request */
   public final static byte TWO_PHASE_COMMIT_ROLLBACK_REQUEST = 3;
   
   // Attributes ----------------------------------------------------
   
   /** Request type */
   public byte requestType = ONE_PHASE_COMMIT_REQUEST;

   /** For 2 phase commit, this identifies the transaction. */
   public Object xid;

   /** messages sent in the transaction */
   public SpyMessage[] messages;

   /** messages acknowleged in the transaction */
   public AcknowledgementRequest[] acks;
   
   // Static --------------------------------------------------------
   
   // Constructors --------------------------------------------------
   
   // Public --------------------------------------------------------
   
   // Externalizable implementation ---------------------------------

   public void readExternal(ObjectInput in) throws IOException
   {
      requestType = in.readByte();
      try
      {
         xid = in.readObject();
      }
      catch (ClassNotFoundException e)
      {
         throw new IOException("Class not found for xid.");
      }
      int size = in.readInt();
      messages = new SpyMessage[size];
      for (int i = 0; i < size; ++i)
         messages[i] = SpyMessage.readMessage(in);
      size = in.readInt();
      acks = new AcknowledgementRequest[size];
      for (int i = 0; i < size; ++i)
      {
         acks[i] = new AcknowledgementRequest();
         acks[i].readExternal(in);
      }
   }

   public void writeExternal(ObjectOutput out) throws IOException
   {
      out.writeByte(requestType);
      // Non Serializable Xid, use our wrapper
      if (xid != null && xid instanceof Xid && xid instanceof Serializable == false)
         out.writeObject(new JBossMQXid((Xid) xid));
      else
         out.writeObject(xid);
      if (messages == null)
         out.writeInt(0);
      else
      {
         out.writeInt(messages.length);
         for (int i = 0; i < messages.length; ++i)
            SpyMessage.writeMessage(messages[i], out);
      }
      if (acks == null)
         out.writeInt(0);
      else
      {
         out.writeInt(acks.length);
         for (int i = 0; i < acks.length; ++i)
            acks[i].writeExternal(out);
      }
   }
   
   // Package protected ---------------------------------------------
   
   // Protected -----------------------------------------------------
   
   // Private -------------------------------------------------------
   
   // Inner classes -------------------------------------------------
}