Main

Flex Archives

June 10, 2007

Cerchi una consulenza su Flex 3, AIR, Livecycle data services e Java per lo sviluppo di RIA ? E' nata Comtaste Consulting

Dopo oltre un decennio di attività da free lance per lo sviluppo e la consulenza su Flash, Flash Media Server e, successivamente, Flex (fin dalla versione 1) e Flash Lite, ho formato e dirigo un team di professionisti che hanno una profonda conoscenza di queste tecnologie ed un solido background in Java, EJB3, Struts, Hibernate, POJO e Spring in ambiente Java Enterprise (J2EE).
Oltre a frequenti attività di supporto ad Adobe in importanti progetti nell’area EMEA (EuropeMiddleEastAfrica), questo team di consulenza e sviluppo è stato ingaggiato più volte da prestigiose aziende worldwide per consulenza in materia di analisi, sviluppo e ottimizzazione di applicazioni in cui gli aspetti gestionali e di sicurezza tipici del mondo enterprise integrano saggiamente l’attenzione alla user experience che è il fulcro dell’approccio RIA (Rich Internet Applications).

Se hai bisogno di assistenza per un'applicazione interna o vuoi rendere un'applicazione eistente più ricca e accattivante, o se hai un'idea che vuoi realizzare utilizzando le più moderne, efficaci ed affidabili tecnologie disponibili sul mercato quello che stai cercando è il mio team! Forniamo consulenza e assistenza in ogni parte del mondo, on site e off site, both on a Time&Material and on a TurnKey basis.

Per contattarmi in merito ad attività di consulenza, scrivi una email a consulting[ AT ]comtaste.com

June 11, 2007

Flex 3 and Flash Player 9 update on the Labs

Today Adobe released a lot of new technologies on its Labs section: Flex 3 Flash Player 9 update 3 and Adobe AIR (Adobe Intergrated Runtime).

flex3_fx_124x120.jpgFlex 3 is the one we are waiting for and the new features of this release are a lot and Adobe made an excellent work. As you can read from the Introduction to Flex 3 article by Matt Chotin :
the Flex 3 release is divided into four major themes: designer/developer workflow, working with data, Adobe AIR applications, and platform evolution. Let's quickly review some of the highlights:

* Native support for Adobe AIR – Flex 3 introduces new components and incorporates the Adobe AIR development tools into the SDK and Flex Builder.
* Persistent framework caching – You can make Flex 3 applications as small as 50K when leveraging the new Flash Player cache for Adobe platform components.
* Flex Builder productivity enhancements – Flex Builder 3 introduces refactoring support, new profilers for performance and memory tuning, and code generation tools for data access.
* Integration with Creative Suite 3 – The Flex Component Kit for Flash CS3 allows Flash CS3 users to build components that can be seamlessly integrated into a Flex application, while Flex Builder 3 adds new wizards for importing assets from CS3 applications as skins.
* Advanced DataGrid – The Advanced DataGrid is a new component that adds commonly requested features to the DataGrid such as support for hierarchical data, and basic pivot table functionality.
* First steps toward open source Flex. As a first step toward making Flex an open source project, we've opened up the Flex and Flex Builder bug tracking system to the public, as well as published detailed roadmap information.


Emmy Huang wrote on his blog about the the Flash Player 9 update 3 and its 300 bug fixes :

The Flash Player 9 update 3 beta (9.0.60.120) has a little something for everyone. In addition over 300 bug fixes, and the new player cache for Adobe platform components that Ted mentioned on Thursday, we've added performance enhancements that will improve your video and interactive content. The hot new feature is full-screen mode with hardware scaling, which can be used to deliver significant improvements in visual quality and performance for video. If you're interested in the technical details behind this feature and the rest of the performance enhancements, Tinic will be talking about the under-the-hood details on his blog and has also written an article on Adobe Labs on the new API for accessing this feature. There is also a video you can use to see the difference between software and hardware full-screen mode. Check back, if it hasn't gone live yet...

June 12, 2007

LiveCycle Data Services ES 2.5 Documentation

Past week the Flex Doc Team at Adobe released the documentation for LiveCycle Data Services Es 2.5. The documentation was realeased in livedocs format so you were able to read on the web.

Randy Nielsen, the Learning Resources Manager at Adobe Systems Incorporated, send me an email to point me out that the LiveCycle Data Services Developer’s Guide has been released in PDF format.
So we're now ready to download and print it !

This is the entire LiveCycle Data Services documentation :

* Getting started - http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcds/getstarted_1.html
* LiveCycle Data Services Developer’s Guide - [ LiveDocs ] | [ PDF ]
* LiveCycle Remoting - http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/sdkHelp/Invoking_LiveCycle/invokingLCRemoting.2.1.html
* LiveCycle ES ActionScript Language Reference (includes Flash Player, Flex SDK 2.0.1 hotfix 2, Data Services, and LiveCycle Form Guide classes) - http://livedocs.adobe.com/livecycle/es/sdkHelp/common/langref/index.html
* LiveCycle Data Services JavaDoc - http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcdsjavadoc


Flex Doc Team rocks !
They made an excellent job for the Flex and LiveCycle Data Services Es 2.5 documentation.
Thanks guys !

June 14, 2007

Adobe AIR, Flex 3 and Integration between Fireworks,Photoshop and Flash CS3 with Flex. All of these topics at the AdobeLive 2007

Today is the second day of AdobeLiveConference here in Italy.
I'm here with Enrique (and some enormous mosquitos) in the business room of the AdobeLive and we're about to start our presentation.

Enrique will present Adobe AIR (formerly Apollo) and talk about Flex 3 and new features.

After his presentantion I'll show the integration of the Adobe CS3 with Flex and Flex Builder.
It's incredible how many things designers and creative are now able to do to help Flex developersin creating the user interface of Flex applications.
Using Photoshop CS3, Fireworks CS, Illustrator CS3 and Flash CS3 , of course, they can export graphic symbols, layouts and components for the Flex enviroment.

With Fireworks CS3 you can now use the Exoprt as MXML features to convert a PNG layouts into MXML code. You can do this using the new Flex Component Common Library (you can also create your own Flex components using an image and a javascript JSF file).
The MXML code generated from Fireworks is ready to be edited and customized by the developer in Flex Builder.

With Illustrator CS3 you can create vector based symbols and export them as SWF files, ready to be used and imported in Flex. For example you can export your vector symbols and then use them for change the style of a button flex component usign :

overSkin: Embed(source='styles.swf', symbol='mysymbol');
upSkin: Embed(source='styles.swf', symbol='mysymbol');
downSkin: Embed(source='styles.swf', symbol='mysymbol');

Then in Flash CS3 you can do whatever you want with the Flash CS3 Component Kit for Flex. You can interact in Flex with Flash contents, call public methods, refer to each single object.

If you're in Milan come to see the sessions !
They're great !

June 18, 2007

Form fields focus and keyboard events in Flex 3 form based applications

We're working on some projects in Flex where the use of the keyboard to navigate through the application is a key aspect.
They're both Flex 2 form based application

Our goals were :
- at the start up of the application give the focus to the first form field
- pressing the tab key cycling the focus through all the form fields

Although it seams like very simple, the focus in Flex 2 is not so easy.
We had strange behaviour that mostly depend on how the Internet Explorer uses the ActiveX contents :
- although when the application has been loaded the foucs was on the first field, pressing the tab key once, the focus goes outside the Flash Player applet to the browser controls

To solve the problem of the fucus lost by the Flash Player you can use this small workaround :

keyFocusChange="event.preventDefault();focusManager.getNextFocusManagerComponent(event.shiftKey).setFocus()"

The keyFocusChange is on the Application tag.

In order to make the focus in Flex 2 works for Internet Explorer, it's not enough to set it up using Javascript when the page loads.
Internet Explorer does not give you the ability to an ActiveX content to get the focus.
So for example in a Flex 2 application that has 3 text inputs when the last one has the focus and you click on the tab, the focus quits from the Flash Player 9 ActiveX and goes to the HTML page content.

That's a bad behavior for your application.

To overcome this problem we have to intercept the key pressed by the user and disable the default action of the browser to prevent the browser handling of the key.

Continue reading "Form fields focus and keyboard events in Flex 3 form based applications" »

Quality Control phase of enterprise Flex application with the The Flex Automation Framework

When you develop enterprise flex application the Quality Control phase (QC) is a fundamental aspect of each software development activity.
Flex and the LiveCycle Data Services ES include The Flex Automation Framework.

The Flex Automation Package provides developers with the ability to create Flex applications
that use the Automation API. You can use this API to create automation agents or to ensure
that your applications are ready for testing. In addition, the Flex Automation Package includes
support for Mercury QuickTest Professional (QTP) automation tool.

You can create applications and components that can be tested with automated testing tools
such as Mercury QuickTest Professional (QTP). This topic includes information intended for
Flex developers who write applications that are then tested by Quality Control (QC)
professionals who use these testing tools.

Continue reading the full Creating Flex Applications for Testing document.

Continue reading "Quality Control phase of enterprise Flex application with the The Flex Automation Framework " »

June 25, 2007

Flex 3,LiveCycle Data Services and Adobe AIR sessions at the MAX 2007 Conference

On the Adobe MAX 2007 blog has been published the pre-conference training day, a full-day hands-on training sessions. These are the tracks dedicated to Flex 3, Adobe AIR and LiveCycle Data Services :

Flex 3: Integrating with ColdFusion
This session provides ColdFusion developers with hands-on, practical experience connecting their Flex 3 client applications to remote, dynamic data provided by ColdFusion and LiveCycle Data Services.

Flex 3: Integration with Java
This session provides experienced application developers with hands-on, practical experience connecting their Flex front ends to remote, dynamic data using LiveCycle Data Services.

Flex 3: Developing Rich Client Applications
Get hands-on, practical experience using Flex.

Adobe Integrated Runtime (AIR): Bringing Rich Internet Applications to the Desktop
This full-day course will include everything you need to get started building applications with Adobe AIR.

June 29, 2007

Enterprise RIA development with Flex/LiveCycle Data Services and Java persistence

LiveCycle Data Services overview

LiveCycle Data Services, formerly known as Flex Data Services, is a powerful Adobe product that allows seamless interaction between a Flex client and any Java EE based server or most J2EE servers.
These services allow Java object or services to be called directly from the Flex client, in a transparent way: all the developer has to do, in the Flex code, is call remote services just like they were Flex functions or methods. All the problems related to marshalling / unmarshalling, mapping Flex and Java classes and types are solved internally by LiveCycle Data Services. For all of this to work, LiveCycle Data Services only requires some configuration to be provided, that will define the required behavior.
Using LiveCycle Data Services is, without doubt, one of the best approaches to consider in developing enterprise RIA applications, as it takes care, in an efficient and scalable way, of all the information exchanged by the Flex client and the Java server.

An eye on the server side

Connecting the client to the server being taken cared of, the development can just focus on creating a client and a server layer that handles any required business logic and persistence. LiveCycle Data Services is a Java EE web application, that has to be deployed into a Java EE container. From there it can access whatever server side required functionality and provide it to the Flex client. This kind of deploy ensures compatibility with existing Java EE application as well as with newly created applications. Connecting a LiveCycle application with an existing Java EE or J2EE application requires a little work, but we’ll cover it up in a future post.
The Java EE applications covered in the following blog posts will be the ones that use either Hibernate as a persistence manager or EJB3 in Java enterprise applications. We will see how to access Hibernate or EJB3 from LiveCycle Data Services, how to keep the data services separated from the Java business logic, using clean, modular and distinct components.

The world behind LiveCycle Data Service and Java

LiveCycle Data Services offers many possibilities, like accessing remote Java objects, binding client to server data sources, using publisher/subscribe messaging to communicate with the server, with or without JMS. Aside all these it’s also possible to configure a LiveCycle Data Services EE application to allow a controlled Flex client access to areas like Hibernate’s named queries, JNDI lookup or web server custom login.
LiveCycle Data Services offers numerous possibilities and can be configured and understood to get the outmost out of this potential.

Web resources
LiveCycle Data Services can be found here, http://www.adobe.com/products/livecycle/dataservices/, Hibernate http://www.hibernate.org/ contains all required resources and libraries. A commonly used Java EE web servers is Tomcat http://tomcat.apache.org/, while JBoss http://labs.jboss.com/ is an enterprise application container.

July 3, 2007

The advantages of going open source with Flex 3

As you probably know, Flex 3 is gonna be open source. But many developers are asking what that means.
There is a great interview by HowSoftwareisbuilt to Phil Costa who is the Director of Product Management for Flex and ColdFusion at Adobe, with responsibility for product definition and strategy of the Flex product line.

This is the answer Phil gave to the question : What are the advantages of going with more of an open source model — what are the advantages of taking something that hasn’t been open source and open sourcing it?

There are a few different elements to it. First, there’s the nature of the product itself. The core part of the product is try hard to internally test, and get all the bugs out, because it’s a development framework. By its nature, it gets used in a million different ways. It’s very hard to actually set up tests for all those ways and to chase down all the bugs.

So having an open source model will actually help us by having more people looking at the code and suggest changes based on their particular use-case. In one respect, we view it as a way of magnifying the QA resources we have, and also magnifying some of the bug-fixing resources. So, that’s a very tactical thing, but that is a proven advantage of an open source project.

The second element refers more to the evolution of the product. We’ve always tried to be very customer-centric in terms of designing the product, working with early adopters, niche users, and new users, to determine what things we should be adding to the product, to make sure that it fits their needs, both on the learning-curve side as well as the power-user side.

We decided that having a group of people who can directly influence that — or at least feel more deeply invested in it — was a good way to continue to evolve the product. With a developer product, the people who develop the product are also the users of the product, and there’s a very efficient feedback loop.

The third piece is more PR and marketing focused. Because people have to make a substantial investment in Flex — in terms of spending a lot of time developing an application and then making their application dependent on the Flex framework — they’re looking for an open source project or a set of standards. In the rich-ended application space, there aren’t really any standards, per se. They’re mostly looking for open source or de facto standards.

It’s become increasingly apparent, as the market has grown up, that to be successful as a platform you need to be an open source project, so that people view the product as being bigger than one individual company, or in some cases one individual product team. In a lot of ways, that was another requirement that more and more customers were raising; they love Flex but they wanted it to be bigger than just Adobe.

July 6, 2007

Creating an ObjectManager for improving the Flex interaction with Ajax or Javascript

In the latest years the growing demand for Rich Internet Applications submitted the following question to the developers' community: which to choose between the Ajax + JavaScript solution on one hand, and the Flash player based Adobe Flex technology on the other hand? The choice is definitely hard, as in most cases both solutions are suitable without particular indications or limitations, and we can insert both Ajax and Flex with no difficulty in the same web pages and applications in case of particular requirements.

What if we want that Flex interacts with Ajax/JavaScript in the same application to render a virtually unlimited user experience? What if we need our Flex application interacts with third parties' applications (e.g. Google Maps)?

Flex Ajax Bridge is a free small library which in such circumstances allows the developer to save many lines of code. Through Flex Ajax Bridge , which is now included in Adobe LiveCycle Data Services 2.5, you can make your ActionScript classes available to JavaScript without any additional coding. After you insert the library, essentially anything you can do with ActionScript, you can do with JavaScript.

While the functionalities offered by the External Interface class of the Flash Player can solve the easiest cases of ActionScript/JavaScript interaction, it is advisable to use the FABridge (Flex Ajax Bridge) in the most complex situations, in presence of user-defined classes or when we should define an interface to make JavaScript dialog with ActionScript and vice-versa.

In both cases we would face a little limit: it causes a problem trying to access Flex component just after html loads using body tags onload attributes while the swf files is not loaded yet.

