Showing posts with label flex. Show all posts
Showing posts with label flex. Show all posts

Monday, 23 January 2012

Calling LiveCycle processes via Remoting, involving Documents

One nice aspect of Adobe's LiveCycle is the ability to easily invoke a process using Flex Remoting. For 'primitive' types, such as Number, XML and String, it's a straight-forward case of passing them to the Remoting call. However, in some instances, it is necessary to pass a LiveCycle Document instance to a Remoting call. The recommended means of doing this involves a two-step process, where the Document is uploaded to the LiveCycle server, which returns a DocumentReference. This reference is passed to the Remoting call and LiveCycle marries everything up on its end.

I encountered an issue with this recently in an enterprise environment, due to the way DocumentReference works. After the Document has been stored on the server, LiveCycle constructs a URL pointing to it - based on the application URL of the Flex application that performed the upload. In our client's case, the application URL does not resolve inside their firewall. This meant that when LiveCycle attempted to load the Document based on the DocumentReference, it was unable to locate it.

Manipulating the DocumentReference on the client side was ruled out, due to the maintenance nightmare and security implications of having internal infrastructure details stored within the application itself. Resolving the issue on the server side was not a straightforward solution, as all processes involving Documents would have to be changed.

It turns out there's a simple solution; instead of performing a HTTP-based Document upload (which also has problems in a HTTPS context on non-IE browsers), it is possible to manually construct a DocumentReference instance, and pass in the file data by hand. For example:

var documentReference: DocumentReference = new DocumentReference(  );
documentReference.referenceType = DocumentReference.REF_TYPE_INLINE;
documentReference.bytes = yourByteArray;

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, 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 ]

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.