Flash Builder Tooling with CAF Tiles using Flex SDK 3.6

1 Introduction

Even though the ADEP tooling doesn’t officially support building CAF tiles that use Flex SDKs earlier than 4.5.0, it is nevertheless possible to do so while taking advantage of many of the features it provides, if you do a little of the work yourself. The following features of the tooling can still be used with 3.6 Tiles, once they have been properly set up:

  • Some automatic catalog entry generation
  • Catalog and Application deployment

The things you give up include:

  • Automatic gxml generation for library projects
  • Code assist in library projects
  • Tile creation wizard

2 General ideas

The main thing you need to do to get started is to undo some of the work that the File->New->ADEP project wizard does for you. You give up all the features of tooling if you don’t ADEP-enable a project, so it’s better to go through the wizard as though creating a 4.5-based project, and then change the settings to make it a 3.6-based project instead. We’ll cover the two main types of tile projects, Module tiles and UIComponent tiles. There are other ways to get the tooling to help, such as telling a 3.6-based non-ADEP project to generate its output into a 4.5-based, ADEP-enabled project, but I won’t cover them here.

3 Creating a 3.6 Module tile project

Let’s start with Module tiles, since they’re the simplest, and are the recommended approach. Throughout this tutorial, we’ll use the default catalog, but all the steps work equally well with any catalog.

Begin by launching FlashBuilder, and ensure that you have all the normal ADEP-related parts set up (AEP_SDKS pointed at the right place, for instance). Then create a new ADEP-project, by choosing File->New Flex Project for ADEP Experience Services. Configure it as you would normally configure a 4.5 tile, but on the first panel of the wizard, choose the 3.6 Flex SDK instead. Accept all the default swc libraries that are added to the build path, even though they’re for 4.5, you’ll remove them after the project is set up. Once your project is ready, open the project build path pane, and remove all the library entries that mention “ux”, “riacore” and “dataservices”. Unfortunately, one of the swc directories just removed has a couple of swcs you still need in addition to many you don’t, so choose “Add SWC…” and enter “${AEP_SDKS}/riaservices/riacore/10.0.0.0/flex/security_api.swc”, and again for security_domain_library.swc.  Then, edit the remaining entries that mention 4.5 and point them at 3.6 instead.  Your build path should now look like this:

Finally, in the Flex Compiler pane, remove the additional compiler argument “-includes=mx.managers.systemClasses.MarshallingSupport”. Your project is now mostly “3.6-ready”, and if you’re in a hurry, you can skip the next step, though in a production environment you’ll need to come back and do it.

The wizard creates a sequence of RSL failover entries that ensure that your application, when it loads Flex SDK swz and swf files, gets them first from the server that served up the application. However, the URLs the wizard uses are for the 4.5 SDK, not the 3.6 one. The wizard will have set the default framework linkage for your project to “Use SDK default”, which is most likely RSL, so the RSL failover paths do need to be edited. Go to the Flex Build Path pane for the project, and open the list of the Flex 3.6 SDK components. The list should include playerglobal.swc, framework.swc, etc. The ones that are available on the CRX server need to have their entries modified. These are:

  • framework.swc
  • datavisualization.swc
  • rpc.swc

Each one needs to have the following failover pattern (replacing “framework” with “datavisualization” and “rpc”):

/content/mosaic/viewer/flex_sdks/flex_sdk_3.6.0.16995/framework_3.6.0_16995.swz
/content/mosaic/viewer/flex_sdks/flex_sdk_3.6.0.16995/framework_3.6.0_16995.swf
framework_3.6.0_16995.swz
framework_3.6.0_16995.swf

http://fpdownload.adobe.com/pub/swz/flex/3.6.0.16995/framework_3.6.0.16995.swz

Next, create a new MXML module in that project. The File->New->Composite Application Tile wizard expects to with with a 4.5 project, and will refuse to create a tile in a 3.6 project, so you’ll have to create the module with the File->New MXML Module dialog instead. Then add the Tile metadata to your module, so it looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
           layout="absolute" width="400" height="300">
  <mx:Metadata>
    [Tile]
  </mx:Metadata>
  <mx:Button label="Tile1 button"/>