It seems a marginal issue, but quite often it happens that our Flex movie will be initialized after the onload event is launched.

A possible solution could be the one of waiting a few seconds by using the Javascript function setTimeout(code,millisec,lang) , however what assures the movie will be ready in that time? If the movie were not ready, either an error is generated or the input to the Flex component goes lost.

The solution on the Flex 3 side is to make our Flex application disabled by using JavaScript :

To get the DOM object of our SWF file we'll use the ExternalInterface class standard function:

function thisMovie(movieName) {

if (navigator.appName.indexOf("Microsoft") != -1) {

return window[movieName];

} else {

return document[movieName];

}

}

In Flex we register the ActionScript method we want to call from the JavaScript side with the addCallback method :

ExternalInterface.addCallback("disableApplication", disableFunction);

We could call the method registering it on the creationComplete Flex event or any other system event.

Then we invoke the function that will call the method exposed by the ExternalInterface class, disableApplication in our case :

function disableMovie(movieName) {

var myMovie = thisMovie(movieName);

if(myMovie == null || myMovie.disableApplication == null)

{

setTimeout("disableFilter("+movieName+")", 100);

}

else

{

myMovie.disableApplication();

}

}

If the SWF file has not been loaded yet or the ExternalInterface.addCallback function has not been invoked on the Flex side, the movie will wait 100 milliseconds to disable the application again.

This method is known as busy waiting, and it's not a CPU intensive processing method, but it continuously calls the JavaScript function until it gets the value.
It's easy to implement this solution for small applications but it has several problems as soon as more and more applications run concurrently or there are race conditions. A more complicated solution to solve some of these problems can be to use some global variables to hold the objects returned by setTimeout() function, so we could call a clearTimeout() when needed.
As you can note, this method could generate unwanted effects when there are several functions and a medium size application.

This example is based on the ExternalInterface class but such a problem comes in also when using Flex Ajax Bridge, as mentioned in the Adobe Labs Wiki.

In the next part of the post we'll create an ObjectManager in JavaScript to handle this issue.

July 20, 2007

Conditional visualization in Cairngorm 2.x using the ChangeWatcher class

Data Binding is one of the most important and powerful flex features and the Cairngorm framework makes a full use of it in its Model View Controller design pattern.
In a standard and simple use of Cairngorm we have a view with some controls with dataProviders directly bound to the ModelLocator, if you don't have a clear view of how these things work you'll have a better outlook viewing the diagram on cairngormdocs.org

Sometimes we want to have in a view only some data that satisfies certain conditions, we have to filter the collection before passing it to the view. Flex gives the possibility to use a filter function associated to the collection; if you are considering a small application this is a viable solution but in an Enterprise RIA application probably we cannot apply a filter function, because that data source can be a data provider for different views that need the complete collection.
The flex ChangeWatcher class provides a complete different solution. From the flex 2 api: “
The ChangeWatcher class defines utility methods that you can use with bindable Flex properties. These methods let you define an event handler that is executed whenever a bindable property is updated.”

Let'see a tipical view in Cairngorm:

<MyView ... >

 <mx:DataGrid dataProvider=”{MyModelLocator.getInstance().myDataSource}”
itemRenderer=”MyItemRenderer” />

</MyView>

seq1.png


We have no way to intercept changes in the data source because the data binding will make changes effective in the view instantaneously.
Using the ChangeWatcher and the view helper we interpose a layer that prepares the data before sending them to the view.


The new View:


<MyView ... >

 <MyViewHelper id="myViewHelper" />

 <mx:ArrayCollection id=”myDataProvider” />

 <mx:DataGrid dataProvider=”{myDataProvider}”
itemRenderer=”MyItemRenderer” />

</MyView>


The ViewHelper:

package ...
{
...

 public class MyViewHelper extends ViewHelper
 {
   private var myChangeWatcher:ChangeWatcher;

   public function MyViewHelper() {

    myChangeWatcher = ChangeWatcher.watch(MyModelLocator.getInstance(), “myDataSource”, prepareDataProvider);
   }


   private function prepareDataProvider(event:Event) {

    var myAC:ArrayCollection = new ArrayCollection();
    for each(var item:Object in MyModelLocator.getInstance().myDataSource) {
     //if item satisfies certain conditions
     myAC.addItem(item);
    }
    view.myDataProvider = myAC;
   }

  }
}
seq2.png


Every time the data source is updated, the handler is called and the collection is filtered. It is convenient that the responder updates the entire collection at once and not adding items one by one, because the handler would be called every time. To stop watching the data source you can call the unwatch() function on the changeWancher instance in the ViewHelper.
This is only one of the possible solutions we can use thanks to the flexibility of data binding.

August 7, 2007

Creating an ObjectManager for improving the Flex interaction with Ajax or Javascript - 2nd part

In my previous post I have illustrated the creation of a simple object manager to make a javascript application correctly dialog with a Flex movie. That is a simple and well functioning solution, however it is not suitable for a more complex context, when it is necessary, for instance, to use several Flex or Javascript/Ajax applications.

What is the right choice in such a situation? The solution often depends more on the developer's creativity than on the possibilities offered by the technology in use.

Let's think, for example, to a comparable situation in actual life: one or more people try to contact the same person that is not available at that moment. If the communication were not much important, each of them could simply try later on, with the hope to find the person available (previous solution), although in the meantime others might anticipate his/her call. What if the communication were extremely important, and risks to arrive too late (after our competitors' communication, for instance)? In order to avoid that possibility and all the related consequences, a voice mail (or a simple answering machine) could be used, as well as, at a later stage, a personal secretary could be hired. The messages will be recorded in their incoming order (for example using a queue or a single instance if we need only the last message), and as soon as the address is available again he/she will listen to the recorded messages or will be informed about them by his/her secretary. We shall now examine how to implement the easiest case, taking again as an example the disabilitation of the Flex application:

- We create a JS class named ObjectManager, it will represent our answering machine. We also create an empty constructor, in this case we shall not use status variables related to the Manager:

ObjectManager = function () {

}

If necessary we could insert variables such as this.available into the object in order to indicate its availability or to initialize global variables.

The only method which is necessary for the object manager's functioning is AddObject. With this function we'll have the possibility to add the desired object (e.g. a Flex movie) to the manager class:

ObjectManager.prototype.AddObject = function (objectName) {

                if(eval('this.' + objectName +' == null')) {

                               eval('this.' + objectName + ' = new Object()');

                               eval('this.' + objectName + '.setStatus = null');

                               eval('this.' + objectName + '.enabled = 1'); //Default status value

                               return true;

                }

                else

                               return false; //object already registered

}

In this way, in the object manager will be created a simple object that we shall use to keep all the information which are necessary to guarantee the proper functioning of the application. Every object created in the object manager is directly linked to the object we want to control through the use of a unique string which represents it. For this reason it is necessary to use the function eval(string), as in the object manager we will not have direct reference to the objects to control.

September 9, 2007

An open source alternative to Adobe LiveCycle Data Services: Granite Data Services

Adobe LiveCycle Data Services ES, formerly called Flex Data Services (FDS), provides data services such as remoting, data push, publish and subscribe for Flex applications. With LCDS you can integrate flex with J2EE infrastructures and a previuos post on our blog shows an example: LiveCycle Data Services and Hibernate integration in Flex RIA applications.
There are a lot of open source projects around flex, flash and AMF, and, on java side, GraniteDS is one of the most promising.
It's developed under the LGPL and proposes itself as an alternative to Adobe® LiveCycle® (Flex™ 2) Data Services for J2EE application servers.
GDS is still in an early development phase, with a 0.3 version released on july 30, while, at the time of writing, the 0.4 one is in a release candidate state; despite this, it's rather stable and you can safely test it in non critical production environment as its home page suggests.
Here they are the features already implemented and the planned ones; this list is continuously updated


  • Full AMF3 support. See GDS AMF3 documentation.

  • EJB3 services with transparent externalization mechanism and lazy initialized ActionScript 3 beans (Entity Beans / Hibernate). See EJB3 Services and Externalizers and Lazy Initialization.
  • EJB3 Entity Bean to ActionScript 3 classes code generator. See AS3 Generation.

  • Spring services. See documentation on Spring Services.

  • POJO services (remote calls to simple Java classes that expose public methods). See Pojo Services.
  • (planned) Data push. A Comet-like implementation with AMF3 data polling over HTTP (event/listener based architecture).

  • (planned) Entity repository: a client side entity repository that ensures uniqueness (only one instance of each entity is present in the flash VM), weakness (only currently bound objects are kept in memory), and that acts as a services frontend (all server calls/events are managed by this central component). This will be loosely inspired by Cairngorm.

  • (planned) Seam integration: a reliable GDS/Seam integration with full scopes (at least conversation) support.
  • (planned) A set of Flex components suitable for complex data structures.

A key feature, implemented in version 0.3, is the support for setCredentials, setRemoteCredentials and logout methods of RemoteObject, more information in the release notes: http://www.graniteds.org/confluence/display/DOC03/Documentation+-+0.3

They provides various demos which you can you use importing them as new eclipse projects:


Moreover a live demo that shows Granite DS in action is available.

If you are interested in testing your LCDS application with Granite Data Services you have to make some changes according to the good documentation ready to help you; however you should check if all the features you need are implemented.
Granite DS is a promising project and the development is going on quite fast, but it still misses some important functionalities like messaging services and data push (planned feature) so by now LCDS is a must in a stable production enviroment, but i can suggest to keep an eye on GDS for the future.

October 11, 2007

Choosing the appropriate RIA Technology: my speech at the Oreilly Web 2.0 Conference

I am very glad to be part of one of the coolest and rich of contents conference made by Oreilly : Web 2.0 Summit .
I'll be present the following speech where I'll give you an overview of pros and cons of different techologies for RIAs development

web2_0_logo.gif
Choosing the final RIA path or Choosing the appropriate RIA Technology
Thursday, 8 November - 11:20 am–12:10 pm

Rich user interfaces and a satisfactory user experience are fundamental factors of Rich Internet Applications. Improved productivity, more effective work, time and cost reduction in the field of both operations and applications development are an important plus which deserves to be higlited when evaluating the suitability of tecnologies for applications projects. New development approaches have recently come to market : Flex, AIR, Flash, XUL, OpenLazlo, Silverlight, WPF, JavaFX. There are so many different technologies that it's easy to lose focus and misjudge goals when choosing a RIA platform. How to choose the best technology? What are their advantages? Which one is going to get the widest adoption? What can you do with them? This session guides you through the ecosystem of RIA's technologies, analyzing and comparing the benefits, features and disadvantages of each approach. Make the final RIA choice for your web applications.

Web 2.0 Expo in Berlin is the place to learn, network, and engage in the European Web 2.0 community.
Join your colleagues at this must-attend event and tap the power of Web 2.0 through:

* A comprehensive 5-track conference: Design and User Experience, Development and Web Operations, Fundamentals, Marketing and Community, and Strategy and Business Models
* Keynotes from thought leaders influencing the future of the web
* An Expo showcasing Web 2.0 services and technologies
* In-depth Workshops to get you up to speed
* Web2Open, an Open Space event for all delegates, where the audience become the speakers
* Great networking events designed to celebrate the Web 2.0 community

November 26, 2007

Choosing the appropriate RIA technology

While choosing the most appropriate RIA technology for a project, we should consider several factors:

1. the reach (% of users who will be able to get the RIA experience with their installed browser and plug-ins)
2. the availability of open source vs. commercial products
3. the company’s internal knowledge
4. the development time (time to market)
5. the community and support infrastructure

In addition to the above factors, that we can define as “supporting considerations” to the process of choosing the most appropriate RIA technology, we should consider a 6th factor which consists of the “intimate” suitability of a RIA technology to manage:

- Users interaction
- Rich media content

At Comtaste, we have defined the following chart to describe the positioning of 6 different RIA technologies respect the 2 above mentioned parameters (each measured in terms of several features): Ajax, Adobe Flex, Java FX, Lazlo, Microsoft Silverlight 1.1 and XUL .

The chart has been named “the RIA domain” because it represents, like for a mathematical function, the area within which an application can be defined as a Rich Internet Application. It corresponds to our personal feeling and experience as RIA developers.

RIA%20technologies%20positioning.JPG

This chart has been included in the slides presented by Marco Casario at the Web 2.0 Expo of Berlin. The complete set of those slides can be found here.

December 13, 2007

Adobe announces open source BlazeDS and the AMF data binary specification release

Adobe has just announced the BlazeDS beta release. On Adobe Labs today we can read that "BlazeDS is the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe® Flex™ and Adobe AIR™ applications for more responsive rich Internet application (RIA) experiences."

As a matter of fact, BlazeDS is an open source part of LiveCycle Data Services, while the complete Live Cycle suite will still be closed source and subject to Adobe’s Licensing policy.

