Using External Templates with Mustache.js and jQuery.

Mustache is a language independent, logicless templating engine which, in the context of a JavaScript / HTML5 style web application, means you can use it to separate your logic (javascript code) from your view (HTML Markup). Mustache comes in a variety of flavours; this article will be focusing on the JavaScript implementation.

Why Bother With Templating At All?

Fair question; when it comes simple JavaScript powered sites it’s pretty easy to just build up your HTML inline:

$('body').append('<p>Hello John, it is 11:19.</p>');

However, it starts getting a bit messy when we start replacing hard-coded values with variables, for example:

var date = new Date();
var name = 'Jonny';
var timeNow = date.getHours() + ':' + date.getMinutes();

$('body').append('<p>Hello ' + name + ', it is ' + timeNow + '.</p>');

Things get even more ugly when we want to start build up complex, nested HTML elements, for example:

$('body').append('<dl><dt>Name</dt><dd>' + name + '</dd><dt>Time</dt><dd>' + timeNow + '</dd></dl>');

As JavaScript doesn’t support heredoc, the only way to sort out this nasty one-liner is to escape the new line literal by using a backslash; however I’m not convinced that this really helps with readability.

$('body').append('<dl>\
 <dt>Name</dt>\
 <dd>' + name + '</dd>\
 <dt>Time</dt>\
 <dd>' + timeNow + '</dd>\
</dl>');

Enter the Templating Engine

Templating engines help us solve half the problem by allowing us to move the logic out of the HTML string. The basic premise is fairly simple; instead of having to break out of the String, we can just drop in tokens which the templating engine will replace for us. So instead of having to concatenate lots of Strings together we can simply express our template like this:

var date = new Date();

// Contains all the values that we want to use in place of the tokens in
// the template
var templateData = {
	name: "Jonny",
	timeNow: date.getHours() + ':' + date.getMinutes()
};

// Define our HTML template, note the tokens match up to the properties
// of the templateData object.
var template = '<p>Hello {{name}}, it is {{timeNow}}.</p>';

// Use Mustache.js to render the template (replace the tokens with the values
// in the templateData object).
var renderedTemplate = Mustache.render(template, templateData);

// And attach the rendered template HTML to the DOM.
$('body').append(renderedTemplate);

Nice, now we have a clear separation between our template HTML and our data Object which supplies the values; however, we are still stuck when it comes to rendering more complex templates…

var template = '<dl>\
 <dt>Name</dt>\
 <dd>{{name}}</dd>\
 <dt>Time</dt>\
 <dd>{{timeNow}}</dd>\
</dl>';

Would you declare your JavaScript in HTML?

So we have managed to simplify our code by replacing String concatenation with token substiution (templating); but we are still having to declare our template’s HTML in JavaScript which is far from ideal. What we really want is to be able to write our template in raw HTML as opposed to a String literal – time for some external templates. John Resig is widely regarded as having coined the concept of declaring templates in script blocks; ie:

<!-- Our Template is declared in a script block, but we
     can just use regular HTML markup -->
<script id="tpl-greeting" type="text/html">
	<dl>
		<dt>Name</dt>
		<dd>{{name}}</dd>
		<dt>Time</dt>
		<dd>{{timeNow}}</dd>
	</dl>
</script>
<script type="text/javascript">
	var date = new Date();

	var templateData = {
		name: "Jonny",
		timeNow: date.getHours() + ':' + date.getMinutes()
	};

	// Use jQuery to reference our 'tpl-greeting' script block
	// and grab the HTML contents it contains.
	var template = $('#tpl-greeting').html();

	// Render this template as before.
	$('body').append(Mustache.render(template, templateData));
</script>

Much nicer! Now we are able to write our template in HTML as opposed to simply mashing Strings together; however, this method still isn’t ideal; in order for it to work we have to define our template in the parent HTML Document; this is fine for a simple example, but in a real world web application you won’t be writing your JavaScript in a script block, you’ll be using external .js files instead – and you don’t really want to have to send all the HTML Templates down in the original page – let’s externalise those templates and load them in as we need them.

Loading External HTML Templates

jQuery makes it really easy to load external content via it’s jQuery.get() method. We can use this to load an external HTML file which contains our template:

<!-- You can define as many templates as you like in a single
	.htm file; just add additional <script /> blocks with
	unique ids. -->
<script id="tpl-greeting" type="text/html">
	<dl>
		<dt>Name</dt>
		<dd>{{name}}</dd>
		<dt>Time</dt>
		<dd>{{timeNow}}</dd>
	</dl>
</script>
$.get('greetings.htm', function(templates) {
	// Fetch the <script /> block from the loaded external
	// template file which contains our greetings template.
	var template = $(templates).filter('#tpl-greeting').html();
	$('body').append(Mustache.render(template, templateData));
});

Now we’re talking! Finally, we are able to define our templates in external HTML files which can easily be loaded and rendered in our application’s JavaScript code. However, the above is only a proof of concept and doesn’t really stand up in the real world; what if we want to render our greetings template more than once? If we are going to have to load the template file each time our code is going to be littered with callback functions – again, not pretty and not easy to maintain – what we need is some kind of plugin…

jQuery-Mustache Plugin

To make working with Mustache in jQuery nice and easy I knocked together my first jQuery Plugin, jquery-mustache.js. This makes it really easy to load all your external templates at the start and then render them as required.

$.Mustache.load('greetings.htm', function() {
	$('body').mustache('tpl-greeting', templateData);
});

Sweet!

Getting Started with Vanilla

A lot of people are excited about the news that Native JSON support is coming with Flash Player 11; however, I’ve also seen a lot of people get a bit confused by what this actually means – if you were hoping that Flash would be able to magically convert your parsed JSON Strings into your own Model objects then you’re going to be left a touch disappointed – until now!

That’s Just Weak…

Let’s start by using the new native JSON methods to parse some JSON and see what we get back, for this example I will be making use of the Yahoo! Weather API to get the forcast for London.

public class Main extends Sprite {
	private var loader : URLLoader = new URLLoader();

	public function Main() {
		loader.addEventListener(Event.COMPLETE, onLoaderComplete);

		// Look up the weather in London (probably raining...)
		loader.load(new URLRequest("http://weather.yahooapis.com/forecastjson?w=44418&u=c"));
	}

	private function onLoaderComplete(event : Event) : void {
		const rawJson : String = loader.data;

		// Use a JSON decoder to convert the rawJson String into an Object.
		const jsonObject : Object = JSON.decode(rawJson);
	}
}

The above code given provides me with a `jsonObject` property, however, it’s completely dynmaic; this means I won’t gain any of the benefits of Strong Typing such as code hinting – if I want to access the properties, I have to know their names, eg:

trace("The weather in " + jsonObject.location.city + " is " + jsonObject.forecast[0].condition + " " + jsonObject.forecast[0].day);

Getting Harder…

If you plan on passing the forecast data around in your application then you are going to start wishing you were making use of Strongly typed Model objects (for example, if you rely on using dyanmic objects then a simple typo in another class may cause you a headache) – ok, not a problem, the first step is to create a couple: (note I am not representing the entire Object Graph here to save space – the .zip file at the end of this example has the entire graph represented as Model Objects).

// Use a JSON decoder to convert the rawJson String into an Object.
const jsonObject : Object = JSON.decode(rawJson);

// Copy of the fields from the jsonObject into our strongly typed Model.
const weatherResult : WeatherResult = new WeatherResult();
weatherResult.url = jsonObject["url"];

