View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2000-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: ObjectMessageImpl.java,v 1.10 2003/08/17 01:32:24 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * 02/26/2000   jimm    Created
47   */
48  
49  package org.exolab.jms.message;
50  
51  import java.io.ByteArrayInputStream;
52  import java.io.ByteArrayOutputStream;
53  import java.io.IOException;
54  import java.io.ObjectInput;
55  import java.io.ObjectInputStream;
56  import java.io.ObjectOutput;
57  import java.io.ObjectOutputStream;
58  import java.io.Serializable;
59  
60  import javax.jms.JMSException;
61  import javax.jms.MessageFormatException;
62  import javax.jms.MessageNotWriteableException;
63  import javax.jms.ObjectMessage;
64  
65  
66  /***
67   * This class implements the <code>javax.jms.ObjectMessage</code> interface.
68   * <p>
69   * An ObjectMessage is used to send a message that contains a serializable
70   * Java object. It inherits from <code>Message</code> and adds a body
71   * containing a single Java reference. Only <code>Serializable</code> Java
72   * objects can be used.
73   * <p>
74   * If a collection of Java objects must be sent, one of the collection
75   * classes provided in JDK 1.2 can be used.
76   * <p>
77   * When a client receives an ObjectMessage, it is in read-only mode. If a
78   * client attempts to write to the message at this point, a
79   * MessageNotWriteableException is thrown. If <code>clearBody</code> is
80   * called, the message can now be both read from and written to.
81   *
82   * @version     $Revision: 1.10 $ $Date: 2003/08/17 01:32:24 $
83   * @author      <a href="mailto:mourikis@intalio.com">Jim Mourikis</a>
84   * @author      <a href="mailto:tima@intalio.com">Tim Anderson</a>
85   */
86  public final class ObjectMessageImpl extends MessageImpl
87      implements ObjectMessage {
88  
89      /***
90       * Object version no. for serialization
91       */
92      static final long serialVersionUID = 1;
93  
94      /***
95       * The byte stream to store data
96       */
97      private byte[] _bytes = null;
98  
99      /***
100      * Construct a new ObjectMessage
101      *
102      * @throws JMSException if the message type can't be set
103      */
104     public ObjectMessageImpl() throws JMSException {
105         setJMSType("ObjectMessage");
106     }
107 
108     /***
109      * Clone an instance of this object
110      *
111      * @return a copy of this object
112      * @throws CloneNotSupportedException if object or attributes aren't
113      * cloneable
114      */
115     public final Object clone() throws CloneNotSupportedException {
116         ObjectMessageImpl result = (ObjectMessageImpl) super.clone();
117         if (_bytes != null) {
118             result._bytes = new byte[_bytes.length];
119             System.arraycopy(_bytes, 0, result._bytes, 0, _bytes.length);
120         }
121         return result;
122     }
123 
124     /***
125      * Serialize out this message's data
126      *
127      * @param out the stream to serialize out to
128      * @throws IOException if any I/O exceptions occurr
129      */
130     public final void writeExternal(ObjectOutput out) throws IOException {
131         super.writeExternal(out);
132         out.writeLong(serialVersionUID);
133         if (_bytes != null) {
134             out.writeInt(_bytes.length);
135             out.write(_bytes);
136         } else {
137             out.writeInt(0);
138         }
139     }
140 
141     /***
142      * Serialize in this message's data
143      *
144      * @param in the stream to serialize in from
145      * @throws ClassNotFoundException if the class for an object being
146      * restored cannot be found.
147      * @throws IOException if any I/O exceptions occur
148      */
149     public final void readExternal(ObjectInput in)
150         throws ClassNotFoundException, IOException {
151         super.readExternal(in);
152         long version = in.readLong();
153         if (version == serialVersionUID) {
154             int length = in.readInt();
155             if (length != 0) {
156                 _bytes = new byte[length];
157                 in.readFully(_bytes);
158             } else {
159                 _bytes = null;
160             }
161         } else {
162             throw new IOException(
163                 "Incorrect version enountered: " + version +
164                 ". This version = " + serialVersionUID);
165         }
166     }
167 
168     /***
169      * Set the serializable object containing this message's data.
170      * It is important to note that an <code>ObjectMessage</code>
171      * contains a snapshot of the object at the time <code>setObject()</code>
172      * is called - subsequent modifications of the object will have no
173      * affect on the <code>ObjectMessage</code> body.
174      *
175      * @param object the message's data
176      * @throws MessageFormatException if object serialization fails
177      * @throws MessageNotWriteableException if the message is read-only
178      */
179     public final void setObject(Serializable object)
180         throws MessageFormatException, MessageNotWriteableException {
181         checkWrite();
182 
183         try {
184             ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
185             ObjectOutputStream out = new ObjectOutputStream(byteOut);
186 
187             out.writeObject(object);
188             out.flush();
189             _bytes = byteOut.toByteArray();
190             out.close();
191         } catch (IOException exception) {
192             MessageFormatException error = new MessageFormatException(
193                 exception.getMessage());
194             error.setLinkedException(exception);
195             throw error;
196         }
197     }
198 
199     /***
200      * Get the serializable object containing this message's data. The
201      * default value is null.
202      *
203      * @return the serializable object containing this message's data
204      *
205      * @throws MessageFormatException if object deserialization fails
206      */
207     public final Serializable getObject() throws MessageFormatException {
208         Serializable result = null;
209         if (_bytes != null) {
210             try {
211                 ByteArrayInputStream byteIn =
212                     new ByteArrayInputStream(_bytes);
213                 ObjectInputStream in = new ObjectInputStream(byteIn);
214 
215                 result = (Serializable) in.readObject();
216                 in.close();
217             } catch (IOException exception) {
218                 MessageFormatException error =
219                     new MessageFormatException(exception.getMessage());
220                 error.setLinkedException(exception);
221                 throw error;
222             } catch (ClassNotFoundException exception) {
223                 MessageFormatException error =
224                     new MessageFormatException(exception.getMessage());
225                 error.setLinkedException(exception);
226                 throw error;
227             }
228         }
229         return result;
230     }
231 
232     /***
233      * Clear out the message body. Clearing a message's body does not clear
234      * its header values or property entries.
235      * If this message body was read-only, calling this method leaves the
236      * message body is in the same state as an empty body in a newly created
237      * message
238      */
239     public final void clearBody() throws JMSException {
240         super.clearBody();
241         _bytes = null;
242     }
243 
244 } // End ObjectMessageImpl