Created the facilities for transmitting distributed objects and derived

classes over the wire (by inspecting their fields and sending those
directly).


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@8 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-05-30 00:16:00 +00:00
parent a523e71302
commit 9cd146a43c
14 changed files with 456 additions and 23 deletions
@@ -0,0 +1,113 @@
//
// $Id: Marshaller.java,v 1.1 2001/05/30 00:16:00 mdb Exp $
package com.samskivert.cocktail.cher.dobj.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Comparator;
import com.samskivert.cocktail.cher.Log;
import com.samskivert.cocktail.cher.dobj.DObject;
import com.samskivert.cocktail.cher.io.ObjectStreamException;
/**
* The marshaller inspects the class with which it is constructed and
* caches the reflection information it needs to marshall and unmarshall
* instances of that class.
*/
public class Marshaller
{
public Marshaller (Class clazz)
{
// we introspect on the class and cache the public data members
_fields = clazz.getFields();
// sort the fields so that they are written and read in the same
// order on all VMs
Arrays.sort(_fields, FIELD_COMP);
// now select field marshallers for each of the fields based on
// their type
_marshallers = new FieldMarshaller[_fields.length];
for (int i = 0; i < _fields.length; i++) {
_marshallers[i] =
FieldMarshallerRegistry.getMarshaller(_fields[i]);
// Log.info("Assigned [field=" + _fields[i] +
// ", marshaller=" + _marshallers[i] + "].");
}
}
/**
* Writes out all of the fields of the specified distributed object to
* the supplied data output stream.
*/
public void writeTo (DataOutputStream out, DObject dobj)
throws IOException
{
// we simply iterate over our marshallers, writing each field
// out in succession
for (int i = 0; i < _fields.length; i++) {
try {
_marshallers[i].writeTo(out, _fields[i], dobj);
} catch (IllegalAccessException iae) {
// this shouldn't happen because we only attempt to marshall
// public fields, but we'll pass it on none the less
String errmsg = "Unable to marshall dobj field " +
"[field=" + _fields[i].getName() +
", dobj=" + dobj + "].";
throw new ObjectStreamException(errmsg);
}
}
}
/**
* Reads in all of the fields of the specified distributed object from
* the supplied data input stream.
*/
public void readFrom (DataInputStream in, DObject dobj)
throws IOException
{
// we simply iterate over our marshallers, reading each field in
// in succession
for (int i = 0; i < _fields.length; i++) {
try {
_marshallers[i].readFrom(in, _fields[i], dobj);
} catch (IllegalAccessException iae) {
// this shouldn't happen because we only attempt to
// unmarshall public fields, but we'll pass it on anyway
String errmsg = "Unable to unmarshall dobj field " +
"[field=" + _fields[i].getName() +
", dobj=" + dobj + "].";
throw new ObjectStreamException(errmsg);
}
}
}
/**
* Used to sort object fields into a predictable order.
*/
protected static class FieldComparator implements Comparator
{
public int compare (Object o1, Object o2)
{
return ((Field)o1).getName().compareTo(((Field)o2).getName());
}
public boolean equals (Object obj)
{
// we don't care about comparing this comparator to others
return obj == this;
}
}
protected Field[] _fields;
protected FieldMarshaller[] _marshallers;
/** We use this to sort the fields into a predictable order. */
protected static final FieldComparator FIELD_COMP = new FieldComparator();
}