weatherResult.location = new Location();
weatherResult.location.city = jsonObject.location.city;
weatherResult.location.locationId = jsonObject.location.location_id;
weatherResult.location.stateAbbreviation = jsonObject.location.state_abbreviation;
weatherResult.location.countryAbbreviation = jsonObject.location.state_abbreviation;
weatherResult.location.elevation = jsonObject.location.elevation;
weatherResult.location.latitude = jsonObject.location.latitude;
weatherResult.location.longitude = jsonObject.location.longitude;

weatherResult.forecast = new Vector.<Forecast>();
for each (var forecastJson : Object in jsonObject.forecast) {
	const forecast : Forecast = new Forecast();
	forecast.day = forecastJson.day;
	forecast.condition = forecastJson.condition;
	forecast.highTemperature = forecastJson.high_temperature;
	forecast.lowTemperature = forecastJson.low_temperature;

	weatherResult.forecast.push(forecast);
}

trace("The weather in " + weatherResult.location.city + " is " + weatherResult.forecast[0].condition + " " + weatherResult.forecast[0].day);

Crikey, that’s a hell of a lot of code; well – at least now if we’ve made a typo anywhere, or if Yahoo decide to change their API at least we only have to make our changes in a single place – there must be an easier way of doing this?!

Adding some Vanilla Extract

Enter Vanilla. Vanilla is an open source AS3 library whose sole purpose it to make converting untyped objects (such as the result of calling JSON.decode) into strongly typed Model objects a breeze, let’s see it in action:

// Use a JSON decoder to convert the rawJson String into an Object.
const jsonObject : Object = JSON.decode(rawJson);

// Use Vanilla to extract the properties into our model objects.
const weatherResult : WeatherResult = new Vanilla().extract(jsonObject, WeatherResult);

trace("The weather in " + weatherResult.location.city + " is " + weatherResult.forecast[0].condition + " " + weatherResult.forecast[0].day);

Yep, that’s it; 20 lines of tedious, error prone code replaced with a single call to Vanilla’s extract() method; pretty neat eh? So, let’s have a look at how it works.

The main design goal of Vanilla was to make the extraction process as simple as possible – infact, if your JSON object matches up perfectly to your Model object then you don’t need to do a thing, for example, here’s our WeatherResult model object’s class definition:

public class WeatherResult {
	public var url : String;
	public var location : Location;
	public var forecast : Vector.<Forecast>;
}

Let’s compare that to a cross section of the JSON object we get back from the Yahoo weather api:

{
   "location":{
      "location_id":"UKXX0085",
      "city":"London",
      "state_abbreviation":"ENG",
      "country_abbreviation":"UK",
      "elevation":56,
      "latitude":51.51000000000000,
      "longitude":"-.08"
   },
   "url":"http://weather.yahoo.com/forecast/UKXX0085.html",
   "forecast":[
      {
         "day":"Today",
         "condition":"Partly Cloudy",
         "high_temperature":"70",
         "low_temperature":"52"
      },
      {
         "day":"Tomorrow",
         "condition":"Partly Cloudy",
         "high_temperature":"72",
         "low_temperature":"58"
      }
   ]
}

As you can see, the three fields in the WeatherResult model object, locationurl andforecast all map exactly to those fields in the JSON object – Vanilla exploits this and guesses that you probably want to map to those fields; however, not everything is always so clear – what if your model object doesn’t map up exactly to the JSON result? Let’s have a look at our Location model:

public class Location {
	public var locationId : String;
	public var city : String;
	public var stateAbbreviation : String;
	public var countryAbbreviation : String;
	public var elevation : Number;
	public var latitude : Number;
	public var longitude : String;
}

If you look closely you will notice how some of the field names do not map to the JSON, for example, the field “country_abbreviation” in the JSON is not present in the Model (I’ve named the field countryAbbreviation, as per the AS3 camelCase convention), so how does Vanilla know what to do? Simple answer, it doesn’t – nothing will be mapped and Location.countryAbbreviation will be null. That’s rubbish; I agree, but Vanilla’s not psychic – it just a program after all.

Using Metadata to define Marshalling Rules

In the above example the JSON field “country_abbreviation” was not being mapped to our model’s “countryAbbreviation” property because Vanilla didn’t know that these two were related – so how can we tell Vanilla about that relationship? Like this:

public class Location {
	[Marshall (field="location_id")] public var locationId : String;
	public var city : String;
	[Marshall (field="state_abbreviation")] public var stateAbbreviation : String;
	[Marshall (field="country_abbreviation")] public var countryAbbreviation : String;
	public var elevation : Number;
	public var latitude : Number;
	public var longitude : String;
}

Here we have annotated the public fields of the Location model object with the [Marshall] Metadata tag – this tells Vanilla that if we see a field named ‘country_abbreviation’ on the source (JSON) object, then we should copy that value to the annotated filed.

Have It Your Way

Although Vanilla aims to be as easy to use as possible, it also tries to be flexible to adapt to different ways of working – lots of teams make use of explicit getter/setter methods instead of using fields; don’t worry – Vanilla can detect metadata on these methods too!

Get Stuck In!

You can download the classes used in this example here – it includes Vanilla 0.1.1 and all of its dependencies (I currently rely on as3commons-reflect for reflection).

If you want to have a play with Vanilla, or start using it in your own project, then you candownload it, and read the documentation from the GitHub page – if you’re interested in getting involved then please fork it – I’ll be happy to merge new features back in!

Converting XML into Objects – Data Marshalling in ActionScript 3

Data Marshalling is a common task that nearly every ActionScript 3 developer will face at some point; put simply it is the process of converting an Object into a data interchange format (for example XMLJSON or AMF) and likewise converting it back into an Object that your application can use again. This tutorial will focus on XML.

Data Modelling

So let’s start nice and simple, with the XML that we want to unmarshall into an ActionScript Object – this could be coming from a local file, or from a server (referred to as an endpoint).

The SlideShow XML Document

<slideshow title="LolCats">
	<slide url="http://checkmybelly.com/wp-content/uploads/2007/11/lolcat-funny-picture-moderator1.jpg" caption="Moderator Kitteh" />
	<slide url="http://www.lolcats.com/images/u/07/24/lolcatsdotcom5x02srq751692std.jpg" caption="Wait... I'll fix it" />
	<slide url="http://icanhascheezburger.files.wordpress.com/2007/01/i-can-has-cheezburger.jpg" caption="Can Has Cheezburger?" />
</slideshow>

So, we need to start by looking at what Objects we create when the parse this XML. This one is quite easy; the XML document defines a Slideshow which contains a number of slides; with this in mind it would seem appropriate that we create two Classes, one which represents a single Slide, and another which represents the entire SlideShow.

The Slide model is straight forward as it just needs to contain the URL of the image and the caption; both of these can be represented as Strings which keeps everything very straight forward:

The Slide Model Object

package slideshow.model
{
	public class Slide
	{
		private var url : String;
		private var caption : String;

		/**
		 * Creates a new Slide Model Object which represents a single image in a SlideShow.
		 *
		 * @param url The URL of the image which makes up this Slide.
		 * @param caption Text which accompanies this Slide.
		 */
		public function Slide(url : String, caption : String) {
			// Ensure this object does not get instantiated with invalid data.
			if (url == null) throw new ArgumentError("url must not be null");
			if (caption == null) throw new ArgumentError("caption must not be null");

			this.url = url;
			this.caption = caption;
		}

		/**
		 * The URL of the image which makes up this Slide.
		 */
		public function getUrl() : String {
			return url;
		}

		/**
		 * Text which accompanies this Slide.
		 */
		public function getCaption() : String {
			return caption;
		}

		public function toString() : String {
			return "[Slide url=" + url + ", caption='" + caption + '"]';
		}
	}
}

