Archive for category flex

Swiz Passive View Example :: Part 2

Introduction

After implementing Part 1 of the Swiz + Passive View (PV) Example, I immediately decided that one thing I missed from the original Spring ActionScript (SAS) version was the ability to create services in an XML file that’s loaded at runtime, thus allowing you to take your app from one environment to another and simply change the XML as opposed to recompiling. Some devs don’t seem to care about this, but I find it quite useful and so do many of my clients so I created a simple DynamicServiceLocator (SL) class and “injected” it into my Example.

Tutorial Goal: Create a Dynamic Service Locator that Instantiates Services from an External XML File at Runtime

Assets

Acronyms

  • PV = PassiveView
  • SAS = Spring ActionScript
  • SL = Service Locator
  • VM = View Mediator
  • CG = Cairngorm
  • IoC = Inversion of Control
  • DTO = Data Transfer Object

Caveats

Please read the previous posts in this series to get up to speed:

  1. Part 1 of the Swiz + Passive View (PV) Example

I won’t go into the details of what Swiz is and how it works as I’d like to let the code speak for itself and you can just hit up the Swiz homepage and view their simple examples; that said, I’ll point out several things I really like about Swiz.

I am using Swiz 0.6.4, as I found issues with the 1.0.0 alpha release (that I’m going to bring up with Ben Clinkenbeard).

Getting Started

The idea is simple:

  1. Create an XML file that defines all of the services leveraged in the app.
  2. Add the DynamicServiceLocator to the BeanLoader (Beans.mxml) and give it the URL to load the services XML file.
  3. Listen to the DynamicServiceLocator’s complete event, indicating that the services are loaded and parsed, and start the app up.
  4. Inject the SL into the Delegates as opposed to injecting the services directly (that were previously defined and hardcoded in the BeanLoader from Part 1).
  5. In the Delegate, request a service from the DynamicServiceLocator via an ID that was set in the service’s definition in the XML file.
  6. Use the service.

Let’s take it piece by piece…

Step 1: Create Services XML File

Let’s start by creating an XML file called services.xml and putting it in src/assets/service-locator/. Next, let’s add some services — truth be told, I took the format for the XML that defines a service directly from the idea behind the application context files used in SAS and then created my own Object Factory…it’s very simple mind you b/c I didn’t need a huge object factory taking up a ton of memory when the only objects it would ever create were 8 different services.

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

<!-- =================================================================== -->
<!-- SERVICE LOCATOR -->
<!-- =================================================================== -->

<!-- =================================================================== -->
<!-- This application context defines multiple test configurations, it
can be expanded to include a deployment configuration as well,
please see comments below.

1. Local Testing: XML Services
2. Dev Server Testing: XML Services
3. Deployment: XML Services
-->
<!-- =================================================================== -->

<!-- =================================================================== -->
<!-- 1. LOCAL TESTING: XML Services -->
<!-- =================================================================== -->

	<object id="loginService" class="mx.rpc.http.mxml.HTTPService">
		<property name="url" value="assets/xml/login.xml" />
		<property name="resultFormat" value="e4x" />
		<property name="method" value="GET" />
	</object>

	<object id="employeeService" class="mx.rpc.http.mxml.HTTPService">
		<property name="url" value="assets/xml/employee_list.xml" />
		<property name="resultFormat" value="e4x" />
		<property name="method" value="GET" />
	</object>

</objects>

The idea is to create a list of services as object nodes. Start by giving each <object> node a unique id attribute, as this is the key we’ll use to request the service later. The following line defines the loginService:

<object id="loginService" class="mx.rpc.http.mxml.HTTPService">

Next, define the concrete Flex service type in the class attr  — right now the service class must be one of the following types:

  • mx.rpc.http.mxml.HTTPService
  • mx.rpc.http.HTTPService
  • mx.rpc.remoting.mxml.RemoteObject
  • mx.rpc.remoting.RemoteObject
  • mx.rpc.soap.mxml.WebService
  • mx.rpc.soap.WebService

Finally, add any additional properties you want to define for the service as <property> nodes with the name and value attrs matching properties that are available for the service type. The following line adds the url property for the HTTPService:

<property name="url" value="assets/xml/login.xml" />

Step 2: Add DynamicServiceLocator to the BeanLoader