The source code will be available for download in early 2008 (http://labs.adobe.com/technologies/blazeds/).

Adobe has also published AMF binary data protocol specification, on which the BlazeDS remoting implementation is based.

BlazeDS introduces the concept of HTTP streaming, that enables clients to maintain persistent connections with backend servers. HTTP streaming will practically allow the same data push functionality that is available with the LiveCycle Data Services, with the difference that the streaming will not use the RTMP messaging channel.

Among the news, Adobe will offer Adobe LiveCycle Data Services, Community Edition, a subscription offering that includes certified builds of BlazeDS, access to Adobe enterprise support resources and additional benefits, such as product warranty and infringement indemnity, as well as additional developer support.

After the release of the Flex SDK open source, Adobe gives further signals of willingness to pursue the construction of a stronger and wider developers' community.

February 9, 2008

The new BlazeDS JMSAdapter allows to pass connection-level credentials to JMS

I want to point out for the readers of this blog (mainly Java, Flex and Livecycle developers) an article I published on my personal blog :
Passing connection-level credentials to the JMSAdapter of BlazeDS
One of the limit if the Messaging Services of Livecycle Data Services is the inability to define a username and password in the configuration file to pass them to the JMS.
I discovered that in BlazeDS there is a new JMSAdapter that allows you to set the connection-level credentials passing the username and password.
The new connection-credentials XML node sets the the username and password used while creating the JMS connection.As the documentation said, use only if JMS connection level authentication is being used :



...

Topic
javax.jms.TextMessage
jms/flex/TopicConnectionFactory

jms/topic/flex/simpletopic

NON_PERSISTENT
DEFAULT_PRIORITY
"true"
AUTO_ACKNOWLEDGE

1

For many developers this new features supported by the JMSAdapter could be very appreciated and could solve problems in many different scenarios where the authentication is required in JMS.

Read the full Passing connection-level credentials to the JMSAdapter of BlazeDS article.

March 27, 2008

Comtaste launches new Adobe Flex 3 and Adobe AIR training courses in New York City, London and Milan

Comtaste has just launched its new training courses on Adobe Flex3 and AIR for late spring-early summer 2008.

First courses to be scheduled are:

"Flex 3 and Flex Builder 3: Developing Rich Internet Applications with the new Flex 3 SDKs" (Milan and London 26-29 May, NYC-Manhattan 2-5 June)

"Developing desktop applications with Adobe AIR, Ajax and Flex" (Milan 14-17 April, NYC-Manhattan 9-12 June, London 23-26 June).

Our educational proposal, designed and set up by Flex expert Marco Casario, is mainly the result of our strong experience in real world enterprise projects.

Our courses reflect our clients' training needs that our consultants have encountered in the day by day running of enterprise-class projects, where Flex and AIR are also connected to backend applications under robust and rigid JEE architectures or other server side technologies.

Training programs and other details on company's website www.comtaste.com/en/training.htm

April 30, 2008

Measuring the ROI of choosing Flex for Enterprise RIAs

The ROI index is a synthetic yet meaningful parameter used to express the benefit of making a project, as well as the benefit of making a certain choice related to a project, for example the technology to be used.

During my speech at the recent 360Flex Conference in Milan I presented the benefits achieved as a consequence of adopting Flex to re-design an enterprise application.

After an overview concerning the practical methods that can be used to evaluate the benefits and to calculate the Return On Investment (ROI), I presented a real-world case of an application for banking operations.

In that case, the benefit was measured in terms of the time saved to execute an ordinary operation (cashing a check) by using the Flex re-designed application respect the time that was formerly necessary to execute the same operation by using a "common" Oracle form-based application (simple html using the "traditional" logic of 1 click=1 page).

A tipically physical kind of measurement (time saved) was then translated into an economic parameter by valueing the time by the standard hourly wage of the staff involved in the operations of that kind.

The final passage was the calculation of the ROI formula.

The important and evident result was that the use of Flex contributed to leverage the ROI formula numerator (return) and to decrease its denominator (investment), for a double action of increment on the final result.

The slides of that speech can be found on SlideShare

May 12, 2008

Improve the ObjectHandles library with a smoother resizing movement

A very common UI element found in many applications are those little square handles around an on-screen object that allow you to move & resize it. To do this you can use the great ObjectHandles library.

ObjectHandles (http://osflash.org/projects/objecthandles) is a library to allow a user to move and resize UI elements in a Flex based application.
It provides drag handles around controls that users can manipulate with their mouse. Any Flex component can be placed within an ObjectHandles container to quickly allow you to add functionality.

It behaves as a container object where you can put any other flex components and use its resizeable functionalities.

Features of the ObjectHandles library:

* Move & Resize Functionality for any flex component
* Ability to limit movement and/or resizing in both vertical and horizontal directions
* Ability to limit movement and/or resizing along an anchor
* Simple 1-file (.swc) install
* Mouse cursors change when over different handles
* Graphical handle support
* Aspect ratio support
* Initial rotatation support has been added

ObjectHandles is a very cool library for your project when you want to implement moving & resizing any kind of flex object.

Example usage:

In the example below you'll see two buttons in a vbox that can be moved together. This is the mxml to achieve that:

<oh:ObjectHandles x="10" y="158" width="107" height="108"
minHeight="30" minWidth="30">
<mx:VBox borderStyle="none" top="0" left="0" right="0" bottom="0">
<mx:Button width="100%" height="50%" />
<mx:Button width="100%" height="50%" />
</mx:VBox>
</oh:ObjectHandles>

Or if you want an Actionscript example:

Here's an example to dynamically load an image into an ObjectHandle and allow resize movements:

protected function init() : void
{
var oh:ObjectHandles = new ObjectHandles();
oh.height = 50;
oh.width = 50;

var image:Image = new Image();
image.source = "snowflake.png";
image.percentHeight = 100;
image.percentWidth = 100;
image.maintainAspectRatio = false;

oh.addChild(image);
oh.allowRotate = false;

genericExamples.addChild(oh); // replace genericExamples with a canvas in your application
}

Improving the experience of the ObjectHandles library

When you drag or resize an object from right to left or from up to down everything works great.

But if you to resize the object back (from right to left) you'll see that the inside object will cause a strange flickering.

To prevent this we can use the "Flex Move Effect" and "Flex Resize Effect" instide of change programmaticaly width and height and x and y.

How it actually works:

Inside the ObjectHandles.as Actionscript 3 class, you can find the protected function onMouseMove(event:MouseEvent) : void.
This is the function that moves and resizes UI elements in a Flex based application. Find the following line inside the ObjectHandles.as:

if( wasMoved || wasResized )
{
applyConstraints(desiredPos,desiredSize);
x = desiredPos.x;
y = desiredPos.y
width = desiredSize.x;
height = desiredSize.y;
}

The applyConstraints() method simply applies restrictions to your objects like xAnchor, minium size, etc. The other four lines simply set the x,y coordinates and the width and height properties of the Flex object.

Now let's change this four lines to prevent the strange flicker bug that affects the object :

if( wasMoved || wasResized )
{
applyConstraints(desiredPos,desiredSize);

if(moveEffect.isPlaying){
moveEffect.end();
}
moveEffect = new Move();
moveEffect.target = this;
moveEffect.duration = 1;
moveEffect.xTo = desiredPos.x;
moveEffect.yTo = desiredPos.y;
moveEffect.play();

if(resizeEffect.isPlaying){
resizeEffect.end();
}
resizeEffect = new Resize();
resizeEffect.target = this;
resizeEffect.duration = 1;
resizeEffect.heightTo = desiredSize.y;
resizeEffect.widthTo = desiredSize.x;
resizeEffect.play();
}

It replaces the brutal property changing of the widget with a smoothness move and resize effect provided by Flex.

In the next post we will see how to create a snap to grid and a snap to line effect.

Conclusion and references:


ObjectHandles google code home
Class Move
Class Resize

May 26, 2008

Google Maps API for Flex and Flash: some tips and notes

Finally the official version of Google Maps for Flash is arrived.
Google has just released the Actionscript API that provides map functionalities to web applications in a way really similar to the Javascript version.
You can follow the instructions in the Setup or Tutorial pages on Google Code to easily build your web map application.
Here is a sample application based on data from Yubuk (click on the image):
GoogleMapsFlex

And now some hints that can be useful when creating your first Flex application with Google Maps:

1) Remember to add the .swc library provided by Google in their SDK in your compiler options. If you are using Flex Builder you can do that simply going in the project properties, under Flex Build Path, then Library Path and click Add SWC. Otherwise, if you like to use the command line, you can use the -library-path command as explained in the Google tutorial.

2) Pay attention to the events: you can't use the standard Flex events but you need that ones provided by the Google SDK, such as MapMouseEvent.CLICK.

3) Custom markers have a bug in the version 1.3. To avoid this bug there's a workaround in Google Code. The example has a small error in the marker event listener, the event should be MapMouseEvent.CLICK (as explained above).

I think that Google made a great work porting their Google Maps API to Flash. It is still incomplete but it's already possible to see the huge potential provided by the cooperation between Google Maps and Flex. I'm sure that in the near future there will be many interesting RIA based on these technologies.

July 8, 2008

Using the Loader class to load and set dimensions of an image from the remote server in Flex 3

Working and creating images in Flex could not be as easy as it looks. When you load an image loaded from the remote server you will tipicaly receive a ByteArray data. The ByteArray image doesn't contain any information such as the width and height of that data. Moreover you must know when the entire bytearray it's been fully loaded on the client.

To do this we need to load the bytearray with the Loader Class.
So we need to extend an mx.control.Image Class and add the loader information:

private var _loader:Loader = new Loader();

Now wee need to implement a method to load the bytes:

public function loadBytes(bytes:ByteArray, context:LoaderContext = null):void
{
_loader.loadBytes(bytes, context);
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBytesLoaded);
}

This method will load the byte array image and add the listener to know when is ready.

After the event.complete handler will bring up with the loader information:

private function onBytesLoaded( e:Event ):void
{
source = _loader.content;
width = _loader.contentLoaderInfo.width;
height = _loader.contentLoaderInfo.height;
removeChild(_loader);
}

You can see that now we can set the source for the image and than set the correct width and height getting the information from the _loader.contentLoaderInfo.

Finally we remove the loader.
Here you can find the complete source for the ByteArrayImage Class:

The Class

package
{
import flash.display.Loader;
import flash.events.Event;
import flash.system.LoaderContext;
import flash.utils.ByteArray;

import mx.controls.Image;

public class ByteArrayImage extends mx.controls.Image
{
private var _loader:Loader = new Loader();

public function ByteArrayImage()
{
}

override protected function createChildren():void
{
_loader.visible = false;
addChild(_loader);
}

public function loadBytes(bytes:ByteArray, context:LoaderContext = null):void
{
_loader.loadBytes(bytes, context);
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBytesLoaded);
}

private function onBytesLoaded( e:Event ):void
{
source = _loader.content;
width = _loader.contentLoaderInfo.width;
height = _loader.contentLoaderInfo.height;
removeChild(_loader);
}
}
}

A simple implementation:

import flash.image.JPEG;
import flash.image.PNG32;
myJPG:ByteArray = new JPEG( bitmapData , 300, 300, 80 );
myPNG:ByteArray = new PNG32( bitmapData , 1500, 1260 );

myByteImage:ByteArrayImage = new ByteArrayImage();
myByteImage.loadBytes( myJPG or myPNG );

Reference:
ByteArray LiveDocs
Loader LiveDocs

September 19, 2008

Extending the ComboBox Flex component to support multiselection

Working in a new dashboard Flex project, I've faced with the need to implement a multi selection feature on a ComboBox control. My goal was to extend the ComboBox component so that the selectedItems and selectedIndexes properties return the selected item contained in the dataprovider and the indices.
And here's how to make it happens.

Implementing this feature is very simple because the ComboBox is a subclass of the ListBase class that works as a dropdown to show and select items. And from the ListBase class it inherits the multiselection property. So all we have to do is to set the allowMultipleSelection property to true:

dropdown.allowMultipleSelection = true;

Multiselection works when the user presses the CTRL or CMD button on the keyboard to select more than one item. So we need to set to true the value of allowMultipleSelection property each time this button is pressed. This can be done by overridding the keyUpHandler and the keyDownHandler events. The event handlers have to:

1) Set the global variable ctrlKey.
2) Set the allowMultipleSelection property of the dropdown List.
2) When ctrl is up close the dropdown and dispatch the change event.

Remember to define the ctrlKey as global property of the combobox so that every functions can be accessed:

public class ComboBoxs extends ComboBox

{
private var ctrlKey:Boolean = false;

Let see how to do this:

override protected function keyDownHandler(event:KeyboardEvent) : void

{
super.keyDownHandler( event );

ctrlKey = event.ctrlKey;

if ( ctrlKey )
dropdown.allowMultipleSelection = true;

}

override protected function keyUpHandler(event:KeyboardEvent) : void

{
super.keyUpHandler( event );

ctrlKey = event.ctrlKey;


if ( !ctrlKey )
{
close();
var changeEvent:ListEvent = new ListEvent( ListEvent.CHANGE )

dispatchEvent( changeEvent );
}
}

Now we have a full ComboBox Flex control able to receive multiselection but when we click on an item the dropDown menu closes.We need to stop the closure of the ComboBox control if the Ctrl key pressed.
To do this we override the close() method:

override public function close(trigger:Event=null) : void

{
if ( !ctrlKey )
super.close( trigger );

}

Finally we can expose the selectedItems and selectedIndices property of the ComboBox and set them to bindable when the change event is dispatched by the keyUpHandler .
We need to check with an if() conditional statement if the dropdown (the istance name of the ListBase class) is not null before getting its selectedItems property:

public function set selectedItems( value:Array ) : void

{
if ( dropdown )
dropdown.selectedItems = value;

}

[Bindable("change")]
public function get selectedItems( ) : Array

{
if ( dropdown )
return dropdown.selectedItems;

else
return null;
}

public function set selectedIndices( value:Array ) : void

{
if ( dropdown )
dropdown.selectedIndices = value;

}

[Bindable("change")]
public function get selectedIndices( ) : Array

{
if ( dropdown )
return dropdown.selectedIndices;

else
return null;
}

It's all done! Now you have a fully multi selectable combo box.
Here you can see the full class code:

package
{
import flash.events.Event;
import flash.events.KeyboardEvent;


import mx.controls.ComboBox;
import mx.events.FlexEvent;
import mx.events.ListEvent;

public class ComboBoxs extends ComboBox

{
private var ctrlKey:Boolean = false;

public function ComboBoxs()

{
super();
}

override public function close(trigger:Event=null) : void

{
if ( !ctrlKey )
super.close( trigger );

}

override protected function keyDownHandler(event:KeyboardEvent) : void

{
super.keyDownHandler( event );

ctrlKey = event.ctrlKey;


if ( ctrlKey )
dropdown.allowMultipleSelection = true;

}

override protected function keyUpHandler(event:KeyboardEvent) : void

{
super.keyUpHandler( event );

ctrlKey = event.ctrlKey;


if ( !ctrlKey )
{
close();
var changeEvent:ListEvent = new ListEvent( ListEvent.CHANGE )

dispatchEvent( changeEvent );
}
}

public function set selectedItems( value:Array ) : void

{
if ( dropdown )
dropdown.selectedItems = value;

}

[Bindable("change")]
public function get selectedItems( ) : Array

{
if ( dropdown )
return dropdown.selectedItems;

else
return null;
}

public function set selectedIndices( value:Array ) : void

{
if ( dropdown )
dropdown.selectedIndices = value;

}

[Bindable("change")]
public function get selectedIndices( ) : Array

{
if ( dropdown )
return dropdown.selectedIndices;

else
return null;
}

}
}

December 18, 2008

Examples and slides of our latest events on PureMVC, BlazeDS, Java, AIR, and RIA User Interface design

Between October and November we held a couple of events for the italian Flex User Group (FlexGala) and Adobe Italy (Adobe TechConnection events).
These are the urls to some of slides and examples showed at those events:


December 23, 2008

Flex Dashboard Panel library v.0.2 released

A few days ago Comtaste has released a new version of its library that includes several improvements coming from our clients' feedbacks.
The Flex library has been released on the Assembla repository public web site:

The Flex Dashboard Panel (ver 0.2) is a library developed by Comtaste to create and manage easily a multi panel applications. The library is totally free.

All the Comtaste's clients that are using the library in their projects can now download the new version of the library and implement it on their project. overriding the older version.

Comtaste is about to release by the first months of 2009, a new version of the library with powerful brand new features, under a open source license (probably LGPL).

December 30, 2008

How to use the Flex Dashboard Panel library

I've created a project to explain how to use the "Flex Dashboard Panel library", here the link of the live application complete of source code.

The principal component of the library are:

1) DashPanelContainer
A canvas Container where we place all the DashPanel window.

2) DashPanel
The window container where you can put all your content.

3) DashLayoutManager
A static multiton manager to control the dashboard.

4) DashPanelEvents
Control your panel programmaticaly using events.


DashPanelContainer properties:
1) dashed:
All DashPanels inside will be tiled to fit on the container and panels can be only switched with each others and not resized.

2) snapped, snapSize:
All DashPanels can be moved and resized constraint to the guide drawed on the background and the snap size can be changed trough the snapSize propeties

3) Nothing:
All DashPanel can be moved and resized without constraint.

DashPanel properties:
1) closable, minimizable, maximizable, draggable, resizable
Control what the panel can do

2) titleBarHeight="20" default 35
Set the height of the title bar if your skin need this.

3) icon, iconXOffset, iconYOffset
Set an icon property an control the position with the offset

4) title, titleColor, titleXOffet, showTitleText
Set the panel title and decide if you want to show or not and where with the offset

5) status
Return the current status of the panel. This status is defined trough constants property of the DashPanel

DashLayoutManager methods:
1) getManager(container.id)
Retrieve the pointer of the manager by passing the container id instance

2) getManager(container.id).tile();
All DashPanel elements will be tiled to fit the space.

3) getManager(container.id).cascade();
All DashPanel elements will be cascaded.

4) getManager(container.id).bringToFront( dashpanel )
Set in fron the element if this is inside the container.

5) getManager(container.id).getOpenedPanelList()
Return the list of current opened panels.

DashPanelEvents:
Using the events you can listen what happen at your panel, but also you can dispatch an event to force panel do something.

1) MAXIMIZE, MINIMIZE, RESTORE, CLOSE
Listen or dispatch this events to control your panel

2) PANEL_MOVING, PANEL_RESIZING
This events can be only listened and inform when panel is currently moving or resizing

