Monday, August 22, 2011

Spring Actionscript v2.0 Progress Report - part II

As promised, here's part II of the progress report on the ongoing development of Spring Actionscript v2.0.

Let's step through the new bits and pieces that were added, some were just literally ported from v1.0, other ones were ported and slightly tweaked while even others are completely new to the fold.

Metadata processing


This has remained largely the same as in Spring Actionscript v1.x, with the exception that most Arrays have been converted into Vector.<String>, so some small refactorings will be needed should you want to port any of your processors from Spring
Actionscript v1.x projects.

Usage hasn't changed at all, simply add an implementation of IMetadataProcessor to the XML configuration and you're good to go.

Eventbus namespace handler


New in Spring Actionscript v2.0 is the Eventbus namespace handler. This allows you to configure eventbus related tasks completely in XML. Spring Actionscript v1.x only offered a metadata solution, so to listen for events on the eventbus you'd need to annotate your class with the [EventHandler]  metadata. This puts a dependency on the framework, and therefore Spring Actionscript v2.0 allows the configuration to be completely external.

Event handlers


First add the eventbus namespace to the XML:

<objects xmlns="http://www.springactionscript.org/schema/objects"
   xmlns:eventbus="http://www.springactionscript.org/schema/eventbus"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springactionscript.org/schema/objects
   http://www.springactionscript.org/schema/objects/spring-actionscript-objects-2.0.xsd
   http://www.springactionscript.org/schema/eventbus
   http://www.springactionscript.org/schema/objects/spring-actionscript-eventbus-2.0.xsd">
</objects>

To configure an object as an eventhandler, first add the object to the configuration as usual:

<objects xmlns="http://www.springactionscript.org/schema/objects"
  xmlns:eventbus="  href="http://www.springactionscript.org/schema/eventbus">http://www.springactionscript.org/schema/eventbus"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springactionscript.org/schema/objects
    http://www.springactionscript.org/schema/objects/spring-actionscript-objects-2.0.xsd
   http://www.springactionscript.org/schema/eventbus
   http://www.springactionscript.org/schema/objects/spring-actionscript-eventbus-2.0.xsd">


<object id="eventHandler" class="com.myclasses.events.handlers.MyEventHandler"/>


</objects>


Now, to configure this object as an eventhandler, add this eventbus specific configuration:

 
<objects xmlns="http://www.springactionscript.org/schema/objects"
xmlns:eventbus="  href="http://www.springactionscript.org/schema/eventbus">http://www.springactionscript.org/schema/eventbus"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscript-objects-2.0.xsd

  http://www.springactionscript.org/schema/eventbus
http://www.springactionscript.org/schema/objects/spring-actionscript-eventbus-2.0.xsd">
 

  <object id="eventHandler" class="com.myclasses.events.handlers.MyEventHandler"/>

  <eventbus:event-handler instance="eventHandler">
  <eventbus:event-handler-method method-name="handler" event-name="testEvent"/>
</eventbus:event-handler>

</objects>

  This basically says: Use the method handler on the instance eventHandler to handle events of type testEvent coming through the eventbus.

  If you need to listen to events of type testEvent that have been associated with a certain topic, configure the topic like this:

 
<eventbus:event-handler-method method-name="handler" event-name="testEvent" topics="topicName"/>

  Its also possible that the topic is defined by one of the properties on the eventHandler instance, let's say the eventHandler instance has a property called securityToken which is also used a topic filter. You can
define this like so:

 
<eventbus:event-handler-method method-name="handler" event-name="testEvent" topic-properties="securityToken "/>

  Both attributes (topics, and topic-properties) can contain multiple entries, just as long as they're entered as comma delimited strings:

 
<eventbus:event-handler-method method-name="handler" event-name="testEvent" topics="topicName1,topicName2"/>

To listen for a specific event class, add the fully qualified class name like this:

<eventbus:event-handler-method method-name="handler" event-class="com.classes.events.MyCustomEvent"/>

Routing events


Spring Actionscript 1.x offers the [RouteEvents] metadata to automatically send certain events dispatched by ordinary IEventDispatchers through the eventbus, Spring Actionscript 2.0 now also offers XML configuration for this:

<eventbus:event-router instance="myEventDispatcher">
  <eventbus:routing-configuration event-names="testEvent"/>
</eventbus:event-router>

This sends each event of type testEvent dispatched by the instance with the object name myEventDispatcher through the eventbus.Same as the event-handler, its possible to define topics
directly or topic defined by properties on the IEventDispatcher instance:

<eventbus:routing-configuration event-names="testEvent" topics="myTopic1,myTopic2"/>

To send multiple types entered the event types comma delimited:

<eventbus:routing-configuration event-names="testEvent, testEvent2" topics="myTopic1"/>

Or if different events need to be dispatched using different topics:

<eventbus:event-router instance="myEventDispatcher">
 <eventbus:routing-configuration event-names="testEvent" topics="myTopic1"/>
 <eventbus:routing-configuration event-names="testEvent2" topics="myTopic2"/>
</eventbus:event-router>

Event interceptors


The as3commons eventbus offers ways to intercept, block or manipulate events coming through the eventbus. For more information, check out the as3commons-eventbus documentation .

