<?xml version="1.0" encoding="UTF-8"?>
<posts type="array">
  <post>
    <body>_This post follows on from a series on architecting a basic PureMVC application. Well, it's actually the final brief installment, and at the same time a completely separate post, as the view and model classes in a PureMVC app should have no knowledge of the framework itself. So if you don't know or care for PureMVC you're in luck - this post just outlines a very simple approach to creating a tag cloud in Flex._

I recently put together a simple tag cloud (is there any other kind?) in Flex. Unsurprisingly others have come up with approaches to constructing a tag cloud in Flex, including "Buttons and FlowBoxes":http://www.glodde.com/blog/default.aspx?id=1&amp;t=Basic-Flex-TagCloud-Component. All perfectly reasonable, but I thought there was no harm in just relying on a humble textfield to do the work.

So to achieve this, I have a @TagCloudView@ class, whose one important method is @setData@:

&lt;code lang="actionscript"&gt;
public function setData( tagCloudData:TagCloudData ):void
{
        var html:String = "";
        var size:uint = MIN_SIZE;
        var step:Number = ( MAX_SIZE - MIN_SIZE ) / tagCloudData.range;
        var tags:ArrayCollection = tagCloudData.sortAndReturnTags();

        var i:uint = 0;
        var l:uint = tags.length;

        for (; i &lt; l; i++)
        {
                var tag:Tag = Tag ( tags[i] );
                size = Math.round( MIN_SIZE + ( (tag.count - tagCloudData.min) * step ) );
                html += "&lt;a href=\"event:"
                     + tag.name
                     + "\"&gt;&lt;font size=\""
                     + size
                     + "\"&gt;"
                     + tag.name
                     + "&lt;/font&gt;&lt;/a&gt; ";
        }
        content.htmlText = html;
}
&lt;/code&gt;
The minimum and maximum font sizes for this tag cloud are constants defined within the class, which are used to calculate the step between each font size to be used in the tag cloud. We need to work out the range of occurrences for each term (and the min and max occurrences), which the tagCloudData model does for us. It also sorts the tags alphabetically and returns an ArrayCollection we can loop through:
&lt;code lang="actionscript"&gt;
public function sortAndReturnTags():ArrayCollection
{
        var sort:Sort = new Sort();
        sort.fields = [ new SortField("name", false) ];
        tags.sort = sort;
        tags.refresh();
        return tags;
}
&lt;/code&gt;
Getting back to the setData method you can see the method simply loops through the tags within the data object to construct a string of html links. Each link href can be prefixed with 'event:' to trigger a "link TextEvent":http://livedocs.adobe.com/flex/3/langref/flash/text/TextField.html#event:link so the action can be handled within the player, or alternatively it can call a url as normal. The font size is calculated by setting it to the minimum size specified, and then adding additional steps for any number of occurrences over the minimum.

That's all there really is to it. All the code, which includes the basic PureMVC application code from the previous posts, is available "here":http://www.experimeme.net/code/flex/tag-cloud.zip</body>
    <created-at type="datetime">2008-12-17T23:31:37Z</created-at>
    <ham-comments-count type="integer">0</ham-comments-count>
    <id type="integer">31</id>
    <permalink>flex-tag-cloud-example</permalink>
    <title>Flex Tag Cloud Example</title>
    <updated-at type="datetime">2010-01-16T12:55:54Z</updated-at>
  </post>
  <post>
    <body>Considering it's such a fundamental task when sharing code with the wider web, there are "many examples":http://stackoverflow.com/questions/151677/tool-for-adding-license-headers-to-source-files of how to add licence / license headers to source code files.

However I needed a reason to start learning a little bit of Ruby, so I used Todd Werth's "app skeleton":http://blog.infinitered.com/entries/show/5 and took Xavier Hanin's "example":http://xhab.blogspot.com/2007/03/adding-license-header-to-whole-code.html to work up a little app called _Sourcify_.

Sourcify is a simple Ruby program (one script + licence template files) which adds and removes licences to source code. It includes licence file templates for the mit, bsd, apache, lgpl, agpl, and gpl licences.

Using it is as simple as @./sourcify.rb mit "John Smith" my-project/@. Help is available via @./sourcify.rb -h@ which will describe all the command line options currently available. *NOTE:* The default behaviour is to make modifications to a copy of the project, leaving the originals untouched.