The model is nice and straight forward; there are a couple of points to note from the design of my Slide Model Object:

  • The URL and Caption properties are passed in the constructor; this way I can ensure that my Slide Model is immutable and can not be changed once is has been created.
  • When the URL and Caption are supplied in the constructor I perform a null reference check to ensure that non-null values were passed; this is important because it means that any other object (known as a “client”) which makes use of my Slide object knows that it will never get a null value back from the getUrl() and getCaption() methods.
  • The Slide Model provides a toString() method – this will be called automatically whenever a Slide model object is concatenated to a String – for example in a trace() statement – this will aid debugging and development.

Next up is the SlideShow model; we know from the XML that a SlideShow has a title and a number of Slides; my SlideShow Class looks like this:

The SlideShow Model Object

package slideshow.model
{
	public class SlideShow
	{
		private var title : String;
		private var slides : Array;

		/**
		 * Represents a collection of Slide images which make up a SlideShow.
		 *
		 * @param title Description of this SlideShow.
		 * @param slides Array of Slide model instances which make up this Slideshow.
		 */
		public function SlideShow(title : String, slides : Array) {
			// Ensure this object does not get instantiated with invalid data.
			if (title == null) throw new ArgumentError("title must not be null");
			assertSlides(slides);

			this.title = title;
			this.slides = slides.concat();	// Take a defensive copy.
		}

		/**
		 * Custom assertion method which ensures that the supplied Slide array is in a valid state.
		 */
		private function assertSlides(slides : Array) : Array {
			if (slides == null) throw new ArgumentError("slides must not be null");

			// Check that the supplied Slides array contains only Slide models.
			for each (var slide : Slide in slides) {
				if (slide == null) throw new ArgumentError("slide array must only contain instances of slideshow.model.Slide.");
			}

			// Everything is OK, return the supplied Slides array for convenience.
			return slides;
		}

		/**
		 * Description of this SlideShow.
		 */
		public function getTitle() : String {
			return title;
		}

		/**
		 * An Array of Slide model instances which make up this SlideShow, note that this is a copy, so any changes
		 * made will not persist.
		 */
		public function getSlides() : Array {
			return slides.concat();		// Return a defensive copy.
		}

		public function toString() : String {
			return "[SlideShow title='" + title + "', slides={" + slides.join(", ") + "}]";
		}
	}
}

Like the Slide model, the SlideShow model is immutable; it achieves this by ensuing that all of the data that it encapsulates (contains) can not be modified once the object has been constructed and that all the supplied data is valid upon construction; as we saw in the Slide model, this is nice and easy with String values, however, as you can see from the SlideShow class definition; it’s a bit trickier to achieve this with an Array as it’s a complex data type.

  • First, in the constructor, we ensure that the supplied slides Array is valid; as this is more involved than a simple null check, we pass it off to a helper function, assertSlides() – if assertSlides() encounters invalid data, it will throw an Error which will prevent the instance from being constructed.
  • Next, we take a defensive copy of the supplied slides Array with the line: this.slides = slides.concat(). This is to prevent modifications to the supplied slide array from modifying the state of our SlideShow model object, here’s an example of this in action:

The Dangers Of Not Taking Defensive Copies of Complex Data Types

// Create a new Array of Slide models.
const slides : Array = new Array();
slides.push(new Slide("http://img.com/cat.png", "A Cat"));
slides.push(new Slide("http://img.com/dog.png", "A Dog"));

// Create a new SlideShow.
const slideShow : Slideshow = new SlideShow("Animals", slides);

// Outputs [SlideShow title='Animals', slides={
//      [Slide url=http://img.com/cat.png, caption='A Cat'],
//      [Slide url=http://img.com/dog.png, caption='A Dog']
// }]
trace(slideShow);

// Add a new slide to our slides Array - should this change the contents of the SlideShow model?
slides.push(new Slide("http://img.com/car.png", "A Car (not an animal!)"));

// Yes it does! Our SlideShow model object now looks like this:
// [SlideShow title='Animals', slides={
//      [Slide url=http://img.com/cat.png, caption='A Cat'],
//      [Slide url=http://img.com/dog.png, caption='A Dog'],
//      [Slide url=http://img.com/car.png, caption='A Car (not an animal!)']
// }]
trace(slideShow);
  • We also return a defensive copy of the slides Array in the getSlides() method – this is done for exactly the same reason – if we didn’t return a defensive copy then our SlideShow model would no longer be immutable, for example, what would happen to our SlideShow model if the client called: slideShow.getSlides().length = 0?

UnMarhshalling – Converting the XML into a Model Object

OK, so now we have both our transmission format (XML) and our ActionScript Model Objects (SlideShow and Slide) which represent the data in our application – let’s look at how we go from one to the other (and back again!); let’s start by unmarshalling – converting from the transmission format to the ActionScript Objects – this will be handled by our SlideShowMarshaller.

The XMLSlideShowMarhshaller Class

package slideshow.model
{
	public class XMLSlideShowMarshaller implements SlideShowMarshaller
	{
		/**
		 * Converts the supplied SlideShow transmission format document into a SlideShow Model object.
		 */
		public function unmarshall(transmissionFormat : *) : SlideShow {
			// First we need to convert the incoming transmission format data to an XML Object so we can parse it.
			const slideShowXML : XML = new XML(transmissionFormat);

			// Now we can parse the data...
			const title : String = slideShowXML.@title;
			const slides : Array = parseSlides(slideShowXML..slide);

			// Ensure that the require attributes have been set.
			if (title == "") throw new Error("SlideShow XML was missing @title attribute");

			// And finally return the new SlideShow model object.
			return new SlideShow(title, slides);
		}

		/**
		 * Parses an Array of Slide model objects from the supplied XMLList, if there are no slides in the supplied
		 * XMLList, an empty Array will be returned.
		 */
		private function parseSlides(slidesXML : XMLList) : Array {
			const slides : Array = [];
			for each (var slideNode : XML in slidesXML) {
				// As the Slide model will throw an error if supplied with invalid data, we need to wrap it in a
				// try/catch block and log that an error occured - note that we do not consider this to be "fatal"
				// to the Unmarshalling operation as we can recover from it (skip over the offending slide).
				try {
					slides.push(new Slide(slideNode.@url, slideNode.@caption));
				}
				catch (e : Error) {
					trace("Failed to parse Slide node: " + slideNode.toXMLString());
				}
			}
			return slides;
		}
	}
}

Note how our XMLSlideShowMarshaller implements the SlideShowMarshaller interface; this is done so we can create future implementations should we wish to change our transmission format. The XMLSlideShowMarshaller class is pretty straight forward, first it converts the incoming raw data into an XML Object, and then it sets about creating and returning a new SlideShow instance. Should anything go awry during this process, an Error will be thrown which the Client will need to handle. Talking of Clients, let’s take a look at the Service object which will make use of our SlideShowMarshaller:

The SlideShowLoaderService Class