3) STARTLOAD, STOPLOAD
Dispatching this events you will freeze the panel and a progress bar will be shown

That's all! Now you can create a fully dashboard application.
Flex Dashboard Panel library Example

January 8, 2009

Importing REST web services in ActionScript with Flex Builder 4

Among the many Flex Builder 4 new features there is the possibility to import REST web services into ActionScript classes, in the same way that the previous builder allowed to import SOAP web services. It can import from XML as well as from JSON data. This new feature can obviously be used to import into ActionScript any kind of services that dynamically generate XML or JSON content.

For the following example I used the MAX preview version of Flex Builder 4, which has many interesting features and, while not yet complete, will become a very good IDE. The example will use a very simple JSP that returns some XML data, dynamically generated as a response to the client invocation. The JSP has contentType="text/xml;", accepts a numeric parameter length and returns a simple structure, with as many nodes as the length parameter. The service called with length=2 will return:

  <root>
    <content value="0"/>
    <content value="1"/>
  </root>

Now we can go to Flex Builder 4 and open the HTTP Service import dialog, right next to the Web Service one. The wizard will ask for the URL of the remote service and will be able to add the parameters accepted by the service. It is possible to define more operations, their parameters and request methods and also import as many HTTP services as we need. The next step will be the creation of the ActionScript classes, by selected the previously defined operations and configure the return type: the wizard will create all necessary classes and the methods to invoke the service, will hide from the developer the conversion between XML/JSON and ActionScript and provide with a transparent and object oriented set of classes ready to be used.

For the above XML the following classes have been created:
  Content.as - with a value property;
  XMLServiceTest - a class containing all the operations to be invoked on this service.
Both of these classes extend a base class, which contains the generated code, so we can safely modify the extending classes, as only the base ones would be overwritten in case of service changes.

Other interesting features of the new builder allow us to rapidly test the newly created services or even to enable paging and data management. By selecting a generated operation and the main application file we can have the builder generate a test datagrid and also all required events for it to work:

  <DataGrid id="DataGrid1" dataProvider="{result1.lastResult}">
    <columns>
      <DataGridColumn headerText="value" dataField="value"/>
    </columns>
  </DataGrid>

With a few clicks we have an application that exchanges strong typed data with a remote server, on top of XML/JSON.

By allowing a transparent conversion between XML/JSON data and ActionScript classes, this HTTP Service import feature makes the development easier for enterprise applications that use REST services or plain XML or JSON as a means of communication.

January 17, 2009

How to enable communication between AIR and Skype through Merapi

Merapi is an interesting project that wants to create a bridge between Air and Java on the desktop, something that already exists between Flex and Java on the web thanks to BlazeDS/LCDS and other similar projects.
It's made up of an actionscript part and a java part, together they build a messaging bridge based on AMF so that you can send messages from java to Air and viceversa.
Merapi is currently in a private alpha state, though a first beta has just been released on their site. If you want to get involved and download the package you have to create an account on http://www.merapiproject.net/ and wait for their approval (usually doesn't take longer than a few days).
The APIs are very simple, you can see an example of their usage on: http://www.merapiproject.net/index.php?option=com_content&view=article&id=47&Itemid=64&limitstart=3.

The idea is simple and is based on sending messages from one endpoint to the other. Sending a message from ActionScript:

var message : Message = new Message();
message.data = "Hello from Merapi Flex.";
message.type = "Reply";
Bridge.instance.sendMessage( message );


Sending a message from Java:

Bridge bridge = Bridge.getInstance();
Message message = new Message();
message.setData("Hello from Merapi Java.");
bridge.sendMessage(message);

Receiving a message in Flex:

<merapi:BridgeInstance
id="bridge" result="handleResult(event)" />
<mx:Script>
<![CDATA[
private function handleResult( event : ResultEvent ) : void
{
var message : IMessage = event.result as IMessage;

Receiving a message in Java:

Bridge.getInstance().registerMessageHandler("Reply", messageHandlerInstance );
public void handleMessage( IMessage message )
{
System.out.println( message.getData() );
}

There is a forum: http://www.merapiproject.net/index.php?option=com_fireboard and some interesting video of application examples: http://www.merapiproject.net/index.php?option=com_content&view=article&id=51&Itemid=84.

I decided to start playing with Merapi creating a AIR client for the Skype chat; first of all I started searching for a Java implementation of the Skype communication API. I found this project "http://skype.sourceforge.jp/index.php?Skype%20API%20For%20Java%20(English)", officially supported by Skype https://developer.skype.com/wiki/Java_API
It's a well written and powerful library so it was very easy to understand.

In my application I used two message types:
- "skype" - for generic API commands
- "skypeChat" - for chat messages

then I created two specific payloads for the Merapi message dependent on its type:

SkypeCommand in ActionScript

package
{
import mx.collections.ArrayCollection;

[RemoteClass(alias="SkypeCommand")]
public class SkypeCommand
{
public static const GET_VERSION:String = "getVersion";
public static const GET_FRIENDS:String = "getFriends";

public var name:String;
public var data:Object;
}
}

SkypeCommand in Java

public class SkypeCommand {
public static final String GET_VERSION = "getVersion";
public static final String GET_FRIENDS = "getFriends";

private String name;
private Object data;

public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

SkypeChatMessage in ActionScript:

package
{
[RemoteClass(alias="SkypeChatMessage")]
public class SkypeChatMessage
{
public var skypeId:String;
public var message:String;
}
}

SkypeChatMessage in Java:

public class SkypeChatMessage {
private String skypeId;
private String message;

public String getSkypeId() {
return skypeId;
}
public void setSkypeId(String skypeId) {
this.skypeId = skypeId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

As you can see, class mapping works exactly the same way it works in BlazeDS.
You have to initialize the bridge on ActionScript:

<merapi:BridgeInstance id="bridge"
  result="bridgeMessageHandler()" />

and on Java you have to register message type handlers:

Bridge.getInstance().registerMessageHandler( "skype", new SkypeMessageHandler() );
Bridge.getInstance().registerMessageHandler( "skypeChat", new SkypeMessageHandler() );

and a Chat message listener

Skype.addChatMessageListener(new SkypeChatListener());

On AIR creationComplete I send two skype commands to get version and friends list:

private function init():void {
var versionCmd:SkypeCommand = new SkypeCommand();
versionCmd.name = SkypeCommand.GET_VERSION;

var listCmd:SkypeCommand = new SkypeCommand();
listCmd.name = SkypeCommand.GET_FRIENDS;

bridge.send("skype", versionCmd);
bridge.send("skype", listCmd);
}

On Java side, in the SkypeMessageHandler, for "skype" type:

SkypeCommand cmd = (SkypeCommand)((Message) message).getData();
Message response = new Message();
response.setType("skype");
SkypeCommand respCmd = new SkypeCommand();

String commandName = cmd.getName();

if(commandName.equals(SkypeCommand.GET_VERSION)) {
respCmd.setName(SkypeCommand.GET_VERSION);
respCmd.setData(Skype.getVersion());
} else if(commandName.equals(SkypeCommand.GET_FRIENDS)) {
ContactList list = Skype.getContactList();
Friend[] friends = list.getAllFriends();
String[] friendIds = new String[friends.length];

for (int i = 0; i < friends.length; i++) {
friendIds[i] = friends[i].getId();
}

respCmd.setName(SkypeCommand.GET_FRIENDS);
respCmd.setData(friendIds);

}

response.setData(respCmd);

Bridge.getInstance().sendMessage(response);

I resend back a SkypeCommand of the same type so that in the AIR app I can recognize the response:

private function bridgeMessageHandler():void
{
if(bridge.lastMessage.type == "skype")
switch(bridge.lastMessage.data.name) {
case SkypeCommand.GET_VERSION:
versionLabel.text = "Skype version: "+bridge.lastMessage.data.data as String;
break;
case SkypeCommand.GET_FRIENDS:
var friendsArray:Array = bridge.lastMessage.data.data as Array;
friendsList.dataProvider = friendsArray;
break;
}

For chat messages sent by AIR, I only forward them to the Skype API:

SkypeChatMessage chatMsg = (SkypeChatMessage)((Message) message).getData();
Chat c = Skype.chat(chatMsg.getSkypeId());
c.send(chatMsg.getMessage());

For chat messages sent by a friend, in the SkypeChatListener I forward the message to the bridge:

public void chatMessageReceived(ChatMessage arg0) throws SkypeException {
SkypeClient.hideSkypeWindow();
Message response = new Message();
response.setType("skypeChat");

SkypeChatMessage msg = new SkypeChatMessage();
msg.setSkypeId(arg0.getSenderId());
msg.setMessage(arg0.getContent());

response.setData(msg);

try{
Bridge.getInstance().sendMessage(response);
} catch(Exception e) {
e.printStackTrace();
}
}

You have to start the java application first, then the AIR, otherwise you will get IOErrors on the bridge. And here is the AIR app in action:
AIRSkype.png

This is the AIR installer: Download file
and the runnable jar file: Download file

Waiting for the next version of AIR, that will let you call executable files, Merapi could be a good starting point to make your apps interoperate with AIR; there is a java implementation for nearly everything you will need, thus Merapi exponentially expands the AIR potential on desktop.

January 27, 2009

ChangeEvent vs Bindable, multiple change events for binding

When you need to define binding based on different custom events you have to use the ChangeEvent metadata tag. The ChangeEvent metadata keyword generates one or more component events when changes are made to one of its properties.

The ChangeEvent metadata keyword has the following syntax:

[ChangeEvent("event_name"[,...)]
property_declaration or a get/set function

You can register multiple change events in the metadata so that more than one event is generated when the property changes, as the following example shows:

[ChangeEvent("change1")]
[ChangeEvent("change2")]
[ChangeEvent("change3")]

Any one of those events indicates a change to the variable. They do not have to occur all to indicate a change.

So lets have a look on how to create different bindings based on different events:
First define the bindable property through the ChangeEvent metadata:

[ChangeEvent("change1")]
[ChangeEvent("change2")]
[ChangeEvent("change3")]
public var myVar:String = "";

Now we need to define some change cases:

Case 1: Change myVar and dispatch the 'change1' event

<mx:Label text="Change myVar and dispatch the 'change1' event:"/>
<mx:TextInput change="myVar = txtArea.text; dispatchEvent( new Event( 'change1' ) );" id="txtArea"/>

Case 2 Change myVar and dispatch the 'change2' event

<mx:Label text="Change myVar and dispatch the 'change2' event:"/>
<mx:TextInput change="myVar = txtArea2.text; dispatchEvent( new Event( 'change2' ) );" id="txtArea2"/>

Case 3 Change myVar and don't dispatch any events:

<mx:Label text="Change myVar and don't dispatch any events:"/>
<mx:TextInput change="myVar = txtArea3.text;" id="txtArea3"/>

And finaly use a TextArea to bind the text property to myVar:

<mx:Label text="Bind text property to myVar:"/>
<mx:TextInput text="{myVar}"/>

You can see the full, working example (right click for source) here.

February 16, 2009

Automatic serialization of ActionScript objects to and from XML

In Flex application that use a backend server for data manipulation and storage, serializing and transferring the objects from a layer to another is an important matter. With products such as BlazeDS and LiveCycle Data Services this step is almost hidden to the developer, that can fully benefit from the AMF transfer and automatic serialization of objects.
Sometimes it is not possible to use AMF and remoting and we have to rely on XML or JSON for transporting the objects. In this cases an automatic serialization from XML to ActionScript and viceversa would come in handy. Suppose we have a JavaEE backend server, that has some model classes that are exported in a custom XML. What follows also applies to JSON.
The first idea would be to get the incoming XML, use the describeType() function and parse its output, cycle through the properties and assign them to a certain ActionScript object. The same could be achieved by directly parsing the incoming XML or by using the for..in construct. The generated ActionScript objects would, however, be typeless and thus the necessity to place in the incoming XML data some hint regarding the type of object that needs to be created.
At this point we can use registerClassAlias() in flex or, more comfortably, the metadata [RemoteClass(alias="")] on top of each of the ActionScript domain classes. The AS classes will be, in this case, identical to the ones used with the remoting functionality, providing a decoupled way of serializing ActionScript objects.
The last step is building the converter class, that receives in input an XML and returns a strongly typed ActionScript object; this class will make use of getClassByAlias() to create the proper classes and fill them with the correct parameters.

Considering the case in which the Java server has a class Persona, with two properties nome and cognome, it can be exported into an XML that is similar to the following:

<?xml version="1.0" encoding="utf-8"?>
<object>
<nome>nome</nome>
<cognome>cognome</cognome>
<metadata>
<type>com.comtaste.model.Persona</type>
</metadata>
</object>

Note that we need a few naming conventions, such as the name of the root tag (in this example object) and an extra XML attribute, the metadata, which contains information about the identity of our remote object.

The target ActionScript class will simply be as if we were using it with remoting:

[RemoteClass(alias="com.comtaste.model.Persona")]
public class Persona {
public var nome:String;
public var cognome:String;
}

Note the RemoteAlias metadata, wich ensures that our class definition is registered with that alias. Inside the converter we will be able to say

var cls:Class = getClassByAlias("com.comtaste.model.Persona");
var output:Object = new cls();

and create an object of the correct ActionScript type Persona. This converter can be placed within a static function that can be called on the remote call result or inside a Cairngorm (or PureMVC) command. Using the latter approach we can benefit from the modularity these micro-architectures provide and only use the converter in few, well known, parts of the application.

The automatic converter can be written as in the following function:

public static function getObject(input:Object):* {
if ((input == null) || !input.hasOwnProperty("metadata"))
return input;

if (!input.metadata.hasOwnProperty("type"))
return input;
var cls:Class = getClassByAlias(input.metadata.type);
if (cls == null)
return input;

var output:Object = new cls();
for (var prop:Object in input) {
if (prop === "metadata")
continue;

if (input[prop] != null) {
if (input[prop].hasOwnProperty("object")) {
if (input[prop].object is ArrayCollection) {
output[prop] = new ArrayCollection();

for each (var o:Object in ArrayCollection(input[prop].object)) {
var newObj:* = getObject(o);
ArrayCollection(output[prop]).addItem(newObj);
}
} else {
output[prop] = getObject(input[prop].object);
}
} else {
output[prop] = input[prop];
}
}
}

return output;
}

This example considers the case of nested objects and uses our named convention for "object" and "metadata"; it obviously does not consider circular references. The drawback is that all of the ActionScript model classes have to be referenced in the main application at least once, so that the classes definitions would register their aliases safely.

February 23, 2009

Styling ItemRenderers in Datagrids

I'm rather new to Flex: my training began a pair of months ago. Last two weeks at Comtaste we were involved in reskinning an old application we decided to update and restyle. So, it was my first time skinning an application not for training purposes. We all already know that real world issues are slightly more subtle than the toy situations proposed in many books. So, enough talking and let's go straight to the problem.

In this example, I'm listing some people in a Datagrid component and I want to provide the user with some controls on the record, using two buttons in two separate datagrid columns.
I'm using Flex Builder, so I'll begin creating a Flex project with the following directory structure:

projtree.gif

The file src/RenderersMadness.mxml contains the following code, that implements a list with some buttons and data inside.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    applicationComplete="init()"
    layout="absolute"
    >
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            [Bindable]
            public var dataArray:ArrayCollection;
            
            private function init():void
            {
                 dataArray = new ArrayCollection(
                        [
                            {
                                name: "Peter",
                                surname: "Venkman"
                            }
                            ,
                            {
                                name: "Egon",
                                surname: "Spengler"
                            }
                            ,
                            {
                                name: "Ray",
                                surname: "Stantz"
                            }
                        ]
                    )
                
            }
        ]]>
    </mx:Script>
    <mx:DataGrid dataProvider="{dataArray}">
        <mx:columns>
            
            <mx:DataGridColumn dataField="name" headerText="First Name"/>
            
            <mx:DataGridColumn dataField="surname" headerText="Surname"/>
            
            <mx:DataGridColumn headerText="Intern him">
                <mx:itemRenderer>
                    <mx:Component>
                        <mx:Button label='Intern him' />
                    </mx:Component>
                </mx:itemRenderer>
            </mx:DataGridColumn>
            
            <mx:DataGridColumn headerText="Slime him">
                <mx:itemRenderer>
                    <mx:Component>
                        <mx:Button label='Slime!'/>
                    </mx:Component>
                </mx:itemRenderer>
            </mx:DataGridColumn>
            
        </mx:columns>
    </mx:DataGrid>
</mx:Application>

The program has the following appearance:

nostile.gif

It is ok, but I may want to add some exciting graphics and colors to customize my application. So i'm going to use the style properties of the Button component to make a stylish application, by adding the following code:


...
<mx:Button label='Intern him'
  fillColors="[0xff0000, 0xcc0000]"
  themeColor="0xff0000"
  color="0x00BBFF"/>
...

and, by storing the icon image file in the directory assets,


...
<mx:Button label='Slime!'
  fillColors="[0x00ff00, 0x00cc00]"
  color="0x0000ff"
  icon="@Embed(source='../assets/slimer.gif')"
  themeColor="0x00ff00"
  />
...

and I'm done. Here's how the component should look now:

stilenocss.gif

Looks fine, but the underlying code gives headaches. I want it to deal just with functional related issues. I don't want strange style properties whose values make the overall code look like some kind of cryptic and geeky script, and most of all, if I'm using the same style properties over a large project I don't want to repeat all of them for all the buttons in my code using such style settings.
An elegant way to separate and loosely couple graphic content such as skinning of components from functional content is to use the styleName property of Flex components and define all that concerns the style business in a .css file. I thought it was straightforward but our application makes a massive use of item renderers to show exotic and unconventional, but useful and comprehensible, representation of data in datagrids and lists. Returning to the example, I could write a CSS file (style/excitingStyle.css) to factorize the style information:


/* CSS file */
Button
{
   fillColors: #ff0000, #cc0000;
   themeColor: #ff0000;
   color:#00BBFF;
}


.slimeButton
{
   fillColors: #00ff00, #00cc00;
   color:#0000ff;
   icon: Embed(source="../assets/slimer.gif");
   themeColor: #00ff00;
}

and import it in src/RenderersMadness.mxml, before the tag:


...
<mx:Style source="../style/excitingStyle.css"/>
...

Then I can get rid of all these creepy style in the Button components, specifying just the slimeButton style for the Slime! button.


...
<mx:Button label='Intern him' />
...
<mx:Button label='Slime!' styleName='slimeButton'/>
...

But it won't work! The resulting datagrid in fact seems to ignore the styleName property.

cssnohbox.gif

Luckily, I found the solution to this problem. All that is needed is to enclose the component whose styleName property one wants to modify in a Box component:


...
<mx:HBox width="100%">
   <mx:Button label='Slime!' width="100%" styleName='slimeButton'/>
</mx:HBox>
...

And here's how the list will look like:

final.gif

The presence of the Box allows furthermore to define the component's position inside the cell. Suppose I want to drop the label "Slime!" and leave just the rather self-explanatory (at least, for me!) slimer icon. I can do the following, known the icon would be 20 pixels large:


...
<mx:HBox horizontalAlign="center" width="100%">
   <mx:Button width="20" styleName='slimeButton'/>
</mx:HBox>
...

Note that I've dropped the label property and I added the horizontalAlign property of the HBox by giving it the value "center", which centers the elements in the box, resulting in the following look:

final2.gif

So in conclusion, enclosing the component we want to use as ItemRenderer in a Box gives two advantages:

1. It is possible to use the styleName property to load styles from external css as in the rest of application.
2. It is possible to position the ItemRenderer in the cell area.

March 6, 2009

Installing and using Weborb.NET platform for Flex clients

Weborb for .NET is one of the best platform to connect Flex, Flash, AJAX and Silverlight clients with .NET objects, XML Web Services, native operating system resources and rich media streams (audio and video). In this post I will show you how to install and start up this platform on XP Professional with IIS 6.0.
First of all you have to install .NET 2.0 Framework on yours machines, following the steps below :

- open a Dos Shell
-go to the directory that contains .NET 2.0 installation files ( usually is C:\WINDOWS
\Microsoft.NET\Framework\v2.0.50727).
- Execute the command: aspnett_regiis -i

After this operation you can proceed with the weborb installation.

In order to download WEBORB platform from MIDNIGHT CODERS web site, you have to register yourself (it is FREE!) and after this you will be able to save WeborbSetup3.6.0.3.zip file on your computer. Now you have to unzip that file and run setup; after few seconds you are ready to test your WEBORB Installation.

Now open your browser and go to http:\\localhost\weborb30. At this address you can find the start page of WEBORB .NET platform.

paginaIniziale.jpg


First of all you can see a lot of example of what you can do with this platform in the section “Example” of the main Menu, but one of the most interest function is the Deployment. In this section you can create your server-side application in two different ways:

paginaDeploy.jpg


The first way is to automatically deploy weborb library in an IIS Virtual directory. It is very simple, in fact is enough to drag and drop the virtual directory from the list on the left to the list on the right, and, after a few seconds, you will have all the configurations files ready in the destination directory.

The second way is to deploy manually the weborb library following the steps below:

-Copy the following files/folders from the default Weborb installation directory to the
corresponding folders in the target virtual directory:

/Licenses/weborblicense.key.config
/bin/weborb.dll (main WebORB assembly)
   /bin/Npgsql.dll (a database driver used by WebORB Data Management)
   /bin/MySql.Data.dll (a database driver used by WebORB Data Management)
   /bin/Mono.Security.dll (a database driver used by WebORB Data Management)
   /weborb.config (product configuration file)
   /weborbee.exe (WebORB Enterprise Edition standalone server)
   /weborbee.exe.config (WebORB Enterprise Edition executable config)
   /Applications (WebORB messaging applications home)
   /Global.asax (includes WebORB messaging server startup and shutdown code. Merge the
contents if the file already exists)
   /diagnostics.aspx (product diagnostics utility)
   /WEB-INF (Flex configuration files home)
   /weborbassets (Code generator stylesheets home)
   /services (WebORB web services, contains backend support for WDMF plugin for Flex Builder)
   /weborb.js (required only for the AJAX clients)

- Add the following XML configuration to web.config in the target virtual directory:

<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="weborb.aspx" type="Weborb.ORBHttpHandler"/>
<add verb="*" path="codegen.aspx" type= "Weborb.Management.CodeGen.CodegeneratorHttpHandler"/>
</httpHandlers>
</system.web>
</configuration>

- Grant Write permission to the user account ASP.NET uses for the following files and directories:

   /weborb.config (required only if making configuration changes from the console)
   /logs (required only if logging is enabled)
   /weborbassets/codegen (required only if codegen is used in the console)
   /weborbassets/uploads
   /weborbassets/wdm
   /weborbassets/wdm/output
   /*.mdb (required only if writing data back on the server in some examples)


Another very important function in the main menu is Management where you can test our remote components without any dedicated client application!

paginaManagement2.jpg

Next time I will show you a small example with a Flex client.

March 13, 2009

Messaging from Java to Flex without JMS

With BlazeDS/LCDS you can send messages to and receive messages from a server side destination thanks to Messaging Services and their client-side API.

In your messaging configuration you can use a ActionScript Adapter:
<adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />

or a JMS Adapter:
<adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/>

that integrates Flex messaging with Java Message Service destinations.

If you don't have JMS or you don't want to use it in your web application you can send messages from Java to Flex in a very simple way.

First of all you should enable the ActionScript adapter and create your destination without additional parameters:


<destination id="actionscriptMessaging">

</destination>

In your Flex application you have your Consumer:


<mx:Consumer id="consumer"
destination="actionscriptMessaging"
message="messageHandler(event);"
fault="faultHandler(event);"/>

that is subscribed to the previous destination so that it can receive messages:


consumer.subscribe();

On the Java side, inside the context of the web application in which LCDS/BlazeDS runs, you can use these lines of codes to send messages to your Flex Consumer:


AsyncMessage msg = new AsyncMessage();
msg.setTimestamp(new Date().getTime());

msg.setClientId("JavaMessageProducer");
msg.setMessageId("JavaMessageId");

//destination configured in messaging-config.xml
msg.setDestination("actionscriptMessaging");

msg.setBody("Message from Java!");

//you can set custom message headers
msg.setHeader("headerParam1", "value1");
msg.setHeader("headerParam2", "value2");

//send message to destination
MessageBroker.getMessageBroker(null).routeMessageToService(msg, null);

This is a solution suitable for uni-directional messaging, if you want to use a bi-directional messaging system it's convenient to use JMS.

March 27, 2009

Understanding and improving Flex bindings

Data binding is the magical process by which changes in a data model are instantly exposed to views. It works because of the Flex framework that generates a lot of code for you under the hood.

Let's see what flex does when we set a property [Bindable] by using the setter and getter method like this:

public class MyComponent
{

private var _myProp:Object;

[Bindable]
public function get myProp( ) : Object
{
return _myProp;
}

public function set myProp( value:Object ) : void
{
_myProp = value;
}

}

Now when you set the myProp to some value:

var myCompInstance:MyComponent = new MyComponent( );
var myPropToSet:Object = new Object( );
myCompInstance.myProp = myPropToSet;

you are going to invoke the statement "function set myProp( value:Object )".
But Flex will do something different.
First of all it will compare the new value, myPropToSet with the last inserted _myProp, by invoking the getter function, and if the value result will be the same, the setter will not be invoked.
All of this because you have marked the property as [Bindable].
So if run a code like this:

myCompInstance.myProp = myPropToSet; <-- only this will be set
myCompInstance.myProp = myPropToSet;
myCompInstance.myProp = myPropToSet;

only the first value will be set.
So if you have the necessity to reset a value on a bindable property you have to define your custom binding:

[Bindable(event="myCustomChangeEvent")]
public function get myProp( ) : Object
{
return _myProp;
}

public function set myProp( value:Object ) : void
{
_myProp = value;
dispatchEvent( new Event( "myCustomChangeEvent" ) );
}

Now you can set the property every time you want and any item who is watching will be regularly notified.

April 27, 2009

Multiple field filtering with ArrayCollection

The flex class ActionScript has a very useful method, filterFunction, that allows to pass as a parameter another function, to be applied as a filter for the data. The filter is effectively applied only after we invoke refresh() on the ArrayCollection. The result is well known: the collection will only show those items that match the filter function, while all elements, filtered or not, can be accessed from the list or source properties of the collection.

Suppose we have a collection of objects with many properties, and we want to filter on a few properties at a time, not always the same. For example we could have the class AirplaneReservation, with a subset of the properties similar to:

public var firstName:String;
public var lastName:String;
public var gender:Number;
public var reservationDate:Date;
public var destination:String;
public var departure:String;
public var seat:String;
public var menuType:Number;

and we want to filter on whatever combination of properties, using a Form component to display them all to the user.

We could create as many filter functions as our use cases, which can be a lot to handle, or we could use different approaches, tweaking the flex framework to our needs. Rotundu made a post about multiple field filtering, that can be found here, by extending the ActionScript class and adding an array of filter functions, to be eventually applied as a single one.

The approach illustrated here is similar, in that it uses many filter functions, but different in that it does not extend ArrayCollection and associates a filter function with a field of our collection object.

We can create the Form component, with input fields for every filter (TextInput, NumericStepper and so on) and, on the change event, call a single function:

<mx:TextInput id="firstName" change="applyFilter('firstName', firstName.text)" />

In most of the cases we can use a single applyFilter() function, that receives in input the name of the property to be filtered and its value. This function will then create an ad hoc filter function and apply it to our collection. We will make use of a Dictionary to associate a field with its filter function:

private function applyFilter(field:String, value:*):void {
var f:Function;
if ((value == null) || (value.length == 0))
f = null;
else {
f = function(item:Object):Boolean {
if ((item == null) || !item.hasOwnProperty(field))
return false;

if (item[field] is Boolean)
return Boolean(item[field]) == value;
if (item[field] is Number)
return Number(item[field]) == value;
if (item[field] is String)
return String(item[field]).localeCompare(value) == 0;
if (item[field] is Date)
return Date(item[field]).time == Date(value).time;
// any other object:
return item[field] == value;
};
}

_filterFunctions[field] = f;

_collection.filterFunction = multipleFilter;
_collection.refresh();
}

This will create a filter function for the field received in input, store it in the Dictionary so that it will be available for multipleFilter():

private function multipleFilter(item:Object):Boolean {
for (var key:Object in _filterFunctions) {
var f:Function = _filterFunctions[key];
if ((f != null) && !f(item))
return false;
}

return true;
}

We can now filter as many fields as we want, at the same time, using these two functions only. The applyFilter function can easily be adapted to custom business objects, by means of object polymorphism and interfaces (Java’s Comparable is a good example).

May 5, 2009

Weborb .NET: a simple example

In my last post I showed you how to install Weborb .Net connector, now I'd like to build a little example using this technology: we will create an object from the server side and send it to the client. It's a very simple example but I think it is the better way to understand the most important functionality of Weborb.
For this example we will use IIS 6.0 and .NET 2.0 for the server side, while for the client we use a simple Flex 3 application.

The server side classes that we build for this project are:

Person.vb
DBManage.vb
DBDelegate.vb

Person class is made by three attributes: idPerson (numeric), name (String) and surname (String). This class is the VO (value object) that we want to manage both in the server and in the client side, so we have to build an ActionScript Class which references the service side class from the client.
The DBManage class has the methods to manage the persistence of data and it will be the remote object called by our flex client, through a Remote Object.

Here is the code of the class:

<Serializable()> Public Class Person
Public idPerson As Integer
Public name As String
Public surname As String
End Class


Public Class DBManage
Function tryPerson() As Person
Dim p As Person
p = New Person()
p.idPerson = 1
p.name = "Mario"
p.surname = "Rossi"
Return p
End Function
End Class


Public Class DBDelegate
Public Function tryPersonWebOrb() As Person
Dim db As DBManage
db = New DBManage()
Return db.tryPerson()
End Function
End Class

with these classes we can create a small DLL file, called weborbTrial.dll.

Before building the client we have to configure the Virtual Directory in IIS in which we will install the Weborb classes and also the client application. So we have to create a virtual directory in our IIS with permission of write and read. For information on how to install Weborb in this Directory you can see my last post.

After the installation we can carry on building the client application. First of all we have to copy into the subdirectory “bin” of our Weborb directory the weborbTrial.dll file. After we can start to create a new Flex Project. Open your Flex Builder and create a new Project. In the first screen insert the name of the Project, select the Flex Checkbox and choose the ASP.NET server configuration and click Next.

flexNewProject.JPG

In the second screen in the web application Run field insert the URL of our virtual directory and the field below insert the locale directory of the application; then in the last field insert the bin-debug directory of the application. Click finish and the project is created.

Inizio2.JPG

Before starting to write the client application, open the properties of our project and in the compiler section add this line: -services [ourDirectory]\WEB-INF\services-config.xml.

First of all we have to create the VO ActionScript class, corresponding to Person.java:

package vo
{
import mx.collections.ArrayCollection;

[Bindable]
[RemoteClass(alias="weborbTrial.Person")]
public class Person
{
public function Person(){}

public var idPerson:Number;

public var name:String;

public var surname:String;
}
}

Now we can create our client. For this example we use a simple button for call the method of the remote object defined in the Application. If the connection with the server works in the right way, we should see in the Panel the object created by the server class.

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>

<![CDATA[

import vo.Person;

import mx.collections.ArrayCollection;

import mx.rpc.events.FaultEvent;

import mx.controls.Alert;

import mx.rpc.events.ResultEvent;

//Result Event of the Remote Object

private function exec(event:ResultEvent):void{

var p:Person = new Person;

p= event.result as Person;

Name.text = p.name;

Surname.text = p.surname;

}

//Fault Event of the Remote Object

private function fault(event:FaultEvent):void{

Alert.show(event.message.toString());



}

private function addPerson():void{



exampleService.tryPersonWebOrb();

}

]]>

</mx:Script>

<mx:VBox width="100%" height="100%" verticalAlign="middle" horizontalAlign="center">

<mx:Panel title="Weborb .NET Example">



<mx:Form width="20%" height="40%" paddingBottom="30" paddingLeft="30" paddingRight="30" paddingTop="30">



<mx:FormItem label="Name">

<mx:TextInput id="Name" />

</mx:FormItem>

<mx:FormItem label="Surname">

<mx:TextInput id="Surname" />

</mx:FormItem>



</mx:Form>



</mx:Panel>



<mx:Button click="addPerson()" label="Pick a Person from .NET Server"/>

</mx:VBox>



<mx:RemoteObject id="exampleService" destination="GenericDestination" source="weborbTrial.DBDelegate" fault="fault(event)">

<mx:method name="tryPersonWebOrb" result="exec(event)" />

</mx:RemoteObject>

</mx:Application>

It is important to focus our attention on the definition of the remote object. This object is connecting to server by a default destination and channel defined in the remote-config.xml file, but it is possible to create our destination and channel and we can also define the source in the destination's property in the remote-config.xml file.

It's no hard to see that the our client application could work well also with a different server backend, with only minor changes to the configuration parameters.

Enjoy yourself with Weborb!

November 20, 2009

LiveCycle Data Services ES2 version 3 is now available

According to the Adobe's definition, LiveCycle Data Services ES2 module is a scalable and optimized framework that abstracts the complexity of creating easy-to-use, personalized, and interactive applications. It includes a rich set of features that streamline the development, integration, and deployment of rich Internet applications (RIAs).

Adobe LiveCycle Data Services 3 provides significant new capabilities, including the following:

- Support for model-driven development of Flash applications, which make application development better, faster, and easier
- Secure and scalable connectivity across the DMZ with the Edge Server.
- New capabilities for developers to control and measure the quality of service of enterprise applications.

All the documentation is ready and available online:
LiveCycle Data Services ES2 version 3 Docs

You can download the LiveCycle Data Services ES2 free developer edition.

modal.jpg

February 19, 2010

Filtering nested elements of a Tree data provider

Rich Internet applications developed with Flex benefit of many of the built-in functionality already provided by this framework. One of such enhancement is the filterFunction, that can be applied to instances of class ListCollectionView (and extending ones, such as the more commonly used ArrayCollection) and allows for fast and easy to implement filtering of data. This feature, used with advanced visualization controls as DataGrid or List, provides a rich environment for the end user, that can fully control the data he/she is working with.

The filter function is best suited with visualization controls that do not consider hierarchical data, but there may be cases in which the filter should be applied to hierarchical objects, displayed, for example, into a Tree component. If we apply the filterFunction to the data provider of a Tree component, the filter will only be applied to the first elements in the hierarchy and will not be applied to nested children. This may appear as an unwanted feature of the Tree, but it was actually meant to be that way, as the Tree control strives to be as independent as possible from the underlying displayed data and allows for personalization through it's descriptor.

In order to filter all nodes of a Flex Tree component, the solution is to apply the filter function to each nested element of the data provider. This can be accomplished by creating a new hierarchical structure, already filtered (can be rather expensive), or using dynamic filtering over the Tree's default descriptor, as shown below.

I extended the DefaultDataDescriptor used by the Tree, into a FilteredDataDescriptor, that has an additional field, namely filterFunction, which is applied as filter to each element of the nested structure:


private var _filterFunction:Function;

public function get filterFunction():Function {
return _filterFunction;
}

/**
* Applies this filter function to the children of every node.
* @param value
*/
public function set filterFunction(value:Function):void {
_filterFunction = value;
}

In order to apply the filter to the children of the data provider we can override getChildren() and, before returning the collection of children, apply the filter function:


override public function getChildren(node:Object, model:Object=null):ICollectionView {
var collection:ICollectionView = super.getChildren(node, model);

if (collection && (collection is ListCollectionView)) {
(collection as ListCollectionView).filterFunction = _filterFunction;
}
return collection;
}

Note that this will work only for classes extending ListCollectionView (obviously Array is out of the picture) and that we also do not need to specifically call refresh() on the children collection, as it will be called later by the framework itself. All that's left now is to assign the newly created tree descriptor to a Tree and pass it the proper filter function(s).

March 4, 2010

Spring BlazeDS Integration

Hi to all, in this post I will explain how simple it is to configure an application that requires

- Front-end in Flex
- Back-end in Spring

with the Spring BlazeDS Integration.

To illustrate the integration support of Spring BlazeDS, I've built a sample application with:

Flex 4
Spring 2.5.6
Tomcat 6
MySql 5
Java 6

Data representation

We just represent information about Employee set. Specifically we represent the following fields:

- name
- surname
- address
- email
- category, to simplify we have supposed only 4 category : analyst – consultant – junior - manager

Architecture layers

Front-end

- Flex application that shows data on Employee set.

Back-end, ORM framework JPA

- Spring bean : EmployeeService
- DAO : EmployeeDAO
- Data : Employee

How to configurate Spring BlazeDS Integration

First of all we have to configure the MessageBroker component, core of the Spring BlazeDS Integration, because HTTP messages from the Flex client will be routed through the Spring DispatcherServlet to Spring managed MessageBroker.
Once this step is complete, we will be sure that remoting calls from the flex client reach their destination, so all we have to do is allow Spring to export its beans. To ensure this we must configure the BlazeDS Remoting service and all the necessary remote destinations.

MessageBroker's configuration

We have to configure MessageBroker into app-context.xml file

Add Flex namespace

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:flex="http://www.springframework.org/schema/flex"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

...
<beans>

Spring provide an XML config namespace for MessageBroker's configuration inside app-context. To use the namespace support we must add the schema location into the Spring XML configuration files. This makes the Spring BlazeDS Integration configuration tags available under the flex namespace into ours configuration files. We have to be sure to refer to the spring-flex-1.0.xsd as every element and attribute is fully documented there.

To complete MessageBroker's configuration we have to add message-broker tag :

<flex:message-broker/>

How to configurate Flex client's mapping towards MessageBroker in three simple steps

1) Definition of the DispatcherServlet in web.xml

The simple request mapping scenario is when the front-end Flex is the only client type for the application. In this case we can just map /messagebroker as top-level path for requests.

<servlet>
<servlet-name>BlazeServlet</servlet-name>
<servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/spring/app-context.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>BlazeServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

2) HandlerMapping into Spring app-context.xml

We have to configure an HandlerMapping to allow the correct requests mapping towards MessageBroker, but in this case we have to do nothing, because when we use a message-broker tag, there is a bean automatically installed that allows the HandlerMapping. This bean is a SimpleUrlHandlerMapping that maps all the incoming requests from DispathcherServlet to MessageBroker through the MessageBrokerHandlerAdapter. In practice the default settings installed by <flex:message-broker/> tag regard how to include the following configuration:

<!-- Maps request paths at /* to the BlazeDS MessageBroker -->
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=_messageBroker
</value>
</property>
</bean>

<!-- Dispatches requests mapped to a MessageBroker -->
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>

So HandlerMapping configuration in the spring app-contex.xml is how to include the message-broker tag.

3) Channel definition in the BlazeDS services-config.xml

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/ {context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>

To complete the correct requests mapping towards MessageBroker we have to define a channel to secure communication from client to server. In this way flex client can send and receive data correctly. Channel definition is in the services-config.xml file and must correspond to the chosen mapping.

Exporting Spring beans for Flex Remoting

1) Remoting Service config

To configure the BlazeDS RemotingService we have to include remoting-config.xml file in the BlazeDS configuration, but with the Spring BlazeDS Integration this configuration file can be left out completely as the inclusion of the message-broker tag in the Spring configuration will cause the RemotingService to be configured with sensible defaults if none already exists at startup time. The end result is essentially equivalent to including the following minimal remoting-config.xml in the BlazeDS configuration.

<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
</service>

We have just set a default channel in the service-config.xml

<services>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
</services>

2) Remoting destination tag

It allows to export existing Spring-managed services for direct remoting from a Flex client. Given the following Spring bean definition for a employeeService bean :

<!-- Bean employeeService -->
<bean id="employeeService" class="service.EmployeeService">
<constructor-arg ref="employeeDAO" />
</bean>

and assuming the existance of a Spring-managed MessageBroker configured via the message-broker tag, the following remoting-destination tag will expose the service for remoting to Flex client as a remote service destination called employeeService:

<!-- REMOTING DESTINATION TAG -->
<flex:remoting-destination ref="employeeService" />

We have seen that with few steps is possible to build an application that support a front-end in Flex and a back-end in Spring through the Spring BlazeDS Integration which focuses on a single main component : MessageBroker.

At this link you'll find the official Spring BlazeDS Integration reference.

March 15, 2010

AutoComplete custom component in Flex

Around the web we can find a lot of interesting e useful flex custom components. In my last works I had the chance to use the Autocomplete component developed by Hillel Coren (http://hillelcoren.com). In this post I'll try to present it briefly.


Customizing behavior and interface of the component :
This component is very similar to a standard ComboBox, although it doesn't extend from that kind of flex UIComponent. It has a fair number settings you can adjust, like:
- selectedItemsStyleName: through this property, developers can control the look of selected items. There are four choices: facebook, macMail, underline and none
- prompt: using this property you can set a string the component will display when no value is set.
- ackSpaceAction: this property determines what to do when a user press backspace. By default the component focus the item, but this can be changed to remove it.
- enableClearIcon: this boolean property, if set to true, make the component to display a little cross icon that allow users to clean the search field of the component.

Customizing drop down aspect
We can control how the item is displayed through out the component setting the labelField or the labelFunction property, like in most other Flex components. AutoComplete has two other properties we can use for customizing the drop down label:
- dropDownLabelFunction: which returns an HTML string to handle formatting the item;
- dropDownItemRenderer: if you like greater control over the layout.

Multiple selections and events
If the boolean property allowMultipleSelection is set to “true”, the component allows user to select more than one item. So the AutoComplete can contain selected items and the search string. Access to all these elements is granted by two properties:
- searchText: this property can be used to get/set the search string.
- text : this property returns a string representation of the selected items.

Related to this there are two main events which the component dispatches: change and searchChange. The change event is dispatched when the selectedItem property changes, while the searchChange event is dispatched when the search string is changed.


Filtering the data
To filter the data you can use the built-in options by setting the “matchType” property; the built-in options are:
- beginning: Only match the beginning of the string.
- word: Match the beginning of any of the words in the string.
- anyPart: Matches any part of the string.

You can also create a custom filter by setting a value for the filterFunction property.


Example Application
I used the AutoComplete component in the “search area” of an application, to supply users with a better experience in navigating data and searching information. It's also very useful in filtering collections of data ( and complex data) represented by listComponent. To demonstrate this I wrote a simple example application in which users can use the autoComplete component to filter the entries of a data grid containing information about people, represented with “name”, “last name” and an “email” address.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
xmlns:hc="com.hillelcoren.components.*">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import com.hillelcoren.utils.StringUtils;
import com.hillelcoren.components.AutoComplete;

private function labelFunction(item:Object):String
{
var str:String = item["name"] +" "+item["lastname"]+ " &lt; "+item["email"]+" &gt;";
return str;
}

private function filterFunction( item:Object, searchStr:String ):Boolean
{
if (searchStr.length == 0)
{
return true;
}

var str:String = labelFunction(item);

switch (autoComplete.matchType)
{
case AutoComplete.MATCH_ANY_PART:
return StringUtils.contains( str, searchStr );
case AutoComplete.MATCH_BEGINNING:
return StringUtils.beginsWith( str, searchStr );
case AutoComplete.MATCH_WORD:
return StringUtils.anyWordBeginsWith( str, searchStr );
}
return false;
}

]]>
</mx:Script>
<mx:ArrayCollection id="dataProvider">
<mx:Array id="dataArray">
<mx:Object name="Peter" lastname="Griffin" email="p.griffin@gmail.com"/>
<mx:Object name="Mario" lastname="Brega" email="m.brega@gmail.com"/>
<mx:Object name="Homer" lastname="Simpson" email="h.simpson@yahoo.com"/>
<mx:Object name="Clark" lastname="Kent" email="c.kent@gmail.com"/>
<mx:Object name="Lex" lastname="Luthor" email="l.luthor@gmail.com"/>
<mx:Object name="Peter" lastname="Parker" email="p.parker@yahoo.com"/>
<mx:Object name="Ned" lastname="Flanders" email="n.flanders@gmail.com"/>
<mx:Object name="Lois" lastname="Lane" email="l.lane@gmail.com"/>
<mx:Object name="John" lastname="Zoidberg" email="j.zoidberg@yahoo.com"/>
</mx:Array>
</mx:ArrayCollection>



<hc:AutoComplete id="autoComplete" dataProvider="{this.dataProvider}"
width="35%"
labelFunction="labelFunction"
enableClearIcon="true"
prompt="Type in name or lastname or email"
filterFunction="filterFunction" />
<mx:Spacer width="10%"/>
<mx:DataGrid id="dataGrid" dataProvider="{this.dataProvider}"
width="40%" />

</mx:Application>

To obtain the correct behavior I customized the functions labelFunction and filterFunction. I needed to rewrite the first function to group the three fields in a single string, that is then used by the second function to filter data using the string representation of those fields. In this way users are allowed to search people in the datagrid, by name, by lastname or email, typing in the search string using one single autoComplete component.

This custom component could be very useful also in input forms, as “smart TextInput” component. Unfortunately in this context this AutoComplete component has a little lack. It has been designed to select one item (or more) from an existing collection, but not to insert new items. The allowNewValues property allows user to insert new values in the search field, but not in the collection set as dataProvider of the AutoComplete. Moreover it is not possible to write in the search text values that have as prefixes strings representing items already in the dataprovider collection. For example: it is not possible to write “Alexander” in the search text if in the data provider there is already an item represented by the string “Alex”. Trying to type-in “Alexander” will automatically select “Alex” at the fourth character.

More information available about the component can be found within its documentation: http://web.me.com/hillelcoren/Site/AutoComplete.html

March 24, 2010

First steps with Mate Flex framework

Mate (pronounced mah-teh) is a Flex framework for the MVC ( Model View Control ) Pattern. Like other frameworks, Mate addresses the common architectural concerns in Flex such as event handling, data binding, and asynchronous processing, but the most important goal is that it's only tag-based so it's very easy to use it in our Flex Applications.
Now we are going to see how Mate manages the events and the operations connected to them and how the Data results are injected into our application.

The core of the Mate framework is the EventMap tag, where we can define all the handlers of the Events, the Objects that manage Data and the View. We can create a lot of Event maps in our application and put them in every Conteiner Components, it's easy to understand that is necessary to be careful about the position where we put them (remember the Event Handlers rule) in our Application hierarchy.
Here is a simple graph of Mate's architecture:

Mate.JPG

Now we go to see how to build an EventMap component.
First of all it's necessary to include in our project the Mate swc library. After this we can create the our EventMap component like this:

<mate:EventMap>

</mate:EventMap>

We can use this tag within our application MXML, but I think it's better to create an external component, so it easy to define the functionalities of the framework, and also we are sure that the pattern MVC isn't violated.

In the EventMap tag we can insert some EventHandler tags, were we can define the attribute “type” that indicates the type of the Event that we want to handler. All the events that we want to manage inside the EventMap could be custom or created by us, but remember to built them with the parameter bubbles set to true:

package com.comtaste.controls
{
import flash.events.Event;

public class MyEvent extends Event
{
public static const CONST_MY_EVENT:String = "constMyEvent"
public function MyEvent(type:String,bubble:Boolean = true,cancelable:Boolean = false)
{
super(type,bubble,cancelable);
}
}
}

Here is a small example of EventHandler tag:

<mate:EventMap>

<mate:EventHandlers type="{MyEvent.CONST_MY_EVENT}">

</mate:EventHandlers>

</mate:EventMap>

Once the setup of our EventHandlers is complete, we can define the Objects and the Methods that retrieve or send data from/to a server. Inside the Mate Framework we have this three tags:


  • RemoteObjectInvoker

  • WebServiceObjectInvoker

  • HTTPServiceObjectInvoker


All of these tags are used to create Object instance based on, respectively, RemoteObject class, WebService Class and HttpServive class. With them we can call a method on the object created and specify the same attributes of the standard classes from mx library. In addition, you can specify the methods to call directly as tag attribute.

Inside the Mate tags above we could define the handlers for the ResultEvent and FaultEvent, as in this part of code:

<RemoteObjectInvoker destination="YourDestination"
source="path.to.your.service"
method="methodToCall"
arguments="{['argument1', 'argument2']}">

<resultHandlers>
... this list executes when server returns results ...
</resultHandlers>

<faultHandlers>
... this list executes when server returns an error ...
</faultHandlers>

</RemoteObjectInvoker>

Into the methods that manage the result of the service, we have to define the input parameters like the contents of what the service returned, and we have to do the same thing for the fault methods (in this case the event.fault).

To specify the methods that handle the results events we can use this tag:

<MethodInvoker generator="WorkerTwo" method="receiveResults" arguments="{resultObject}" />

Here we define the class that contains the method in the attribute “generator”, the method's name in the “method” attribute and the resultObject in the “arguments” attribute. The resultObject contains the data returned by our service.
For the faults handler we can use the same tag shown above but we have to insert into it the attribute “arguments”. View the code below:

arguments="{event.fault}"

in this way we can manage the fault messages returned by the service.

So we have seen how to manage the controller layer in a Flex Application, now we are going to see the Model Layer.
Mate framework gives us an MXML-based class for the injection of the data coming from our services into the View Layer: Injector class.

The Injector Class is located as a tag inside our EventMap. In it we can push the value coming from the result of the services into the property of the object in our Application Components. Remember that the visibility of the view-object by the EventMap depends on the position of this tag inside the application hierarchy.
Below you can see an example of the Injector tag:

<Injectors target="{MyView}">
<PropertyInjector targetKey="myVar" source="{MyModel}" sourceKey="modelVar" />
</Injectors>

In the Injector tag the “target” attribute indicates the target component of the injection and the “targetKey” attribute in the ProjectInjector tag indicates the attribute of the target component that must to be change. Moreover the “source” and the “sourceKey” attributes, both in the ProjectInjector tag, are respectively the Class and the value where the injection starts.

What I explained in this post is a very simple demonstration of the architectural structure of the Mate Framework. Next time I will show you a little example where we could see something more and afew best-practice rules to applicate for a correct use of this framework.

Regards

March 29, 2010

Flex WebService: how to list available operations at runtime

The Flex WebService component provides a operations property but this is set by the MXML compiler and contains only the operations listed in the tag.
If you want to access an unknown webservice and list at runtime all available operations, you can parse the WSDL xml by yourself or, more easily, use the WSDL parser of the Flex SDK.

Here a small example that I will explain later:


<mx:Script>
   <![CDATA[
      import mx.rpc.soap.LoadEvent;
      import mx.rpc.wsdl.WSDLOperation;

      protected function loadHandler(event:LoadEvent):void
      {
         if(event.wsdl) {
            for each(var op:WSDLOperation in event.wsdl.getPort().binding.portType.operations()) {
               trace(op.name);
            }
         }
      }
   ]]>
</mx:Script>

<mx:WebService load="loadHandler(event)" useProxy="false"
   wsdl="http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl"/>

One of the events for the WebService component is the load event. As stated on the reference the wsdl property of the LoadEvent class contains the WSDL object of the webservice just loaded. I'm not sure if this property could be null but I prefer to add a control to avoid a null pointer exception.
Now we have a WSDL object, but this class is not included in Flex language reference, so let's take a look to its source:


[ExcludeClass]
/**
* Manages a WSDL top-level definitions element. WSDL definitions
* may contain imports to other WSDL definitions. Only SOAP bindings are
* supported.
*
* @private
*/
public class WSDL

Well, this class will neither show up in the docs nor in the Flex Builder intellisense. This could indicate that it can be not stable or it could change with any SDK update, so pay attention!
Digging in the source I found that the interesting part is in parseBinding. Here for every tag parsed a WSDLOperation is created and added

to a WSDLPortType object. This portType is stored in a WSDLBinding object that is returned by this function. The parseBinding method is called by the method itself and in the parsePort method. parsePort is called by parseService that is in getService method. You can call getService directly or through getPort.

These two methods both accept a serviceName and a portName parameter, both optional. The WSDLBinding object is stored in a WSDLPort that you can access using the getPort method.

In this way you can build a dynamic client to access every WebService without the need to know its structure in advance.

April 2, 2010

Dynamic creation of messaging destinations in BlazeDS

In a former post on this blog I wrote about messaging from java to flex without using JMS. That can be a good starting point for the current post's topic: http://blog.comtaste.com/2009/03/messaging_from_java_to_flex_wi_1.html.

In that case I was relying on a correct blazeds messaging configuration where a messaging destination called actionscriptMessaging was created.
I can think about several use cases where the number and configuration of messaging destinations cannot be determined at implementation or deploy time: think about social or collaborative applications where users are organized in different groups depending on their interest or a common goal, or a much simpler example, a chat where a user can create a private chat room.

If you want to send messages only to some clients you can use the consumer selector property: http://livedocs.adobe.com/blazeds/1/blazeds_devguide/help.html?content=messaging_6.html or alternatively you can create multiple destinations.
Creating a destination from a J2EE backend (where BlazeDS is deployed) is as simple as writing these lines of code:

        MessageBroker broker = MessageBroker.getMessageBroker(null);
        service = (MessageService) broker.getService("message-service");
        destination = (MessageDestination) service.createDestination("myDest");
 
        if (service.isStarted()) {
        	destination.start(); 
        }

The service id must be the one specified in messaging-config.xml:

<service id="message-service" class="flex.messaging.services.MessageService">

The message broker is obtained in the same way as the former post, the null parameter is better explained in the class javadocs: http://help.adobe.com/en_US/livecycle/9.0/programLC/javadoc/flex/messaging/MessageBroker.html#getMessageBroker(java.lang.String)

The destination must be started before any client tries to subscribe, otherwise you would get the "No destination configured" error. Here it is the client side subscription:

    var c:Consumer = new Consumer();
    c.destination = "myDest";
 
    var channelSet:ChannelSet = new ChannelSet();
    channelSet.addChannel(new AMFChannel("my-polling-amf", "http://localhost:8080/ContextRoot/messagebroker/amfpolling"));
 
    c.channelSet = channelSet;
    c.subscribe();

Of course the destination must match the newly created server side messaging destination; the other peculiarity is the manual setting of the channel used: not having configured a channel server side we can specify the desired channel. That must be among the channels defined in services-config.xml

        <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
 
            <properties>
                <polling-enabled>true</polling-enabled>
                <polling-interval-seconds>4</polling-interval-seconds>
            </properties>
        </channel-definition>

The message sending is the same as specified in the former blog post:

        AsyncMessage msg = new AsyncMessage();
        msg.setClientId("Java dispatcher");
        msg.setTimestamp(new Date().getTime());
        // Unique ID
        msg.setMessageId(UUIDUtils.createUUID());
        msg.setDestination("myDest");
        msg.setBody("My message");
 
        //send message to destination
        MessageBroker.getMessageBroker(null).routeMessageToService(msg, null);

Note that the message body (in this example a simple string) can be any object mapped in ActionScript with the RemoteClass tag.

April 13, 2010

Swiz Framework - Inversion of Control micro-architecture

Swiz is a Flex framework that aims at simplicity in development of Rich Internet Applications by hiding most of the boilerplate code behind well-designed metadata that implement Inversion of Control and simply inject objects where they are required. Besides this, Swiz also introduces Custom Metadata Processors, with which developers can easily introduce their own, meaningful metadata and extend processors to grant them functionality.
In this post we will see how to configure and use the last available version of Swiz, 1.0.0 beta, that can be downloaded from their site as a pre-compiled library or source code from their GIT repository.
All of Swiz configuration is done within the main application file; for example, in MXML:


<fx:Declarations>
<swiz:SwizConfig id="swizConfig" strict="true"
eventPackages="com.comtaste.rss.events"
viewPackages="com.comtaste.rss.view" />
<swiz:Swiz id="swiz" config="{swizConfig}">
<swiz:beanProviders>
<swiz:BeanProvider>
<control:RSSController />
<model:RSSModel />
<swiz:Bean name="serviceLocator">
<model:ServiceLocator />
</swiz:Bean>
</swiz:BeanProvider>
</swiz:beanProviders>
</swiz:Swiz>
</fx:Declarations>

SwizConfig defines the global configuration:


  • eventPackages - name of the package(s) where custom events are defined. These events will be automatically associated with custom controllers that perform logical or remote operations.

  • viewPackages - name of the package(s) where views of the application are defined. Swiz listens for custom events launched by these views and triggers the mapped controller(s).


These two properties ensure that launched events are captured and mapped to their actions, automatically in the background. It is possible to use Swiz injection without automatic event mapping, simply by not setting these properties.

Swiz uses the previously defined SwizConfig to define which objects are to be injected: each instance of this class has its own set of beans, that can be defined in two ways:


  • by class type, inserting each type in the bean provider list

  • by name, inserting a Bean object with a name and a type in the bean provider list

In this example I have chosen to create three beans: controller, model and service locator. I used the service locator in reference to Cairngorm's one, as a repository of remote services, but in this case it's just a simple Object. One can make many other choices, such as placing the remote services within delegates, controllers, or define them as additional beans.

A powerful feature of this new version of Swiz is that it can define multiple bean contexts, each with its set of beans, simply by defining Swiz instances.

The last set of classes we need are the controllers, that may or may not extend Swiz's AbstractController. Extending this class provides methods such as executeServiceCall or executeURLRequest, which allow to call a remote service and assign handler methods:


[Mediate(event="RSSEvent.GET_RSS_FEED")]
public function getFeed():void {
super.executeServiceCall(serviceLocator.rssService.send(), onFeedResult, onFault);
}

Another powerful feature of Swiz comes with the Mediate metadata, that allows a custom event that is defined in one of the packages configured through the eventPackages property to be automatically associated with a method. This handler method can also take parameters in input, as for example the event itself:


[Mediate(event="RSSEvent.GET_RSS_FEED")]
public function getFeed(event:RSSEvent):void {}

More than this, if the event has properties, they can be defined within the metadata and their values are passed to the handler method. Suppose the event has two properties, url and date:


[Mediate(event="RSSEvent.GET_RSS_FEED", properties="url,date")]
public function getFeed(url:String, date:Date):void {}

The properties of each metadata are carefully checked by the Swiz engine, at runtime, and errors are thrown when event names or properties are spelled wrong. These errors are descriptive and it's rather easy to understand which property of which metadata is wrong.

Bean injection is realized through the use of the Inject metadata. This metadata replaces the Autowire one, which got deprecated from the previous stable version:


[Inject(bean="serviceLocator")]
public var serviceLocator:ServiceLocator;

[Inject]
public var model:RSSModel;

In this example, serviceLocator is injected through the name of its bean while model is injected through the type of its class, as defined in the bean providers above.

Swiz, with its dependency injection and custom metadata, is a powerful framework and offers a lot of interesting possibilities. In future posts we will see how to take full advantage of it and use custom metadata.

This working example and its source-code can be found here.

May 11, 2010

Mate Framework - an example

In my last post I showed you how Mate framework works. Now I would like to deepen the study on this framework with a short example, and I'd like to show one of best practice ways to use it. For this project I used Flex 4 and Mate_08_9.swc library.

In respect of the Model View Control Pattern I create a project with six packages: business, component, controls,maps, model and view.

MateProject.JPG

In the business package I create all the classes that can communicate with remote services (like http services or wsdl services ), in fact you can find there a ServiceLocator class as an MXML file, that extends the Object class, where I put an httpService tag, from which I would like to obtain an XML File.

 <?xml version="1.0" encoding="UTF-8"?>
<DataPerson>
	<Person>
		<name>Name</name>
		<surname>Surname</surname>
		<phone>12345678</phone>
	</Person>
	<Person>
		<name>Name 1</name>
		<surname>Surname 1</surname>
		<phone>123456789</phone>
	</Person>
</DataPerson>

In the Component package I create the components of my application (in this example only MyDataGrid.mxml) that I use into my View.
In the controls package I put my Event class, in the maps package My Mate EventMap, and in the model package I create a singleton call MateExampleModel where I manage all the data structure used by my view components that are in View package.

Hope that the project structure is easy to understand, I would like to analize the core of the project in particular how I follow the MVC Pattern with Mate Framework.

First of all we can see into the Application tag (view.MateExample.xml) all the View components present in my project, and it's easy to see that there are only an event dispatcher, a data binding with a property of the model, and the build of the EventMap component (component.MyEntityMap).

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:component="component.*" xmlns:maps="maps.*">
	<mx:Script>
		<![CDATA[
			import controls.XMLLoadMateEvent;
			import model.ModelMateExample;
 
			public var evt:XMLLoadMateEvent = new XMLLoadMateEvent(XMLLoadMateEvent.XML_LOAD);
		]]>
	</mx:Script>
 
	<mx:HBox width="100%" height="100%">
		<mx:VBox width="30%">
			<s:Button label="Fill the Datagrid" click="{dispatchEvent(evt)}" />
			<component:MyDataGrid width="100%" height="100%" dataProvider="{ModelMateExample.instance().gridDB}"/>
		</mx:VBox>
	</mx:HBox>
	<maps:MyEntityMap />	
</mx:Application>

The Control components are the Event Class, dispatched by the view, and the HttpServiceManage Class that contains all the methods for manage the resultObject coming from the HttpService (result and fault methods).

The Mate Entity Map is separated by the other Control classes, and it contains all the tags that we analized in my last post... but I think is a good idea to deepen how I used that tags. First we can see how I manage the httpService: on the bottom of the file MyEventMap.mxml I build an object from my ServiceLocator and I used it to generate an instance of an httpService into the HttpServiveInvoker tag, and, inside it, I manage the resultObject and the fault with the methods of an instance of the HttpServiceManage Class (view the code below).

<?xml version="1.0" encoding="utf-8"?>
<mate:EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:mate="http://mate.asfusion.com/" xmlns:business="business.*">
	<mx:Script>
		<![CDATA[
			import controls.HttpServiceManage;
			import controls.XMLLoadMateEvent;
		]]>
	</mx:Script>
  
	<!-- enable debugger -->
	<mate:Debugger level="{Debugger.ALL}"/>
  
	<!-- handler of the XMLLoadMateEvent -->
	<mate:EventHandlers type="{XMLLoadMateEvent.XML_LOAD}" debug="true">
		<!-- HTTP Service -->
		<mate:HTTPServiceInvoker instance="{service.httpService}" debug="true" >
			<!-- result handlers -->
			<mate:resultHandlers >
				<mate:MethodInvoker generator="{HttpServiceManage}" method="result" arguments="{resultObject}" >
				</mate:MethodInvoker>
			</mate:resultHandlers>
 
			<!-- fault handlers -->
			<mate:faultHandlers>
				<mate:MethodInvoker generator="{HttpServiceManage}" method="fault" arguments="{fault}" >
				</mate:MethodInvoker>
			</mate:faultHandlers>
		</mate:HTTPServiceInvoker>		
	</mate:EventHandlers>
 
	<!-- Service Locator -->
	<business:ServiceLocator id="service"/>
</mate:EventMap>

It's very import to see that I manage the model of my application without the PropertyInjector tag . In fact, if you see the code of the HttpServiceManageClass, you can observe that I use the model's objects inside the result method of my httpService.

package controls
{
	import model.ModelMateExample;	
	import mx.controls.Alert;
	import mx.rpc.Fault;
  
	public class HttpServiceManage
	{
		public function HttpServiceManage()
		{
		}
		public function result(obj:Object):void{
			ModelMateExample.instance().gridDB = obj.DataPerson.Person;
		}
		public function fault(faultObj:Fault):void{
			Alert.show("Error: "+faultObj.message);
		}
	}
}

Generally I prefer to use this kind of solution because I think it could be clearer for whom want to analize my code to understand the funcionalities and the model's properties managed by the methods.
This approach is not the only one that you can use in your Mate Project, in fact it would like to be only an example of the flexibility of this framework.I think that Mate could be a very simple and power solution for create Flex Project with a solid structure that guarantees good quality for our projects.

Download example source code

Regards

May 31, 2010

Swiz framework - Custom Metadata Processor

In my last post I briefly introduced Swiz framework and uncovered part of its great potential. This post will be about Swiz's custom metadata processor, a powerful tool available with the 1.0 release. The metadata processors were available in previous versions also, but now their API is open and allows developers to create their own ActionScript metadata and handle them rather easily.

As an example shows on their site, one has to choose a new metadata name and extend org.swizframework.processors.BaseMetadataProcessor (this class was called MetadataProcessor in the alpha release). In the example, a Random metadata was created, that assigns a random numeric value to any variable it decorates:


[Random]
public var randomNumber:Number;

Such custom metadata are is extremely easy to use: once the processor class is created, it can simply be added to Swiz's custom processors:


<swiz:customProcessors>
<processors:RandomProcessor />
</swiz:customProcessors>

Obviously one should remember to edit the compiler parameters in order to add support for the newly created metadata: -keep-as3-metadata+=Random.

Since it came out, many useful custom metadata processors have been developed and released. Some of them, in no particular order, are:


  • Log processor: just add a [Log] decoration to an instance of ILogger, to enable fast access to Flex logging API.

  • Geocode Processor: automatizes parts of the ESRI geolocation features.

  • Yahoo Finance: proof of concept that uses live data from Yahoo to populate a list decorated with custom metadata.

  • Foomonger: metadata processor that simplifies the use of Swiz with AS3signals

ActionScript metadata are customizable by themselves, but using Swiz framework makes the task more easy and fun. Looking forward to see a [WrittenWhile] metadata!

June 24, 2010

Security Data Trasfer - AS3 Encrypting Libraries and Http Monitor Softwares

One of the most important problem in Application development is the Security of Data Transfer from\to Client to\from Server. The Flash Player environment has a lot of security rules and controls to safeguard data in the Web, but sometimes it's not enough, so we have to integrate them with Encrypting Algorithms develops in our ActionScript Classes. Now we are going to see a little overview that allows us a knowledge of the most simple and useful AS library for encrypting data.

The first library is the as3crypto library. This is available in the Google Code at this address . As you can see on the documentation, the library provides a lot of Hashing Algorithms, like MD5 and SHA-256, Public Key Encryption Algorithms , like RSA, and Secret Key Encryption Algorithms, and introduces a SSL engine. I suggest to see the demo with all the functionalities of the as3crypto library. Another Encrypting Library is as3corelib. Like the as3crypto, the as3corelib is published on Goggle Code at the address, here is the source code of the library and the documentation, but there isn't a demo about it. as3corelib also does not have Encryption Algorithms but only Hashing Algorithms.

Sometimes it is useful to measure the Security of our applications, so we can use these free products to see the data transfer between Client and Server : SWFScan by HP and Charles. SWFScan automatically find security vulnerabilities in applications built on the Flash Platform. It decompiles applications built on the Flash Platform to extract the ActionScript code and statically analyzes it to identify security issues such as information disclosure; identifies and reports insecure programming and deployment practices; and suggests solutions. You can download it from this site.
HP SWFScan offers several other features to help developers, code auditor/reviewers, and pen-testers examine the contents of Flash applications, including:


  • Highlighting the line of source code that contains the vulnerability to help better understand the context of the issue.

  • Providing summaries, details, and remediation advice for each vulnerability in accordance with Adobe's recommendation for secure Flash development.

  • Generating a vulnerability report to share and solve the detected issues.

  • Exporting the decompiled source code for use with other external tools.

  • Revealing all the URLs and web services the Flash Application contacts.

  • Flagging class names, function names, or variable names that may be of interest such as
    loadedUserXml or crypt().

Charles is an Http Proxy and an HTTP Monitor, it is enable to see all the data transfer in a browser web or between a client and a server, it is also ables to monitor the AMF protocol traffic. You can have more information here . I think it's a very useful tool for the visualization of Data Trasfer between client and Server and it takes a great support for evidence the bugs in security in our SWF Applications. Next time i will deepen all the functionalities of this Software.

Regards

July 3, 2010

Flex Webservice: how to list available parameters for each operation

In a previous post I explained how to list available operations provided by a WebService, parsing the WSDL document using some undocumented classes of the Flex 3 and 4 SDKs.
This time I want to give you some suggestions about the next step: listing parameters of every operation.
NB: most of the classes in the package mx.rpc.wsdl have the tag [ExcludeClass] so they could change with an SDK update or they can be not stable. Flex Builder intellisense will not work for these classes, so you have to import them manually.
Note that I'm testing this code using a WSDL from a Axis2 WebService, it may not work on WSDL with a different structure or it may need some tweaks.

<mx:Script>
	<![CDATA[
		import mx.rpc.soap.LoadEvent;
		import mx.rpc.wsdl.WSDLMessagePart;
		import mx.rpc.wsdl.WSDLOperation;
		import mx.rpc.xml.Schema;
		protected function loadHandler(event:LoadEvent):void
		{
			if(event.wsdl) {
				for each(var op:WSDLOperation in event.wsdl.getPort().binding.portType.operations()) {
					var param:WSDLMessagePart = op.inputMessage.getPart("parameters");
					if(param) {
						var schema:Schema = event.wsdl.schemaManager.getResourcesForURI(param.element.uri)[0] as Schema;
						var element:Object = schema.getNamedDefinition(new QName(schema.schemaConstants.xsdURI,param.element.localName),schema.schemaConstants.elementTypeQName);
						trace(element.definition, element.schema);
					} 
				}
			}
		}
	]]>
</mx:Script>

This small script, based on the code of the previous post, analyze the inputMessage of the WSDLOperation. If there is a WSDLMessagePart with name "parameters", it looks for the related Schema and then it searches the definition of the element of the WSDLMessagePart. This definition is just the XML of the complexType of the parameter, then you have to write your custom logic to use it. Some WSDL may non have the "part" node, instead there is the name of the element, you have to slightly modify the code above.

This is just a sketch and not a ready-to-use solution but it can point you in the right direction.

July 12, 2010

Adobe Alchemy: a comparative example

In my last post I introduced the Alchemy Project and I explained how to install/set up the Alchemy environment on a Window machine to compile a very simple "c" file in a swc.
Today I'll go deeper and talk about Alchemy through a comparative example: Alchemy aimes to allow users to take advantage of efficient C/C++ (existing or not) designed to accomplish very cpu-intensive tasks. The performance improvements of flex applications can be very significant e I'll try to give you a sample, with a simple test: I've implemented an inefficient and decidedly didactic ordering algorithm, the BubbleSort, either in Actionscript and in C/Alchemy. Then I've tested both implementation to order an actionscript reverse ordered array of integers with 20,000 elements(the worst case for the bubblesort algorithms).

Here is the Actionscript implementation:

public function bubbleSort(array:Array):void
{
	var temp:int = 0;
	var alto:int = array.length;
	while(alto > 0)
	{
		for(var i:int = 0; i<alto; i++)
		{
			if(array[i] > array[i+1])
			{
				temp = array[i];
				array[i] = array[i+1];
				array[i+1] = temp;
			}
		}
		alto--;
	} 
}

and here I show you the C implementation

void BubbleSort(int *array, int array_size)
{
   
  int i, tmp;
  int bound = array_size; 
 
  while (bound > 1)
  {
	for (i=0; i<bound-1; i++)
    {
        if (array[i] > array[i+1]) 
        { 
			tmp = array[i]; 
            array[i] = array[i+1]; 
            array[i+1] = tmp;
        } 
    }
    bound--; 
  }
}

Unfortunately I couldn't use the C implementation as it is. I needed to write some more code using Alchemy actionscript/C Api to realize the translation of the Actionscript array to the C integer array data structure:

#include <stdlib.h>
#include <stdio.h>
 
//Header file for AS3 interop APIs
//this is linked in by the compiler (when using flaccon)
#include "AS3.h"
 
//INSERT HERE THE C IMPLEMENTATION OF THE BUBBLESORT ALGORITHM
 
static AS3_Val orderArray(void* self, AS3_Val args)
{
	//Creating a C representation of the Actionscript Array object
	AS3_Val actionscript_array = NULL;
	AS3_ArrayValue( args, "AS3ValType", &actionscript_array );
	 
	/*
	 *         Translation process from Actionscript to C in 4 steps:
	 */
	//STEP 1 : calculating the dimension of the Actionscript array
	AS3_Val actionscript_array_size =  AS3_GetS(actionscript_array, "length");
	int array_size = AS3_IntValue(actionscript_array_size);
 	
	//STEP 2: declaring the C array to use with BubbleSort
	int array_c[array_size];
 	
	//STEP 3 : ActionScript function pop() of Array Class
	AS3_Val pop_function = AS3_GetS(actionscript_array, "pop");
	AS3_Val emptyParams = AS3_Array("");
 	
	//STEP 4(iterative): Extracting the actionscript integer values from the actionscript array
	//and storing them into the c array
	int i = 0;
	for(i = array_size-1; i >= 0 ; i--)
	{
		AS3_Val temp_actionscript_Int = AS3_Call(pop_function, actionscript_array, emptyParams);
		int tmp = AS3_IntValue(temp_actionscript_Int);
		array_c[i] = tmp;
		AS3_Release(temp_actionscript_Int);
	}
	AS3_Release(pop_function);
	/*
	 *   END of Translation process from actionscript to C
	 */
 	
	/*
	 *      Ordering operations: invoking the Bubble Sort on the c array of integers
	 */
	BubbleSort(array_c, array_size);
 	
	/*
	 *         Translation process from C to actionscript:
	 */
 	 
	//ActionScript function push() of Array Class
	AS3_Val push_function = AS3_GetS(actionscript_array, "push");
 	
	//Storing the ordered integer values into a new actionscript array object
	int j;
	for( j = 0; j < array_size ; j++)
	{
		AS3_Val int_to_push = AS3_Array("IntType", array_c[j]);
		AS3_Call(push_function, actionscript_array, int_to_push );
		AS3_Release(int_to_push);
	}
	AS3_Release(push_function);
 	
	return actionscript_array;
	/*
	 *   END of Translation process from C  to actionscript
	 */
}
 
//entry point for code
int main()
{
	//define the methods exposed to ActionScript
	//typed as an ActionScript Function instance
	AS3_Val orderArrayMethod = AS3_Function( NULL, orderArray );
 
	// construct an object that holds references to the functions
	AS3_Val result = AS3_Object( "orderArray: AS3ValType", orderArrayMethod );
 
	// Release
	AS3_Release( orderArrayMethod );
 
	// notify that we initialized -- THIS DOES NOT RETURN!
	AS3_LibInit( result );
 
	// should never get here!
	return 0;
}

As a consequence, when analyzing the test results, we have to consider the extra work the C/Alchemy implementation of the algorithm did to realize the ordering task.

To compile the previous code follow the instruction I showed in this post
to obtain a file .swc you can use in a flex test application as I did in may test example.

Here the code of my flex test application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" creationComplete="init();">
	
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			
			import cmodule.bubblesort.CLibInit;			
			
			private var startDate:Date;
			private var stopDate:Date;
			
			private function init():void
			{
				
				this.addEventListener("actionscriptSortComplete",handler);
				this.addEventListener("cSortComplete",handler);
				var intArray:Array = new Array();
				var intArray2:Array = new Array();
				for(var i:int = 20000; i > 0; i--)
				{
					intArray.push(i);
					intArray2.push(i);
				}
				list.dataProvider = intArray;
				list2.dataProvider = intArray2;
			}
			
			
			//INSERT HERE THE CODE OF THE ACTIONSCRIPT IMPLEMENTATION OF BUBBLESORT ALGORTHM
			
			public function orderArray(event:Event):void
			{
				startDate = new Date;
				
				if(event.target.id == "actionscriptOrderingButton" )
				{
					var source1:Array = (list.dataProvider as ArrayCollection).source;
					bubbleSort(source1);
					this.dispatchEvent(new Event("actionscriptSortComplete"));
				}
				else
				{
					var loader:CLibInit = new CLibInit();
					var lib:Object = loader.init();
					var source2:Array = (list2.dataProvider as ArrayCollection).source;
					list2.dataProvider = lib.orderArray(source2);
					this.dispatchEvent(new Event("cSortComplete"));
				}
				
				
			}
			
			public function handler(event:Event):void
			{
				stopDate = new Date();
				var diff:Number = stopDate.getTime() - startDate.getTime();
				if(event.type == "actionscriptSortComplete")
				{
					timeLabel.text = "time elapsed : "+diff/1000+" sec!";
					(list.dataProvider as ArrayCollection).refresh();
				}
				else
				{
					timeLabel2.text = "time elapsed :"+diff/1000+"sec!";
					(list2.dataProvider as ArrayCollection).refresh();
				}
				
			}
			
		]]>
	</mx:Script>
	
	<mx:List id="list" width="30%"  />
	<mx:VBox>
		<mx:Button id="actionscriptOrderingButton" label="Actionscript BubbleSort" click="orderArray(event);"  />
		<mx:Label id="timeLabel" text="..." />
	</mx:VBox>
	<mx:List id="list2" width="30%"/>
	<mx:VBox>
		<mx:Button id="cOrderingButton" label="C BubbleSort" click="orderArray(event);"  />
		<mx:Label id="timeLabel2" text="..." />
	</mx:VBox>
	<mx:Label id="lb2" text="" />
	
	
</mx:Application>

And here are some screenshots of the results obtained by the test application:
test-actionscriptbubblesort.PNG

test-cbubblesort.PNG

To order an array of 20,000 integers in the worst case:
- the actionscript algorithm spent : 32.031 sec
- the Alchemy/C algorithm spent : 7 sec
Using the Alchemy/C implementation of bubblesort I got an improvement in speed of about 75%.
This is certainly an encouraging result and an evidence that Alchemy can be exploited by developers to improve performance of the most intensive task executed by their flex application.

About Flex

This page contains an archive of all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in the Flex category. They are listed from oldest to newest.

Flash Player is the previous category.

Flex Data Services is the next category.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33