Posts in Category "General Knowledge"

Dispatching Events from an ActionScript Class

A little while ago I was working on a project that required data from an external source.  In trying to follow good development practices, I divided the interface code for the external source into a separate ActionScript class.  No problems there, but the external source may not respond to a request immediately.   This means that my ActionScript class is asynchronous, and will need to tell the calling object when the data is ready.

I’ve used Flex long enough to know that when I see anything asynchronous, I will be dealing with the event model.   “No problem.”, says I,  “I’ve used events in MXML components before.  Add a meta-data tag, dispatch the event using dispatchEvent, and add a listener in the calling object.  Bob’s your uncle, its done.  I can even create a small custom event to be really fancy.  The syntax is all in the help files.

Alas, it was not so easy.   When using MXML components, the dispatchEvent function is a property of the mx.core.UIComponent object, but pure ActionScript classes aren’t derived from the UIComponent and therefore don’t have access to the dispatchEvent function.  So how do I dispatch the event form an ActionScript class?

It took me quite a while to find the answer to this simple question.  If you search the internet, there are tons of examples of using the event dispatcher in MXML components.  There are not that many when it comes to using pure ActionScript classes.  The problem isn’t that its difficult to do, its just hard to find how to do it amongst the thousands of results returned in a search.

So in the interest of spreading the knowledge, here is how to dispatch a custom event from a pure ActionScript class.

Source code can be found here.

 

The parts list:

The solution consists for three parts:

  • The ActionScript class.  This is a pure ActionScript object (no MXML) that will perform an asynchronous task.  In this case it will make an external call to get data.
  • The custom event.  This is a custom build event object that will be thrown by the ActionScript class when the asynchronous task is complete.
  • The calling object (aka parent).  This is the MXML, class, etc.  that will use the ActionScript class to get data.

The order of operations is quite simple as well:

  1. The parent object will add an event listener to watch for the custom event
  2. The parent object will then call a function in the ActionScript class
  3. The ActionScript class’ function will perform an asynchronous task.   This may require the addition of its own event listener to know when the task is complete.
  4. The ActionScript class will dispatch a custom event that includes data from the asynchronous task.
  5. The parent object will get the data from the custom event and do something with it.

Here’s a simple diagram that shows what happens:

eventModel

 

The code:

To keep from having to jump around, lets start looking from the bottom up:

The Custom Event

I could have easily used the existing Event object, but a custom event allows me a bit more freedom.  I can create my own event types as well as having my own data objects passed back in the event.

  • The class is fairly simple, it extends the flash.events.Event object
  • There are three types of event that can be returned:
    • EXTERNALDATA_DATAREADY – everything is good and the data is ready to go
    • EXTERNALDATA_NODATAFOUND – there is no data found
    • EXTERNALDATA_ERROR – something went wrong
  • There is an attribute that holds the data called externalData, which uses the ActionScript convention around getters and setters.
  • The constructor has been modified to include the event type and the data itself.

Here is the source code:

package events

{

import flash.events.Event;

public class ExternalDataEvent extends Event {

public static const EXTERNALDATA_DATAREADY:String = ‘ExternalDataReady’;

public static const EXTERNALDATA_NODATAFOUND:String = ‘ExternalDataNoDataFound’;

public static const EXTERNALDATA_ERROR:String = ‘ExternalDataError’;

private var _externalData:XML;

public function ExternalDataEvent(type:String, exData:XML, bubbles:Boolean=false, cancelable:Boolean=false) {

super(type, bubbles, cancelable);

this.externalData = exData;

}

public function get externalData():XML {

return _externalData;

}

public function set externalData(value:XML):void {

_externalData = value;

}

}

}

The ActionScript Class

The ActionScript class serves as the model for this project.  It is called by the parent object, performs an asynchronous call, and returns the result in an ExternalDataEvent event.