</mx:Module>

Since the project is ADEP-enabled, you should also now have a new entry in your catalog that looks like this:

<tile:TileClass fitContent="true" height="300" label="Tile1" name="Tile1" width="600">
  <ct:Metadata>
    <ct:Description/>
  </ct:Metadata>
  <tile:Content contentType="application/x-shockwave-flash" flexSDKVersion="3.6.0"
                loadAs="module" uri="${catalogURL}/tiles/Tile1/Tile1.swf"/>
</tile:TileClass>

The tooling does know that your project uses Flex SDK 3.6, and it successfully puts that information in the catalog entry, there should be no need to edit it by hand.

Now create a new CAF application, either in this project or a separate one, using the File->New->Composite Application, and add a reference to this tile:

<tile:TileReference catalog="${catalog}" name="Tile1" label="Tile1"
                    optional="true" width="100%" height="100%" />

Your 3.6-based module tile is now ready for use. You can right-click on the application file and choose Composite Application Framework->Deploy Composite Application, and then navigate to its URL in your browser.

4 Creating a 3.6 UIComponent tile

Follow these steps to create a new Composite Application tile or tiles from a Flex Library project, or to augment an existing Flex Library project so parts of it work as tiles and can be included in a Composite Application.

4.1 Creating the UIComponent project and tile

If you already have a Flex Library project that has a component or components in it that you want to expose as Tiles, skip this step and proceed to the next one, where you’ll modify the existing project to make an existing component into a Tile.

Otherwise, begin by creating a new Flex Library project, File->New->Flex Library project, making sure to choose Flex SDK 3.6. Then create a new component in that project, with File->New->MXML Component. For this example, base your component on mx:Button, and add a label to it so we will recognize it when we see it:

<?xml version="1.0" encoding="utf-8"?>
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" label="3.6 Button Component">
</mx:Button>

So far, there is nothing special about this component. In the next steps, we’ll make it into a Composite Application tile.

4.2 Modifying an existing Library project to make it into a Tile

There are three primary steps to take in order to convert an existing Flex component into a tile. The first is to mark the component as a tile, and then provide it with the necessary libraries to allow it to communicate with the rest of the Composite Application Framework. Second, since a Library project normally only produces a SWC file and CAF needs a SWF to load, we have to create a wrapper project that includes the SWC. Normally, this step is handled by the ADEP tooling, but it’s not supported for 3.6-based projects, so we have to do this step manually. Finally, we have to create a gxml file so that CCF can load the tile.

4.2.1 Prepare the Library Project

Begin by adding the needed library directories to the project. They are:

  • ${AEP_SDKS}/riaservices/mosaic/10.0.0.0/flex3.6.0/frameworks/libs
  • ${AEP_SDKS}/riaservices/gravity/10.0.0.0/flex/3.6.0/libs
  • ${AEP_SDKS}/riaservices/gravity/10.0.0.0/flex/core/libs

Then switch the framework linkage to RSL, which will reduce the size of the tile, and add the following to the Flex Compiler options: -locale en_US -keep-as3-metadata+=Tile,Application,ContextBind,SecurityManager

Finally, update the RSL failovers as described in the earlier section.

You are now ready to add CAF-specific constructs to the project, specifically the [Tile] annotation. If you are using the extended button from the previous step, your new source code would look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Metadata>
  [Tile]
</mx:Metadata>
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" label="3.6 Button Component">
</mx:Button>

4.2.2 Create the wrapper project

Create a new ADEP-enabled project, with File->New->Flex Project for ADEP-Experience services, make sure it’s set to use Flex SDK 3.6, and complete the dialog as you did for the section “Creating a 3.6 Module tile project”. Also as in the earlier section, remove the unused libraries, and update the necessary ones from 4.5 to 3.6. Then make this wrapper project depend on the Library project.