package slideshow.service
{
	// imports omitted...

	public class SlideShowLoaderService extends EventDispatcher
	{
		private var loader : URLLoader;
		private var slideShow : SlideShow;
		private var slideShowMarhsaller : SlideShowMarshaller;

		/**
		 * Static factory method which should be used to load XML SlideShow Data.
		 */
		public static function createXMLLoader() : SlideShowLoader {
			return new SlideShowLoader(new XMLSlideShowMarshaller());
		}

		/**
		 * Creates a new SlideShowLoaderService which will use the supplied SlideShowMarshaller object to convert the
		 * loaded data into a SlideShow model.
		 *
		 * @param slideShowMarhsaller Converts the raw data at the service endpoint into a SlideShow model object.
		 */
		public function SlideShowLoader(slideShowMarhsaller : SlideShowMarshaller) {
			this.slideShowMarhsaller = slideShowMarhsaller;
		}

		/**
		 * Begins the load operation; if the load operation is successful Event.COMPLETE will be dispatched, should it
		 * fail, ErrorEvent.ERROR will be dispatched.
		 *
		 * @param endpointUrl URL which returns the SlideShow transmission data which will be converted into a
		 * SlideShow Model object.
		 */
		public function load(endpointUrl : String) : void {
			// Clear out any pre-existing state.
			slideShow = null;

			loader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, onLoaderComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR, onLoaderError);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderError);

			try {
				loader.load(new URLRequest(endpointUrl));
			}
			catch (e : Error) {			{
				handleError(e.message);
			}
		}

		private function onLoaderComplete(event : Event) : void {
			removeLoaderListeners();

			// Use our marshaller to create the SlideShow model instance from the loaded data.
			try {
				slideShow = slideShowMarhsaller.unmarshall(loader.data);
				handleComplete();
			}
			catch (e : Error) {
				handleError("Marshalling error: " + e.message);
			}
		}

		private function removeLoaderListeners() : void {
			loader.removeEventListener(Event.COMPLETE, onLoaderComplete);
			loader.removeEventListener(IOErrorEvent.IO_ERROR, onLoaderError);
			loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderError);
		}

		private function onLoaderError(event : ErrorEvent) : void {
			removeLoaderListeners();
			handleError("Loading error: " + event.text);
		}

		private function handleError(message : String) : void {
			dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, message));
		}

		private function handleComplete() : void {
			dispatchEvent(new Event(Event.COMPLETE));
		}

		/**
		 * Returns a SlideShow model object which was parsed from the service endpoint; note that this method will
		 * always return null unless a succesful call to load() was made.
		 */
		public function getSlideShow() : SlideShow {
			return slideShow;
		}
	}
}

The SlideShowLoaderService class provides a clean and simple Facade to ActionScript’s own URLLoader class and our SlideShowMarshaller class; it serves as a specialisation of these two objects, providing a simple interface which only deals with loading, and marshalling from the Slide Show transmission format into a SlideShow Model Object; the Client (the class which makes use of the SlideShowLoaderService) doesn’t need to know that a URLLoader or an XMLSlideShowMarshaller are being used.

One interesting choice about the design of the SlideShowLoaderService is the way that the default constructor requires the Client to supply an instance of the SlideShowMarshaller interface. The reason is does this is to make the SlideShowLoader as flexible as possible; if we are loading our SlideShow data from XML, then we would invoke it like so:

Creating a SlideShowLoaderService instance which works with XML

const slideShowLoader : SlideShowLoaderService = new SlideShowLoaderService(new XMLSlideShowMarhshaller());
slideShowLoader.addEventListener(Event.COMPLETE, onSlideShowLoaderComplete);
slideShowLoader.addEventListener(ErrorEvent.ERROR, onSlideShowLoaderError);
slideShowLoader.load("slideshow.xml");

Likewise, if we needed to work with a JSON service endpoint, we could modify our client code to provide a JSONSlideShowMarshller (of course, you would need to create this class first!) – but you will notice that the SlideShowLoader works in exactly the same way!

Creating a SlideShowLoaderService instance which works with JSON

const slideShowLoader : SlideShowLoaderService = new SlideShowLoaderService(new JSONSlideShowMarhshaller());
slideShowLoader.addEventListener(Event.COMPLETE, onSlideShowLoaderComplete);
slideShowLoader.addEventListener(ErrorEvent.ERROR, onSlideShowLoaderError);
slideShowLoader.load("slideshow.json");

To make the developer’s life easier, we supply a Static Factory Method, SlideShowLoaderService.createXMLLoader() – this means the Client doesn’t have to know that they need to provide an XMLSlideShowMarhshaller instance in the constructor, the difference is subtle, but it makes it much easier to use:

Creating a SlideShowLoaderService instance using the Static Factory Method

const slideShowLoader : SlideShowLoaderService = SlideShowLoaderService.createXMLLoader();
slideShowLoader.addEventListener(Event.COMPLETE, onSlideShowLoaderComplete);
slideShowLoader.addEventListener(ErrorEvent.ERROR, onSlideShowLoaderError);
slideShowLoader.load("slideshow.xml");

Marhshalling – Converting the Model Object into XML

OK, so now we’ve seen how to unmarshall the transmission format into an ActionScript Object, let’s look at how to do the reverse and convert our Object back into the transmission format so we can send it over to a server. As a side note, you may know this concept as serialisation; however there is a very subtle difference between the two (at least according to the Java world); in my own view, serialisation concerns converting the object into a ByteArray (raw bytes) which is transmitted to the service layer, whereas marshalling deals with converting the object into a transmission format (which in itself is turned into raw bytes, but by another layer). This aside, lets look at how we get our SlideShow model back into XML; as we are still dealing with the marshalling process, let’s add a new method to our XMLSlideShowMarshaller in the form of marshall(slideshow):

Adding the marshall Method to XMLSlideShowMarshaller

// ... rest of class omitted for brevity

/**
 * Converts the supplied SlideShow model object into an XML representation.
 */
public function marshall(slideShow : SlideShow) : * {
	const result : XML = <slideshow title={slideShow.getTitle()} />;
	for each (var slide : Slide in slideShow.getSlides()) {
		result.* += <slide url={slide.getUrl()} caption={slide.getCaption()} />;
	};
	return result;
}

By making use of E4X we make light work of creating the XML representation of the Slideshow; this is also helped by the fact that we have guaranteed immutability of both the SlideShow and Slide objects, we know they are both in a valid state which certainly makes things easier and more concise.

Making use of this marhshall() method is nice and straight forward; all we need to do is pass a populated SlideShow model and we get the XML back:

Invoking the SlideShow Marshaller

// Create a SlideShow Model object instance.
const slideShow : SlideShow = new SlideShow("LolCats", [
	new Slide("http://checkmybelly.com/wp-content/uploads/2007/11/lolcat-funny-picture-moderator1.jpg", "Moderator Kitteh"),
	new Slide("http://www.lolcats.com/images/u/07/24/lolcatsdotcom5×02srq751692std.jpg", "Wait… I'll fix it"),
	new Slide("http://icanhascheezburger.files.wordpress.com/2007/01/i-can-has-cheezburger.jpg", "Can Has Cheezburger?")
]);

// Convert the SlideShow Model object to our transmission format.
const xml : XML = new XMLSlideShowMarshaller().marshall(slideShow);

