Archive for May, 2006

Architecting a Flex App

Web developers who take Flex for a spin may initially be confused by the user interface model.  Although a typical, servlet-style, request-response model will work in Flex, There Is A Better Way.  Thanks to the "[Binding]" tag in the Actionscript language, you can bind your view to your model data so that changes to the model are automatically reflected in the view.  The Cairngorm microarchitecture formalizes this approach, and is a great starting point for developers who want to figure out how to "make it all work together".  In this post I’ll describe how variable binding, feature-driven development, and Cairngorm all work together for NoteTag.

Here’s how a typical, non-trivial Flex app might be architected:

Domain

  • The classes that make up the domain model.  In NoteTag, this includes Notes, Tasks, and Subscriptions.  (A Subscription is a collection of related Notes or Tasks.)

Model

  • A Singleton that holds bindable instances of the domain model.  In NoteTag, the ModelLocator Singleton holds the user’s list of Subscriptions, the user’s Connections, the current Subscription, the current Note, etc.

View

  • The UI components (generally, though not always, MXML files).  The UI components that are state-dependent are bound to instance variables in the ModelLocator.  Any changes to data in the ModelLocator will cause the UI to automatically update, provided that that data is marked as "[Bindable]".  An example in NoteTag is the NoteListView, which presents the list of Notes in the current Subscription.  If the current Subscription or any of its Notes change then the NoteListView will automatically update to reflect the changes.

Controller

  • Infrastructure for implementing features as event-driven Commands.  Examples in NoteTag include GetSubscriptionCommand, GetNoteCommand, etc.

Business

  • Business logic classes perform operations on Domain objects, often making calls to remote services and returning the results asynchronously.  The SubscriptionManager class is the entry point for most of NoteTag’s business logic.

Service

  • The services layer, which holds all classes that are used to make remote service (HTTPService, RemoteService, and WebService) calls.  NoteTag uses a set of service factory classes, which decouple the configuration of specific HTTP services from the components that make calls to HTTP services.

Most application features touch on some or all of these components.  Here’s the workflow for a typical feature:

  1. The View broadcasts an event.
  2. The singleton Controller receives the event, maps it to its corresponding Command, and executes the Command.
  3. The Command delegates to the appropriate Business object to perform the business logic.
  4. The Business object performs the business logic, possibly making one or more asynchronous calls to various Services, and returns the result by dispatching a new event to the Command.
  5. The Command assigns the result to the singleton Model.
  6. Any Views that are bound to the data in the singleton Model are automatically updated.

So how would this work for a specific feature?  When the user selects a Note from the list of Notes (at the top of the screen, below), the Note is loaded from the appropriate repository (Blogger or TypePad) and displayed in the editor (at the bottom of the screen, below):

 

1. Broadcasting the Event

When the user clicks on the first Note in the list, NoteListView dispatches an event, as follows:

// NoteListView.mxml
private function getSelectedEntry(event:ListEvent) : void
{
  var selectedEntry:TagBasedEntry =
    TagBasedEntry(currentFeed.entries[event.rowIndex-1]);

  Application.application.dispatchEvent(
    new GetNoteEvent(selectedEntry.metadata,true));
}

2. Responding to the Event

Because NoteTag’s Front Controller has registered itself to listen for all Command Events, it will be notified when GetNoteEvent is dispatched:
// NoteTagController.as
public class NoteTagController extends FrontController
{
  public function NoteTagController()
  {
    addCommand(LoginEvent.EVENT_LOGIN, LoginCommand);
    addCommand(GetNoteEvent.EVENT_GET_NOTE, GetNoteCommand);
    addCommand(GetTaskEvent.EVENT_GET_TASK, GetTaskCommand);
    addCommand(PostNoteEvent.EVENT_POST_NOTE, PostNoteCommand);
    // more commands...
  }
}

Cairngorm’s FrontController provides the infrastructure for listening for events and responding to them by executing the appropriate command.

3. Executing the Command

To retrieve the Note, NoteTag needs to make a call to the blog server that stores the user’s notes.  The GetNoteCommand, which implements Cairngorm’s Command interface, takes care of this:

// GetNoteCommand.as
internal class GetNoteCommand extends ChainedCommand
{
 
public override function execute(event:CairngormEvent):void
 
{
    var initialEvent:GetNoteEvent = GetNoteEvent(event);

   
var subscriptionManager:SubscriptionManager =
     
ModelLocator.getInstance().subscriptionManager;

   
setNextEventHandler(subscriptionManager,
     
handleLoadNote,
     
LoadNoteEvent.EVENT_LOAD_NOTE,
     
onSubscriptionFault,
     
SubscriptionFaultEvent.EVENT_SUBSCRIPTION_FAULT);

    subscriptionManager.loadNote(initialEvent.metadata);
  }

  private function handleLoadNote(event:LoadNoteEvent):void
  {
    // handle result here...
  }

  // ...
}

(You may have noticed that GetNoteCommand extends ChainedCommand — this class chains asynchronous calls together using the setNextEventHandler method.  In a future post, I’ll go into greater detail on ChainedCommand, and asynchronous responders in general.)

4. Performing the Business Logic

The SubscriptionManager handles the loading of the Note by executing a series of HTTP service calls to the tag server and the blog server.  When the note has been loaded, the SubscriptionManager will dispatch a LoadNoteEvent, which will be handled by GetNoteCommand.handleLoadNote (see the next item).

5. Updating the Model

GetNoteCommand responds to the event by assigning the loaded Note to the appropriate data member on the ModelLocator:

// GetNoteCommand.as
internal class GetNoteCommand extends ChainedCommand
{
 
// ...

  private function handleLoadNote(event:LoadNoteEvent):void
  {
    ModelLocator.getInstance().currentNote = event.note;
  }

  // ...
}

6. Updating the View

Any views that are bound to the ModelLocator’s currentNote member will automatically update themselves to reflect the new data.  NoteView, the component that’s responsible for displaying the Note in an editor, is one such view:

// NoteView.mxml
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
   
xmlns:view="com.adobe.kiwi.notetag.view.*"
 
 
xmlns="*">
 
<mx:Script>
  <![CDATA[
    import com.adobe.kiwi.notetag.model.*;

    [Bindable] private var model:ModelLocator = ModelLocator.getInstance();
  ]]>
  </mx:Script>

  <view:NoteEdit id="noteEditor" width="100%" height="100%"
   
note="{model.currentNote}" />

</mx:VBox>

 

Every other feature — publishing a Note, fetching a Subscription, updating a Task — is implemented with the same Event-to-Command-to-Model-to-View approach.  Command-specific Events can be dispatched from multiple contexts, without knowing which Views will be affected.  Views can bind to Model changes without knowing where the originating Event was dispatched from.  Loose coupling leads to cleaner, more maintainable code.

NoteTag Installation: Tips From the Field

Here are some “tips from the field” to help with the NoteTag installation process. If you have any problems (or suggestions!), add them to the comments for this thread.

1) There are a few references to “C:\Dev\workspace” in the installation guide. This is the suggested workspace folder location, but feel free to use any path.

2) With regard to the SSL keystore file, be sure that the name you use with keytool.exe is the same as the element in jrun.xml. For example, if the command to generate the keystore file is:

keytool -genkey -alias localhost -validity 9999 -keyalg RSA -keystore c:\notetag.keystore -keypass mypass -storepass mypass

then the SSL service in jrun.xml should look like this:

<service class="jrun.servlet.http.SSLService" name="SSLService">
    <attribute name="port">9100</attribute>
    <attribute name="keyStore">{jrun.rootdir}/lib/notetag.keystore</attribute>
    <attribute name="keyStorePassword">mypass</attribute>
    <attribute name="trustStore">{jrun.rootdir}/lib/trustStore</attribute>
    <attribute name="socketFactoryName">jrun.servlet.http.JRunSSLServerSocketFactory</attribute>
    <attribute name="deactivated">false</attribute>
    <attribute name="bindAddress">*</attribute>
    <attribute name="interface">*</attribute>
    <attribute name="clientAuth">false</attribute>
</service>

AS3 programming 101 for C/C++ coders

In my previous article, I covered ActionScript 3 languange syntax and constructs that may be of interest to C/C++ coders starting out on ActionScript 3. This article covers areas of AS3 that are different from C/C++ in regards to functional issues that may be interesting to people with C/C++ experience. ActionScript 3 is a powerful language with some very nice features. However, as a long time C/C++ coder I found ActionScript lacking things I was used to having.

Continue reading…