We’ll add the SL to the BeanLoader just like we did for all the other objects we want managed by the IoC Container, except we’ll also provide her with the URL to our services.xml file that we just created. When the url property is set on the SL, it will automatically load the services, parse the XML, instantiate a service for each <object> node it finds that matches one of the aforementioned service classes, and then adds that service to it’s hash or Dictionary object’s list of services via the id as it’s key.

<service:DynamicServiceLocator id="serviceLocator" eventDispatcher="{this.dispatcher}" url="assets/service-locator/services.xml" />

The other thing to make note of is that we’re again passing a reference to the BeanLoader’s dispatcher so the SL can broadcast events to other objects in the Swiz IoC Container.

Step 3: Listen to the SL’s Services Load Complete Event

Since this is more of an application level event, we’ll make the ApplicationController object handle this event:

[Mediate( event="serviceLocatorServicesLoadComplete" )]
public function onServiceLocatorLoadComplete():void
{
	logger.debug("onServiceLocatorLoadComplete");

	this.eventDispatcher.dispatchEvent(new DynamicEvent("showMainView"));
}

Which then in turn broadcasts a “showMainView” event that’s handled by the ApplicationViewMediator and ultimately removes a simple preloader (which is there in case the SL should take any significant amount of time to load and parse — unlikely here, but useful in the future) and adds the MainView to the stage.

[Mediate( event="showMainView" )]
public function showMainView():void
{
	logger.debug("showMainView");

	this.view.removeChild(this.view.progressBar);
	this.view.addChild(new MainView());
}

Now this may seem like overkill for this extremely simple example, as I could have just listened to the “serviceLocatorServicesLoadComplete” in the ApplicationViewMediator, but I wanted to proxy the event through the ApplicationController in case more needed to be done…What if we wanted to update a model level var to indicate that the SL was complete? What if we wanted to tell other objects that the SL was complete?…we wouldn’t want to do that from the ApplicationViewMediator as it’s sole purpose is to lend a hand to the MainView UI component and not to orchestrate application level processing, work, etc. Again, overkill in this example, but I wanted to put it in here as an example of what you might want to do in a much larger application.

Step 4: Inject the SL into the Delegates

Next we’ll want to inject the SL into the Delegates as opposed to injecting the hardcoded services defined in the BeanLoader. First, let’s declare the new serviceLocator property for the Delegate:

[Autowire(bean="serviceLocator")]
public var serviceLocator:DynamicServiceLocator;

Next, let’s remove the service var’s declaration and create a simple getter method for it instead:

public function get service():HTTPService
{
	return this.serviceLocator.getMXMLHTTPService("loginService");
}

Step 5: Request Service From SL

This allows us to leave the actual use of the service property untouched in our service method calls - this code hasn’t changed from Part 1, but I’m showing it for clarity. We’ll look at the Login Delegate for example:

public function login(dto:LoginDTO):AsyncToken
{
	logger.debug("login");

	return this.service.send();
}

Wrapping Up

The only other thing that I failed to mention that’s different from Part 1 is the use of a simple ProgressBar component in the Application root to provide the user with some additional feedback while the SL is loading and parsing. If you look at the main application file EmpMgmtConsoleSwizPassiveView you’ll notice that the MainView is now replaced by the ProgressBar component — once the SL is complete the ProgressBar is removed from the stage and the MainView is added (as mentioned in Step 3).

Finally, to test out the dynamic SL, open up the services.xml file in the example source code and comment out the first set of services that point to local, project-level XML files and ucomment the services that point to the WASI server. See, no recompiling.

And that about does it. Any questions?

Post to Twitter Tweet This Post

, ,

No Comments

Swiz Passive View Example :: Part 1

Introduction

If you followed my previous posts on the Employment Management Console application leveraging Spring ActionScript + Cairngorm, then you’ll be familiar with this small example as I simply ported it over from SAS + CG to Swiz using the Passive View (PV) design pattern.

Tutorial Goal: Create an Employee Management Console using Swiz and the Passive View Design Pattern

Assets

Acronyms

  • PV = PassiveView
  • VM = ViewMediator
  • CG = Cairngorm
  • IoC = Inversion of Control
  • DTO = Data Transfer Object

Caveats

I won’t go into the details of what Swiz is and how it works as I’d like to let the code speak for itself and you can just hit up the Swiz homepage and view their simple examples; that said, I’ll point out several things I really like about Swiz.

I am using Swiz 0.6.4, as I found issues with the 1.0.0 alpha release (that I’m going to bring up with Ben Clinkenbeard).

