Monday, November 17, 2008

swfutils.jar, the back bone of the new Flex Builder 3 skin import feature

If any of you have checked out the flex sdk source at opensource.adobe.com, you know there is a ton of code in there. The trunk is split up into sub projects which contribute to the sdk as a whole. One project that I found to be really interesting is trunk/modules/swfutils. The jar file that this project builds is used in the the Flex Builder 3 swf skin import feature. If you haven't seen this feature yet it lets you select a swf and it lists out the symbols in the swf available for import.

So how does Flex Builder use this jar and how can I get it? Flex Builder has a new wizard the contained in this jar com.adobe.flexbuilder.importartwork_3.0.194161.jar, this has the ui that drives the import feature and creates and instance of the class flash.swf.TagDecoder. The TagDecoder class is what actually parses out the symbols in the swf file that you select while using the wizard. Building the swfutils.jar is very easy but may require you to install some software. You will need Java 1.5.0 and Ant 1.7.0, I'm not sure if the sdk source uses an specific features of either yet since they just upgraded from Java 1.4.2 and Ant 1.6.2. So you may be able to get by with either of those for now. Environment variables for each will need to be set if don't already have them, JAVA_HOME and ANT_HOME. Now you need access to the flex sdk source tree, this page gives you details on accessing and using Subversion to checkout the files. Once you have the trunk checked out you can build the swfutils.jar by running this command in the main project dir that contains the build.xml and build.properties files, ant swfutils. Once ant has finished running you should fine the jar here /lib/swfutils.jar.

So how can I use the TagDecoder class found in swfutils.jar to list out the symbols compiled into a swf like the skin import in Flex Builder? First you need a swf exported for Flash Player 8 with some symbols exported in the library. If you have Illustrator CS3 or Flash CS3 you can download skinning extensions that will help you create a set of Flex skins exported as a swf. The TagDecoder class take two parameters in it's constructor a java.net.URL and an java.io.InputStream. Once you have a new instance of the class you can call the parse method that will start the swf parsing. The parse method takes a flash.swf.TagHandler instance which is sent the swf data through a bunch of public handler methods. The two handlers we are interested right now are the flash.swf.TagHandler.header() and the flash.swf.TagHandler.exportAssets() methods. The header handler does just what it sounds like passed back the swf file header information as a flash.swf.Header instance. The exportAssets handler passes back a list of the exported symbols found in the swf as a flash.swf.tag.ExportAssets instance. The code below shows what this would look like, notice the MyTagHandler extends TagHandler so we can pass a reference to it's self as the parameter for the TagDecoder.parse method. Then we just need to override the handler methods we want to use so we can parse the data sent to them.


package;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import flash.swf.Header;
import flash.swf.TagDecoder;
import flash.swf.TagHandler;
import flash.swf.tags.ExportAssets;
import flash.util.FileUtils;

public class MyTagHandler extends TagHandler
{

public void parseSwf( File f )
{
try
{
URL fileUrl = FileUtils.toURL( f );
InputStream input = url.openStream();
TagDecoder t = new TagDecoder( input, fileUrl );
t.parse(this);
}
catch ( IOException e )
{
e.printStackTrace();
}
}

public void header( Header h )
{
//data here
}

public void exportAssets( ExportAssets tag )
{
//data here
}
}


There is a handler that will list out the exported symbols from a swf exported for Flash Player 9 but the Flex Builder 3 feature only supports Flash 8 for now. So hopefully this has give a little peek under the Flex Builder 3 hood, all thanks to the open source Flex SDK. There is a lot of interesting code in there have fun exploring.