View Javadoc

1   /*** 
2    * 
3    * Copyright 2004 Protique Ltd
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License"); 
6    * you may not use this file except in compliance with the License. 
7    * You may obtain a copy of the License at 
8    * 
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License. 
16   * 
17   **/
18  
19  package org.codehaus.activemq.message;
20  
21  
22  import javax.jms.JMSException;
23  import javax.jms.MessageNotWriteableException;
24  import javax.jms.ObjectMessage;
25  import java.io.DataInput;
26  import java.io.DataOutput;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.ObjectInputStream;
30  import java.io.ObjectOutputStream;
31  import java.io.OutputStream;
32  import java.io.Serializable;
33  
34  /***
35   * An <CODE>ObjectMessage</CODE> object is used to send a message that contains
36   * a serializable object in the Java programming language ("Java object").
37   * It inherits from the <CODE>Message</CODE> interface and adds a body
38   * containing a single reference to an object. Only <CODE>Serializable</CODE>
39   * Java objects can be used.
40   * <p/>
41   * <P>If a collection of Java objects must be sent, one of the
42   * <CODE>Collection</CODE> classes provided since JDK 1.2 can be used.
43   * <p/>
44   * <P>When a client receives an <CODE>ObjectMessage</CODE>, it is in read-only
45   * mode. If a client attempts to write to the message at this point, a
46   * <CODE>MessageNotWriteableException</CODE> is thrown. If
47   * <CODE>clearBody</CODE> is called, the message can now be both read from and
48   * written to.
49   *
50   * @see javax.jms.Session#createObjectMessage()
51   * @see javax.jms.Session#createObjectMessage(Serializable)
52   * @see javax.jms.BytesMessage
53   * @see javax.jms.MapMessage
54   * @see javax.jms.Message
55   * @see javax.jms.StreamMessage
56   * @see javax.jms.TextMessage
57   */
58  
59  public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMessage {
60  
61      private Serializable object;
62  
63  
64      /***
65       * Return the type of Packet
66       *
67       * @return integer representation of the type of Packet
68       */
69  
70      public int getPacketType() {
71          return ACTIVEMQ_OBJECT_MESSAGE;
72      }
73  
74      /***
75       * @return Returns a shallow copy of the message instance
76       * @throws JMSException
77       */
78  
79      public ActiveMQMessage shallowCopy() throws JMSException {
80          ActiveMQObjectMessage other = new ActiveMQObjectMessage();
81          this.initializeOther(other);
82          other.object = this.object;
83          return other;
84      }
85  
86      /***
87       * @return Returns a deep copy of the message - note the header fields are only shallow copied
88       * @throws JMSException
89       */
90  
91      public ActiveMQMessage deepCopy() throws JMSException {
92          return shallowCopy();
93      }
94  
95      /***
96       * Clears out the message body. Clearing a message's body does not clear
97       * its header values or property entries.
98       * <p/>
99       * <P>If this message body was read-only, calling this method leaves
100      * the message body in the same state as an empty body in a newly
101      * created message.
102      *
103      * @throws JMSException if the JMS provider fails to clear the message
104      *                      body due to some internal error.
105      */
106 
107     public void clearBody() throws JMSException {
108         super.clearBody();
109         this.object = null;
110     }
111 
112 
113     /***
114      * Sets the serializable object containing this message's data.
115      * It is important to note that an <CODE>ObjectMessage</CODE>
116      * contains a snapshot of the object at the time <CODE>setObject()</CODE>
117      * is called; subsequent modifications of the object will have no
118      * effect on the <CODE>ObjectMessage</CODE> body.
119      *
120      * @param newObject the message's data
121      * @throws JMSException if the JMS provider fails to set the object
122      *                      due to some internal error.
123      * @throws javax.jms.MessageFormatException
124      *                      if object serialization fails.
125      * @throws javax.jms.MessageNotWriteableException
126      *                      if the message is in read-only
127      *                      mode.
128      */
129 
130     public void setObject(Serializable newObject) throws JMSException {
131         if (super.readOnlyMessage) {
132             throw new MessageNotWriteableException("The message is read-only");
133         }
134         this.object = newObject;
135     }
136 
137     void setObjectPayload(Object newObject) {
138         this.object = (Serializable) newObject;
139     }
140 
141 
142     /***
143      * Gets the serializable object containing this message's data. The
144      * default value is null.
145      *
146      * @return the serializable object containing this message's data
147      * @throws JMSException
148      */
149 
150     public Serializable getObject() throws JMSException {
151         if (this.object == null) {
152             try {
153                 super.buildBodyFromBytes();
154             }
155             catch (IOException ioe) {
156                 JMSException jmsEx = new JMSException("failed to build body from bytes");
157                 jmsEx.setLinkedException(ioe);
158                 throw jmsEx;
159             }
160         }
161         return this.object;
162     }
163     
164     /***
165      * Prepare a message body for delivery
166      * @throws JMSException
167      */
168     public void prepareMessageBody() throws JMSException{
169         try {
170             convertBodyToBytes();
171             this.object = null;
172         }
173         catch (IOException ioe) {
174             JMSException jmsEx = new JMSException("failed to convert body to bytes");
175             jmsEx.setLinkedException(ioe);
176             throw jmsEx;
177         }
178     }
179 
180     /***
181      * Used serialize the message body to an output stream
182      *
183      * @param dataOut
184      * @throws IOException
185      */
186 
187     protected void writeBody(DataOutput dataOut) throws IOException {
188         ObjectOutputStream objOut = new ObjectOutputStream((OutputStream) dataOut);
189         objOut.writeObject(this.object);
190         objOut.flush();
191     }
192 
193     /***
194      * Used to help build the body from an input stream
195      *
196      * @param dataIn
197      * @throws IOException
198      */
199 
200     protected void readBody(DataInput dataIn) throws IOException {
201         ObjectInputStream objIn = new ObjectInputStream((InputStream) dataIn);
202         try {
203             this.object = (Serializable) objIn.readObject();
204             objIn.close();
205         }
206         catch (ClassNotFoundException ex) {
207             throw new IOException(ex.getMessage());
208         }
209     }
210 }