As an additional side note, I chose the PV because I was always a fan of code-behind — I like separation of concerns so much that I actually detest looking at MXML with ActionScript in it — what a mess!..that and the fact that MXML is declarative and should just perform basic UI layout and not presentation logic. What I love about the PV is that it relies on composition as opposed to inheritance (ie the biggest issue I have with code-behind).

Finally, there are other examples of the PV + Swiz out there, like Ben Clinkenbeard’s example, but I went ahead and created an AbstractViewMediator that takes care of some race conditions when working with Views in a ViewMediator, like setting event handlers and data bindings. And I did some other things that I didn’t see in others that I’ll point out.

Swiz is Noninvasive

Swiz is a noninvasive framework that allows you to provide well organized structure and architecture to your app without writing a ton of boilerplate code that can be overly verbose and time consuming. Remember CG and how you were forced to do the following for service calls:

  1. Create an Event that extends the CairngormEvent.
  2. Create a Command to act as a responder for your service call.
  3. Create a corresponding Delegate that actually makes the service call and transforms your data to client-side types before returning it to the Command.
  4. Don’t forget to map your Custom CG Event to your Command in the FrontController.
  5. Wash, rinse, repeat…and repeat…and repeat…and…mehhh

With Swiz, you can (and I emphasize can b/c you can still do it the old school way too) just broadcast a DynamicEvent from any object in the IoC Container (those objects that are defined in the Swiz BeanLoader — in my example, it’s in the class Beans.mxml) and then add some metadata to another object in the Container to “Mediate” that event.

Here’s an example — so in my LoginViewMediator I want to broadcast a “login” type event and pass the username and password along with it and I want my LoginController to handle this event:

private function submitBtnClickHandler(evt:MouseEvent):void
{
logger.debug("submitBtnClickHandler");

var dto:LoginDTO;

// create a login dto to contain the required fields for login
dto = new LoginDTO();
dto.userName = this.view.userNameTextInput.text;
dto.password = this.view.passwordTextInput.text;

var dynEvt:DynamicEvent = new DynamicEvent("login");
dynEvt.dto = dto;
this.eventDispatcher.dispatchEvent(dynEvt);
}

And now we handle this event in the LoginController like so:

[Mediate( event="login", properties="dto" )]
public function login( dto:LoginDTO ):void
{
logger.debug("login");

// TODO - make service call -- see in example src code
}

So let’s dig a bit deeper here and note all the cool stuff that’s going on and why I’m psyched about Swiz + PV:

No Custom Events (If You Don’t Want To)

Notice that I didn’t have to create a custom Event — less code — YES! Now, you can by all means create a custom event and Swiz will type check the event object and the event type to make sure they exist — check it out in the Swiz Docs for Event Handling — or you can save yourself some extra code and do what I did. While I’m usually a stickler for strongly typed objects, sometimes you have to ask yourself it it’s not just overkill for something as simple as this…personally preference I suppose, but less code without sacrificing organization and good practices wins that battle in my head.

Event Mediation

Swiz automatically handles the event and passes the meat of the event (the LoginDTO that I packages in my DynamicEvent) for me…uhm, yeah…that’s frigging cool! And you can pass multiple args as well. Again, see Swiz Docs. NOTE: One thing to remember about event mediation is that the handler method must be marked public — I’m used to making event handlers protected (and sometimes even private), but this won’t allow the Swiz event mediation to work it’s magic so make sure event handler methods are marked as public.

No Logic in MXML

My LoginViewMediator grabs the username and password from it’s corresponding LoginView and creates the event and DTO. The actual LoginView is just MXML…nuff said.

Event Dispatching and Handling Thereof in IoC Container Objects

Notice that the LoginViewMediator broadcasts the event from a class member variable called “eventDispatcher”. This next part is important: in order for Swiz to Mediate events, the events need to go through the central event bus using Swiz.dispatch(<eventType>) or by using the event dispatcher in the BeanLoader — I have chosen the latter. Why?…I have 2 reasons:

  1. I don’t like having a reference of Swiz in my classes — it’s just unnecessary and makes my application that much more coupled to the framework, something Swiz tries to get developers away from to begin with.
  2. The Swiz.as class is a singleton and singletons are bad…this is too long a topic to get into, but my main reason has to do with the use of Modules in large Flex apps and while this example doesn’t require modules, I’d still rather just stay the hell away from singletons.

I shove a reference of the BeanLoader’s eventDispatched into my IoC Container managed objects like this:

<controller:LoginController id="loginController" eventDispatcher="{this.dispatcher}" />
<mediator:LoginViewMediator id="loginViewMediator" eventDispatcher="{this.dispatcher}" />

Note that they both don’t need it in order for the controller to hear events from the view mediator — just the object broadcasting the event needs to have a reference to it, but I pushed it into the controller as well as since I’m broadcasting other events from it that I’d like other managed objects to listen to via mediation.

AbstractViewMediator

Since all of my views need a reference to their corresponding view, I decided to create a super class for all the mediators called AbstractViewMediator. This bad boy does several things starting with the injection of the view:

[Autowire( view="true" )]
public function set view( value:* ):void
{
logger.debug("AUTOWIRE :: view = " + value);
this._view = value;

// determine if the view has been initialized...
// NO...listen for it;s creation complete event
if(this._view.initialized == false)
{
this._view.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
}
// YES...call the init() method to kick off the instation of the view mediator
else
{
this.init();
}

// don't get in GC's way if the view is removed
this._view.addEventListener(Event.REMOVED_FROM_STAGE, cleanup);
}

Again, there’s a couple things to note about this method:

  1. The argument for the method is untyped, so how does the concrete ViewMediator (VM) know how to inject the correct view? And then what about code-hinting for the view in the VM? Well, if you look at an actual implementation of a VM, like the LoginViewMediator you’ll see the following method:
    public function get view():LoginView
    {
    return this._view as LoginView;
    }
    

    Put this into method into each concrete VM with it’s corresponding view type and you’re good to go! Problem solved.

  2. We check to see if the view has been initialized, ie, has the creationComplete event fired and can I start to work with children components of this view without getting runtime errors. If it has, then we call the init() method (which can and should be overridden by concrete VMs to initialize themselves); if not, then we listen for the creationComplete event and call the init() method then and only then. This ensures that when we want to set event handlers and data bindings on the view’s children we know they exist and we don’t hit nulls leading to runtime errors.
  3. Finally, if you look at the init() method in the AbstractViewMediator, you’ll see that it also calls the setViewListeners() and setViewDataBindings() methods — these are placeholder methods where developers can again add concrete event handlers and data bindings in VM subclasses by overriding them.

The last thing the AbstractViewMediator does is provide the event dispatcher class member variable that we discussed earlier: public var eventDispatcher:IEventDispatcher;

Controllers & Delegates

In Swiz, we eliminate the idea of a Command class (from Cairgorm) and kind of replace it with the controller — I say kind of b/c it’s not exact mapping as the Cairngorm Command follows the actual J2EE Command design pattern whereas Swiz uses a controller to handle events from the UI to make service calls, act as a responder for the service calls, and finally to orchestrate what happens in the app after the service call (usually by dispatching an event). Since we already looked at the event mediation of the in the LoginController we won’t discuss that, but we will dig into how the controller leverages a corresponding LoginDelegate to call the service and perform data transformations on the service’s response object. So let’s look at the internals of the actual login event mediation in the LoginController:

[Mediate( event="login", properties="dto" )]
public function login( dto:LoginDTO ):void
{
logger.debug("login");

var call:AsyncToken = this.delegate.login(dto);

// I created 2 ways to handle the login service delegate
// you can either have the result come back to the controller
// or you can catch the result in the delegate and have it perform
// the necessary data transformations (traditional approach) before
// kicking it back to this controller via an event

// APPROACH 1) have the results come back directly to this controller
//this.executeServiceCall(call, onLoginResult, onLoginFault);

// APPROACH 2) have the results come back the delegate for data transformations
// before coming back to this controller
this.executeServiceCall(call, this.delegate.result, onLoginFault);
}

Out of the box, Swiz recommends that the controller handle the actual service response and data transformations before deciding what the app should do next…that’s too much responsibility for one object in my opinion, so as you can see I decided to allow the LoginDelegate to handle the actual service response: this.executeServiceCall(call, this.delegate.result, onLoginFault);. After the delegate finishes with the response, it dispatches an event:

LoginDelegate

public function result(resultEvent:ResultEvent):void
{
logger.debug("result");

var userModel:UserModel;
var xml:XML;
var dynEvt:DynamicEvent;

// get the response typed as desired
userModel = this.getTypedResponse(resultEvent);

// let something know that the login delegate is done
dynEvt = new DynamicEvent("loginDelegateComplete");
dynEvt.userModel = userModel;
this.eventDispatcher.dispatchEvent(dynEvt);
}