// Outputs:
// <slideshow title="LolCats">
//    <slide url="http://checkmybelly.com/wp-content/uploads/2007/11/lolcat-funny-picture-moderator1.jpg" caption="Moderator Kitteh"/>
//    <slide url="http://www.lolcats.com/images/u/07/24/lolcatsdotcom5×02srq751692std.jpg" caption="Wait… I'll fix it"/>
//    <slide url="http://icanhascheezburger.files.wordpress.com/2007/01/i-can-has-cheezburger.jpg" caption="Can Has Cheezburger?"/>
//</slideshow>
trace(xml.toXMLString());

To wrap up the marshalling phase, let’s have a look at a potential client, for this example I’ve created a SlideShowSaverService which could be used to transmit a user generated SlideShow to a server.

The SlideShowSaverService Class

package slideshow.service
{
	// imports omitted...

	public class SlideShowSaverService extends EventDispatcher
	{
		private var loader : URLLoader;
		private var slideShow : SlideShow;
		private var slideShowMarshaller : SlideShowMarshaller;

		/**
		 * Static factory method which will transmit the SlideShow to the service endpoint as XML.
		 */
		public static function createXMLSaver(slideShow : SlideShow) : SlideShowSaverService {
			return new SlideShowSaverService(slideShow, new XMLSlideShowMarshaller());
		}

		/**
		 * Creates a new SlideShowSaverService which will send the supplied slideShow Model Object to a service endpoint
		 * in the transmission format dictated by the supplied SlideshowMarshaller.
		 *
		 * @param slideShow The SlideShow instance to transmit to the service endpoint.
		 * @param slideShowMarhsaller Converts the SlideShow model object into a transmission format.
		 */
		public function SlideShowSaverService(slideShow : SlideShow, slideShowMarshaller : SlideShowMarshaller) {
			this.slideShow = slideShow;
			this.slideShowMarshaller = slideShowMarshaller;
		}

		/**
		 * Contacts the Service Endpoint; if the operation is succesful Event.COMPLETE will be dispatched, should the
		 * operation fail, ErrorEvent.ERROR will be dispatched.
		 *
		 * @param endpointUrl URL to transmit the marhshalled SlideShow Model object to.
		 */
		public function save(endpointURL : String) : void {
			const request : URLRequest = createURLRequest(endpointURL, slideShowMarshaller.marshall(slideShow));

			loader.addEventListener(Event.COMPLETE, onLoaderComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR, onLoaderErrror);
			loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderErrror);
			loader.load(request);
		}

		/**
		 * Creates a URLRequest object which will be used by the URLLoader instance, this default implementation
		 * will make use of a POST request, the body of which will be the transmission data format.
		 */
		protected function createURLRequest(endpointURL : String, data : *) : URLRequest {
			const request : URLRequest = new URLRequest(endpointURL);
			request.method = URLRequestMethod.POST;
			request.data = data;
			return request;
		}		

		private function onLoaderComplete(event : Event) : void {
			removeLoaderListeners();
			dispatchEvent(new Event(Event.COMPLETE));
		}

		private function removeLoaderListeners() : void {
			loader.removeEventListener(Event.COMPLETE, onLoaderComplete);
			loader.removeEventListener(IOErrorEvent.IO_ERROR, onLoaderErrror);
			loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoaderErrror);
		}

		private function onLoaderErrror(event : ErrorEvent) : void {
			removeLoaderListeners();
			handleError("Loader error: " + event.text);
		}

		private function handleError(message : String) : void {
			dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, message));
		}
	}
}

Next Steps

To complete this example I’ve created a simple GUI which allows you to see the SlideShowLoaderService and SlideShowMarshaller in action, you can download the complete project here; to recompile the project you will need to modify the user.properties file and point the FLEX_HOME property at your Flex SDK. It makes use of Keith Peter’sexcellent MinimalComps UI library.

There are plenty of avenues to explore from here as this has just scratched the surface; you could start by extending the application to load, and marshall JSON data; prehaps taking advantage of the Adobe JSON Serialisation library (part of AS3 CoreLib), or you could reduce the amount of code you need to write by annotating your Model with Metadata and using an automatic marshalling library like ASAXB. I hope to cover these topics in later blog posts (time permitting)

Delcare Your FLEX_HOME Environment Variable in Windows

When you compile your Flash applications using ANT, you’ll often come across the fun problem of having to point to a Flex SDK to get access to the MXMLC, COMPC and ASDOC jars. One approach is to simply hard-code the location of the SDK into the ANT file; sure, it will work for you, but it’s not going to work for anyone else

A quick and easy solution is to simply create a new Environment Variable, named FLEX_HOME which points to your working Flex SDK – in Windows 7 you can do this easily by selecting:

Right Click My Computer -> Properties -> Advanced System Settings -> Environment Variables

Now enter a new User variable called FLEX_HOME which points to your Flex SDK folder.

Once you’ve done this, you can verify it has worked by issuing the following command on the Command Prompt:

echo %FLEX_HOME%

Now, all you have to do to reference your Flex SDK path in your ANT script is to include the following line:

<property environment="env" />
<taskdef resource="flexTasks.tasks" classpath="${env.FLEX_HOME}/ant/lib/flexTasks.jar" />

Maven and ANT – Managing Your Flash Project’s Build Dependencies

Project build dependency management and resolution is one of the more difficult problems you’ll face as your project grows in size; however even the smallest of projects (and teams) can benefit greatly from getting automatic dependency resolution in place.

So What Are My Project’s Build Dependencies?

Most of us are aware of dependencies in object orientated programming – these are the objects that our class in question needs to operate and most of us know the design patterns which we can use to externalise these dependency. Project build dependencies aren’t radically different; instead of referring to objects and instances; we are talking about the source code files (.as) that your project needs when it compiles. Any source code that you haven’t directly written for your project is a build dependency, here’s an example:

A project with a build dependency in FDT

hardcoded-build-dependency

In the screenshot above you can see an example of a (very simple!) project which makes use of TweenLite. However, you can also see that the source files (.as) for the TwenLite library have been copied into the source folder (src). Now if this were a real project it would result in the greensock code also being committed to our SVN repo. So, what’s the problem with this? Here’s a couple of potential issues:

  • The project compilation time will be increased as MXMLC will be forced to recompile all the greensock code
  • Developers need to checkout all the source code for TweenLite even tho they will never be editing it – furthermore, some developers may get over excited and decide to start making modifications to this code (at which point it stops being a 3rd party library!)
  • If your project consists of multiple modules (ie: Other SWFs which are loaded at runtime) you will need to make sure they all have exactly the same copy of the TweenLite source code available on the source-path due to the way Flash manages loaded Class Definitions in LoaderContexts.

Using Linked Resource Folders To Share Dependencies Across Projects

Nearly all IDEs allow you to create Linked Resource Folders; the concept is pretty simple – projects can import other projects source folders to allow them to share code – sounds great – however in practice it can cause lots of headaches!

An example of Linked Resource Folders in FDT 4

build-dependencies-linked-libraries

In the above screenshot you can see three projects:

  • 3rdparty – This project doesn’t compile or create anything, it simply serves as a dumping ground for all application’s shared dependencies, in this case, TweenLite.
  • main – This is our application’s Main project (hence the name!) this makes use of TweenLite and also loads in other module SWFs at runtime.
  • module – This is a module which the Main application will load in at runtime – it also makes use of TweenLite (let’s face it, what Flash app doesn’t!)

