« Securing your Solr server on Tomcat | Main | Styling ItemRenderers in Datagrids »

Automatic serialization of ActionScript objects to and from XML

In Flex application that use a backend server for data manipulation and storage, serializing and transferring the objects from a layer to another is an important matter. With products such as BlazeDS and LiveCycle Data Services this step is almost hidden to the developer, that can fully benefit from the AMF transfer and automatic serialization of objects.
Sometimes it is not possible to use AMF and remoting and we have to rely on XML or JSON for transporting the objects. In this cases an automatic serialization from XML to ActionScript and viceversa would come in handy. Suppose we have a JavaEE backend server, that has some model classes that are exported in a custom XML. What follows also applies to JSON.
The first idea would be to get the incoming XML, use the describeType() function and parse its output, cycle through the properties and assign them to a certain ActionScript object. The same could be achieved by directly parsing the incoming XML or by using the for..in construct. The generated ActionScript objects would, however, be typeless and thus the necessity to place in the incoming XML data some hint regarding the type of object that needs to be created.
At this point we can use registerClassAlias() in flex or, more comfortably, the metadata [RemoteClass(alias="")] on top of each of the ActionScript domain classes. The AS classes will be, in this case, identical to the ones used with the remoting functionality, providing a decoupled way of serializing ActionScript objects.
The last step is building the converter class, that receives in input an XML and returns a strongly typed ActionScript object; this class will make use of getClassByAlias() to create the proper classes and fill them with the correct parameters.

Considering the case in which the Java server has a class Persona, with two properties nome and cognome, it can be exported into an XML that is similar to the following:

<?xml version="1.0" encoding="utf-8"?>
<object>
<nome>nome</nome>
<cognome>cognome</cognome>
<metadata>
<type>com.comtaste.model.Persona</type>
</metadata>
</object>

Note that we need a few naming conventions, such as the name of the root tag (in this example object) and an extra XML attribute, the metadata, which contains information about the identity of our remote object.

The target ActionScript class will simply be as if we were using it with remoting:

[RemoteClass(alias="com.comtaste.model.Persona")]
public class Persona {
public var nome:String;
public var cognome:String;
}

Note the RemoteAlias metadata, wich ensures that our class definition is registered with that alias. Inside the converter we will be able to say

var cls:Class = getClassByAlias("com.comtaste.model.Persona");
var output:Object = new cls();

and create an object of the correct ActionScript type Persona. This converter can be placed within a static function that can be called on the remote call result or inside a Cairngorm (or PureMVC) command. Using the latter approach we can benefit from the modularity these micro-architectures provide and only use the converter in few, well known, parts of the application.

The automatic converter can be written as in the following function:

public static function getObject(input:Object):* {
if ((input == null) || !input.hasOwnProperty("metadata"))
return input;

if (!input.metadata.hasOwnProperty("type"))
return input;
var cls:Class = getClassByAlias(input.metadata.type);
if (cls == null)
return input;

var output:Object = new cls();
for (var prop:Object in input) {
if (prop === "metadata")
continue;

if (input[prop] != null) {
if (input[prop].hasOwnProperty("object")) {
if (input[prop].object is ArrayCollection) {
output[prop] = new ArrayCollection();

for each (var o:Object in ArrayCollection(input[prop].object)) {
var newObj:* = getObject(o);
ArrayCollection(output[prop]).addItem(newObj);
}
} else {
output[prop] = getObject(input[prop].object);
}
} else {
output[prop] = input[prop];
}
}
}

return output;
}

This example considers the case of nested objects and uses our named convention for "object" and "metadata"; it obviously does not consider circular references. The drawback is that all of the ActionScript model classes have to be referenced in the main application at least once, so that the classes definitions would register their aliases safely.

TrackBack

TrackBack URL for this entry:
http://blog.comtaste.com/mt-tb.cgi/82

Comments (3)

Gordon:

Hi Constantin,

This looks very useful. I am have been struggling with this exact problem trying to get my complex value objects in and out of a PHP server using AMF to simplify things I just want to serialize on the client and dump the object data as XML to a backend database.

However, I am still a newbie to some of the more advanced actionscript stuff. I am little confused on how the getClassByAlias method works.

When I put this function in my PureMVC proxy that needs to serialize the data I get following error:

1180: Call to a possibly undefined method getClassByAlias.

Do you possibly have a more complete example of how this might function in say a PureMVC context? ie with a proxy, command, and vo in the model?

Thanks,
Gordon

Hi Gordon,
you need to import getClassByAlias, which is a function in the flash package:

import flash.net.getClassByAlias;

If you use the Flex Builder, it should do that for you with the Content Assist (Ctrl space).

In the above example, I would call the converter function inside the result of a command and place the resulting object inside the proxy (the model class, Persona.as, would be a vo).

HTH,
Constantin

amy:

How can we do the reverse
i.e I have an Actionscript object (with nested objects and arrayCollections) and I want to convert it to an XML.

Any ideas?

Thanks

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on February 16, 2009 5:28 PM.

The previous post in this blog was Securing your Solr server on Tomcat.

The next post in this blog is Styling ItemRenderers in Datagrids.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33