And then the event is mediated by the LoginController where it updates the necessary model properties and dispatches an event to signify the end of the login process.

[Mediate( event="loginDelegateComplete", properties="userModel" )]
public function completeLogin(userModel:UserModel):void
{
logger.debug("completeLogin");

var role:String;

// populate the model with data from the response DTO
this.appModel.user = userModel;

// determine of user is an admin
for each ( role in userModel.rolesList )
{
if(role == RolesConstants.ROLE_ADMIN)
{
this.appModel.user.isAdmin = true;
break;
}
}

// set this last as this is what binds the view change
this.appModel.isUserAuthenticated = true;

var evt:DynamicEvent = new DynamicEvent(EVENT_LOGIN_COMPLETE);
this.eventDispatcher.dispatchEvent(evt);
}

I think that about covers it for this edition. Any questions?

More to come on Swiz in the future.

Post to Twitter Tweet This Post

,

6 Comments

FlexUnit 4 Testing Services In Flash Player Issue

We’ve created a number of FlexUnit 4 (FU4) tests for our current, large project and the suite of tests that seems to be of the most importance to both us and our client is the one that tests the services. Our client’s back-end services are simple JSPs that return XML payloads for a number of CRUD operations on various objects in the system, so we’d like to test sending good required data as well as bad required data to our delegate before hitting the service directly.

The issue we ran into was quite frustrating and it took me some time to figure it out — I actually had to explain the system of tests to my partner before it dawned on me what was going wrong. In order to actually hit the services and get data back, you need to be logged into our client’s system…except this isn’t done through a Flex login, but rather via the larger application’s HTML login in which our smaller app lives (SSO)…once you’re logged in, a cookie is sent back and forth between the client and server…such is the security design of our client’s application framework and there wasn’t any wiggle room to change this.

SWF Browser Association

Change SWF to Open With Browser

Now think about FU4 and how it actually runs the tests (when using Ant and not building and running with FlexBuilder)…it simply opens up a TestRunner.swf in the Flash Player to execute it’s tests…this means no browser wrapper for our SWF and thus no access to cookies…and ultimately no working services in my tests…grrrr.

So here’s a simple solution (on Mac)…open up Finder and locate your TestRunner.swf, right-click on it and select “Get Info”. Find the section “Open with” and change the application to your browser (I use FireFox), but don’t click the button change for all, as we just want to change this for this file and this file only. Voila! Now your TestRunner.swf will run in thr browser when your Ant buld runs and you will have access t cookies (assuming you’ve already logged into the system you need access to in the same browser session).

Post to Twitter Tweet This Post

, , , , , , ,

3 Comments

Dude, Where’s My Chart Labels?

Wondering where your Flex Chart labels are? Well, you’re not alone. Turns out it may be related to your use of Embedded Fonts and Modules.

Surfacing a charting component in a Module works just fine when not making use of Embedded Fonts. Embed fonts in your main application or the Module itself and Presto! Your labels will disappear.

A number of bug tickets have been opened and closed with Adobe, i.e. http://bugs.adobe.com/jira/browse/FLEXDMV-1883, indicating that the issue was resolved with DMV 3.3.0. Currently using DMV 3.4.0.9271, however, and the problem seems to have re-emerged.

Opening another bug ticket with Adobe and in the meantime commenting out the use of Embedded Fonts.

More to follow…

Post to Twitter Tweet This Post

No Comments

Headless Flex Builds on EC2 Using Hudson Against Remote SVN Repo on Assembla with FlexPMD

We’re doing a current project requiring continuous integration. We also maintain the SVN repo. There’s a lot here and you may/may not need all the pieces. We’re specifically doing headless Flex/DataViz Builds on Amazon EC2 Ubuntu with Hudson against a remote SVN repo on Assembla and have thrown in FlexPMD to see what it can add to our process.

First, some stuff I’ll assume you already have and know how to work with:

  • EC2 machine running in the Amazon cloud. We’re using one of the Ubuntu disty’s. I’m going to assume you have all the necessary ports open for things like email and such.
  • Hudson. We’re using version 1.326. We’ve used other CI tools but find Hudson to be very user friendly. You’ll need to have a servlet container ie Tomcat and you just pop hudson.war in and you’re ready to rock.
  • Remote SVN. You can be using a local one, but. We’re using Assembla since it’s got all the stuff we need to do business in one place and it’s simple to use. Time is money.
  • Java installed on your server. We’re using version 1.6.0_07