Dissecting a Mashup: NoteTag’s Reusable Flex Components

Whenever I come across a new Flex 2.0 project, my first two questions are:

  • "How do I try it out?"
  • "Can I see the source?"

(Short answers: "Go to the NoteTag Labs page!" and "Yes, go to the NoteTag Labs page!")  After that, my next question is usually:

  • Is there anything here I can reuse?

In NoteTag’s case, the answer is a resounding "Yes!"  Interested in publishing to a blog server that supports the Atom Publishing Protocol?  Take a look at our AtomProtocol library.  Interested in working with a read/write Feed object model that supports the various flavors of RSS and Atom?  Try the Feeds library.  In this post I’ll give a brief overview of each reusable library that’s included with NoteTag.

Below is a rough diagram of the NoteTag architecture.  In future posts I’ll talk about the NoteTag specific components, but today I’ll focus on the lower part of the diagram.

notetag arch.jpg

 

From bottom to top:

corelib

The corelib library is an ActionScript 3.0 library developed by the Adobe Developer Relations team, and made available on the Adobe Labs site.  The Kiwi team didn’t develop this library, but we use it heavily (for URI support, date parsing,and WSSE authentication), and I expect that most Flex developers will want to add it to their arsenal of tools.

Connections

The Connections library provides basic support for connection management. Read/write web applications typically make calls to multiple web services, often authenticating with different credentials for each service — NoteTag is a good example of this, using del.icio.us to store metadata relating to notes and tasks, and Blogger or TypePad to store the note content.  The Connections library provides an object model for user-specific Connections to an Endpoint (e.g. Blogger) that supports a specific Protocol (e.g. the Atom Publishing Protocol).

Feeds

The Feeds library provides a format-independent Feed object model for Atom 0.3, Atom 1.0, RSS 1.0, and RSS 2.0.  The Feeds library is similar in spirit to the existing RSS and Atom libraries, but provides a few key additions:

  • support for Atom 0.3 (required by Blogger and TypePad)
  • support for reading from and writing to Feed objects
  • support for feed extensions

Let’s take a look at the second bullet point.  Here’s how you might create a new Atom 1.0 entry from scratch:

// Create an empty entry.

var factory:IFeedElementFactory = new Atom10FeedFactory();

var entry:IEntry = factory.createEntry();

 

// Assign a title to the entry.

var title:IContent = factory.createTitle();

title.value = "My Latest Entry"; // assign the content to the title

entry.title = title; // assign the title to the entry

 

// Assign an id to the entry.

entry.id = "id:1234567890";

 

// The entry is being published "right now".

entry.published = new Date();

 

// Display the XML for the entry.

trace(entry.xml);

What’s nice about this approach is that you only have to change one of line of code if you’re working with a different feed format:

var factory:IFeedElementFactory = new RSS20FeedFactory(); // switch to RSS2.0!

TagServerProtocol

The TagServerProtocol library provides a generic interface for a tag server protocol, and one specific implementation: del.icio.us.  There are a variety of tag servers (more commonly referred to as social bookmarking services) out in the wild, most of which provide different flavors of the same API.  The ITagServerProtocol interface is a "least-common denominator" interface that should work for most of these services.  We’d love to see someone try to implement it for Simpy or Shadows and then plug it in to NoteTag…

AtomProtocol

The AtomProtocol library provides a generic interface for the Atom Publishing Protocol, and two specific implementations: Blogger and TypePad.  The protocol interface  and introspection document object model conform as closely as possible to the current draft (08) of the APP specification, though there are some features (such as collection paging and media collections) which we punted on.  Still, it ought to be possible to create a plugin for Google’s GData

AS3 language 101 for C/C++ coders

This article covers aspects of ActionScript 3 that would be helpful to C/C++ application engineers transitioning to application development in Flex and Flash.

I’ve used C/C++ through most of my educational and professional career. I’ve also done a respectable share of Javascript and Perl. ActionScript 3 could be viewed as an interesting blend of features from all of these languages. Actionscript 3 conforms to the ECMAscript 4 spec. So, it is a standard languange. In addition to the standard language syntax, AS3 contains a custom class framework for working with Flex/Flash.

The following are areas in the AS3 language that I personally found interesting.

Continue reading…

An Overview of NoteTag