To define them using XML configuration, first define an object that implements the IEventInterceptor  instance and then use mark-up like this to configure it:

<eventbus:event-interceptor instance="myEventInterceptor">
 <eventbus:interception-configuration event-name="testEvent"/>
</eventbus:event-interceptor>

Of course, this can be configured for an event class as well, with optionally topics or topic-properties attributes:

<eventbus:interception-configuration event-class="testEvent" topics="myTopic"/>

An interceptor can have multiple interception configurations:

<eventbus:event-interceptor instance="myEventInterceptor">
 
<eventbus:interception-configuration event-name="testEvent"/>
 
<eventbus:interception-configuration event-class="com.classes.events.MyCustomEvent"/>
</eventbus:event-interceptor>

Event listener interceptors


There is also such a thing as event listener interceptors, they can be used, for instance, to control the number of event listeners for a specific event or event class. The configuration for this is almost the same a event interceptors, only make sure to first define an object that implements the IEventListenerInterceptor interface. Then configure it like this:

<eventbus:event-listener-interceptor instance="myEventListenerInterceptor">
  <eventbus:interception-configuration event-name="testEvent"/>
 <eventbus:interception-configuration event-class="com.classes.events.MyCustomEvent"/>
</eventbus:event-listener-interceptor>

Configuration packs


An application context on its own contains as little custom functioanlity as possible. The only things that are automatically part of the ApplicationContext are dependency injection, autowiring, stage interception and the metada processor registration. To prevent having to type lengthy bootstrap code, Spring Actionscript v2.0 contains configuration packs.
These packs are defined by IConfigurationPackage implementations. For instance, to add the stageprocessing, eventbus, task and util namespace handlers to the XMLApplicationContext, simply invoke the XMLApplicationContext.configure() method and pass in an instance of FullXMLConfigurationPack .

var applicationContext:XMLApplicationContext = new XMLApplicationContext("application-context.xml");
applicationContext.configure(new FullXMLConfigurationPack());
applicationContext.addEventListener(Event.COMPLETE, onComplete);

That way normal users can just add the whole she-bang in one go, while the power users can pick and choose and add the specific functionality they need.

Child application contexts


Spring Actionscript v1.x enables you to add a parent context to an ApplicationContext, this functionality remains in version 2.0.
However, the idea of a context having a direct reference to its parent also goes against IoC principles, where an instance shouldn't know where to get its dependencies, it should instead just receive them. (Thanks Martin! :))

Spring Actionscript v2.0 now enables an ApplicationContext to receive one or more child contexts. They can be added using the ApplicationContext.addChildContext() method.

The advantage of having a parent->child relationship, instead of a child->parent is that the parent can decide what it will share with its child contexts. Let's first take a look at the signature
of the addChildContext method:

function addChildContext(childContext:IApplicationContext, shareDefinitions:Boolean=true, shareSingletons:Boolean=true, shareEventBus:Boolean=true):void;

So, by default the parent context will share everything with its children. It will register clones of all of its object definitions, it will register all of its singletons in the child's cache and will make sure that all of its eventbus events will be routed through its child eventbus as well.
Obviously, by setting one of these parameters to false will prevent a specific action from happening.

Its also possible to define which object definitions and/or singletons will be shared. The ObjectDefinition class has a property called childContextAccess which is of type
ChildContextObjectDefinitionAccess. This is an enumration which has the following values and related meaning:

  • NONE - No access, do not share with child contexts
  • DEFINITION - Only share the object definition
  • SINGLETON - Only share the singleton
  • FULL - Share both the definition and the singleton
This will hopefully give enough control to a developer to decide what to share and what not. If somebody has ideas on how to improve this, we'd love to hear about :)

In conclusion


Right, that's about it for part II of the Spring Actionscript v2.0 Progress Report. Like stated in the previous post, if you feel up for it, checkout the sources from SVN, use the provided maven script to create a build and start testing around a bit.

Here's all the information again:


You can use the maven pom in the root directory to create a working build of the Spring Actionscript core. It assumed you have Maven version 3.0.3 installed. All of the dependencies will copied to the target/dependencies directory.
Use mvn clean compile to create a build and mvn clean test to run the unit tests.

Either leave a comment on this blog or visit our JIRA system for any criticism, ideas or suggestions:


Thanks a lot for again for listening to me ramble, it is greatly appreciated :)

Happy coding!

4 comments:

  1. Hi Roland,

    Progress for v2 looks awesome! Thank you guys (i know you're not doing this alone) for all the effort you put in this great piece of software. Hope i can find the time to play with it soon.

    cheers,

    Arnoud

    ReplyDelete
  2. Thanks Arnoud :) Watch out for the third progress report, coming this week. (I hope hehe).

    cheers,

    Roland

    ReplyDelete
  3. Nice! Will pureMVC still be supported?

    ReplyDelete
  4. Hey there,

    yea, I'm planning to keep supporting the Cairngorm and PureMVC extensions, they shouldn't be hard to port anyways. I'm not sure if they'll be immediately available upon the first release, but its definitely in the pipeline.

    ReplyDelete