Stuff you’ll end up downloading/installing/configuring:

  • Flex SDK
  • Flex Dataviz components
  • SVN client
  • Ant
  • Flex Ant
  • Email

Step 1, Flex

We’re currently building with the latest stable build of Flex 3.4. Get yourself all logged into your EC2 account and let’s roll. I create a flex/3.4 directory and cd to that directory and then get the latest Flex rev. This is the latest URL:

wget http://download.macromedia.com/pub/flex/sdk/flex_sdk_3.4.zip

Let’s get the dataviz components as well since they’re a separate install

wget http://download.macromedia.com/pub/flex/sdk/datavisualization_sdk_3.4.zip

Oh yeah, and if you’re going to be doing unit testing, might as well get that sucker as well

wget http://download.macromedia.com/pub/flex/sdk/automation_sdk_3.4.zip

Great, so we have all the pieces we need so far. You’ll want to unzip and cp these to wherever you keep your software installs on the server. I’m no unix guru, but, near as I could find out, the common location is /opt.

So, create a /opt/flex directory and unzip the flex_sdk_3.4.zip files there. Then, copy the dataviz zip there and unzip it.

cp datavisualization_sdk3.4.zip /opt/flex

cd /opt/flex

unzip datavisualization_sdk3.4.zip

This will extract the following into the SDK 3 installation

  1. datavisualization.swc into the frameworkslibs folder
  2. datavisualization__3.0.9147.swz and datavisualization__3.0.9147.swf into the frameworksrsls folder
  3. datavisualization_rb.swc into the appropriate frameworkslocale<locale> folder

Let’s make sure we put the Flex compiler on the class path. On our server, the default shell is bash. You’re setup may be different, but essentially, you want to find the properties file for you shell (I’m using /root/.bashrc) and add the following line to the bottom of it:

export PATH=/opt/flex/bin:$PATH

Now let’s test it. You may need to log out and then back into your shell. At the command prompt, enter mxmlc and hit return. You should see something like

Loading configuration file /opt/flex/frameworks/flex-config.xml

Error: a target file must be specified

That’s a good error. It means that the Flex compiler is now accessible on your system. If nothing comes back, you’re just at the command prompt, you may not be using the right shell properties file.

In order to build projects that use the dataviz components without having the watermark on your charts and graphs, you’ll need to apply a Flex license to the installation. You do this in the flex-config.xml file located in /opt/flex/frameworks. Towards the bottom of the file you’ll see some commented out xml for doing so:

<licenses>
<license>
<product>string</product>
<serial-number>number</serial-number>
</license>
</licenses>

Step 2, SVN

We are accessing an SVN repo on our Assembla account. The easiest way to make this happen from the EC2 is to just install SVN. So, from the command prompt:

apt-get install subversion

If you run into any errors, I always find it helpful to refresh the list:

apt-get update


If all went well, you should be able to log into your remote repo:

svn –username <your_username> –password <your_password> –no-auth-cache checkout <some_project_name>


If successful, you’re going to have a checked out version of some_project_name in your current directory.


Step 3, Ant


We’re going to be using Ant as our build process. It will called via a Hudson job. Let’s get and install Ant.

apt-get install ant


Once that completes, you should be able to type ant at a command prompt. If it installed successfully, you should see something similar to (unless there happens to be a build.xml file in your current directory):

Buildfile: build.xml

BUILD FAILED


This is good. We now have Ant installed. The only other Ant specific thing we’ll need to do is copy the FlexTasks.jar from your Flex SDK into your new Ant install.


Let’s find where Ant was installed. At a command prompt:

which ant

(which will most likely return)

/usr/bin/ant


Now, navigate to your Flex SDK Ant lib directory. The Flex SDK now contains the flexTasks.jar we need.

cd /opt/flex/an/lib


Now just copy this to the location of your Ant install’s lib directory (typical):

cp flexTasks.jar /usr/share/ant/lib


If you do not copy this file to the lib directory, you must specify it by using Ant’s -lib

option on the command line when you make a project.

Step 4, Setup Hudson Job


Plugins

I’m assuming you have a working familiarity with Hudson. If not, there’s a ton of info via your install directly and on the web. We have a few extra plugins installed. The Violations plugin is useful for code analysis via PMD files if you structure your ant files to use it. The Email Extension gives you a bit more flexibility than the basic email tool.

plugins

