Sunday, September 4, 2011

Spring Actionscript v2.0 Progress Report - part III

We're gradually getting ready for a first beta release. Most of the foundational parts of the IoC container have now been refactored and unit tested. (Although the unit testing is still an ongoing process)
Spring Actionscript 2.0 was put on the backburner just a little bit the past week since a bunch of debugging work for the AS3Commons-Bytecode library took up just a little bit more time than was anticipated... Apologies for this. (But expect a new AS3Commons-Bytecode release as well in the coming days :))
In the past few weeks the following has been added:

IMetadataDestroyer interface

To be able to undo the processing of an IMetadataprocessor a second interface has been added. Its much like the IStageObjectProcessor and IStageObjectDestroyer logic. One performs certain logic, the other is able to undo this logic in case this is necessary. The interface is quit simple:
public interface IMetadataDestroyer {
  function get metadataNames():Vector.<String>;
  function destroy(instance:Object, container:IMetadataContainer, metadataName:String, objectName:String):void;
}

MXML Application context

Besides the XML based configuration, naturally, the MXML based configuration makes its comeback as well. It has changed slightly compared to the one in Spring Actionscript 1.x, but the changes aren't enormously disrupting.
The MXMLApplicationContext itself is now also an MXML element, so here's how its declared in an application:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"
   xmlns:sas="http://www.springactionscript.org/mxml/config"
   creationComplete="application1_creationCompleteHandler(event)">
<fx:Declarations>

<sas:MXMLApplicationContext configurations="{[TestObjects]}"
configurationPackage="{new FullConfigurationPackage()}"
id="MXMLContext"
autoLoad="true"
complete="{onComplete(event)}"/>


</fx:Declarations>
</s:Application>
As you can see, the configuration is fed to this Application Context usingits 'configurations' property, which accepts an Array of Classes. In this casethe TestObjects class is also an MXML file and looks like this:

<sas:SASObjects xmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark"xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:sas="http://www.springactionscript.org/mxml/config">
<fx:Script>
<![CDATA[
import classes.MetadataHandler;

import mx.collections.ArrayCollection;
[Bindable]
public var collection:ArrayCollection = new ArrayCollection(['value1', 'value2']);
]]>
</fx:Script>
<fx:Declarations>
<sas:Object id="test"
clazz="{Object}">
<sas:Property name="list"
  ref="collection"/>
</sas:Object>

<sas:Object clazz="{MetadataHandler}"
id="metadataHandler"/>
</fx:Declarations>

</sas:SASObjects>
The object definitions haven't changed at all from Spring Actionscript 1.x, apart from the extra properties that were described in part I of the progress report. As you can see, it's also possible to just declare regular object instantiatons in the configuration and have them being treated as singletons in the context. For instance the ArrayCollection called collection can be retrieved from the ApplicationContext simply by invoking MXMLContext.getObject('collection');.
As you can also see, the collection singleton is also being injected into the object called 'test' in its property called 'list'.
Naturally, MXML object such as RemoteObject can also directly be declared inside the configuration, without having to resort to creating an <Object/> element for it. Direct declaration only works for singleton of course.
The MXMLApplicationContext is, like the XMLApplicationContext, nothing but a convenience subclass. It also very much possible to construct one manually like this:
var applicationContext:DefaultApplicationContext = new DefaultApplicationContext(null, rootView);
var provider:MXMLObjectDefinitionsProvider = new MXMLObjectDefinitionsProvider();
provider.addConfiguration(TestObjects);
applicationContext.addDefinitionProvider(provider);
applicationContext.addEventListener(Event.COMPLETE, handleComplete);
applicationContext.load();

ICustomObjectDefinitionComponent interface