Adjust the RSL failovers, switch the project to RSL linkage, and add the compiler options you added earlier to the Library project. Then create a new MXML Module called, for example, “ComponentWrapper.mxml”. This file will be very simple, it serves only to wrap the component in a particular way to enable it to be loaded by CAF:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
           width="400" height="300">
	<mx:Script>
          MyButton;
	</mx:Script>
</mx:Module>

MyButton would be the name of the component you created earlier, or the name of the existing component. If the component is not in the default package, you’d do something slightly different:

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
           width="400" height="300">
	<mx:Script>
          include com.acme.MyButton;MyButton;
	</mx:Script>
</mx:Module>

Finally, we have to create the GXML file. This will go in the “mosaic” folder, which is created automatically when you create an ADEP-enabled project. The file should be named “MyButton-com-acme.gxml”, if MyButton is in the com.acme package, or just “MyButton.gxml” if it’s in the default package. The content should be as below:

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns="http://ns.adobe.com/gravity/manifest/1.0">
  <bundle location="ComponentWrapper.swf" parentDomain="flex3.6.0">
    <beans xmlns="http://ns.adobe.com/gravity/di/1.0">
      <bean id="MyButtonAdaptedBeanFactory" lazyInit="true" scope="prototype">
        <constructorArg ref="gravityContainer.getBean"/>
        <constructorArg>
          <array>
            <bean lazyInit="true">
              <constructorArg value="MyButtonUIService"/>
            </bean>
          </array>
        </constructorArg>
      </bean>      

      <service interface="com.adobe.gravity.ui.IUIServiceFactory"
               ref="MyButtonModuleUIServiceFactory">
        <serviceProperties>
          <entry key="purpose" valueRef="MyButtonPurpose"/>
          <entry key="description" valueRef="MyButtonDescription"/>
        </serviceProperties>
      </service>

      <bean id="MyButtonModuleUIServiceFactory" scope="prototype">
        <constructorArg ref="MyButtonAdaptedBeanFactory"/>
      </bean>

      <bean id="MyButtonCreator" factoryMethod="createWrapper" scope="prototype">
        <constructorArg ref="gravityBundleContext" index="0"/>
        <constructorArg value="com.adobe.threesix.components.MyButton" index="1"/>
      </bean>

      <bean id="MyButtonPurpose" lazyInit="true">
        <constructorArg value="${catalog}/com.adobe.threesix.components.MyButton"/>
      </bean>

      <bean id="MyButtonDescription" lazyInit="true">
        <constructorArg value="MyButton's UI Service"/>
      </bean>
      <bean id="MyButtonUIService" parent="MyButtonCreator"
            lazyInit="true" scope="prototype">
      </bean>
    </beans>
    <flexModule sdk="3.6.0"/>
  </bundle>

</manifest>

It may be instructive to compare this gxml file with one that the Tooling generates automatically for a Library component tile built with SDK 4.5. You may see several differences, but only some of them are significant. Many of the “id” attributes serve only as identifiers within the gxml, and need only match each other where they appear, but their actual names are not significant. However, there are a couple of instances where the values of strings are important:

  • The bundle element’s location attribute must name the swf built by the project.
  • The constructorArg value attribute in the “Creator” bean and the “Purpose” bean must have the fully qualified class name of the wrapped component that you marked as a Tile.

Even though this tile is ADEP-enabled, an entry in the catalog will not be generated, because nothing directly inside the project was marked with the [Tile] annotation. Therefore, we need to add an entry manually to the catalog. In this case, it will refer to the gxml file we created, rather than the swf. The entry should look like this:

<tile:TileClass fitContent="true" height="300" width="600"
                label="com.acme.MyButton" name="com.acme.MyButton">
  <ct:Metadata>
    <ct:Description/>
  </ct:Metadata>
  <tile:Content contentType="application/xml" flexSDKVersion="3.6.0" loadAs="module"
                uri="${catalogURL}/tiles/com.acme.MyButton/com.acme.MyButton.gxml"/>
</tile:TileClass>

You can now add a reference to this tile in your application:

<tile:TileReference catalog="MixedSDKS"
   name="com.acme.MyButton" label="My Button" optional="true" width="100%" height="100%" />

You’re finished!