From d9089e10d3804919565c4ee60c9f8b109947ce5e Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Mon, 12 Feb 2007 03:03:51 +0000 Subject: [PATCH] Widening, one additional log message added in STREAM_DEBUG mode. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4558 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/io/BasicStreamers.java | 131 ++++------ .../com/threerings/io/FieldMarshaller.java | 112 ++++----- .../com/threerings/io/ObjectInputStream.java | 16 +- src/java/com/threerings/io/Streamer.java | 228 ++++++++---------- 4 files changed, 189 insertions(+), 298 deletions(-) diff --git a/src/java/com/threerings/io/BasicStreamers.java b/src/java/com/threerings/io/BasicStreamers.java index 9a7beebe4..35d2d00aa 100644 --- a/src/java/com/threerings/io/BasicStreamers.java +++ b/src/java/com/threerings/io/BasicStreamers.java @@ -93,16 +93,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeBoolean(((Boolean)object).booleanValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -120,16 +118,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeByte(((Byte)object).byteValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -147,16 +143,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeShort(((Short)object).shortValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -167,23 +161,20 @@ public class BasicStreamers public static class CharacterStreamer extends Streamer { // documentation inherited - public Object createObject (ObjectInputStream in) - throws IOException + public Object createObject (ObjectInputStream in)throws IOException { return Character.valueOf(in.readChar()); } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeChar(((Character)object).charValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -201,16 +192,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeInt(((Integer)object).intValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -228,16 +217,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeLong(((Long)object).longValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -255,16 +242,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeFloat(((Float)object).floatValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -282,16 +267,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeDouble(((Double)object).doubleValue()); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -309,16 +292,14 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { out.writeUTF((String)object); } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // nothing to do here @@ -336,8 +317,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { boolean[] value = (boolean[])object; @@ -349,8 +329,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { boolean[] value = (boolean[])object; @@ -372,8 +351,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { byte[] value = (byte[])object; @@ -383,8 +361,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { byte[] value = (byte[])object; @@ -411,8 +388,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { short[] value = (short[])object; @@ -424,8 +400,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { short[] value = (short[])object; @@ -447,8 +422,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { char[] value = (char[])object; @@ -460,8 +434,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { char[] value = (char[])object; @@ -483,8 +456,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { int[] value = (int[])object; @@ -496,8 +468,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { int[] value = (int[])object; @@ -519,8 +490,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { long[] value = (long[])object; @@ -532,8 +502,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { long[] value = (long[])object; @@ -555,8 +524,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { float[] value = (float[])object; @@ -568,8 +536,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { float[] value = (float[])object; @@ -591,8 +558,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { double[] value = (double[])object; @@ -604,8 +570,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { double[] value = (double[])object; @@ -627,8 +592,7 @@ public class BasicStreamers } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { Object[] value = (Object[])object; @@ -640,8 +604,7 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { Object[] value = (Object[])object; @@ -660,17 +623,15 @@ public class BasicStreamers throws IOException { return new ArrayList(0); // minimally sized - // (We thought about using a ThreadLocal to assist here... - // we could read the length of the list here and construct - // the ArrayList with the right size, and then read the - // length out of the ThreadLocal down in readObject(). Instead, - // we simply create a 0-length list here, which generates - // minimal garbage when we ensureCapacity() down in readObject.) + // (We thought about using a ThreadLocal to assist here... we could read the length of + // the list here and construct the ArrayList with the right size, and then read the + // length out of the ThreadLocal down in readObject(). Instead, we simply create a + // 0-length list here, which generates minimal garbage when we ensureCapacity() down in + // readObject.) } // documentation inherited - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { List list = (List)object; @@ -690,12 +651,10 @@ public class BasicStreamers } // documentation inherited - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { - @SuppressWarnings("unchecked") ArrayList value = - (ArrayList)object; + @SuppressWarnings("unchecked") ArrayList value = (ArrayList)object; int ecount = in.readInt(); value.ensureCapacity(ecount); // resize the array once for (int ii = 0; ii < ecount; ii++) { diff --git a/src/java/com/threerings/io/FieldMarshaller.java b/src/java/com/threerings/io/FieldMarshaller.java index 88315712e..19b8efcdb 100644 --- a/src/java/com/threerings/io/FieldMarshaller.java +++ b/src/java/com/threerings/io/FieldMarshaller.java @@ -31,23 +31,21 @@ import java.util.HashMap; public abstract class FieldMarshaller { /** - * Reads the contents of the supplied field from the supplied stream - * and sets it in the supplied object. + * Reads the contents of the supplied field from the supplied stream and sets it in the + * supplied object. */ - public abstract void readField ( - Field field, Object target, ObjectInputStream in) throws Exception; + public abstract void readField (Field field, Object target, ObjectInputStream in) + throws Exception; /** - * Writes the contents of the supplied field in the supplied object to - * the supplied stream. + * Writes the contents of the supplied field in the supplied object to the supplied stream. */ - public abstract void writeField ( - Field field, Object source, ObjectOutputStream out) throws Exception; + public abstract void writeField (Field field, Object source, ObjectOutputStream out) + throws Exception; /** - * Returns a field marshaller appropriate for the supplied field or - * null if no marshaller exists for the type contained by the field in - * question. + * Returns a field marshaller appropriate for the supplied field or null if no marshaller + * exists for the type contained by the field in question. */ public static FieldMarshaller getFieldMarshaller (Field field) { @@ -64,8 +62,7 @@ public abstract class FieldMarshaller // if we have an exact match, use that FieldMarshaller fm = _marshallers.get(ftype); - // otherwise if the class is a streamable, use the streamable - // marshaller + // otherwise if the class is a streamable, use the streamable marshaller if (fm == null && Streamer.isStreamable(ftype)) { fm = _marshallers.get(Streamable.class); } @@ -74,8 +71,7 @@ public abstract class FieldMarshaller } /** - * Used to marshall and unmarshall classes for which we have a basic - * {@link Streamer}. + * Used to marshall and unmarshall classes for which we have a basic {@link Streamer}. */ protected static class StreamerMarshaller extends FieldMarshaller { @@ -85,8 +81,7 @@ public abstract class FieldMarshaller } // documentation inherited - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { if (in.readBoolean()) { @@ -99,8 +94,7 @@ public abstract class FieldMarshaller } // documentation inherited - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { Object value = field.get(source); @@ -117,9 +111,8 @@ public abstract class FieldMarshaller } /** - * Creates instances of all known field marshaller types and populates - * the {@link #_marshallers} table with them. This is called the first - * time a marshaller is requested. + * Creates instances of all known field marshaller types and populates the {@link + * #_marshallers} table with them. This is called the first time a marshaller is requested. */ protected static void createMarshallers () { @@ -128,132 +121,111 @@ public abstract class FieldMarshaller // create a generic marshaller for streamable instances FieldMarshaller gmarsh = new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { + System.err.println("Reading generic"); field.set(target, in.readObject()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeObject(field.get(source)); } }; _marshallers.put(Streamable.class, gmarsh); - // use the same generic marshaller for fields declared to by type - // Object or Object[] with the expectation that they will contain - // only primitive types or Streamables; the runtime will fail - // informatively if the user attempts to store non-Streamable - // objects in that field + // use the same generic marshaller for fields declared to by type Object or Object[] with + // the expectation that they will contain only primitive types or Streamables; the runtime + // will fail informatively if we attempt to store non-Streamable objects in that field _marshallers.put(Object.class, gmarsh); _marshallers.put(Object[].class, gmarsh); // create marshallers for the primitive types _marshallers.put(Boolean.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setBoolean(target, in.readBoolean()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeBoolean(field.getBoolean(source)); } }); _marshallers.put(Byte.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setByte(target, in.readByte()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeByte(field.getByte(source)); } }); _marshallers.put(Character.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setChar(target, in.readChar()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeChar(field.getChar(source)); } }); _marshallers.put(Short.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setShort(target, in.readShort()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeShort(field.getShort(source)); } }); _marshallers.put(Integer.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setInt(target, in.readInt()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeInt(field.getInt(source)); } }); _marshallers.put(Long.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setLong(target, in.readLong()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeLong(field.getLong(source)); } }); _marshallers.put(Float.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setFloat(target, in.readFloat()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeFloat(field.getFloat(source)); } }); _marshallers.put(Double.TYPE, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.setDouble(target, in.readDouble()); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeDouble(field.getDouble(source)); } }); _marshallers.put(Date.class, new FieldMarshaller() { - public void readField ( - Field field, Object target, ObjectInputStream in) + public void readField (Field field, Object target, ObjectInputStream in) throws Exception { field.set(target, new Date(in.readLong())); } - public void writeField ( - Field field, Object source, ObjectOutputStream out) + public void writeField (Field field, Object source, ObjectOutputStream out) throws Exception { out.writeLong(((Date)field.get(source)).getTime()); } @@ -263,12 +235,10 @@ public abstract class FieldMarshaller int bscount = BasicStreamers.BSTREAMER_TYPES.length; for (int ii = 0; ii < bscount; ii++) { _marshallers.put(BasicStreamers.BSTREAMER_TYPES[ii], - new StreamerMarshaller( - BasicStreamers.BSTREAMER_INSTANCES[ii])); + new StreamerMarshaller(BasicStreamers.BSTREAMER_INSTANCES[ii])); } } - /** Contains a mapping from field type to field marshaller instance - * for that type. */ + /** Contains a mapping from field type to field marshaller instance for that type. */ protected static HashMap _marshallers; } diff --git a/src/java/com/threerings/io/ObjectInputStream.java b/src/java/com/threerings/io/ObjectInputStream.java index e1a27db63..c31d65e4d 100644 --- a/src/java/com/threerings/io/ObjectInputStream.java +++ b/src/java/com/threerings/io/ObjectInputStream.java @@ -141,26 +141,28 @@ public class ObjectInputStream extends DataInputStream // sanity check if (cmap == null) { // this will help with debugging - log.warning("Internal stream error, no class metadata " + - "[code=" + code + ", ois=" + this + "]."); + log.warning("Internal stream error, no class metadata [code=" + code + + ", ois=" + this + "]."); Thread.dumpStack(); - log.warning("ObjectInputStream mappings " + - StringUtil.toString(_classmap) + - "."); + log.warning( + "ObjectInputStream mappings " + StringUtil.toString(_classmap) + "."); String errmsg = "Read object code for which we " + "have no registered class metadata [code=" + code + "]"; throw new RuntimeException(errmsg); } } + if (STREAM_DEBUG) { + log.info(hashCode() + ": Reading with " + cmap.streamer + "."); + } + // create an instance of the appropriate object Object target = cmap.streamer.createObject(this); readBareObject(target, cmap.streamer, true); return target; } catch (OutOfMemoryError oome) { - throw (IOException) - new IOException("Malformed object data").initCause(oome); + throw (IOException)new IOException("Malformed object data").initCause(oome); } } diff --git a/src/java/com/threerings/io/Streamer.java b/src/java/com/threerings/io/Streamer.java index 775afaee3..4d3965cea 100644 --- a/src/java/com/threerings/io/Streamer.java +++ b/src/java/com/threerings/io/Streamer.java @@ -43,18 +43,16 @@ import com.samskivert.util.StringUtil; import static com.threerings.NaryaLog.log; /** - * Handles the streaming of {@link Streamable} instances as well as a set - * of basic object types (see {@link ObjectOutputStream}). An instance of - * {@link Streamer} is created for each distinct class that implements - * {@link Streamable}. The {@link Streamer} reflects on the streamed class - * and caches the information necessary to efficiently read and write - * objects of the class in question. + * Handles the streaming of {@link Streamable} instances as well as a set of basic object types + * (see {@link ObjectOutputStream}). An instance of {@link Streamer} is created for each distinct + * class that implements {@link Streamable}. The {@link Streamer} reflects on the streamed class + * and caches the information necessary to efficiently read and write objects of the class in + * question. */ public class Streamer { /** - * Returns true if the supplied target class can be streamed using a - * streamer. + * Returns true if the supplied target class can be streamed using a streamer. */ public synchronized static boolean isStreamable (Class target) { @@ -74,17 +72,15 @@ public class Streamer return Streamable.class.isAssignableFrom(target); } - // otherwise extract the component type and loop back around for - // another check... + // otherwise extract the component type and loop back around for another check... target = target.getComponentType(); } } /** - * Returns the class that should be used when streaming this object. In - * general that is the object's natural class, but for enum values, that - * might be its declaring class as enums use classes in a way that would - * otherwise pollute our id to class mapping space. + * Returns the class that should be used when streaming this object. In general that is the + * object's natural class, but for enum values, that might be its declaring class as enums use + * classes in a way that would otherwise pollute our id to class mapping space. */ public static Class getStreamerClass (Object object) { @@ -93,18 +89,16 @@ public class Streamer } /** - * Obtains a {@link Streamer} that can be used to read and write - * objects of the specified target class. {@link Streamer} instances - * are shared among all {@link ObjectInputStream}s and {@link - * ObjectOutputStream}s. + * Obtains a {@link Streamer} that can be used to read and write objects of the specified + * target class. {@link Streamer} instances are shared among all {@link ObjectInputStream}s and + * {@link ObjectOutputStream}s. * - * @param target the class that is desired to be streamed. This should be - * the result of a call to {@link #getStreamerClass} if the caller has an - * instance they wish to stream. + * @param target the class that is desired to be streamed. This should be the result of a call + * to {@link #getStreamerClass} if the caller has an instance they wish to stream. * - * @throws IOException when a streamer is requested for an object that - * does not implement {@link Streamable} and is not one of the basic - * object types (@see {@link ObjectOutputStream}). + * @throws IOException when a streamer is requested for an object that does not implement + * {@link Streamable} and is not one of the basic object types (@see {@link + * ObjectOutputStream}). */ public synchronized static Streamer getStreamer (final Class target) throws IOException @@ -128,15 +122,14 @@ public class Streamer log.info("Creating a streamer for '" + target.getName() + "'."); } - // create our streamer in a privileged block so that it can - // introspect on the to be streamed class + // create our streamer in a privileged block so that it can introspect on the to be + // streamed class try { - stream = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Streamer run () throws IOException { - return new Streamer(target); - } - }); + stream = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Streamer run () throws IOException { + return new Streamer(target); + } + }); } catch (PrivilegedActionException pae) { throw (IOException) pae.getCause(); } @@ -150,19 +143,16 @@ public class Streamer * * @param object the instance to be written to the stream. * @param out the stream to which to write the instance. - * @param useWriter whether or not to use the custom - * writeObject if one exists. + * @param useWriter whether or not to use the custom writeObject if one exists. */ - public void writeObject ( - Object object, ObjectOutputStream out, boolean useWriter) + public void writeObject (Object object, ObjectOutputStream out, boolean useWriter) throws IOException { // if we're supposed to and one exists, use the writer method if (useWriter && _writer != null) { try { if (ObjectInputStream.STREAM_DEBUG) { - log.info("Writing with writer " + - "[class=" + _target.getName() + "]."); + log.info("Writing with writer [class=" + _target.getName() + "]."); } _writer.invoke(object, new Object[] { out }); @@ -184,13 +174,12 @@ public class Streamer if (_target.isArray()) { int length = Array.getLength(object); out.writeInt(length); - // if the component class is final, we can be sure that all - // instances in the array will be of the same class and thus - // can serialize things more efficiently + + // if the component class is final, we can be sure that all instances in the array will + // be of the same class and thus can serialize things more efficiently int cmods = _target.getComponentType().getModifiers(); - if ((cmods & Modifier.FINAL) != 0) { - // compute a mask indicating which elements are null and - // which are populated + if (Modifier.isFinal(cmods)) { + // compute a mask indicating which elements are null and which are populated ArrayMask mask = new ArrayMask(length); for (int ii = 0; ii < length; ii++) { if (Array.get(object, ii) != null) { @@ -199,6 +188,7 @@ public class Streamer } // write that mask out to the stream mask.writeTo(out); + // now write out the populated elements for (int ii = 0; ii < length; ii++) { Object element = Array.get(object, ii); @@ -208,9 +198,8 @@ public class Streamer } } else { - // otherwise we've got to write each array element with - // its own class identifier because it could be any - // derived class of the array element type + // otherwise we've got to write each array element with its own class identifier + // because it could be any derived class of the array element type for (int ii = 0; ii < length; ii++) { out.writeObject(Array.get(object, ii)); } @@ -218,9 +207,9 @@ public class Streamer return; } - // if we're writing an enum; write its string value (to avoid future - // compatibility issues if someone serializes an enum to a file and - // then adds a value to the enum, changing the ordinal assignments) + // if we're writing an enum; write its string value (to avoid future compatibility issues + // if someone serializes an enum to a file and then adds a value to the enum, changing the + // ordinal assignments) if (_target.isEnum()) { out.writeUTF(((Enum)object).name()); return; @@ -232,10 +221,8 @@ public class Streamer Field field = _fields[ii]; FieldMarshaller fm = _marshallers[ii]; if (fm == null) { - String errmsg = "Unable to marshall field " + - "[class=" + _target.getName() + - ", field=" + field.getName() + - ", type=" + field.getType().getName() + "]"; + String errmsg = "Unable to marshall field [class=" + _target.getName() + + ", field=" + field.getName() + ", type=" + field.getType().getName() + "]"; throw new IOException(errmsg); } try { @@ -245,8 +232,7 @@ public class Streamer } fm.writeField(field, object, out); } catch (Exception e) { - String errmsg = "Failure writing streamable field " + - "[class=" + _target.getName() + + String errmsg = "Failure writing streamable field [class=" + _target.getName() + ", field=" + field.getName() + "]"; throw (IOException) new IOException(errmsg).initCause(e); } @@ -254,75 +240,63 @@ public class Streamer } /** - * Creates a blank object that can subsequently be read by this - * streamer. Data may be read from the input stream as a result of - * this method (in the case of arrays, the length of the array must be - * read before creating the array). + * Creates a blank object that can subsequently be read by this streamer. Data may be read + * from the input stream as a result of this method (in the case of arrays, the length of the + * array must be read before creating the array). */ public Object createObject (ObjectInputStream in) throws IOException { try { - // if our target class is an array type, read in the element - // count and create an array instance of the appropriate type - // and size + // if our target class is an array type, read in the element count and create an array + // instance of the appropriate type and size if (_target.isArray()) { int length = in.readInt(); if (ObjectInputStream.STREAM_DEBUG) { log.info(in.hashCode() + ": Creating array '" + - _target.getComponentType().getName() + - "[" + length + "]'."); + _target.getComponentType().getName() + "[" + length + "]'."); } return Array.newInstance(_target.getComponentType(), length); } else if (_target.isEnum()) { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + ": Creating enum '" + - _target.getName() + "'."); + log.info(in.hashCode() + ": Creating enum '" + _target.getName() + "'."); } - @SuppressWarnings("unchecked") Object value = - Enum.valueOf(_target, in.readUTF()); + @SuppressWarnings("unchecked") Object value = Enum.valueOf(_target, in.readUTF()); return value; } else { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + ": Creating object '" + - _target.getName() + "'."); + log.info(in.hashCode() + ": Creating object '" + _target.getName() + "'."); } return _target.newInstance(); } } catch (InstantiationException ie) { - String errmsg = "Error instantiating object " + - "[type=" + _target.getName() + "]"; + String errmsg = "Error instantiating object [type=" + _target.getName() + "]"; throw (IOException) new IOException(errmsg).initCause(ie); } catch (IllegalAccessException iae) { - String errmsg = "Error instantiating object " + - "[type=" + _target.getName() + "]"; + String errmsg = "Error instantiating object [type=" + _target.getName() + "]"; throw (IOException) new IOException(errmsg).initCause(iae); } } /** - * Reads and populates the fields of the supplied object from the - * specified stream. + * Reads and populates the fields of the supplied object from the specified stream. * * @param object the instance to be read from the stream. * @param in the stream from which to read the instance. - * @param useReader whether or not to use the custom - * readObject if one exists. + * @param useReader whether or not to use the custom readObject if one exists. */ - public void readObject ( - Object object, ObjectInputStream in, boolean useReader) + public void readObject (Object object, ObjectInputStream in, boolean useReader) throws IOException, ClassNotFoundException { // if we're supposed to and one exists, use the reader method if (useReader && _reader != null) { try { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + ": Reading with reader '" + - _target.getName() + "." + + log.info(in.hashCode() + ": Reading with reader '" + _target.getName() + "." + _reader.getName() + "()'."); } _reader.invoke(object, new Object[] { in }); @@ -348,28 +322,24 @@ public class Streamer // if we're reading in an array, do some special business if (_target.isArray()) { int length = Array.getLength(object); - // if the component class is final, we can be sure that all - // instances in the array will be of the same class and thus - // have serialized things more efficiently + // if the component class is final, we can be sure that all instances in the array will + // be of the same class and thus have serialized things more efficiently int cmods = _target.getComponentType().getModifiers(); - if ((cmods & Modifier.FINAL) != 0) { + if (Modifier.isFinal(cmods)) { // read in the nullness mask ArrayMask mask = new ArrayMask(); mask.readFrom(in); - // now read in the array elements given that we know which - // elements to read + // now read in the array elements given that we know which elements to read for (int ii = 0; ii < length; ii++) { if (mask.isSet(ii)) { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + - ": Reading fixed element '" + ii + "'."); + log.info(in.hashCode() + ": Reading fixed element '" + ii + "'."); } Object element = _delegate.createObject(in); in.readBareObject(element, _delegate, useReader); Array.set(object, ii, element); } else if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + - ": Skipping null element '" + ii + "'."); + log.info(in.hashCode() + ": Skipping null element '" + ii + "'."); } } @@ -377,8 +347,7 @@ public class Streamer // otherwise we had to write each object out individually for (int ii = 0; ii < length; ii++) { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + - ": Reading free element '" + ii + "'."); + log.info(in.hashCode() + ": Reading free element '" + ii + "'."); } Array.set(object, ii, in.readObject()); } @@ -397,31 +366,27 @@ public class Streamer Field field = _fields[ii]; FieldMarshaller fm = _marshallers[ii]; if (fm == null) { - String errmsg = "Unable to marshall field " + - "[class=" + _target.getName() + - ", field=" + field.getName() + - ", type=" + field.getType().getName() + "]"; + String errmsg = "Unable to marshall field [class=" + _target.getName() + + ", field=" + field.getName() + ", type=" + field.getType().getName() + "]"; throw new IOException(errmsg); } try { if (ObjectInputStream.STREAM_DEBUG) { - log.info(in.hashCode() + - ": Reading field '" + field.getName() + "'."); + log.info(in.hashCode() + ": Reading field '" + field.getName() + "'."); } - // gracefully deal with objects that have had new fields - // added to their class definition + // gracefully deal with objects that have had new fields added to their class + // definition if (in.available() > 0) { + log.info("Using " + fm); fm.readField(field, object, in); } else { - log.info("Streamed instance missing field (probably " + - "newly added) [class=" + _target.getName() + - ", field=" + field.getName() + "]."); + log.info("Streamed instance missing field (probably newly added) " + + "[class=" + _target.getName() + ", field=" + field.getName() + "]."); } } catch (Exception e) { - String errmsg = "Failure reading streamable field " + - "[class=" + _target.getName() + - ", field=" + field.getName() + - ", error=" + e + "]"; + e.printStackTrace(System.err); + String errmsg = "Failure reading streamable field [class=" + _target.getName() + + ", field=" + field.getName() + ", error=" + e + "]"; throw (IOException) new IOException(errmsg).initCause(e); } } @@ -436,9 +401,10 @@ public class Streamer */ public String toString () { - return "[target=" + _target.getName() + ", delegate=" + _delegate + - ", fcount=" + _fields.length + ", reader=" + _reader + - ", writer=" + _writer + "]"; + return (_target == null) ? getClass().getName() : + "[target=" + _target.getName() + ", delegate=" + _delegate + + ", fcount=" + (_fields == null ? 0 : _fields.length) + + ", reader=" + _reader + ", writer=" + _writer + "]"; } /** @@ -457,15 +423,14 @@ public class Streamer // keep a handle on the class _target = target; - // if our target class is an array, we want to get a handle on a - // streamer delegate that we'll use to stream our elements + // if our target class is an array, we want to get a handle on a streamer delegate that + // we'll use to stream our elements if (_target.isArray()) { _delegate = Streamer.getStreamer(_target.getComponentType()); // sanity check if (_delegate == null) { - String errmsg = "Aiya! Streamer created for array type " + - "but we have no registered streamer for the element " + - "type [type=" + _target.getName() + "]"; + String errmsg = "Aiya! Streamer created for array type but we have no registered " + + "streamer for the element type [type=" + _target.getName() + "]"; throw new RuntimeException(errmsg); } // and that's all we'll need @@ -481,8 +446,8 @@ public class Streamer for (int ii = 0; ii < fcount; ii++) { _marshallers[ii] = FieldMarshaller.getFieldMarshaller(_fields[ii]); if (ObjectInputStream.STREAM_DEBUG) { - log.info("Using " + _marshallers[ii] + " for " + - _target.getName() + "." + _fields[ii].getName() + "."); + log.info("Using " + _marshallers[ii] + " for " + _target.getName() + "." + + _fields[ii].getName() + "."); } } @@ -500,8 +465,7 @@ public class Streamer } /** - * Creates our streamers table and registers streamers for all of the - * basic types. + * Creates our streamers table and registers streamers for all of the basic types. */ protected static void createStreamers () { @@ -518,28 +482,24 @@ public class Streamer /** The class for which this streamer instance is configured. */ protected Class _target; - /** If our target class is an array, this is a reference to a streamer - * that can stream our array elements, otherwise it is null. */ + /** If our target class is an array, this is a reference to a streamer that can stream our + * array elements, otherwise it is null. */ protected Streamer _delegate; - /** The non-transient, non-static public fields that we will stream - * when requested. */ + /** The non-transient, non-static public fields that we will stream when requested. */ protected Field[] _fields; - /** Field marshallers for each field that will be read or written in - * our objects. */ + /** Field marshallers for each field that will be read or written in our objects. */ protected FieldMarshaller[] _marshallers; - /** A reference to the readObject method if one is - * defined by our target class. */ + /** A reference to the readObject method if one is defined by our target class. */ protected Method _reader; - /** A reference to the writeObject method if one is - * defined by our target class. */ + /** A reference to the writeObject method if one is defined by our target + * class. */ protected Method _writer; - /** Contains the mapping from class names to configured streamer - * instances. */ + /** Contains the mapping from class names to configured streamer instances. */ protected static HashMap _streamers; /** The name of the custom reader method. */