Both the ‘main’ project and the ‘module’ project make use of a Linked Resource named ‘ThirdParty’ which in turn resolves to the location of the ’3rdparty’ project in our workspace. This allows them to include the TweenLite source code without having to copy/paste it into each project. This solves one of the major problems we’ve outlined above – all our application’s projects (including the modules) will now make use of the exact same version of their dependencies thanks to the ‘ThirdParty’ Linked Resource folder – also, when we want to update to a newer version of a library we just have to update the library in a single place and recompile everything – easy.

However, apart from not solving the other two issues (slower compilation and the fact we are checking in raw source code that we don’t wish to maintain) we have also just created a new, much uglier problem with our project – it’s no longer easy to build!

When creating a large project you should always strive to make the build as simple and easy as possible; I try and keep the following things in mind:

  • You should be able to check the entire application’s source out of version control with a single command; no more.
  • You should be able to create a fresh build of the application (including all modules) with a single command (eg: by issuing ant package from a fresh checkout of the source code
  • Developers should be able to work on the project using whichever IDE or tool they wish; don’t rely on a particular environment use, such as FlashBuilder or FDT

By using linked resources we have broken these rules – the whole Linked Resource concept is tightly coupled to a given IDE; even if you check in all your .project and .settings files it isn’t going to work if someone decides they want to give IntelliJ a spin.

SWCs To The Rescue!

When ActionScript 3 became available, Adobe provided Flash developers with a new tool, the SWC. SWCs are just zip files in disguise (if you don’t believe me, rename the extension from .swc to .swc.zip and then open it) which contain a SWF file and an XML catalouge which allows your IDE to parse all the class definitions the SWF contains. All the major Actionscript IDEs provide tools for working with SWC files; below is an example of the same project making use the greensock.swc file which is included in the TweenLite bundle.

A project making use of a SWC in FDT 4

hardcoded-build-dependency-swc

SWCs are preferable to just dumping the source code into your project for a number of reasons – infact they solve nearly all the points we listed above…

  • Compilation becomes faster as SWCs are already pre-compiled
  • Instead of checking the entire source tree of the 3rd party library into SVN we are now only checking a single, compressed file – this makes checkout faster and also means that developers won’t be able to start modifying the library.

But one thing is not checked off – what about projects which make use of multiple modules – it would appear we still have the same problem that all of our modules must use the exact same version of the library – now you could just solve this by making use of a LinkedResource which points to a bunch of SWCs but that’s still not great; and when it really comes down to it – should these SWCs really be in version control at all – after all you are in not in control of their development and you don’t decide when they get updated.

Automatically Managing Your SWCs with Maven

So, it’s now becoming clear that you and your application have some serious dependency issues when it comes to 3rd Party SWCs; don’t worry, the first step is admission – let’s start by declaring them. This article is going to focus on using Maven to declare and resolve your project’s dependencies – other solutions are available :)

Maven’s dependency management work on the simple premise that the dependencies your application relies upon (in our case, SWCs) exist out on the Internet on a special type of file server, known to Maven as a Maven Repository. Maven Repositories can either be public facing (in the case of the Central Maven Repo.) or internal on a company’s own Intranet. Maven Repositories sole purpose is to house and catalogue build artefacts so that they can be fetched (resolved) during a project’s build. Instead of checking your applications dependencies into version control, you instead just list the dependencies in your project and then Maven will fetch them when required.

So, let’s start with a very simple application which consists of a single project which has a single build dependency on AS3Commons Logging. (I would have used TweenLite as an example, but it’s not available on any public Maven repositories). The first thing we need to do is get a simple build script on the go – I’m going to use ANT to perform the build (Maven, which describes itself as a project management tool is more than capable of both compiling and managing your project’s dependencies, but this article is is just focuses on using Maven for managing dependencies). Maven and ANT get along just fine (although their user’s doing always see eye to eye on the Internet!); all we need to do is grab a copy of the Maven ANT Tasks JAR, add it to our project and reference it in our ANT Script:

A Skeleton ANT Build Script Which Makes Use Of the Maven ANT Tasks

<project name="maven-dependencies" xmlns:artifact="antlib:org.apache.maven.artifact.ant">

	<!-- Inclde the Maven ANT Tasks -->
	<path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.1.jar" />
	<typedef resource="org/apache/maven/artifact/ant/antlib.xml"
		uri="antlib:org.apache.maven.artifact.ant"
		classpathref="maven-ant-tasks.classpath" />

	<!-- Include the FlexSDK ANT Tasks -->
	<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
</project>

In the example above I have copied the maven-ant-tasks.jar file into my project; however another approach is to copy the maven-ant-tasks.jar file into your ANT_HOME folder (if you’re on Windows this will be Users{username}.antlib). For more information on getting the Maven ANT Tasks setup on your machine, please refer to the Maven ANT Tasks Installation Documentation.

Now that we have access to the Maven ANT Tasks in our application’s build, the next thing we want to do is list, and resolve our dependencies. This is accomplished by in the “resolve” target shown below:

The Resolve ANT Target which Lists and Pulls Down Dependencies

<!-- =================================
	  target: resolve
	  Uses the Maven ANT Tasks to define and resolve all the dependencies require to build
	  this application.
	 ================================= -->
<target name="resolve" description="Resolve the project's dependencies">

	<!-- The pathId value 'resolves.swcs.classpath' will be an ANT FileSet which points to all the
		SWC files we are about to define -->
	<artifact:dependencies filesetId="resolved.swcs.classpath" versionsId="resolved.swcs.versions">

		<!-- This is where we list our dependency on as3commons-logging version 2.0; by adding this
			line here, we are telling Maven that our application depends upon this SWC -->
		<dependency groupId="org.as3commons" artifactId="as3commons-logging" type="swc" version="1.2" />

		<!-- This is where we provide Maven with the URL of the remote repository where some, or all of
			our dependencies can be retrieved from - if you work with a team you will probably want to
			setup your own Maven Repository in house -->
		<remoteRepository id="adobe-opensource" url="http://opensource.adobe.com/svn/opensource/cairngorm3/maven-repository" />

	</artifact:dependencies>

	<!-- Copies all the files resolved in the task above into the "libs" folder -->
	<copy todir="libs">
		<fileset refid="resolved.swcs.classpath" />

		<!-- This Mapper will remove all the folder heirarchy and version numbers from the resolved SWCs -->
		<mapper classpathref="maven-ant-tasks.classpath" classname="org.apache.maven.artifact.ant.VersionMapper"
			from="${resolved.swcs.versions}" to="flatten" />
	</copy>
</target>

The above target breaks down into two major parts – the artifact:dependencies task lists and resolves the project’s dependencies and the copy task then copies these dependencies into the “libs” folder in the project. The two interesting lines int he artifact:dependenciestask are the dependency line which lists as3commons-logging as a dependency (note how we specify the type as “swc” (Maven defaults the type to “jar”) and the version at 1.2). and the remoteRepository line which tells Maven which Maven Repository the dependency should be resolved from – in this project’s case we are using Adobe’s OpenSource Maven Repository; however as mentioned in the comments, you will probably want to create and maintain your own Maven Repo to house your project’s artifacts in (I’m hoping to cover how to setup your own Repo in another post).

Right, if you’re still following then it’s time to play along at home. Start off by downloading the above project. Once you have extracted the zip file have a quick peek inside an notice how there is no as3commons-logging.swc (if you’re using an IDE, it should complain about errors in Main.as as it can’t resolve the import statements). This is the missing dependency that Maven will resolve for us.

