package org.mockejb.jms;

import java.io.*;
import javax.jms.*;

/**
 * <code>ObjectMessage</code> implementation.
 * @author Dimitar Gospodinov
 * @see javax.jms.ObjectMessage
 */
public class ObjectMessageImpl extends MessageImpl implements ObjectMessage {

    private byte[] serializedObject = null;

    /**
     * Creates empty <code>ObjectMessageImpl</code>.
     */
    public ObjectMessageImpl() {
        super();
    }

    /**
     * Creates new <code>ObjectMessageImpl</code> and sets its body to
     * <code>object</code> 
     * @param object
     * @throws JMSException
     */
    public ObjectMessageImpl(Serializable object) throws JMSException {
        setObject(object);
    }

    /**
     * Creates new <code>ObjectMessageImpl</code> and sets its header, properties
     * and body to the corresponded values from <code>msg</code>
     * @param msg
     * @throws JMSException
     */
    public ObjectMessageImpl(ObjectMessage msg) throws JMSException {
        super(msg);
        setObject(msg.getObject());
    }

    /**
     * @see javax.jms.ObjectMessage#setObject(java.io.Serializable)
     */
    public void setObject(Serializable object) throws JMSException {
        checkBodyWriteable();
        try {
            ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
            ObjectOutputStream objectOut = new ObjectOutputStream(bytesOut);
            objectOut.writeObject(object);
            objectOut.flush();
            objectOut.close();
            serializedObject = bytesOut.toByteArray();
            bytesOut.close();
        } catch (IOException ex) {
            throw new JMSException(ex.getMessage());
        }
    }

    /**
     * @see javax.jms.ObjectMessage#getObject()
     */
    public Serializable getObject() throws JMSException {
        if (serializedObject == null) {
            return null;
        }
        Serializable result;
        try {
            ByteArrayInputStream bytesIn =
                new ByteArrayInputStream(serializedObject);
            ObjectInputStream objectIn = new ObjectInputStream(bytesIn);
            result = (Serializable) objectIn.readObject();
            objectIn.close();
            bytesIn.close();
            return result;
        } catch (IOException ex) {
            throw new JMSException(ex.getMessage());
        } catch (ClassNotFoundException ex) {
            throw new JMSException(ex.getMessage());
        }
    }

    /**
     * @see javax.jms.ObjectMessage#clearBody()
     */
    public void clearBody() throws JMSException {
        super.clearBody();
        serializedObject = null;
    }

    // Non-standard methods

    /**
      * Sets message body in read-only mode.
      * @throws JMSException
      */
    void resetBody() throws JMSException {
        setBodyReadOnly();
    }

}