1 Reply Latest reply on Mar 12, 2007 4:28 PM by bldrbldr

    enum serialization

    bldrbldr
      Has anyone ever tried to use the RemoteClass metatag for serializing between Java and AS3 implementations of an enum? The guide gives a good example of how to fake an enum in AS3, but I'm assuming I would have to develop custom serialization for enums. True?
        • 1. enum serialization
          bldrbldr Level 1
          Here's the best way to serialize an enum I can think of. Here's an example of an AS3 enum:

          public class MyEnum {
          public static var APPLES:MyEnum = new MyEnum("APPLES");
          public static var ORANGES:MyEnum = new MyEnum("ORANGES");

          private var name:String;

          public function MyEnum(str:String) {
          name = str;
          }

          public function toString() {
          return name;
          }
          }

          Unfortunately, implementing the IExternalizable interface for the enum class is pretty much useless. By the time readExternal() is called on your AS3 enum object, it has already been created and you have no hope of limiting the instances of your enum class to those defined as static members. AS3 serialization does not allow a class to define how it is created, only how it populates it's own fields after it has been created, which happens mysteriously at the top of the call stack for the main thead.

          Without any way of controlling the creation of the enum object such as registering a Factory or implementing readResolve() as in Java, you have to implement IExternalizable in an enclosing class such as:

          public class MyEnclosure implements IExternalizable {
          var myEnum:MyEnum;

          public function readExternal(input:IDataInput):void {
          myEnum = MyEnum[input.readUTF()];
          }

          public function writeExternal(output:IDataOutput):void {
          output.writeUTF(myEnum.toString());
          }
          }

          Of course, the Java implementation must have an analogous implementation for IExternalizable. If your Java class does not implement IExternalizable, your AS3 readExternal() method will not be called, even though the standard Java enum serialization format is just fine for our purposes.

          Worse, if your enum is a member of multiple enclosing value objects, you have to externalize the serialization for all of these classes.

          Even worse, the default AS3 deserialization (unfortunately) does something for a Java enum when the IExternalizable interface is not implemented. It creates a new instance of your enum, and apparently throws away the "name" that is included in the Java serialization stream.

          Why?? At the Flex framework level, implementing serialization using a scheme I have defined here would be trivial. However, if that gets implmented now it would break backward compatibility. The only options for framework support of deserialization of enums would be to formally introduce enums into the language (not happening), or to create a [RemoteEnum] metatag that would enforce the semantics I describe, or to offer something analogous to the Java readResolve() method.

          The upshot is that every class that aggregates an enum, must implement IExternalizable, instead of the more intuitive approach of implementing IExternalizable for the enum class itself.

          For completeness, here is the Java implementation of the enclosing class:

          public class MyEnclosure implements IExternalizable {
          private MyEnum myEnum;

          public void writeExternal(ObjectOutput output) throws IOException {
          output.writeUTF(myEnum.name());
          }

          public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
          myEnum = Enum.valueOf(MyEnum.class, input.readUTF());
          }
          }