Wednesday 2 November 2011

Emplore: A Constraint Engine

I've started putting together a framework I'm code naming Emplore. It's a constraint engine that was born out of having data models being manipulated in multiple places in applications and a subsequent need to perform constraint checking in those places.

The general concept is that annotations will be used to decorate the model with constraint definitions. For example:

public class MyModel
{
  [Required]
  [ConstrainLength( minLength=1, maxLength=100 )]
  public var aString: String;

  [ConstrainRange( minValue=-123.4, maxValue=234.5 )]
  public var aNumber: Number;
}
The intention from here is that there will be functionality for automated validator generation and API-based constraint checking. Stay tuned for more.

Monday 24 October 2011

Quick Tip: Flex 4.5 Form Spacing

Users of the new Flex 4.5 Form will notice that the vertical spacing between FormItems is quite significant. A quick fix to this is to alter the gap of the layout, e.g.:

<s:Form>
  <s:layout>
    <s:FormLayout gap="-14"/> 
  </s:layout>

...

</s:Form>

Do note, however, that this will cause layout issues when adding controls to the Form that are not wrapped in FormItems. An alternative solution is to roll a custom FormItem skin which alters the  row constraint declaration as follows:

<s:constraintRows>
  <!--- @private -->
  <s:ConstraintRow id="row1" baseline="maxAscent:0" height="100%"/>
</s:constraintRow>

instead of the default

<s:constraintRows>
  <!--- @private -->
  <s:ConstraintRow id="row1" baseline="maxAscent:10" height="100%"/>
</s:constraintRow>

Sunday 25 September 2011

Quick Tip: Ignoring XML Namespaces

This is another small follow up to Common Mistakes: XML Namespaces and E4X: sometimes you may wish to completely ignore the namespace information, rather than explicitly traverse it. Consider the following example:

var xml: XML = <root xmlns:space="http://www.something.com">
 <space:tag>
  <node>Hello, world!</node>
 </space:tag>
</root>;

It is possible to reference node containing Hello, world! using the following:

var node: XML = xml.*::space.node;

Sunday 14 August 2011

Quick Tip: Checking for XML nodes with a namespace

This is a small follow up to Common Mistakes: XML Namespaces and E4X: when working with namespaces, calling hasOwnProperty() may not work as expected. Consider the following example:

var xml: XML = <root xmlns:space="http://www.something.com">
 <space:tag>
  <node>Hello, world!</node>
 </space:tag>
</root>;

trace( xml.hasOwnProperty( "tag" ) );

In this case, hasOwnProperty() will return false as the 'tag' tag is part of the 'space' namespace. In order to overcome this, use the QName construct, e.g.:

xml.hasOwnProperty( new QName( "http://www.something.com", "tag" ) )

Alternatively, if you have declared a namespace previously, you can do the following:

namespace space = "http://www.something.com"; 

// ...

xml.hasOwnProperty( new QName( space, "tag" ) )

Thursday 11 August 2011

Quick Tip: FlashBuilder 4.5 Premium Upgrade Download

Just a really quick one: Adobe's consumer site (in Australia, at least) does not have the option to allow the FlashBuilder 4 Premium to FlashBuilder 4.5 Premium Upgrade to be purchased as a download - it's only available as a shipped box. if you need it quicker than that, the solution is to purchase it from the Adobe Business site instead: http://volumelicensing.adobe.com/AU Note that a serial and download link is not provided immediately; after roughly 24 hours you will receive access to the Adobe Volume Licensing site where you can access these details.

Thursday 21 July 2011

Quick Tip: Passing Varargs Parameters

Occasionally the need arises to pass the varargs parameters of a function directly onto another function that accepts varargs, such as if you are writing a wrapper or using a Composite or Decorator pattern to add complimentary behaviour. Suppose we have the following interface:

package
{
 public interface IMyInterface
 {
  function myFunction( singular: String, ... varargs ): void;
 }
}

If we're implementing a basic Decorator-style pattern to extend some functionality, we're going to want to pass the parameters on to the child unaffected. If we tried the following:

package
{
 public class NewFeature implements IMyInterface
 {
  private var _child: IMyInterface;

  public function NewFeature( child: IMyInterface )
  {
   _child = child;
  }

  public function myFunction( singular: String, ... varargs ): void
  {
   _child.myFunction( singular, varargs );
  }
 }
}

Then the varargs will get passed to the child function's varargs parameter as a single array, rather than the unrolled varargs. That is, assuming we had the following:

package
{
 public class CoreFeature implements IMyInterface
 {
  public function myFunction( singular: String, ... varargs ): void
  {
   trace( "Singular: " + singular );
   trace( "Varargs: " + varargs );
  }
 }
}

