Creating the ColdFusion Service Layer
A Flex RIA is the client-side component of the application. It only runs within the browser, requiring a server-side component for interaction with databases and message queues. For the Task List application, the service layer is provided by ColdFusion running within a local JBoss environment.
To create the ColdFusion infrastructure, I downloaded and installed the free developer edition of ColdFusion 8 from the Adobe website, selecting a JEE-style installation that results in a WAR file. After expanding the WAR into a directory structure, I copied it to my JBoss server's deployment directory, using a context-root of /tasks. Visiting http://localhost:8080/tasks/CFIDE/administrator completed my installation and displayed the ColdFusion management application.
While I could have used PHP, .NET, or other server-side technologies, I chose ColdFusion because it makes real-time messaging straightforward. When you're in the management application, you're ready to perform the single-step process of configuring the real-time messaging infrastructure. This consists of creating an "Event Gateway," providing a conduit from ColdFusion to an external system such as the Flex messaging infrastructure. Task List uses a gateway instance named taskGateway that lets ColdFusion code send real-time messages to the Flex application via the configured-by-convention ColdFusionGateway destination. The point-and-click UI in the ColdFusion administrator lets you create this real-time messaging bus without having to find and install dependency JARs, edit XML files, or deal with other complicated configuration chores.
Just as with the front end, designing the back end begins with the construction of a Task model. Next, you design an interface and implementation of a Data Access Object for persisting and recalling Tasks. Finally, you develop a simple Façade pattern implementation exposing coarse-grained functions such as listTasks() and saveTask() to your Flex application.
CFEclipse provides an ideal development environment for writing ColdFusion-powered Flex applications. Because it is an Eclipse plug-in, CFEclipse acts as an add-on to Flex Builder 3, letting you work in a single IDE as you work with both the server and client sides of Task List. With CFEclipse installed, you're ready to edit CFML files.
Like Flex Builder 3, CFEclipse provides a wizard for creating new projects. The server-side code for Task List is contained in {JBoss root}/tass.war/com/firemoss/tasks. Because ColdFusion uses the filesystem for its packaging scheme, instructing the wizard to create a new package in this directory creates a com.firemoss.tasks package.
Inside this package there is a ColdFusion component (the ColdFusion version of a class or object) named Task.cfc. This model of a task (Listing Six) is visible to the ColdFusion class loader as com.firemoss.tasks.model.Task. Because this is equivalent to the RemoteClass alias to which you earlier pointed your ActionScript 3.0 Task, any ActionScript 3.0 Task instances sent to ColdFusion are automatically turned into instances of the Task.cfc component. Inside the Tasks.cfc file, a similar alias annotation states that an instance of a ColdFusion Task sent to Flex should be marshalled into an instance of an ActionScript 3.0 Task.
<cfcomponent output="false" hint="DTO for a Task" alias="com.firemoss.tasks.model.Task"> <cfproperty name="id" type="string" hint="UUID of this task." /> <cfproperty name="task" type="string" hint="Name of this task, e.g., ""Buy Milk""" /> <cfproperty name="complete" type="boolean" hint="Is this task complete?" /> <!--- Initialize ---> <cfset this.id = "" /> <cfset this.task = "" /> <cfset this.complete = false /> </cfcomponent>
With this aliasing in place, when Task instances are sent back-and-forth between ColdFusion and the Flex application, properties declared in both Tasks.as and Tasks.cfc are automatically populated, thanks to a technology known as "Flash Remoting." Without this capability, you would need something like SOAP or XML/REST, and write code to parse XML.
With a model in place, the server-side components need a persistence mechanism. In a production environment, this would probably involve a relational database. With ColdFusion's flexibility and Java foundation, you have options for working with databases. You could hand-write SQL for persistence, use a native ColdFusion Object-Relational Mapping (ORM) framework such as Transfer, or employ a pure Java solution such as Hibernate.
Task List maintains a memory-resident list of Task instances, simulating the presence of a database. To enable future expansion to a true database, this knowledge is hidden inside of a Data Access Object pattern implementation. The ColdFusion interface com.firemoss.tasks.persistence.ITaskDAO is used to define methods such as list() and save(). A MockTaskDAO component then implements these methods using the memory-resident application scope provided by ColdFusion. Obviously, use of such global variables is strongly discouraged for production applications.
With a model and persistence mechanism implemented, the server must expose its functionality. All that's required is a Remote Façade Pattern implementation that's implemented as another ColdFusion component, TaskService.cfc, within /com/firemoss/tasks/service. This provides two coarse-grained methods corresponding to the high-level use cases within the application: listTasks() and saveTask().
The listTasks() method is simple, using MockTaskDAO to read the tasks. The saveTasks() method, however, must also perform real-time pushing of updated tasks to all clients currently running the application. Thanks to ColdFusion event gateways, this requires just four lines of code (Listing Seven). A ColdFusion structure (HashTable) is created and populated with the configured-by-convention destination of "ColdFusionGateway." A body consisting of the Task instance to push is also created and then dispatched to the appropriate event gateway instance with the sendGatewayMessage() function.
<!--- Notify client applications ---> <cfset taskMessage = structNew() /> <!--- Flex messaging destination to use: Matches <mx:Consumer /> tag attribute ---> <cfset taskMessage.destination = "ColdFusionGateway" /> <cfset taskMessage.body = arguments.task /> <cfset sendGatewayMessage("taskGateway", taskMessage) />
When this code is executed, the Flex application's Consumer tag receives the HashTable as a messaging object, invoking an appropriate event handler that modifies its collection of tasks.
Your application is now ready to run. Simply click the green Run arrow in Flex Builder 3 and the application executes. If there's an error in Task List, you can use the Eclipse-based ColdFusion Debugger (provided by ColdFusion 8) and the Flex Debugger (built into Flex Builder 3) to step through the code without ever leaving Eclipse.
Creating a Deployable WAR
When the application is debugged, you can create a deployable WAR of your application that compresses the application into a single file, much like a ZIP archive. To deploy a WAR to most Java application servers, the only installation step is to place the WAR file into the deployment directory.
When Flex Builder 3 compiles a Flex application, it creates a debug build. For production purposes, it provides an Export Release Build wizard, which lets you create an optimized Flash SWF file. To complete the tasks.war file, the Export Release Build wizard is used to build the application into /tasks.war, which contains files such as {JBoss root}/server/default/deploy/tasks.war/Tasks.html.
To create a distributable WAR of both the client and server applications, ColdFusion provides a wizard that's accessed through the ColdFusion administrator. The ColdFusion J2EE Archive wizard handles all of the building and configuration for you. Pointing it at the /tasks.war directory creates a single WAR file ready to be deployed to any compatible JEE serverno deployment scripts necessary and the Task List application is packaged as a WAR.
Conclusion
If you're still using HTML, JavaScript, complicated server deployments, and other technologies that don't "just work," try downloading the free Adobe Flex 3 SDK, a trial edition of Adobe Flex Builder 3 Professional, and the free developer edition of Adobe ColdFusion 8 to begin building better web applications with fewer headaches.