| By Victor Rasputnis, Yakov Fain, Anatole Tartakovsky | Article Rating: |
|
| October 5, 2006 12:00 PM EDT | Reads: |
26,374 |
The simplest way to explain Flex Data Services (FDS) is to compare them with Flex Remoting. Simply put, FDS addresses only a subset of operations facilitated via Flex Remoting - result set requests. However, whereas Flex Remoting enables one-way requests, FDS combines one-way requests with the publish/subscribe mechanism so that besides the original result set FDS sends the client live updates produced by other clients of the same destination. And there's one more dimension in which Data Services depart from Flex Remoting - support for hierarchical collections, but we won't be covering that subject in this book.
In other words, FDS resolves the task of programming data collaboration: Several users may edit different rows and columns of the "same" DataGrid and see each other's changes automatically pushed by the server. Now, what if they overlap each other's work? In terms of FDS that's called a conflict and the FDS API provides for flexible conflict resolution, which may require the user's intervention.
An FDS destination can be configured for working with the data that is persisted to a data store as well as supporting scenarios that persist the data in the server's memory. To that end, FDS provides Java and ActionScript data adapters that are responsible for reading and updating a persistent data store according to its type. In this chapter we'll focus on use cases involving Java adapters.
Flex Data Services & Automation: Problem Statement & Solution
Robust in enabling collaborative manipulation of data, FDS demands a substantial development effort in case of persistent data stores. In particular, you need to build:
- A Java Data Access Object class that implements retrieve, update, delete, and insert of the data;
- Java Data Transfer Objects (DTO);
- A matching ActionScript data transfer object class;
- A configuration file, which registers identity columns of the result set and, optionally, argument types for every retrieval method and other parameters.
Addressing this complexity, the main idea of this chapter is not to cover every twist of the FDS API, but rather automate the development effort that FDS takes for granted. We'll start with a "manual," albeit simplified, example of using DataServices. Then we'll introduce you to the methodology of complete code generation based on the pre-written XSL templates and FDS-friendly XML metadata, which will be extracted from the annotated Java abstract classes.
This methodology is fully implemented in DAOFlex - an Open Source utility that's a complementary addition to this book. We'll gradually introduce this tool by leading you through a process of creating the most comprehensive template that generates a complete DataServices Data Access Object DAO. Finally, we'll show you how to run and customize DAOFlex in your development environment so that writing and synchronizing routine DataServices support classes becomes a task of the Ant building tool and not yours!
A "Manual" FDS Application
Let's handcraft the application presented in Figure 6.1. This application displays a Panel with a scrollable DataGrid that we consciously did not size in the horizontal dimension, so that all columns can be viewed without shrinking. The database result set is ultimately produced by the following SQL query that will use a bound variable in place of the question mark:
select * from employee where start_date < ?
There are two buttons below the DataGrid: Fill and Commit. As the names imply, these buttons pull the original data from the database table and submit the data changes back to an FDS destination. A separate Parameters panel permits entering parameters of the back-end method behind the Fill button, which, in our case, is the employee start date :
Building the Client Application
Let's build the client application first. The full listing of the application is presented in Listing 6.1. We start with defining the mx:DataServices object (a k a ds), which points to the destination "Employee." Later, when we get to the server components we'll discuss mapping this destination to the backing Java class:
<mx:DataService id="ds" destination="Employee" fault="onFault(event)" />
We provide only a rudimentary handler of the fault event that's sufficient to keep us aware of any anomalies that may occur along the way. Dynamic referencing fault and faultString properties will spare us from casting to a specific event:
private function onFault(evt:Event):void {
Alert.show(evt["fault"]["faultString"], "Fault");
}
Then we define a handler of the application's onCreationComplete event where we instantiate a collection to be eventually associated with our mx:DataService object and, most importantly, set both autoCommit and autoSyncEnabled of the ds to false:
private function onCreationComplete() : void {
collection = new ArrayCollection();
ds.autoCommit=false;
ds.autoSyncEnabled=false;
}
By setting autoCommit to false we state that all updates have to be batched and explicitly submitted to the server as a single transaction during the ds.commit() call. By setting autoSyncEnabled to false we effectively protect our local instance of data from delivery of messages caused by other clients connected to destination "Employee." Setting autoSyncEnabled to false is entirely optional, and we use it to avoid dealing with application specific conflict resolution. In particular, in the handler of the Commit button's click event you might uncomment the first line to support the "optimistic" way of handling the conflicts:
private function commit_onClick():void {
//ds.conflicts.acceptAllClient();
// Optimistic conflict handling, as oppose to
ds.conflicts.acceptAllServer();
ds.commit();
}
Last, we have to initiate the population of the local collection with the ds.fill() method, which we do inside the click event handler of the button Fill:
private function fill_onClick():void {
ds.release();
ds.fill(collection, param_getEmployees_startDate.selectedDate);
}
The scripting portion of the application is completed so let's build the UI. We create a DataGrid with the dataProvider bound to our collection in Listing 6.1. For brevity's sake, we didn't list all the columns here: you'll have a chance to scrutinize them in the subsequent section of this chapter.
The DataGrid and ControlBar with Fill and Commit buttons are put inside a Panel, with DataGrid's title bearing the name of the destination and a specific getEmployees method of that destination, which will ultimately be invoked during the ds.fill() call. The second panel, titled Parameters, contains a form with a single item mx:DateField. Both panels are embraced by the VDividedBox.
We've included a linkage variable of the data transfer type to ensure that the corresponding ActionScript class (EmployeeDTO) will be linked into the generated SWF file.
<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="#FFFFFF"
creationComplete="onCreationComplete()">
<mx:DataService id="ds" destination="Employee" fault="onFault(event)" />
<mx:VDividedBox width="800" height="100%">
<mx:Panel title="Employee::getEmployees()" width="800" height="70%">
<mx:DataGrid id="dg" dataProvider="{collection}" editable="true" height="100%">
<mx:columns><mx:Array>
<mx:DataGridColumn dataField="EMP_ID" headerText="Emp Id" />
<mx:DataGridColumn dataField="MANAGER_ID" headerText="Manager Id" />
<mx:DataGridColumn dataField="EMP_FNAME" headerText="Emp Fname" />
. . . .
</mx:Array></mx:columns>
</mx:DataGrid>
<mx:ControlBar>
<mx:Button label="Fill" click="fill_onClick()"/>
<mx:Button label="Commit" click="commit_onClick()" enabled="{ds.commitRequired}"/>
</mx:ControlBar>
</mx:Panel>
<mx:Panel title="Parameters" width="100%" height="30%">
<mx:HBox height="100%" width="100%">
<mx:Form label="getEmployees()">
<mx:FormItem label="startDate:">
<mx:DateField id="param_getEmployees_startDate" selectedDate="{new Date()}"/>
</mx:FormItem>
</mx:Form>
</mx:HBox>
</mx:Panel>
</mx:VDividedBox>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import com.theriabook.datasource.dto.EmployeeDTO;
private var linkage:com.theriabook.datasource.dto.EmployeeDTO = null;
[Bindable]
private var collection : ArrayCollection;
private function fill_onClick():void {
ds.release();
ds.fill(collection, param_getEmployees_startDate.selectedDate);
}
private function onCreationComplete() : void {
collection = new ArrayCollection();
ds.autoCommit=false;
ds.autoSyncEnabled=false;
}
private function commit_onClick():void {
ds.conflicts.acceptAllClient();
ds.commit();
}
private function onFault(evt:Event):void {
Alert.show(evt["fault"]["faultString"], "Fault");
}
]]>
</mx:Script>
</mx:Application>
Published October 5, 2006 Reads 26,374
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Victor Rasputnis
Dr. Victor Rasputnis is a Managing Principal of Farata Systems. He's responsible for providing architectural design, implementation management and mentoring to companies migrating to XML Internet technologies. He holds a PhD in computer science from the Moscow Institute of Robotics. You can reach him at vrasputnis@faratasystems.com
More Stories By Yakov Fain
Yakov Fain is a Managing Director of Farata Systems, consulting, training and product company. He has authored several Java books, dozens of technical articles. SYS-CON Books released his latest co-authored book , Rich Internet Applications with Adobe Flex and Java: Secrets of the Masters in Spring 2007. Sun Microsystems has nominated and awarded Yakov with the title Java Champion. He leads the Princeton Java Users Group. He is an Adobe Certified Flex Instructor. Currently Yakov works on the book for O'Reilly "Enterprise Application Development with Flex". He twits at twitter.com/yfain.
More Stories By Anatole Tartakovsky
Anatole Tartakovsky is a Managing Principal of Farata Systems. He's responsible for creation of frameworks and reusable components. Anatole authored number of books and articles on AJAX, XML, Internet and client-server technologies. He holds an MS in mathematics. You can reach him at atartakovsky@faratasystems.com
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Executives Feature on Cloud Computing Expo Power Panel
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- Adobe Unveils LiveCycle Enterprise Suite 2 for Deployment in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Ph.D. in Twitter Anyone?
- Adobe Flex Developer Earns $100K in New York City
- Eolas Sues the Internet
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Special Report on the Emerging Cloud Computing Trend
- My Thoughts on Ulitzer
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Ulitzer Live! New Media Conference & Expo
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Executives Feature on Cloud Computing Expo Power Panel
- Software Flexibility in the Cloud - Part 4 of 5
- Is Microsoft as Free as Open Source?
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- Adobe Unveils LiveCycle Enterprise Suite 2 for Deployment in the Cloud
- Where Are RIA Technologies Headed in 2008?
- Cover Story: How to Increase the Frame Rates of Your Flash Movies
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Your First Adobe Flex Application with a ColdFusion Backend
- Adobe Flex 2: Advanced DataGrid
- i-Technology Blog: Death-Knell For "Rich Media? Hardly!
- Adobe/Macromedia - Microsoft, Look Out!
- How To Create a Photo Slide Show ...
- Adobe Flex Interface Customization - Themes, Styles, Skins
- Personal Branding Checklist
- Has the Technology Bounceback Begun?
- "Real-World Flex" by Adobe's Christophe Coenraets


