Similar to namespace handlers that make the XML configuration a little easier to read, the MXML configuration can contain ICustomObjectDefinitionComponents. Implementations of this interface can define a custom configuration for a certain type of object and offer a few shortcuts for this configuration. The interface is quite easy again:
public interface ICustomObjectDefinitionComponent extends IMXMLObject {
  function execute(applicationContext:IApplicationContext, objectDefinitions:Object):void;
}
Once the MXMLApplicationContext starts loading its MXMLObjectDefinitionsProvider and encounters an ICustomObjectDefinitionComponent, it will invoke its execute() method and pass in a reference to the MXMLApplicationContext and its objectDefinitions instance.
The objectDefinitions instance is an anonymous object that serves as a Name->IObjectDefinition lookup for the definitions
that are created by the MXMLObjectDefinitionsProvider. So an ICustomObjectDefinitionComponent implementation can just add its own
definitions to this instance.
No implementations are yet available in Spring Actionscript 2.0, but we're planning to create some shortcuts for the eventhandling and interception, similar to the XML shortcuts described in part II of this progress report.

Metadata Application Context

Lastly, there is the MetadataApplicationContext, which does exactly as its name suggests: It creates ObjectDefinitions that are defined in metadata. This ApplicationContext needs to have its rootView set, this is because it uses this rootView to resolve the correct loaderInfo reference which is used to scan the SWF's bytecode for the necessary metadata annotations. So, if the MetadataApplicationContext is part of a regular application, this would suffice:
var context:MetadataApplicationContext = new MetadataApplicationContext(Application(FlexGlobals.topLevelApplication));
context.addEventListener(Event.COMPLETE,onComplete);
context.load();
The metadata hasn't changed, you can check out the existing doc sections for
it: Spring Actionscript Component Scan.
Only one addition has been made actually, it is now also possible to define an external properties file in metadata. To do so annotate any class in your project with the following metadata:
[ExternalProperties(location="properties.txt")]
public final class ConfigurationClass {
}
Naturally, you can also add required='true' or preventCache='false' to the metadata arguments.

spring-actionscript-flex.swc

As promised, all Flex specific functionality is now part of a separate .swc.
So in order to use the MXMLApplicationContext you will need to add the spring-actionscript-flex.swc to your library path. The library also offers some extra namespace handlers that target flex specific classes. So in order to easily use those they have been packaged in an IConfigurationPackage implementation called FullFlexXMLConfigurationPackage.
As described in part II of this progress report, you can add such a configuration package using the configure() method on the application context:
var context:XMLApplicationContext = new XMLApplicationContext();
context.configure(new FullFlexXMLConfigurationPackage());

Creating a build

The SVN repository has changed a little bit, so in order to create your own beta build things have changed slightly. First, check out this directory from the Spring SVN repository:
In the checked out directory simple run this maven command: mvn clean compile in order to create a build.
Run mvn clean test to run the unit tests.
You will find the spring-actionscript-core and spring-actionscript-flex .swc's in their respective subdirectories. (spring-actionscript-core/target and spring-actionscript-flex/target)

In the near future...

Next up there's still a number of unit tests to be ported from Spring Actionscript 1.x. After that the documentation site will be overhauled. The current site is very rich in information but we feel it needs to be organised better into smaller bite-sized chunks that might be easier to digest for developer's who are new to the framework.
So we'll try and make a couple of 'Getting started' pages without immediately throwing every detail of the framework into the casual reader's face.
We'll try and get http://beta.springactionscript.org up and running as soon as possible.

In the further future...

We are in the planning stages of AOP support. In the past year we have been working hard on as3commons-bytecode which is the library that provides the most low-level support for AOP functionality, namely the creation of dynamic proxy classes and the dynamic manipulation of existing classes.
Next we will release an as3commons project called as3commons-aop which will provide a foundational library offering advice and aspect interfaces, a pointcut scanning system combined with an expression dialect. The template for this will naturally be Spring AOP, but we will try to make the foundational library framework agnostic enough so that other frameworks might use it as well.
This AOP library will then be used to implement the eventual Spring Actionscript AOP support.
All of this is a huge task which is mostly done in our spare time, so naturally we can't give you any release schedule... :)
Any help, however, is always welcome. So if you feel up for it, contact us either at as3commons.org or springactionscript.org (depending on what you'd like to do) and we'll see how we can help eachother out.
And like previous posts, we'd love to hear feedback from you. So any criticisms, ideas, suggestions are more than welcome.

Happy coding!

No comments:

Post a Comment