Configuration

Here’s a look at few items we needed in the Hudon configuration page to get things to work smoothly

Specify the Ant location on your server.


ant

For the Extended E-mail Notification plugin. We’ve defined an email account on our system called hudson. We also use gmail for our corporate email. We’re essentially relaying to gmail which requires SMTP auth and SSL (note: we haven’t entered anything in the default Hudson E-mail section):


email

Job Setup

Go the usual steps of creating a new job. Here are the pertinent parts.

In Source Code Management, we’ll need to point to our remote SVN. When you click on the “?” next to the Repository URL, you will see the grey box and be able to provide login credentials to your SVN repo and test the connection:


svn

We’re not going to specify any build triggers. The reason is that Assembla gives the ability to access the post-commit hook in SVN via their “Webhook” plugin. In that tool, all we have to do is specify the Hudson job URL and with each check in of code, the project is checked out, built, and success/failure notification sent to our dev group. This is the key to the ‘continuous integration’ aspect of this whole setup.


webhook

We do need to tell Hudson to use Ant to do the builds. We have a target in the build.xml file (that is in the root of our Flex project) called main.hudson. To be on the safe side, I’ve specified the full path to the build file. We specify the ant install we configured in the Hudson configuration page earlier. It would probably be helpful to give it more meaningful name like ‘ant_version_x’.

jobant

FlexPMD is another great tool we use that profiles your code based upon a bunch of best practices defined by the Flex group at Adobe. You can also specify your own criteria to use in the analysis. It’s worth checking out. Note the format of the XML filename pattern used. It took a while to figure that part out!


flexpmd

We configure the Editable Email Notification accordingly:


jobemail

And that’s pretty much it. I’ll be pushing up a blog shortly that will walk through the whole ant build used for this project. It uses modules, all sorts of RSLs, FTP, and so on.

Happy Flexing.

Post to Twitter Tweet This Post

, , , , , , , , ,

3 Comments

Axiis Drill Down Example

I’ve seen a number of requests for a drill down version of an Axiis chart. We have a current client that will need that functionality as well so I figured I’d give it a shot.

The approach I’m taking is pretty straight forward. Put a drill down layout on the stage and make it invisible initially. When the user clicks on an item in the primary chart that we want to drill in, capture the event, set a dataProvider specific to the portion of the data that represents the drill down, hide the primary layout and show the drill down layout.

Building off the familiar approach for the Axiis examples, add a few objects for the drill down layout to use

<mx:Object id=“dataProvider”/>
<mx:String id=“verticalField”/>
<mx:String id=“dataField”>date</mx:String>
<mx:String id=“labelField”>date.value</mx:String>
<mx:Object id=“drilldataProvider”/>
<mx:String id=“drilldataField”/>
<mx:String id=“drilllabelField”/>

The drill down layout can be whatever type you choose. Here I’m just going to display the data as a simple bar chart.

<axiis:HBoxLayout
      id=“drillDownLayout”
      x=“25”
      y=“0”
      showDataTips=“true”
      height=“{dc.height-70}”
      width=“{dc.width-25}”
      visible=“false”
      dataProvider=“{drilldataProvider}”
      percentGap=“0”
      dataField=“{drilldataField}”
      labelField=“{drilllabelField}”
      itemClick=“this.itemClick(event);”>

    <axiis:drawingGeometries>
       <degrafa:RegularRectangle
             id=“drillRectangle”
             x=“{drillDownLayout.currentReference.x}”
             y=“{drillDownLayout.height-vScale.valueToLayout(drillDownLayout.currentValue)}”
             width=“{drillDownLayout.currentReference.width}”
             height=“{vScale.valueToLayout(drillDownLayout.currentValue)}”
             stroke=“{colStroke}”/>

       <degrafa:RasterText
             text=“{drillDownLayout.currentLabel}”
             fontFamily=“Arial”
             align=“center”
             x=“{drillDownLayout.currentReference.x}”
             width=“{drillDownLayout.currentReference.width}”
             y=“{drillDownLayout.height+5}”/>
     </axiis:drawingGeometries>
</axiis:HBoxLayout>

The only real piece of interest in this is the addition of a handler for the itemClick event.

itemClick="this.itemClick(event)"

Here’s the code that will handle the click of an item in the layout. Note that it will check to see which layout is currently visible so we can get back to the primary chart.