In this case I’m just making a simple HTTP request to load an external XML file, but this could just as easily been an SQL call to a database, a web service request, a LiveCycle Data Services call or any other asynchronous request.

  • The class extends flash.events.EventDispatcher. This is very important.   Because the ActionScript class is not an MXML object, it does not have access to the mx.core.UIComponent object.  By extending the EventDispatcher class we can now dispatch our custom event using the dispatchEvent function.
  • The class has one public method readData
  • Since the data is loaded from an HTTPService (an asynchronous event), we need a listener for the returned data.  This is done by the loadData function.
  • The loadData function fires our custom event.  Which event depends on the data.  During the call the type and data are set into the event itself
  • There is also an error function, fault, as a basic error trap.

Here is the source code:

package model

{

import events.ExternalDataEvent;

import flash.events.EventDispatcher;

import flash.events.Event;

import mx.rpc.events.FaultEvent;

import mx.rpc.events.ResultEvent;

import mx.rpc.http.mxml.HTTPService;

public class ExternalData extends EventDispatcher {

private var HttpService:HTTPService = new HTTPService();

private var xmlURL:String = new String();

public function readData(dataUrl:String):void{

this.load(dataUrl);

}

private function load(dataUrl:String):void{

xmlURL = dataUrl;

HttpService.resultFormat = “e4x”;

HttpService.addEventListener(ResultEvent.RESULT,loadData);

HttpService.addEventListener(FaultEvent.FAULT,fault);

HttpService.url = xmlURL;

HttpService.send();

}

private function loadData(event:ResultEvent):void{

if (event.result != null){

dispatchEvent (new ExternalDataEvent (ExternalDataEvent.EXTERNALDATA_DATAREADY,event.result as XML));

}else {

dispatchEvent (new ExternalDataEvent (ExternalDataEvent.EXTERNALDATA_NODATAFOUND,null));

}

}

private function fault(event:FaultEvent):void{

trace (“ERROR: Problem loading XML data. Stack Trace follows:”);

trace(event.message);

dispatchEvent (new ExternalDataEvent (ExternalDataEvent.EXTERNALDATA_ERROR,null));

}

}

}

 

The Parent Object

Finally we have the parent object.  In this case I built a simple MXML application that will call the ActionScript class and get the returned data from the custom event.

  • The application consists of a button and a text area.  When the button is clicked a click handler function is fired and the retrieved data is displayed in the text area.
  • The click handler adds three listeners.  One for each type of event that can come from the custom event object.
  • The click handler also sets some data and calls the public method in our ActionScript class.
  • The event listeners will be triggered by the ActionScript when it dispatches the custom event (with data).
  • The event listeners set the text of the text area field

Here is the source code:

<?xml version=”1.0″ encoding=”utf-8″?>

<s:Application xmlns:fx=”http://ns.adobe.com/mxml/2009

xmlns:s=”library://ns.adobe.com/flex/spark

xmlns:mx=”library://ns.adobe.com/flex/mx” minWidth=”955” minHeight=”600” xmlns:model=”model.*>

<fx:Declarations>

<model:ExternalData id=”externalData/>

</fx:Declarations>

<fx:Script>

<![CDATA[

import events.ExternalDataEvent;

import model.ExternalData;

protected function getDataBtn_clickHandler(event:MouseEvent):void {

externalData.addEventListener(ExternalDataEvent.EXTERNALDATA_DATAREADY,dataReady);

externalData.addEventListener(ExternalDataEvent.EXTERNALDATA_NODATAFOUND,noDataFound);

externalData.addEventListener(ExternalDataEvent.EXTERNALDATA_ERROR,fault);

var dataURL:String = "\\assets\\testData.xml";

externalData.readData(dataURL);

}

private function dataReady(event:ExternalDataEvent):void{

dataResults.text = event.externalData.toXMLString();

}

private function noDataFound(event:ExternalDataEvent):void{

dataResults.text = "No Data Found";

}

private function fault(event:ExternalDataEvent):void{

dataResults.text = "Data Fault";

}

]]>

</fx:Script>

<s:Button id=”getDataBtn” x=”31” y=”40” label=”Get Data” click=”getDataBtn_clickHandler(event)”/>