To compile the project (and generate Main.swf in the “target” folder, issue:

ant build

The ANT output should show that the as3commons-logging SWC was fetched (it will also complain that the as3commons-logging POM file could not be resolved, you can ignore this one as it would appear Adobe forgot to include it in the repo!). If you now have a peek inside the “libs” folder you should find a single file, as3commons-logging.swc – magic!

Next Steps

The above is really just the tip of the iceberg; if you want to really get to grips with dependency management through Maven then you are going to want to start listing your dependencies (and the Maven Repositories they can be resolved from) in a POM file (Project Object Model). POM files not only serve as a place to list dependencies and the URLs of Repositories, but they can define the entire build cycle of the project when using Maven (and in the case of Flash, FlexMojos) to compile. POM files include an inheritance model (so a Modules’ POM file can extend the main Project’s POM file) allowing you to keep all your dependency definitions in a central place.

Also, this tutorial hasn’t touched on one of the most powerful feature of Maven, transitive dependency resolution. A quick example would be if your project depends on theRobotLegs Framework; from the example above you can see how you could define a dependency on RobotLegs:

Now, you would expect Maven to pull down RobotLegs.swc for you – but those of you familiar with RobotLegs will remember that RobotLegs itself has a dependency upon SwiftSuspenders.swc – Maven will automatically pull down both RobotLegs.swc AND the required version of the SwiftSuspenders.swc for you, even tho you only listed RobotLegs as a dependency! However, in order for this to work, RobotLegs needs to be uploaded to a Maven Repo along with a POM file which lists SwiftSuspenders as a dependency (and where it can be fetched from in turn) – The Java community is all over this and it works like magic – unfortunatley the Flash community is lagging quite far behind – it would be amazing if FlashDevs started pushing their SWCs up to the Central Maven Repo (it would certainly save people from having to setup and maintain their own local repos!)

Revisiting the Builder Pattern in ActionScript for Immutable Models

A while back I made a post on using the Builder Pattern to create Fluent Constructors – the principle being that instead of having a Model object with a bajillion (in practice, more than 3) arguments, you make use of a companion Builder class which creates the instance. Now, the implementation of this pattern in ActionScript 3 is always going to be a little bit ‘unique’ as we lack useful constructs such as private constructors; however, over the past few months I have been making use of these Builders and have settled at the following design:

The Model Object

package nutrition.model {
	public class NutritionFacts {
		private var _servingSize : uint;
		private var _servings : uint;
		private var _calories : uint;
		private var _fat : uint;
		private var _salt : uint;
		private var _carbohydrate : uint;

		/**
		 * Static construction method which returns a NutritionFactsBuilder which you can use to create your instance
		 * of NutritionFacts model object in a fluent fashion.
		 */
		public static function builder(servingSize : uint, servings : uint) : NutritionFactsBuilder {
			return new NutritionFactsBuilder(servingSize, servings);
		}

		/**
		 * Please make use of NutritionFacts.builder() instead of using this Class constructor.
		 * @private
		 */
		public function NutritionFacts(builder : NutritionFactsBuilder) {
			_servingSize = builder._servingSize;
			_servings = builder._servings;
			_calories = builder._calories;
			_fat = builder._fat;
			_salt = builder._salt;
			_carbohydrate = builder._carbohydrate;
		}
	}
}

This model object is then accompanied by the Builder which is referenced in the static factory method NutritionFacts.builder(). This class is package-internal so it can not be instantiated by the client (presuming the client is outside the nuturion.model package that is!) – as a result it can only be accessed via the static factory method NutritionFacts.builder().

The Companion Builder Object

package nutrition.model {
	internal class NutritionFactsBuilder {
		internal var _servingSize : uint;
		internal var _servings : uint;
		internal var _calories : uint;
		internal var _fat : uint;
		internal var _salt : uint;
		internal var _carbohydrate : uint;

		public function NutritionFactsBuilder(servingSize : uint, servings : uint) {
			_servingSize = servingSize;
			_servings = servings;
		}

		public function withCalories(value : uint) : NutritionFactsBuilder {
			_calories = value;
			return this;
		}

		public function withFat(value : uint) : NutritionFactsBuilder {
			_fat = value;
			return this;
		}

		public function withSalt(value : uint) : NutritionFactsBuilder {
			_salt = value;
			return this;
		}

		public function withCarbohydrate(value : uint) : NutritionFactsBuilder {
			_carbohydrate = value;
			return this;
		}

		public function build() : NutritionFacts {
			return new NutritionFacts(this);
		}
	}
}

Finally, we can see an example of the Builder being used in the following client class – notice how the client requests an instance of the NutritionFactsBuilder via the static builder() method – it is forced to do this because the NutritionFactsBuilder class is package-internal so it can not instantiate it.

An Example of a Client object using the Companion Builder

package nutrition {
	import nutrition.model.NutritionFacts;

	public class Client {
		const colaNutritionFacts : NutritionFacts = NutritionFacts.builder(330, 1)
			.withCalories(303)
			.withSalt(0)
			.build();
	}
}

ANT: This compilation unit did not have a factoryClass

A coworker of mine just asked me how to deal with this MXMLC error which was being thrown during her ANT script when using the FLEX 4 SDK.

This compilation unit did not have a factoryClass specified in Frame metadata to load the configured runtime shared libraries. To compile without runtime shared libraries either set the -static-link-runtime-shared-libraries option

This issue is caused by the new default settings of the flex-config settings that ship with the FLEX 4 SDK.  Luckily the solution is fairly simple, you just need to add the following line to your mxmlc target in your ANT build script:

<mxmlc file="src/Main.as" output="bin/main.swf">
    <source-path path-element="src" />
    <external-library-path file="libs" append="true">

    <!-- Here's the magic line that you need to add! -->
    <static-link-runtime-shared-libraries>true<static-link-runtime-shared-libraries>;

</mxmlc>

Hope that helps.

MySQL Dump / Backup Batch Script for Windows

This is a small Windows Batch Script which I’ve created for dumping out all tables from a local MySQL Service; all the data gets dumped as a plain SQL file which is then archived using 7Zip. This script will also attempt to start (and then stop) the MySQL Service on your local machine if it is not already running.

@echo off
REM MySQL Dump / Backup Script for Windows NT Systems.
REM
REM This Script will dump all tables from your MySQL Instance to a 7zip archive;
REM it will Also take care of starting and stopping the MySQL Service on the machine.
REM
REM @author Jonny Reeves - http://www.jonnyreeves.co.uk/

setlocal
set mysql_username="myuser"
set mysql_password="mypassword"
set mysql_service="wampmysqld"
set mysql_path="C:\Program Files (x86)\WAMP\bin\mysql\mysql5.5.8\bin"
set zip_path="C:\Program Files\7-Zip\"
set output_path="D:\Users\Jonny\Scripts\mysql_dumps"

REM Start of Script.
IF NOT EXIST %output_path% (mkdir %output_path%)

REM Check to see if the MySQL Service is running
for /f "tokens=*" %%a IN ('sc query "%mysql_service%" ^| find "RUNNING"') do set servicerunning=%%a
if "X%servicerunning%%" == "X" (goto service_stopped) ELSE (goto service_running)

:service_stopped
	echo Starting MySQL Service: %mysql_service%
	net start %mysql_service%
	call :dump_and_zip
	echo Stopping MySQL Service: %mysql_service%
	net stop %mysql_service%
	goto end

:service_running
	echo MySQL Service is already running.
	call :dump_and_zip
	goto end

:dump_and_zip:
	REM Dump out the MySQL Database to a timestamped .sql file
	for /f "tokens=1,2,3 delims=/ " %%a in ('DATE /T') do set date=%%c-%%b-%%a
	for /f "tokens=1,2 delims=:" %%a in ('TIME /T') do set time=%%a-%%b
	%mysql_path%\mysqldump.exe --user %mysql_username% --password=%mysql_password% --all-databases --opt > "%output_path%\%date%_%time%.sql"

	REM Check for Errors.
	if %ERRORLEVEL% NEQ 0 (goto error)

	REM Zip it up and remove the temp file.
	%zip_path%\7z.exe a -t7z %output_path%\%date%_%time%.7z %output_path%\%date%_%time%.sql
	del "%output_path%\%date%_%time%.sql"
	goto :EOF

:error
	echo An error occured.
	EXIT /B 42

:end
	endlocal

Please note that in order to start and stop your MySQL Service, this still will need the appropriate privileges when executed.

Builder Pattern in ActionScript – Fluent Constructors

How many times have you come across a class which looks like this:

package nutrition.model {
	public class NutritionFacts {
		private var _servingSize : uint;	// (mL) required
		private var _servings : uint;		// (per container) required
		private var _calories : uint;		// optional
		private var _fat : uint;		// (g) optional
		private var _salt : uint;		// (mg) optional
		private var _carbohydrate : uint;	// (g)  optional

		public function NutritionFacts(servingSize : uint, servings : uint, calories : uint = 0, fat : uint = 0, salt : uint = 0, carbohydrate : uint = 0)  {
			_servingSize = servingSize;
			_servings = servings;
			_calories = calories;
			_fat = fat;
			_salt = salt;
			_carbohydrate = carbohydrate;
		}
	}
}

I’m not a great fan of this style of object construction, it ends up making massive single lines of code which are confusing to read for example, in the following example, what does the 4th argument actually set, why is it zero?

const colaFacts : NutritionFacts = new NutritionFacts(330, 1, 500, 0, 35, 22)

One soltution to this problem is to only demand the required fields in the constructor and use setters for the other fields, we end up with something similar to this:

package nutrition.model {
	public class NutritionFacts {
		private var _servingSize : uint;	// (mL) required
		private var _servings : uint;		// (per container) required
		private var _calories : uint;		// optional
		private var _fat : uint;			// (g) optional
		private var _salt : uint;			// (mg) optional
		private var _carbohydrate : uint;	// (g)  optional

		public function SetterNutritionFacts(servingSize : uint, servings : uint) {
			_servingSize = servingSize;
			_servings = servings;
		}

		public function set calories(value : uint) : void {
			_calories = value;
		}

		public function set fat(value : uint) : void {
			_fat = value;
		}

		public function set salt(value : uint) : void {
			_salt = value;
		}

		public function set carbohydrate(value : uint) : void {
			_carbohydrate = value;
		}
	}
}

To create our ColaFacts object using the above we would code:

const colaFacts : NutritionFacts = new NutritionFacts(330, 1);
colaFacts.calories = 500;
colaFacts.salt = 35;
colaFacts.carbohydrate = 22;

In my opinion this approach is preferable, but now it has introduced a different problem, one of design. In the first example where all the arguments were passed in the constructor, the NutritionFacts object was immutable – its values could not be modified once the object had been instantiated. However, with the NutritionFacts object shown above the calories, fat, salt and carbohydrate values can all be modified elsewhere in the code. If we have our purist Object Orientated Developer hat on we would declare this as a violation of encapsulation.

The Builder Pattern offers us a solution, it allows us to create an immutable object (ie: no setters) which doesn’t end up having a massive constructor for all the optional values it can contain. In Effective Java, 2nd Edition, Joshua Bloch covers this under the title of “Consider a Builder when faced with many constructor parameters”. In his book, Josh makes use of an inner class to create the Builder, although we have inner classes in ActionScript, they do not share the same behaviour as those in Java, especially when it comes to the visibility of member properties – this makes implementing Josh’s example in ActionScript difficult, however, by using the internal visibility modifier we can create a close approximation.

First we have the NutritionFactsBuilder, this is based upon the Builder pattern and make use of a fluent interface:

package nutrition.model {
	public class NutritionFactsBuilder {
		internal var servingSize : uint;
		internal var servings : uint;
		internal var calories : uint;
		internal var fat : uint;
		internal var salt : uint;
		internal var carbohydrate : uint;	

		public function NutritionFactsBuilder(servingSize : uint, servings : uint) {
			this.servingSize = servingSize;
			this.servings = servings;
		}

		public function withCalories(value : uint) : NutritionFactsBuilder {
			calories = value;
			return this;
		}

		public function withFat(value : uint) : NutritionFactsBuilder {
			fat = value;
			return this;
		}

		public function withSalt(value : uint) : NutritionFactsBuilder {
			salt = value;
			return this;
		}

		public function withCarbohydrate(value : uint) : NutritionFactsBuilder {
			carbohydrate = value;
			return this;
		}

		public function build() : NutritionFacts {
			return new NutritionFacts(this);
		}
	}
}

Next up we have the NutritionFacts class, note that now the only argument it expects in the constructor is a NutritionFactsBuilder instance:

package nutrition.model {
	public class NutritionFacts {
		private var _servingSize : uint;	// (mL) required
		private var _servings : uint;		// (per container) required
		private var _calories : uint;		// optional
		private var _fat : uint;		// (g) optional
		private var _salt : uint;		// (mg) optional
		private var _carbohydrate : uint;	// (g)  optional

		public function NutritionFacts(builder : NutritionFactsBuilder) {
			_servingSize = builder.servingSize;
			_servings = builder.servings;
			_calories = builder.calories;
			_fat = builder.fat;
			_salt = builder.salt;
			_carbohydrate = builder.carbohydrate;
		}
	}
}

We can now employ the builder to create us our NutritionFacts object:

const colaFacts : NutritionFacts = new NutritionFactsBuilder(330, 1)
	.withCalories(500)
	.withSalt(35)
	.withCarbohydrate(22)
	.build();

Note that we are supplying the required servingSize and servings values in the NutritionFactsBuilder() constructor, but all the other optional values can now be supplied via method chaining. When build() is called the NutritionFactsBuilder will return a new instance of NutrionFacts for us; this constructed NutritionFacts object is now immutable and the reader can easily see which properties are going to be set on the instance. Because we have made the properties of the NutritionFactBuilder object internal, they are only visible to classes inside the “nutrition.model” package, as the consumers of models shouldn’t be in the models package they will not be visible (only the public with… methods will be). Another nice benefit is that we have split construction of our object (performed by the NutritionFactsBuilder) out from the actual object (NutrtionFacts) – if NutritionFacts was instead an interface, the Builder could return a different concrete instance to the user without them ever knowing.

By using the Builder Pattern in this fashion we are creating something similar to named parameters as found in other languages – other ActionScript developers have already found their own solutions to this, the most recognisable being Greensock’s excellent TweenLite, where an untyped object is used to optional provide parameters ie:

new TweenLite(target, 0.8, { x: 50, y: 100 });

I think this works well for TweenLite, however, I often find myself having to head on over to greensock.com whenever I need to do something a little bit more complicated (for example, is it onCompleteParams, or onCompleteArgs?), the above Builder Pattern approach could have possibly answered that for us:

new TweenBuilder(target, 0.8)
	.x(50)
	.y(150)
	.onCompleteParams([ "foo" ])
	.tween();