It'll be a nice toy project to learn some more Ruby: on the todo list would be: adding all popular licence files in multiple languages, adding in interactive prompts to fill out required details for some licences (like the Mozilla Public Licence), adding in actual licence files to the root of a project, accepting file types as arguments, adding in support for more programming languages, and packaging Sourcify as a Ruby gem.

I wouldn't say it's the sexiest project to obsess over, but if it had templates for most popular open source licences, as well as information on how to select the right licence, it could be a nice one-stop licence shop for developers.

Once I've done a bit more work I'll open up a public git repository, but for now it's available right "here":http://www.experimeme.net/sourcify.zip.</body>
    <created-at type="datetime">2008-12-15T19:25:06Z</created-at>
    <ham-comments-count type="integer">0</ham-comments-count>
    <id type="integer">30</id>
    <permalink>sourcify-add-licence-headers-to-source-files</permalink>
    <title>Sourcify: Add licence headers to source files</title>
    <updated-at type="datetime">2009-05-10T22:37:49Z</updated-at>
  </post>
  <post>
    <body>The "Proxy":http://en.wikipedia.org/wiki/Proxy_pattern is used throughout PureMVC to access model data. Proxies are registered with the facade, and then retrieved when required by other proxies, commands, and mediators whenever data needs to be accessed. Proxies broadcast notifications when a change to model state occurs, but do not listen for notifications.

Previously we registered two proxies for the data of interest to this application, the FlashVarsProxy and the RemoteProxy. The FlashVarsProxy is self-explanatory and trivial, so we'll move our focus on to the RemoteProxy. In this example tag cloud app we only have one remote service, so we define and set the service within the RemoteProxy class itself. (For larger applications you'd want to create a service class that can be shared across proxies.)

As we're using the MultiCore version of PureMVC we must do this in an overridden @onRegister@ method to avoid any "Error: multitonKey for this Notifier not yet initialized!". It sounds overly complex but it isn't - MultiCore just lets you run multiple versions of the framework at the same time, and even if you're not after the additional capabilities it's sensible to use MultiCore by default. If you'd like more details on the two options "this blog post":http://lowpitch.com/blog/puremvc-multicore-vs-standard-singlecore/ is worth reading. Anyway, onto some code:
&lt;code lang="actionscript"&gt;
override public function onRegister():void
{   
        var gateway:String = flashVarsProxy.gateway;

        var service:RemoteObject = new RemoteObject();

        var channelSet:ChannelSet = new ChannelSet();
        var amfChannel:Channel = new AMFChannel( "rubyamf", gateway );
        channelSet.addChannel( amfChannel );
        service.destination = "rubyamf";
        service.source = "PostsController";
        service.channelSet = channelSet; 

        var responder:Responder = new Responder( getTagsResult, getTagsFault );
        var call:AsyncToken = service.tag_counts();
        call.addResponder(responder);
}
&lt;/code&gt;
Flex allows you to define services in a services.config xml file, but at least in this instance I prefer doing it directly in ActionScript. I'm using RubyAMF to connect to my PostsController and get the tag information as you can see above. Once the service returns a result, it will call our @getTagsResult@ method:
&lt;code lang="actionscript"&gt;
public function getTagsResult( e:ResultEvent ):void
{
        _tagCloudData = new TagCloudData();

        for each ( var tag:Tag in e.result )
        {
                _tagCloudData.addTag( tag );
        }

        sendNotification( Notify.TAGS_LOADED );
}
&lt;/code&gt;
The _tagCloudData instance variable is our actual model. If this weren't a toy app, you'd most probably have a TagCloudDataProxy which wrapped around it and was used throughout the application to access the model.

