Source code: org/activemq/message/ActiveMQObjectMessage.java
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.activemq.message;
20
21
22 import java.io.DataInput;
23 import java.io.DataOutput;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.Serializable;
28
29 import javax.jms.JMSException;
30 import javax.jms.MessageFormatException;
31 import javax.jms.MessageNotWriteableException;
32 import javax.jms.ObjectMessage;
33
34 import org.activemq.util.SerializationHelper;
35
36 /**
37 * An <CODE>ObjectMessage</CODE> object is used to send a message that contains
38 * a serializable object in the Java programming language ("Java object").
39 * It inherits from the <CODE>Message</CODE> interface and adds a body
40 * containing a single reference to an object. Only <CODE>Serializable</CODE>
41 * Java objects can be used.
42 * <p/>
43 * <P>If a collection of Java objects must be sent, one of the
44 * <CODE>Collection</CODE> classes provided since JDK 1.2 can be used.
45 * <p/>
46 * <P>When a client receives an <CODE>ObjectMessage</CODE>, it is in read-only
47 * mode. If a client attempts to write to the message at this point, a
48 * <CODE>MessageNotWriteableException</CODE> is thrown. If
49 * <CODE>clearBody</CODE> is called, the message can now be both read from and
50 * written to.
51 *
52 * @see javax.jms.Session#createObjectMessage()
53 * @see javax.jms.Session#createObjectMessage(Serializable)
54 * @see javax.jms.BytesMessage
55 * @see javax.jms.MapMessage
56 * @see javax.jms.Message
57 * @see javax.jms.StreamMessage
58 * @see javax.jms.TextMessage
59 */
60
61 public class ActiveMQObjectMessage extends ActiveMQMessage implements ObjectMessage {
62
63 private Serializable object;
64
65
66 /**
67 * Return the type of Packet
68 *
69 * @return integer representation of the type of Packet
70 */
71
72 public int getPacketType() {
73 return ACTIVEMQ_OBJECT_MESSAGE;
74 }
75
76 /**
77 * @return Returns a shallow copy of the message instance
78 * @throws JMSException
79 */
80
81 public ActiveMQMessage shallowCopy() throws JMSException {
82 ActiveMQObjectMessage other = new ActiveMQObjectMessage();
83 this.initializeOther(other);
84 other.object = this.object;
85 return other;
86 }
87
88 /**
89 * @return Returns a deep copy of the message - note the header fields are only shallow copied
90 * @throws JMSException
91 */
92
93 public ActiveMQMessage deepCopy() throws JMSException {
94 return shallowCopy();
95 }
96
97 /**
98 * Clears out the message body. Clearing a message's body does not clear
99 * its header values or property entries.
100 * <p/>
101 * <P>If this message body was read-only, calling this method leaves
102 * the message body in the same state as an empty body in a newly
103 * created message.
104 *
105 * @throws JMSException if the JMS provider fails to clear the message
106 * body due to some internal error.
107 */
108
109 public void clearBody() throws JMSException {
110 super.clearBody();
111 this.object = null;
112 }
113
114
115 /**
116 * Sets the serializable object containing this message's data.
117 * It is important to note that an <CODE>ObjectMessage</CODE>
118 * contains a snapshot of the object at the time <CODE>setObject()</CODE>
119 * is called; subsequent modifications of the object will have no
120 * effect on the <CODE>ObjectMessage</CODE> body.
121 *
122 * @param newObject the message's data
123 * @throws JMSException if the JMS provider fails to set the object
124 * due to some internal error.
125 * @throws javax.jms.MessageFormatException
126 * if object serialization fails.
127 * @throws javax.jms.MessageNotWriteableException
128 * if the message is in read-only
129 * mode.
130 */
131
132 public void setObject(Serializable newObject) throws JMSException {
133 if (super.readOnlyMessage) {
134 throw new MessageNotWriteableException("The message is read-only");
135 }
136 try {
137 setBodyAsBytes(null);
138 this.object = newObject;
139 getBodyAsBytes(); // This serializes the object.
140 } catch (IOException e) {
141 throw (MessageFormatException)new MessageFormatException("Could not serialize the object: "+e.getMessage()).initCause(e);
142 }
143 }
144
145 public void setObjectPayload(Object newObject) {
146 this.object = (Serializable) newObject;
147 }
148
149
150 /**
151 * Gets the serializable object containing this message's data. The
152 * default value is null.
153 *
154 * @return the serializable object containing this message's data
155 * @throws JMSException
156 */
157
158 public Serializable getObject() throws JMSException {
159 if (this.object == null) {
160 try {
161 super.buildBodyFromBytes();
162 }
163 catch (IOException ioe) {
164 throw createFailedToBuildBodyException(ioe);
165 }
166 }
167 return this.object;
168 }
169
170 /**
171 * Prepare a message body for delivery
172 * @throws JMSException
173 */
174 public void prepareMessageBody() throws JMSException{
175 try {
176 convertBodyToBytes();
177 this.object = null;
178 }
179 catch (IOException ioe) {
180 throw createFailedToBuildBodyException(ioe);
181 }
182 }
183
184 /**
185 * Used serialize the message body to an output stream
186 *
187 * @param dataOut
188 * @throws IOException
189 */
190
191 public void writeBody(DataOutput dataOut) throws IOException {
192 SerializationHelper.writeObject((OutputStream)dataOut,this.object);
193 }
194
195 /**
196 * Used to help build the body from an input stream
197 *
198 * @param dataIn
199 * @throws IOException
200 */
201
202 public void readBody(DataInput dataIn) throws IOException {
203 try {
204 this.object = (Serializable) SerializationHelper.readObject((InputStream)dataIn);
205 }
206 catch (ClassNotFoundException ex) {
207 throw new IOException(ex.getMessage());
208 }
209 }
210
211 public String toString() {
212 String objValue = "null";
213 try {
214 if (!isMessagePart()){
215 Object obj = getObject();
216 if (obj != null){
217 objValue = obj.toString();
218 }
219 }else {
220 objValue = "message part";
221 }
222 }
223 catch (JMSException e) {
224 object = e;
225 }
226 return super.toString() + " ActiveMQObjectMessage{ " +
227 "object = " + objValue +
228 " }";
229 }
230
231 protected JMSException createFailedToBuildBodyException(IOException ioe) {
232 JMSException jmsEx = new JMSException("Failed to build body from bytes. Reason: " + ioe);
233 jmsEx.setLinkedException(ioe);
234 return jmsEx;
235 }
236 }