PageRenderTime 41ms CodeModel.GetById 11ms app.highlight 22ms RepoModel.GetById 2ms app.codeStats 0ms

/interpreter/tags/at2dist090708/src/edu/vub/at/actors/natives/Packet.java

http://ambienttalk.googlecode.com/
Java | 143 lines | 85 code | 17 blank | 41 comment | 0 complexity | f0e28c5028c5b6946e9728344310cdfa MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * Packet.java created on 29-dec-2006 at 19:15:00
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.actors.natives;
 29
 30import edu.vub.at.actors.net.SerializationException;
 31import edu.vub.at.exceptions.InterpreterException;
 32import edu.vub.at.exceptions.XClassNotFound;
 33import edu.vub.at.exceptions.XIOProblem;
 34import edu.vub.at.objects.ATObject;
 35
 36import java.io.ByteArrayInputStream;
 37import java.io.ByteArrayOutputStream;
 38import java.io.IOException;
 39import java.io.InputStream;
 40import java.io.ObjectInputStream;
 41import java.io.ObjectOutputStream;
 42import java.io.ObjectStreamClass;
 43import java.io.Serializable;
 44
 45/**
 46 * Packet instances are the serialized representation of AmbientTalk messages or other objects.
 47 * They are exchanged directly in between local actors and in a wrapped VMCommand object between
 48 * remote actors.
 49 *
 50 * @author tvcutsem
 51 */
 52public class Packet implements Serializable {
 53	
 54	private final byte[]	payload_;
 55	private final String	description_;
 56
 57	public Packet(String description, ATObject object) throws XIOProblem {
 58		description_ = description;
 59		try {
 60			payload_ = serialize(object);
 61		} catch (IOException e) {
 62			throw new XIOProblem(e);
 63		}
 64	}
 65	
 66	public Packet(ATObject object) throws XIOProblem {
 67		this(object.toString(), object);
 68	}
 69	
 70	public ATObject unpack() throws InterpreterException {
 71		try {
 72			return (ATObject) deserialize(payload_);
 73        } catch (SerializationException e) {
 74          throw e.getWrappedException();
 75		} catch (IOException e) {
 76			throw new XIOProblem(e);
 77		} catch (ClassNotFoundException e) {
 78			throw new XClassNotFound(e.getMessage(), e);
 79		} 
 80	}
 81	
 82	/** deserialize this message, using a custom class loader to load the classes into the JVM */
 83	public ATObject unpackUsingClassLoader(ClassLoader cld) throws InterpreterException {
 84		try {
 85			return (ATObject) deserialize(payload_, cld);
 86        } catch (SerializationException e) {
 87          throw e.getWrappedException();
 88		} catch (IOException e) {
 89			throw new XIOProblem(e);
 90		} catch (ClassNotFoundException e) {
 91			throw new XClassNotFound(e.getMessage(), e);
 92		} 
 93	}
 94	
 95	public boolean equals(Object other) {
 96		return ((other instanceof Packet) &&
 97				((Packet) other).payload_.equals(payload_));
 98	}
 99	
100	public int hashCode() { return payload_.hashCode(); }
101	
102	public String toString() { return "packet["+description_+"]"; }
103	
104	private static byte[] serialize(Object o) throws IOException {
105		ByteArrayOutputStream out = new ByteArrayOutputStream();
106		ObjectOutputStream stream = new ObjectOutputStream(out);
107		stream.writeObject(o);
108		stream.flush();
109		stream.close();
110		return out.toByteArray();
111	}
112	
113	private static Object deserialize(byte[] b) throws IOException, ClassNotFoundException {
114		ByteArrayInputStream in = new ByteArrayInputStream(b);
115		ObjectInputStream instream = new ObjectInputStream(in);
116		return instream.readObject();
117	}
118	
119	/**
120	 * A dedicated subclass of {@link ObjectInputStream} that hooks into
121	 * that class's facility to define additional sources to look for classes
122	 * that are read from the input stream.
123	 */
124	private static class HookedObjectInputStream extends ObjectInputStream {
125		private final ClassLoader loader_;
126		protected HookedObjectInputStream(ClassLoader cld, InputStream is) throws IOException, SecurityException {
127			super(is);
128			loader_ = cld;
129		}
130
131		protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
132			return loader_.loadClass(desc.getName());
133		}
134	}
135	
136	// deserialize and use the given class loader to try and load any missing classes
137	private static Object deserialize(byte[] b, ClassLoader cld) throws IOException, ClassNotFoundException {
138		ByteArrayInputStream in = new ByteArrayInputStream(b);
139		ObjectInputStream instream = new HookedObjectInputStream(cld, in);
140		return instream.readObject();
141	}
142	
143}