Best practice (not always reflected in the PureMVC site examples) dictates that you keep thin proxies. That is to say both the model and proxy should implement the same interface, and a proxy should merely delegate calls to the model and send notifications when appropriate. That way your domain logic stays entirely within the model, which makes it transportable and easier to unit test (very much like the view - if you see any imports from the org.puremvc namespace in your model classes you're doing it wrong).

This wraps up the basic architecture of a PureMVC application. It's a little overkill for something as straightforward as a tag cloud (which I can already generate automatically via rails) but illustrates the basic application flow and architecture which forms the basis of all PureMVC applications.

Coming at PureMVC fresh it might seem like an overly-complex, possibly invasive framework, but the opposite is true. You register Commands, Proxies, and Mediators, use Notifications to communicate, and your model and view are completely separate from the framework itself. Because of this, I'll hold off on talking through the TagCloudView and TagCloudData till the next post.</body>
    <created-at type="datetime">2008-12-12T23:04:01Z</created-at>
    <ham-comments-count type="integer">0</ham-comments-count>
    <id type="integer">29</id>
    <permalink>basic-architecture-of-a-puremvc-application-part-iii</permalink>
    <title>Basic Architecture of a PureMVC Application: Part III</title>
    <updated-at type="datetime">2008-12-12T23:33:47Z</updated-at>
  </post>
  <post>
    <body>In PureMVC, the "Mediator":http://en.wikipedia.org/wiki/Mediator_pattern design pattern is used to mediate between the view and the framework. This reduces coupling, as the view knows nothing about the framework (if you're importing any org.puremvc classes into your view, you're doing it wrong), and knowledge of the view's public API is limited to the Mediator which manages it. To kick things off we pass the view component to the Mediator, and register it with the framework:
&lt;code lang="actionscript"&gt;
public class ViewPrepCommand extends SimpleCommand
{
	facade.registerMediator( new TagCloudViewMediator( new TagCloudView ) );
}
&lt;/code&gt;

The Mediator itself should provide limited functionality. It should advertise which notifications it's interested in (via its listNotifications method, which is queried when the Mediator is registered via the facade), and respond to those same notifications by manipulating the view it mediates for. For instance, in our tag cloud example, we want to know when data about the tags has been received, and then retrieve this data from the relevant proxy and pass it to the view:
&lt;code lang="actionscript"&gt; 
override public function listNotificationInterests():Array
{   
    return [ Notify.TAGS_LOADED ];
}   

override public function handleNotification( note:INotification ):void
{   
    var name:String = note.getName();

    switch( name )
    {   
        case Notify.TAGS_LOADED:
            view.setData( getTags() );
           break;
    }   
}   

private function getTags():Array
{   
    return remoteProxy.getTags();
}   

private function get view():TagCloudView
{   
    return TagCloudView( viewComponent );
}

private function get remoteProxy():RemoteProxy
{
    return facade.retrieveProxy( RemoteProxy.NAME ) as RemoteProxy;
}
&lt;/code&gt;

As you run through this example, you'll see that there isn't much to our TagCloudMediator. That should be true of most mediators, if you find yours are much heavier than this or rely on a variety of private setup functions you should seriously consider moving this application logic to a command. We've already touched on the @listNotificationInterests@ method, so moving on you can see that the @handleNotification@ method determines how to act based on the name of the notification. In our case we're only interested in Notify.TAGS_LOADED, and once this occurs, we pass the relevant data to the view.

One style we've settled on is to use an implicit getter called view() to cast the viewComponent Object to the specific type and return it. 'tagCloudView' is perhaps more descriptive, but there are certainly benefits in only having to locate and parse 'view' as you work across multiple mediators within an application.

You'll notice we get tags via the RemoteProxy, so it's a good time to back up, and look at the @ModelPrepCommand@ we skipped over a little earlier:
&lt;code lang="actionscript"&gt;
    public class ModelPrepCommand extends SimpleCommand
    {   
        override public function execute( notification:INotification ):void
        {   
            super.execute( notification );
            facade.registerProxy( new FlashVarsProxy( Application.application.parameters ) );
            facade.registerProxy( new RemoteProxy() );
        }   
    }   
}
&lt;/code&gt;
Here we register two proxies: a new FlashVarsProxy, which is used to store and return any variables set on the swf file from within the html, and a RemoteProxy, which is reasonably straightforward. We're calling it the @RemoteProxy@ because in this simple example it is the one and only proxy for accessing remote data. In the next post I'll run through our RemoteProxy in detail.</body>
    <created-at type="datetime">2008-12-09T21:28:14Z</created-at>
    <ham-comments-count type="integer">0</ham-comments-count>
    <id type="integer">28</id>
    <permalink>basic-architecture-of-a-puremvc-application-part-ii</permalink>
    <title>Basic Architecture of a PureMVC Application: Part II</title>
    <updated-at type="datetime">2009-04-21T07:24:36Z</updated-at>
  </post>
</posts>