<s:TextArea id=”dataResults” x=”88” y=”86/>

</s:Application>

Results

When the user clicks on the Get Data button the ActionScript class is called.  Data is loaded and the custom event is dispatched.  The parent application is watching for the custom event and it populates the text area with the data from that event.

If all goes well, here’s what you should see once you click on the button:

image

 

Like I said earlier, its not terribly difficult.  At least its no more difficult than doing custom events using MXML components.   There just doesn’t seem to be too many sample using pure ActionScript classes rather than visual based components.

Source code can be found here.

Server Side PDF Flattening*

This blog entry is based on an internal document I wrote some time ago.  I’ve updated it for the current release of LiveCycle ES2.5 and cleaned it up a bit so it is more accessible to an external audience.

*Please note that the title contains a purposeful anachronism. Although the term “Flattening” has entered the vernacular, most PDFs are not really transformed into a flat PDF. Except in limited special cases, the Form is re-rendered as a flat PDF.

 

There has been much confusion around the ability of LiveCycle ES/ES2/ES2.5 to create flat PDFs from various types of interactive PDF forms. This has been exacerbated by functions added to LiveCycle ES Assembler which includes the ability to remove XFA (NoXFA) and form (NoForm) capabilities from a PDF. Specifically, there have been many questions, rumors and theories as to how flat PDFs can be created with and without LiveCycle ES Output.

Despite the ability of various LC components to create flat documents in certain cases, the most comprehensive application for creating flat PDFs is LiveCycle ES Output. As you will see there are certain circumstances where Output is not required to create a flat PDF.  However; these are specific circumstances.  The decision to propose a non LC Output solution must be taken carefully with understanding of the limitations that will be imposed being understood by the development team and customer. This will avoid the trap of what worked in a simple proof is not working when the customer proceeds with the actual application.

This post lays out these limitations and provides some guidance as to when Output is required.

Common Definitions

The following terms are used throughout this document. You shouldn’t consider these to be tremendously technically accurate, but they will work for the purposes of this discussion. 

Interactive Form – A form that can be filled in and potentially signed with a definition of the form in XFA and the data stream in XML.

Non-interactive Form – This is an interactive form with fields locked. It still has all of the XFA and XML in it, but the fields are all locked to be read-only.

Flat PDF – A PDF with no XFA stream and no non-signature elements. Basically there are no fields in the document.  It is important to note that a “Flat” PDF may still have some layers, such as the comment layer.  In this case the flatness refers to the lack of data fields.

Static PDF – A PDF which contains an XFA stream and the form layout does not change. Static forms may be interactive (a user can still fill in fields). If a dynamic XDP is rendered with LiveCycle Forms with the Render At Client option set to “No” then the resulting PDF is no longer dynamic – it is now static and behaves like any other static PDF.

Dynamic PDF – Dynamic PDFs allow the layout of the form to be altered either through user interaction or through script. An example is a form that adds subforms based on a user input. If a static XDP is rendered with LiveCycle Forms with the Render At Client option set to “Yes” then the resulting PDF is no longer static – it is now dynamic and behaves like any other dynamic PDF.

Acroform – A non-XFA based PDF form, usually created directly in Adobe Acrobat (as opposed to using LiveCycle Designer).

Artwork or XFAF – A PDF form created with from a flat PDF document using the “Create an Interactive Form with Fixed Pages” option in designer. For the purpose of this document Artwork PDFs operate the same as static PDFs.

Different Methods

There are a variety of ways to create a non-interactive form out of an interactive form using Adobe LiveCycle ES/ES2/ES2.5. The use of these different methods depends on the customer process:

  • Assembler – Assembler can invoke a DDX operation that can have either a noXFA or noForms tag. The result of both of these operations is to turn an interactive PDF into a flat PDF
  • DocConverter – DocConverter includes a feature (Convert to PDF/A) that will convert PDFs to a PDF/A format. PDF/A documents are flat PDFs with additional archival restrictions
  • Output – LiveCycle Output includes a transformPDF feature that, amongst other things, can create flat PDFs.