public function itemClick(evt:LayoutItemEvent):void
{
       // Switch back to main view
       if ( this.drillDownLayout.visible )
       {
            this.drilldataProvider = null;
            this.drillDownLayout.visible = false;
            this.hLayout.visible = true;
            dc.invalidateDisplayList();
         }else {
             var ac:ArrayCollection = evt.item.layout.dataProvider as ArrayCollection;
             this.hLayout.visible = false;
             this.drillDownLayout.visible = true;
             this.drilldataField = &amp;quot;value&amp;quot;;
             this.drilllabelField = &amp;quot;value&amp;quot;;
             this.drillRectangle.fill = ( evt.item.data.type == "receivables" ) ? this.receivablesStack.fill : this.payablesStack.fill;
             this.drilldataProvider = ac;
             dc.invalidateDisplayList();
        }
}

Post to Twitter Tweet This Post

No Comments

Where Can I Find fds.swc?

If you ever need to compile a Flex app that requires classes like:

mx.messaging.channels.RTMPChannel
mx.messaging.channels.SecureRTMPChannel

then you’ll need fds.swc which isn’t shipped with the Flex SDK, but is shipped with LCDS. Download a trial vr of LCDS and grab this file from the web-app:

WEB-INF/flex/libs/fds.swc

…why might you need these classes?…perhaps if you’re building a Bootstrap loader for LCDS apps loading sub-apps and you want to share the messaging classes between the parent and child apps…I had to do this for an Xcelsius application.

Post to Twitter Tweet This Post

, , , ,

No Comments

Axiis Examples with Lots of Comments

We’ve begun using Axiis on a current client’s project. The application is loaded with graphs and charts and when we hand off the project, we needed to provide a framework for the development staff to quickly build and add new graphing components. Some of the charts are simple but there are some more complicated ones we need to build and will be built in the future. The current Flex DataViz components work fine for simple tasks. But, anyone who has had to go beyond the basics understands the pain that you quickly begin to feel.

Fortunately, I caught Tom Gonzalez’s, (BrightPoint Consulting) lecture at MAX this month and was blown away. The things they’re doing with the Axiis framework and Degrafa are off the charts! (pun intended)

I’ll leave the real discovery to you to check out the Axiis site, but, Axiis is a ’specialized framework that implements specific design patterns that can be used to create your own visualizations’. It’s not a pre-built collection of charting components. They’ve developed a great way of abstracting the basic building blocks of doing data visualization.

Axiis is currently in beta release. There are a lot of great examples on their site so check them out. If you’re new to Degrafa, it’s worth your while to do a bit of reading and check out the cool examples they have on their site as well since many of the examples use Degrafa.

Being in beta, the documentation is a work in progress. The examples from the site are great and really cover a lot of space, but I did struggle with some of the concepts at first. So I’ve taken three of the first examples we needed to borrow from and hyper-commented them for clarity.
I’ll continue to add to the collection over time.

Cluster Stack Example

Linear Series Example

Cluster Column Example

Post to Twitter Tweet This Post

, ,

2 Comments

Workaround to Flex SDK 3.4 Bug 22333 :: HTTPService Responders Are Called Twice…Here’s a Fix!

This one kicked my team’s ass for a couple of hours so I’m hoping it’ll help somone else…so we updated our Flex SDKs to 3.4 and all of a sudden all of our Delegates’ result handlers were getting called twice. We thought it was due to our service orchestration object (we have a base object that allows us to make sequential Cairngorm service calls) and somehow we were calling the services 2x, but nope…wasn’t it. Seemed our AbstractDelegate that sets up the responders for all of our service calls like so had the issue:

public function executeHTTPService(requestDTO:AbstractRequestDTO=null):void
{
	logger.debug("executeHTTPService");

	var token:AsyncToken;
	var responder:mx.rpc.Responder;

	// create a responder for the service
	responder = new mx.rpc.Responder(result, fault); // WTF mate?

	// execute the service
	token = this.service.send(requestDTO);
	token.addResponder(responder); // why yall busted up now???
}

Apparently, SDK 3.4 reintroduces an old defect that causes this implementation of setting up the responder with the async token to call the result handler twice…bummer, eh? So what to do…well, a simple workaround until they fix this is to do the following:

this.service.addEventListener(ResultEvent.RESULT, result);
this.service.addEventListener(FaultEvent.FAULT, fault);

Just create your handlers with good-ole fashioned event handlers…DONE.

Get more info on the defect here.

Post to Twitter Tweet This Post

, , , , ,

3 Comments