// // $Id: FieldMarshallerRegistry.java,v 1.16 2002/07/17 23:05:28 mdb Exp $ package com.threerings.presents.io; import java.lang.reflect.Field; import java.util.Hashtable; import com.threerings.presents.Log; import com.threerings.presents.io.Streamable; /** * Field marshaller instances are registered for each type of field that * is supported in a distributed object. */ public class FieldMarshallerRegistry { /** * Returns a field marshaller that can marshall and unmarshall the * specified type of field. If no marshaller is registered for that * field type, an illegal argument exception will be thrown. * Distributed objects must not contain fields that cannot be * transmitted on the wire. */ public static FieldMarshaller getMarshaller (Field field) { Class clazz = field.getType(); FieldMarshaller marsh = (FieldMarshaller)_registry.get(clazz); // if we don't have a marshaller registered for this specific // class, see if the class is an instance of streamable in which // case we stick the streamable marshaller into the registry for // this class if (marsh == null) { if (Streamable.class.isAssignableFrom(clazz)) { marsh = _streamableMarsh; _registry.put(clazz, marsh); } else if (STREAMARRAY_CLASS.isAssignableFrom(clazz)) { marsh = _streamarrayMarsh; _registry.put(clazz, marsh); } } // if we still don't have a marshaller, we're out of luck if (marsh == null) { String errmsg = "No field marshaller registered for fields " + "of type " + clazz.getName() + "."; throw new IllegalArgumentException(errmsg); } return marsh; } /** * Registers the specified field marshaller as the one to use for * fields of the specified class. This assumes that the field * marshaller implementation provides a prototype field of the type it * knows how to marshall by the name of prototype. * * @param clazz the field marshaller class to be registered. */ protected static void registerMarshaller (Class clazz) { try { FieldMarshaller fm = (FieldMarshaller)clazz.newInstance(); _registry.put(fm.getFieldType(), fm); } catch (Exception e) { Log.warning("Unable to register field marshaller " + "[class=" + clazz.getName() + "]."); Log.logStackTrace(e); } } /** A mapping of classes to marshallers. */ protected static Hashtable _registry = new Hashtable(); /** Used for marshalling instances of {@link Streamable}. */ protected static FieldMarshaller _streamableMarsh = new StreamableFieldMarshaller(); /** Used for marshalling arrays of {@link Streamable}. */ protected static FieldMarshaller _streamarrayMarsh = new StreamableArrayFieldMarshaller(); /** Used to identify streamable array instances. */ protected static final Class STREAMARRAY_CLASS = (new Streamable[0]).getClass(); static { // register our field marshallers registerMarshaller(BooleanFieldMarshaller.class); registerMarshaller(ByteFieldMarshaller.class); registerMarshaller(ShortFieldMarshaller.class); registerMarshaller(IntFieldMarshaller.class); registerMarshaller(IntegerFieldMarshaller.class); registerMarshaller(LongFieldMarshaller.class); registerMarshaller(FloatFieldMarshaller.class); registerMarshaller(DoubleFieldMarshaller.class); registerMarshaller(StringFieldMarshaller.class); registerMarshaller(ByteArrayFieldMarshaller.class); registerMarshaller(IntArrayFieldMarshaller.class); registerMarshaller(StringArrayFieldMarshaller.class); registerMarshaller(OidListFieldMarshaller.class); registerMarshaller(DSetFieldMarshaller.class); } }