What works and what doesn’t

The following matrix lists what works (Y) and what does not work (N) when you try to convert interactive PDF documents to flat PDFs.

whatWorks

Notes:

  • [2] With LiveCycle ES, if a PDF (XFA or Acroform based) is merged with data using LiveCycle Forms (or Form Data Integration), the resulting document is not fully rendered. If the resulting PDF is processed with Assembler and the NoXFA or NoForms tags are used then the resulting PDF will have no data. The reason the PDF is not re-rendered is to increase server performance. The solution is to use LiveCycle Output to render the flat PDF directly instead of using a combination of Forms and Assembler.  I understand that this was changed with LiveCycle ES2, so it should not be a problem if you are using a more recent version of the product.
  • Artwork based PDFs work in the same way as other static PDFs.
  • Some developers have attempted to use the toPS operation to convert an interactive PDF into a PostScript file with the intention of converting the PS file back to a flat PDF using LiveCycle Generator. This will not work as toPS only works with flat PDFs.

Explanation

Dynamic PDFs require regeneration of the layout because they contain dynamic XFA. Only LiveCycle Output ES and LiveCycle Forms ES (Forms can only generate interactive PDFs so is not applicable in this case) include the XFAForm.exe application.  XFAForm.exe is called behind the scenes through the use of the LiveCycle services and is used in the layout creation. So any scenario that requires rendering XFA, such as merging data or displaying dynamic XFA, will ultimately require Output to do the rendering. Static XFA is already rendered, so unless there is new data being merged, Output is not required.

AcroForms can be rendered by the Gibson libraries (within the limitations of the Assembler and PDF Generator implementations), and therefore do not require Output.

The key message is that, in general, LiveCycle Output ES is the product for documents of record (flat PDF) from XFA and forms.

Creating an Organized Mosaic Project Structure

Lately, I’ve been working a lot with people that are new to LiveCycle ES2 Mosaic.  One thing always seems to come up is the question of the best way to organize Mosaic projects.    There aren’t any hard and fast rules (with the exception of the Catalog folder layout), but I’ve seen enough similarities in unrelated projects to suggest that there are some unofficial conventions that are forming.  I won’t go as far as to call the following “best practices”, rather consider them suggestions based on experience.  When combined with standard Flex best practices, these suggestions may make developing your Mosaic applications a bit easier.

Folder Structure

Organization will set you free – Alton Brown

Mosaic applications consist of quite a few moving parts.  There are the application descriptors, tile code, services and interfaces, authentication policies, shell skins, etc.  Keeping these sorted out will definitely make your life easier, especially when it comes to deploying and debugging.  Whenever possible, I prefer to keep all of the files/folders for a single Mosaic undertaking under a single folder.  That may mean having more than one application in the same folder, but at least the related code will be close by.

Under that parent folder I usually create one folder for each major Mosaic component.  The folder names are in lower case to differentiate them from the Catalog’s folders (more on that later).  For example:  I have a project called the Sales Dashboard, which will contain an application, catalog, several tiles, a service, a custom style sheet, etc.  To keep from going insane, I created the following folder structure:

topLevel

  • applications – this folder contains the application descriptor xml file(s)
  • catalogs – this folder contains the deployable contents for the project’s catalog.  If I was to have multiple catalogs, then they would each go in a separate subfolder.  A catalog’s structure is one of the few things that must have a specific structure.  This is because the catalog folder gets zipped and then deployed to the Mosaic server.  For more on the catalog folder’s structure, see the section below.
  • interfaces – this project uses a Mosaic Service component that is used by several tiles.  Each service component consists of two parts – the interface library and the service class.  This folder contains sub folders for each of the interface library projects.  Those subfolders contain a Flex Builder project that includes the source code for the interface.  In this example I have a single interface library called the “SalesDashboardInterfaceLibrary”, so the interface folder has a single subfolder with that name.  In the subfolder is a Flex Builder project for the interface:
    interfaces
  • policies – if you are using the Mosaic fine grained authorization, then this folder contains the XACML files that provide authorization information for the elements.
  • services – this folder is related to the interfaces folder.  It contains subfolders for each of the service class files.  Inside those subfolders is a Flex Builder project used to develop the service code.  For example, this application includes a “SalesDashboardService”. That subfolder contains a Flex Builder project for that service library:
    service
  • stylesheets – this project contains a custom skin for the Mosaic application.  The Flex Builder project for this skin is in a subfolder under the stylesheets folder.  If I had more than one skin, then each would get its own subfolder.  For example, my skin project is called “GlobalCorpSkins”:
    stylesheet
  • tiles – this folder contains sub folders for each of the Flex Builder tile projects.  Usually I try to keep related tiles in the same Flex Builder project (it makes debugging a bit easier), so a single sub folder may contain many tiles.  There are some cases, however, where a particular tile needs  its own project.  For example, if it uses a different Flex SDK or comes from a legacy application.  How fine grained you want to make the tile projects is really up to you, but keeping them all under this one tiles folder will make them easier to find.  In this example I have two tile projects – Flex 4 tiles (which contains several tiles) and Map (which contains a single, very complex tile):
    tiles

Catalog Structure

As I said earlier, the catalog structure is the one thing that must be in a specific format.  The catalog contains the deploy objects (compiled code, resources, etc.) and it will be zipped, then sent to the Mosaic server.  The server is expecting specific things to be in specific folders.  And yes, those folders are case sensitive.

catalog

  • descriptor.xml – this is the catalog’s definition file.  It must be named descriptor.xml and it must be at the root of the catalog zip file
  • Interfaces – contains the compiled swf for the interface libraries.
  • Resources – this is where the miscellaneous stuff needed for tiles and services is stored.  Things like images, XML files, videos, etc. are put here.
  • Services – contains the compiled swf for the service classes
  • Stylesheets – contains the skin classes complied into a swf
  • Tiles – contains subfolders for each of the tiles in the catalog.  The subfolder names is the same name as the tile, and they contain the tile swf files.

Flex Builder Linked Resources

Since tiles, services and skin projects rely on the Mosaic SDK, you’ll need to include the appropriate SDK swc in each of your projects.  Rather than hard coding the path, it is a good idea to create a pointer to the SDK folder and let Flash Builder sort out the location.  This makes your code more portable, if you give it to someone else, they don’t have to have the SDK in exactly the same location as you do.

To set up a linked resource to the Mosaic SDK:

  • Open Flex Builder
  • Choose Window –> Preferences
  • Choose General –> Workspace –> Linked Resources
  • Click the New button
  • Give it a name of MOSAIC_SDK
  • Click the Folder button and browse to your Mosaic SDK folder.  Don’t go any lower than the “sdk” folder.
  • Click OK to close the dialogs

When you create a new Mosaic project you can use the linked resource in your Flex Build Path.  Then if someone else opens your project and has the SDK in a different location, Flash Builder will sort out the reference (assuming they have a MOSAIC_SDK resource).

ANT Scripts

It may seem that I’ve gone a little berserk with the organization of the project.  I mean, how anal retentive can you get?  Why not just lump everything together in one or two folders and be done with it?

The answer lies in the application deployment through ANT scripts.  Having a highly organized structure like this allow you to build the deployment code as a few, small ANT files.  These can be combined together to quickly deploy code changes in an efficient manner.  There are few things more annoying than testing against the wrong code.

For example; At the root of the project I have an ANT script that deploys the catalog, application and policies.  Before that section executes, it calls ANT scripts in the sub folders that re-compile the interface, service, style sheet and tile classes, and move them to the appropriate location in the catalog structure.  Using this, I can make changes to a tile, run the root ANT script and ensure that everything is the current version.

True, it takes a bit more effort to set up, but the time and frustration savings are well worth it.  Here’s what my final folder structure looks like:

folderStructure

Request for Comments

For what its worth, most of the above is my opinion based on my own experiences.  If you have any additional suggestions, I’d love to hear them.