001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.mq;
023:
024: import java.io.ByteArrayInputStream;
025: import java.io.ByteArrayOutputStream;
026: import java.io.Externalizable;
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.io.ObjectInput;
030: import java.io.ObjectInputStream;
031: import java.io.ObjectOutput;
032: import java.io.ObjectOutputStream;
033: import java.io.ObjectStreamClass;
034: import java.io.Serializable;
035:
036: import javax.jms.JMSException;
037: import javax.jms.MessageFormatException;
038: import javax.jms.MessageNotWriteableException;
039: import javax.jms.ObjectMessage;
040:
041: import org.jboss.util.Classes;
042:
043: /**
044: * This class implements javax.jms.ObjectMessage
045: *
046: * @author Norbert Lataille (Norbert.Lataille@m4x.org)
047: * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
048: * @version $Revision: 57198 $
049: */
050: public class SpyObjectMessage extends SpyMessage implements
051: ObjectMessage, Externalizable {
052: // Constants -----------------------------------------------------
053:
054: /** The serialVersionUID */
055: private final static long serialVersionUID = 8809953915407712952L;
056:
057: // Attributes ----------------------------------------------------
058:
059: /** Is it a byte array */
060: boolean isByteArray = false;
061: /** The bytes */
062: byte[] objectBytes = null;
063:
064: // Static --------------------------------------------------------
065:
066: // Constructors --------------------------------------------------
067:
068: // Public --------------------------------------------------------
069:
070: // ObjectMessage implementation ----------------------------------
071:
072: public void setObject(Serializable object) throws JMSException {
073: if (header.msgReadOnly) {
074: throw new MessageNotWriteableException("setObject");
075: }
076: if (object == null) {
077: objectBytes = null;
078: return;
079: }
080: try {
081: if (object instanceof byte[]) {
082: //cheat for byte arrays
083: isByteArray = true;
084: objectBytes = new byte[((byte[]) object).length];
085: System.arraycopy(object, 0, objectBytes, 0,
086: objectBytes.length);
087: } else {
088: isByteArray = false;
089: ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
090: ObjectOutputStream objectOut = new ObjectOutputStream(
091: byteArray);
092: objectOut.writeObject(object);
093: objectBytes = byteArray.toByteArray();
094: objectOut.close();
095: }
096: } catch (IOException e) {
097: MessageFormatException mfe = new MessageFormatException(
098: "Object cannot be serialized: " + e.getMessage());
099: mfe.setLinkedException(e);
100: throw mfe;
101: }
102: }
103:
104: public Serializable getObject() throws JMSException {
105:
106: Serializable retVal = null;
107: try {
108: if (null != objectBytes) {
109: if (isByteArray) {
110: retVal = new byte[objectBytes.length];
111: System.arraycopy(objectBytes, 0, retVal, 0,
112: objectBytes.length);
113: } else {
114:
115: /**
116: * Default implementation ObjectInputStream does not work well
117: * when running an a micro kernal style app-server like JBoss.
118: * We need to look for the Class in the context class loader and
119: * not in the System classloader.
120: *
121: * Would this be done better by using a MarshaedObject??
122: */
123: class ObjectInputStreamExt extends
124: ObjectInputStream {
125: ObjectInputStreamExt(InputStream is)
126: throws IOException {
127: super (is);
128: }
129:
130: protected Class resolveClass(ObjectStreamClass v)
131: throws IOException,
132: ClassNotFoundException {
133: return Classes.loadClass(v.getName());
134: }
135: }
136: ObjectInputStream input = new ObjectInputStreamExt(
137: new ByteArrayInputStream(objectBytes));
138: retVal = (Serializable) input.readObject();
139: input.close();
140: }
141: }
142: } catch (ClassNotFoundException e) {
143: throw new MessageFormatException("ClassNotFoundException: "
144: + e.getMessage());
145: } catch (IOException e) {
146: throw new MessageFormatException("IOException: "
147: + e.getMessage());
148: }
149: return retVal;
150: }
151:
152: // SpyMessage overrides ------------------------------------------
153:
154: public void clearBody() throws JMSException {
155: objectBytes = null;
156: super .clearBody();
157: }
158:
159: public SpyMessage myClone() throws JMSException {
160: SpyObjectMessage result = MessagePool.getObjectMessage();
161: result.copyProps(this );
162: result.isByteArray = this .isByteArray;
163: if (objectBytes != null) {
164: result.objectBytes = new byte[this .objectBytes.length];
165: System.arraycopy(this .objectBytes, 0, result.objectBytes,
166: 0, this .objectBytes.length);
167: }
168: return result;
169: }
170:
171: // Externalizable implementation ---------------------------------
172:
173: public void writeExternal(ObjectOutput out) throws IOException {
174: super .writeExternal(out);
175: out.writeBoolean(isByteArray);
176: if (objectBytes == null) {
177: out.writeInt(-1);
178: } else {
179: out.writeInt(objectBytes.length);
180: out.write(objectBytes);
181: }
182: }
183:
184: public void readExternal(ObjectInput in) throws IOException,
185: ClassNotFoundException {
186: super .readExternal(in);
187: isByteArray = in.readBoolean();
188: int length = in.readInt();
189: if (length < 0) {
190: objectBytes = null;
191: } else {
192: objectBytes = new byte[length];
193: in.readFully(objectBytes);
194: }
195: }
196:
197: // Package protected ---------------------------------------------
198:
199: // Protected -----------------------------------------------------
200:
201: // Private -------------------------------------------------------
202:
203: // Inner classes -------------------------------------------------
204: }
|