The Kiwi team is focused on enabling developers to build read/write web components in Flex and Apollo. NoteTag is a proof-of-concept Flex 2.0 application which offers a solution to a common problem: how to keep track of tasks while taking notes for a meeting.

Let’s jump straight into the user experience. I’m in a meeting with my Kiwi cohorts, and I’m in charge of note-taking duties. I launch my browser, navigate to the NoteTag URL, and immediately start taking notes.

After the usual status round-robin, Darrick points out that there’s a bug which he needs to investigate further. Aha! We have our first task! I highlight the text of the task ("Need to locate RichTextEditor source") and click the "Tag as Task" button on the control bar. The task’s text now changes to red, and the property inspector at the bottom of the screen is pre-populated with values. I set the owner to "darrick" and continue taking notes.

When the meeting ends I click "Publish", and the note and tasks are posted to our backend. (More on that later.) If I want, I can browse through the previously-posted meeting notes in an RSS aggregator-like view…

.. but most likely, I’m done. Darrick, on the other hand, has some work to do. He connects to NoteTag and clicks on "My Tasks" to see his aggregated list of tasks. If the text of the task alone doesn’t provide the context he needs, he can click on the task to see the enclosing note.

After Darrick has finished his investigation, he needs to mark the task as completed. He checks the box next to the Task, and the task instantly turns from red to green in the note.

This is more than just a local change: anyone who views either the note or Darrick’s list of tasks will see that the task has been finished.

At this point you might be thinking, "I’ve seen plenty of applications that help people keep track of tasks. What’s unique about NoteTag?" Two things…

First, NoteTag is a completely free, completely open-source Flex 2.0 application. Want to figure out how we’re aggregating tasks? Just dive in to the source code. Want to see how we’re publishing notes to the web? It’s all there. Want to use our source code in your application? Help yourself! NoteTag should be a great resource for developers who are ramping up on Flex, and who want to understand how to build an app that involves more than a handful of classes.

The other unique thing about NoteTag is the backend: there is none! (Well, none that we wrote, at least.) Here’s where the notes are stored:

Blogger! (NoteTag also supports TypePad, and theoretically could use any service that supports the Atom Publishing Protocol.)

And here’s where we store references to the notes and tasks:

Delicious! Every note and task is tagged with information about the author, owner, status, etc., and points to the URL of the note on the blog server.

What this means is that NoteTag doesn’t replace existing workflows and services, it complements them. You can view your tasks in NoteTag, or you can log into your delicious account and use delicious’s support for filters, related tags, and tag clouds to view them in new and interesting ways.

All that being said — we on the Kiwi project think NoteTag will be less interesting as an end-user product and more interesting as an application that developers can use to learn how to build their own read/write web applications in Flex. In the next post, I’ll talk about the overall design and architecture of NoteTag, as well as the reusable components that we’ve developed.

Introductions

File under: ,,,,,,,

Hello everyone, and welcome to the Kiwi Project blog. As our tag line says, the Kiwi Project is focused on creating read/write web components for Flex. What does this mean? 

Over the last year or so the Web 2.0 meme has grown phenomenally.  While the definition of Web 2.0 has been hotly debated, people are starting to focus on a fundamental attributeā€¦

Hal Stern: The Morning Snowman : Weblog

Everything that Tim O’Reilly posits as Web 2.0 examples is distinguished from a Web 1.0 counterpoint as being writeable. Three words: read-write web.

We couldn’t agree more.  In fact, from (the "new") Adobe’s perspective, we’ve been promoting the read/write web for years thru our Contribute product, which is both an HTML browser and a WYSIWYG HTML editor all in one application.

With the rising interest in AJAX and RIAs, it became important for us to understand how to empower our Flex environment to create read/write web applications. This means developing Flex components that understand specific Web 2.0 technologies such as RSS, blogging, tagging, and microformats. And with hints of Apollo emerging, this means understanding how to build Flex components that work both in the browser and on the desktop.

Thus the Kiwi Project was born.  The team is comprised of engineers who have been involved with the development of both Dreamweaver and Contribute, who are intimitely familiar with the challenges of read/write web applications.   The team also has experience in both desktop and web development, but like many of us at this time, is new to Flex development.  This blog will chronicle our experiences in mastering Flex and our progress in exploring and developing that set of read/write web components for Flex developers.

Our first proof-of-concept release is just around the cornerā€¦