/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. */
  28. package edu.vub.at.actors.natives;
  29. import edu.vub.at.actors.net.SerializationException;
  30. import edu.vub.at.exceptions.InterpreterException;
  31. import edu.vub.at.exceptions.XClassNotFound;
  32. import edu.vub.at.exceptions.XIOProblem;
  33. import edu.vub.at.objects.ATObject;
  34. import java.io.ByteArrayInputStream;
  35. import java.io.ByteArrayOutputStream;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.io.ObjectInputStream;
  39. import java.io.ObjectOutputStream;
  40. import java.io.ObjectStreamClass;
  41. import java.io.Serializable;
  42. /**
  43. * Packet instances are the serialized representation of AmbientTalk messages or other objects.
  44. * They are exchanged directly in between local actors and in a wrapped VMCommand object between
  45. * remote actors.
  46. *
  47. * @author tvcutsem
  48. */
  49. public class Packet implements Serializable {
  50. private final byte[] payload_;
  51. private final String description_;
  52. public Packet(String description, ATObject object) throws XIOProblem {
  53. description_ = description;
  54. try {
  55. payload_ = serialize(object);
  56. } catch (IOException e) {
  57. throw new XIOProblem(e);
  58. }
  59. }
  60. public Packet(ATObject object) throws XIOProblem {
  61. this(object.toString(), object);
  62. }
  63. public ATObject unpack() throws InterpreterException {
  64. try {
  65. return (ATObject) deserialize(payload_);
  66. } catch (SerializationException e) {
  67. throw e.getWrappedException();
  68. } catch (IOException e) {
  69. throw new XIOProblem(e);
  70. } catch (ClassNotFoundException e) {
  71. throw new XClassNotFound(e.getMessage(), e);
  72. }
  73. }
  74. /** deserialize this message, using a custom class loader to load the classes into the JVM */
  75. public ATObject unpackUsingClassLoader(ClassLoader cld) throws InterpreterException {
  76. try {
  77. return (ATObject) deserialize(payload_, cld);
  78. } catch (SerializationException e) {
  79. throw e.getWrappedException();
  80. } catch (IOException e) {
  81. throw new XIOProblem(e);
  82. } catch (ClassNotFoundException e) {
  83. throw new XClassNotFound(e.getMessage(), e);
  84. }
  85. }
  86. public boolean equals(Object other) {
  87. return ((other instanceof Packet) &&
  88. ((Packet) other).payload_.equals(payload_));
  89. }
  90. public int hashCode() { return payload_.hashCode(); }
  91. public String toString() { return "packet["+description_+"]"; }
  92. private static byte[] serialize(Object o) throws IOException {
  93. ByteArrayOutputStream out = new ByteArrayOutputStream();
  94. ObjectOutputStream stream = new ObjectOutputStream(out);
  95. stream.writeObject(o);
  96. stream.flush();
  97. stream.close();
  98. return out.toByteArray();
  99. }
  100. private static Object deserialize(byte[] b) throws IOException, ClassNotFoundException {
  101. ByteArrayInputStream in = new ByteArrayInputStream(b);
  102. ObjectInputStream instream = new ObjectInputStream(in);
  103. return instream.readObject();
  104. }
  105. /**
  106. * A dedicated subclass of {@link ObjectInputStream} that hooks into
  107. * that class's facility to define additional sources to look for classes
  108. * that are read from the input stream.
  109. */
  110. private static class HookedObjectInputStream extends ObjectInputStream {
  111. private final ClassLoader loader_;
  112. protected HookedObjectInputStream(ClassLoader cld, InputStream is) throws IOException, SecurityException {
  113. super(is);
  114. loader_ = cld;
  115. }
  116. protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
  117. return loader_.loadClass(desc.getName());
  118. }
  119. }
  120. // deserialize and use the given class loader to try and load any missing classes
  121. private static Object deserialize(byte[] b, ClassLoader cld) throws IOException, ClassNotFoundException {
  122. ByteArrayInputStream in = new ByteArrayInputStream(b);
  123. ObjectInputStream instream = new HookedObjectInputStream(cld, in);
  124. return instream.readObject();
  125. }
  126. }