and then made a call as per:

var feature: IMyInterface = new NewFeature( new CoreFeature(  ) );

feature.myFunction( "foo", "bar", "qwerty", "asdf" );

Then the debug console would contain the following output:

Singular: foo
Varargs: [ [ bar, qwerty, asdf ] ]

That is, when passing the varargs variable to a function call, it is treated as an array. Thus, when it is passed on to a varargs parameter, it becomes the first element of the subsequent varargs array.

The fix here is to use some basic runtime reflection to call the function, rather than invoking it directly. By using the Function.apply() method, we're able to pass an array of parameters into the function call. AVM2 will correctly match up the explicit parameters, and then group the rest into the varargs variable. For example:

package
{
 public class NewFeature
 {
  private var _child: IMyInterface;

  public function myFunction( singular: String, ... varargs ): void
  {
   varargs.unshift( singular );
   _child.myFunction.apply( _child, varargs );
  }
 }
}

In this example, we need to stick singular at the start of the array, so that it is correctly applied to the child function.

Calling the function as per the example above, would now result in the following debug console output:

Singular: foo
Varargs: [ bar, qwerty, asdf ]

Sunday 10 July 2011

Remote Debugging in FlashBuilder

Disclaimer: There may be a better way to achieve this goal, but this trick has served me well for many years.

Occasionally the need to debug a Flex application that has not been launched from FlashBuilder arises: the application may be present in a UAT environment or it might need to be tested outside of the security-sandbox-free-zone.. In any case, you may not be able to launch it by simply clicking the "Debug" button on FlashBuilder's toolbar.

A workaround to this problem involves creating another debug profile for the application, by either selecting the "Run -> Debug Configurations..." menu item, or clicking the down arrow to the right of the "Debug" toolbar button and selecting "Debug Configurations..." In this screen, you should right-click on the configuration of the application of note, and select "Duplicate." The duplicated item will appear with a name like, "SampleApplication (1)." Select this debug profile in the tree, and then change the "URL or path to launch" configuration as follows:

  1. Untick the "Use default" checkbox.
  2. Enter "about:blank" as the URL.
Save your configuration by clicking the "Close" button, or launch it by clicking the "Debug" button.

The idea here is that when you launch this new debug profile, the browser associated with FlashBuilder will not open a page containing the Flex application, and thus a debug connection will not be established. However, FlashBuilder will still open up a debug listening service that will wait a short time before terminating. During this time, it is possible to manually load the application to be tested. As the application loads, it should connect to the debug session waiting within FlashBuilder, permitting the usual debug operation.

Friday 17 June 2011

Making Flex More Testable: Part 1

Testing is a fundamental aspect of any enterprise development; it underpins the assurance we need to provide that our application does what it is supposed to, aids confidence in refactoring and when working in a TDD paradigm, is an integral part of development. This is the first of a multi-part series that aims to address some of the difficulties faced when trying to develop testable code that involves the use of core Flash or Flex libraries.

One software concept that makes proper unit testing difficult is static references, as they introduce dependent coupling that is very difficult to break. This makes testing in isolation very difficult to achieve, and in some cases can make automated testing impossible (due to referencing external resources which may not be available in the test environment). It's one thing to keep this in mind when designing our own implementations, but the Flash Player and Flex Frameworks have their own static methods and variables we need address.

ExternalInterface
Classes like ExternalInterface provide utility functionality through a series of static properties and methods. As this class' prototype is purely static in nature, my preference to break the coupling is to write an interface that has the same footprint as ExternalInterface, minus the static declarations. For example:

package
{
 public interface IExternalInterface
 {
  /**
   * Indicates whether this player is in a container that offers an external interface.
   */
  function get available(  ): Boolean;

  // ...

  /**
   * Registers an ActionScript method as callable from the container. After a successful
   * invocation of addCallBack(), the registered function in Flash Player can be called
   * by JavaScript or ActiveX code in the container.
   * 
   * @param functionName The name by which the container can invoke the function.
   * 
   * @param closure   The function closure to invoke. This could be a free-standing
   *       function, or it could be a method closure referencing a method
   *       of an object instance. By passing a method closure, you can direct
   *       the callback at a method of a particular object instance.
   */
  function addCallback( functionName: String, closure: Function ): void;

  // ...
 }
}


This interface can then be referenced by any classes that depend upon ExternalInterface. In order to complete the implementation, we need to write a basic wrapper class that implements our new IExternalInterface interface, and delegates calls off to ExternalInterface. Whilst this class will contain static references, we are isolating them from the remainder of the application. For example:

package
{
 /**
  * A wrapped implementation of ExternalInterface, for decoupling and dependency injection.
  * 
  * @see flash.external.ExternalInterface
  * @see IExternalInterface
  */
 public class WrappedExternalInterface implements IExternalInterface
 {
  /**
   * @inheritDoc
   */
  public function get available(  ): Boolean
  {
   return ExternalInterface.available;
  }

  // ...
 }
}


Lastly, all that's needed is to wire this up. With RobotLegs/SwiftSuspenders (my current MVCS and dependency injection framework of choice), this would look something like:

injector.mapSingletonOf( IExternalInterface, WrappedExternalInterface );


However, it is worth nothing that even without a Dependency Injection framework in place, there is a lot of benefit to be had by decoupling these sort of static references and manually wiring up the dependent wrapper classes.

Application
At some point, Flex projects will invariably require access to Application.application (Flex 3) or FlexGlobals.topLevelApplication (Flex 4). Removing these static references are not as straightforward as the previous example; we reference it as a dependency and have our dependency injection framework sort out the wiring, for example:

injector.mapSingleton( Application );

// ...

[Inject]
public var application: Application;

However, mocking the behaviour out at test-time might be a bit challenging. Alternatively, we could take a step back and examine the information we're trying to obtain from the Application instance. For example, trying to determine the application URL may be invalid or unavailable in a testing context. Developing a simple service to provide this information abstracts the implementation and makes testing simpler.

This could be facilitated with a simple service definition, as follows:

package
{
 public interface IApplicationURLProvider
 {
  /**
   * The URL that the application was loaded from.
   */
  function get applicationURL(  ): String;
 }
}

Obviously this is a trivial example, but it can be quite a useful abstraction. On a number of projects that I have been involved with recently, the application URL was used as a reference point for making server-side calls. Due to a number of different reasons, the server-side implementation was not available on the (Flex) developers' machines. Whilst it might have been possible to arrange deployment of the Flex application on the server, this can get quite messy with multiple developers wanting to perform their testing.

Alternatively, we were able to provide a mock implementation for our URL provider, e.g.:

package
{
 public class MockApplicationURLProvider
 {
  /**
   * @inheritDoc
   */
  public function get applicationURL(  ): String
  {
   return "http://my.server.location";
  }
 }
}

This concept is also useful when developing Flex-platform-agnostic library code. For example, I've recently developed a RemoteObject pooling system for communicating with Adobe LiveCycle, but it may be used with Flex 3 or Flex 4. The way that we determine the application URL is different for each of these platforms. The core library implementation just needs to depend upon a service declaration similar to the one above. Then it is possible to develop appropriate adapters for each platform, e.g.:

package
{
 public class Flex3ApplicationURLProvider
 {
  /**
   * @inheritDoc
   */
  public function get applicationURL(  ): String
  {
   return Application.application.url;
  }
 }
}

and

package
{
 public class Flex4ApplicationURLProvider
 {
  /**
   * @inheritDoc
   */
  public function get applicationURL(  ): String
  {
   return FlexGlobals.topLevelApplication.url;
  }
 }
}

Saturday 11 June 2011

Common Mistakes: XML Namespaces and E4X

From time to time I stumble upon application code that has an unusual way of handling XML namespaces. The most common case is where a regular expression substitution (or similar) is used to strip out namespace declarations and references from the raw XML prior to being parsed into an XML object. Whilst this may function correctly accordion to the defined application behaviour, there are more elegant ways to handle namespaces in E4X. Consider the following XML snippet:

<root xmlns:space="http://www.something.com">
 <space:tag>
  <node>Hello, world!</node>
 </space:tag>
</root>

Assuming that this XML has been parsed into an XML variable named xml, we could determine the contents of the node node using the following code:

namespace space = "http://www.something.com";

var helloWorld: String = xml.space::tag.node.toString(  );

That is, we are able to declare a namespace identifier by using the namespace keyword, and then reference it in our E4X statements to select the appropriate nodes (using the same notation that we would use to reference custom namespaces in ActionScript 3). Note that the identifier we declare does not have to match the one used in the XML document - only the namespace URI has to match. The example below is equally correct:

namespace different = "http://www.something.com";

var helloWorld: String = xml.different::tag.node.toString(  );

Using this technique avoids the need to manipulate XML content before it is parsed; it is simpler and avoids the chance of incorrectly preprocessing the data.

Introduction

I've created this blog as a means of documenting my experiences and thoughts on developing enterprise applications that involve the Adobe Flex platform. Much of this will be derived from my professional career, but some may come from my personal interest in the technology, and software engineering in general. It will be a focus on design patterns, methodology, testing and real-world problem solving.