Sunday, February 24, 2013

Flash Builder shortcuts and tricks

Recently I found come really interesting and useful shortcuts in Flash Builder. I always hate unnecessary imports in the code. We have a shortcut:

ctrl + shift + o (the letter is o as in orange)

This will remove all unnecessary imports. Also to indent, select the code (as or mxml) and then use shortcut:

ctrl + i to indent a piece of code.

We can also use:

ctrl + d (to delete the current line).
ctrl + space (twice) to get all code templates.

One really good article can be found here:
http://www.adobe.com/devnet/flash-builder/articles/tips-tricks.html

Problem with ObjectUtil copy

We all have used this wonderful method copy() in ObjectUtil class. It does a deep copy of the object using the following lines of code:
public static function copy(value:Object):Object
    {
        var buffer:ByteArray = new ByteArray();
        buffer.writeObject(value);
        buffer.position = 0;
        var result:Object = buffer.readObject();
        return result;
    }

As the code implies it does not copy each and every property recursively but the object is serialized into a array of bytes which is then de-serialized to get a new object. It makes use of built in Flash player AMF capabilities and it is exactly the same serialization mechanism that is used for remoting. When we send an object using remoting we send an AMF array of bytes which is de-serialized at the other end. As AMF is used to copy few things happen:

1. If we try to cast the result of copy to a class it may fail. For example when I tried to use 'as' operator to cast the result it failed.
2. Also when we use transient metadata tag output gets affected.

When the object gets de-serialized it does not create an instance of the class automatically. The object may have all the properties but still not a true instance (rather an object of class Object or ObjectProxy) unless the AMF packet includes type information about the object. This information gets added to the packet in two ways:

1. If the remoting tag is used: [RemoteClass]
2. If the class is registered using registerClassAlias() method

If we use remoting tag then it is easy. For example:

//assume employee has [RemoteClass] metadata.
var employee:Employee = Employee (ObjectUtil.copy(emp));

We may not always have this tag. In one of my project I was having a class ProfileMetaData which was making use of various properties of other value objects and was not sent back to business layer. So there was no question of remoting. And as expected after copy() I was not able to cast the result. So we need to register the class against a string alias. For example:

registerClassAlias("com.app.vo.ProfileMetaData",ProfileMetaData);
//Now we can copy and caste
var profileCopy:ProfileMetaData = ProfileMetaData (ObjectUtil.copy (report) );

What about the transient? If a property is transient it gets removed from the AMF packet during serialization. The reason they are not sent over the network via Flash Remoting is because  they are not included in the AMF packet. So there is no question of reading them back. In some cases it is useful.

More:
http://archive.darronschall.com/weblog/2007/08/on-transient-objectutilcopy-and-casting.html
http://stackoverflow.com/questions/14576627/how-to-work-registerclassalias-method-for-custom-mxml-components