Thursday, March 29, 2012

Released: AS3Commons-Bytecode v1.1!

Just a quick heads-up here: We have just released version 1.1 of AS3Commons-Bytecode:

Download Page

Documentation has been updated a little bit as well:

Proxy docs

Christophe has been getting his hands dirty in this release as well, he's managed to squash some last bugs that paved the way for the v1.1 release. So thanks a lot for his blood, sweat, tears and sanity ;)

We have added some extra speed optimizations in the ByteCodeType parser. This is, of course, an ongoing process, every time we find some new tricks we implement them. The speed improvements are only slight this time, but every millisecond counts :)
I did a simple test where I invoke a ByteCodeType.fromLoader() in an AIR application with all framework libraries included (which results in about a 2MB SWF mainly consisting of class information) which took about 2225 ms to complete in debug mode.

Furthermore, we have improved the proxying of getters, it now works properly actually ;)
In version 1.0 it was impossible to receive a reference to the getter function itself and pass it on to the interceptors. This was due to a technical limitation at the opcode level, where it is also impossible to get a reference to the actual getter function. So, what the proxy factory now does is create a custom namespaced method in the proxy class that basically does this:

Imagine your proxied class has a getter called 'name':

public function get name():String {
  return _name;
}

AS3Commons-Bytecode v1.1 will then generate an extra method on the proxy class that looks like this:

as3commons_bytecode function getter_name():String {
  return super.name;
}

After that, in the overridden getter method the function getName() will be passed into into the interceptors. That way the interceptors themselves can choose to invoke the getter or not, or at least determine at which time the getter will be invoked.

An important note has been added to the proxy documentation as well, concerning the ApplicationDomain reference that needs to be passed in to the defineProxy() method.

ByteCodeType now caches its type info per application domain (when before it only kept one cache). This allows the library to cache different type info for different app domains that potentially could share the same names.

So, it is very important to pass the correct ApplicationDomain reference into defineProxy(), otherwise the ProxyFactory won't be able to find the appropariate ByteCodeType info.
This ApplicationDomain needs to be the same reference as the loaderInfo.applicationDomain property that was passed into ByteCodeType.fromLoader().

It sounds more complicated than it is actually. What you do is simply keep a reference to loaderInfo.applicationDomain, and use that in each invocation of defineProxy().
Existing code that makes use of AS3Commons-bytecode 1.0 probably doesn't do this yet, so if you experience errors after upgrading to version 1.1, this is probably what's going on. The fix is fairly simple, as explained.

At the same time work is very slowly progressing on as3commons-aop as well, we have no idea yet when it'll see an official release, but the website will be up soon, we promise ;)

AS3Commons is busy with some other new project releases as well, projects donated by the likes of Claus Wahler and Brian Riley, so these are exciting times for the project!

That was all, happy coding to everyone!

cheers,

Roland

Monday, March 5, 2012

Spring Actionscript 2.0 Progress Report - Part IV

Well, hello there!
Time for another progress report on the ongoing development of Spring Actionscript version 2.0. I think we're inching towards a true beta version, once I think we're feature-complete that'll happen. But not just yet. :)
So far I do encourage people to start using the library, right now within my company Stack & Heap we've been using version 2.0 in at least three of our current projects and things are running very smoothly.
Let's run through the new stuff that has been added, changed or improved.

Lazy dependency injection
This is a feature that I needed in my current project. Basically I stumbled upon a use-case where the container needed to instantiate an object that has a dependency on another object that isn't available yet at container startup.
The object in question is retrieved from the server and needs to be injected into that particular object.
Of course, its possible to just inject the instance from within the presentationmodel that performs the service call, but things get more interesting if more than one object has a dependency on the server object. And what if the server object itself needs to receive injections as well?

It would be a lot nicer to be able to just define an object definition for this server object and, once it has arrived from the server, hand it over to the container and let it handle it from there.

New Object Definition Scopes
In order to facilitate the configuration for lazy dependencies we decided to add some extra scopes to the ObjectDefinitionScope enumeration. The new scopes are:
  • ObjectDefinitionScope.STAGE
  • ObjectDefinitionScope.REMOTE
The first one, ObjectDefinitionScope.STAGE, was added to indicate that an object definition is associated with a stage component. (doh...) Before, we recommended to set the scope to ObjectDefinitionScope.PROTOTYPE for such definitions, to make sure the component didn't get instantiated as a singleton unnecessarily. But this new scope will hopefully add some clarity to the configuration.

The second one, ObjectDefinitionScope.REMOTE, is meant for the server objects I mentioned. So, the object definition is added to the configuration just as any other, with the exception that the scope is set to the aforementioned value:

 <sas:Object id="myServerObject" scope="remote" clazz="MyServerObjectClass"/>  

Now, after the object has been retrieved from the server (or any other origin than the container) it needs to be added to the container. For this you can use the manage() method on the application context:

 applicationContext.manage(serverObject);

The object definition that is associated with the instance will be looked up by type in the container. If no class can be defined in the configuration (because the class isn't available at startup for instance) its also possible to define the definition id as an optional argument:

 applicationContext.manage(serverObject, "myServerObject");

After this invocation any already existing object instances that have a dependency on myServerObject will be injected with the server object.

EventBus Configuration
As reported before, eventbus configuration can be added to the object definition in version 2.0. The original MXML config looked like this:

 <sas:Object id="dispatcher" clazz="MyDispatchingClass"/>

 <sas:EventRouter instance="dispatcher">  
  <sas:EventRouterConfiguration eventNames="{MyEventClass.SOME_TYPE}"/>  
 </sas:EventRouter>  

This has been simplified slightly, its now possible to just nest the event routing configuration directly with the object definition:

 <sas:Object id="dispatcher" clazz="MyDispatchingClass">  
  <sas:EventRouterConfiguration eventNames="{MyEventClass.SOME_TYPE}"/>  
 </sas:Object>  

Same works for event handling configuration:

  <sas:Object id="handler" clazz="{MyHandlingClass}">   
  <sas:EventHandlerMethod name="eventHandlerMethod"  
   eventName="{MyEventClass.SOME_TYPE}"/>  
  </sas:Object>  
That ought to make the overall configuration a little more concise and readable, I hope.

Context Customization
it is now possible swap out most of the internals of the object factory by adding custom implementations of the following interfaces to the configuration:
  • IDependencyInjector
  • IEventBus
  • IObjectDestroyer
  • IAutowireProcessor
Hopefully this will enable Spring Actionscript users to support more unusual use-cases that the default container logic isn't prepared for.

ApplicationPropertiesObjectFactoryPostProcessor
This processor is already present in the Spring Actionscript v1.0 and now ported to version 2.0. (Thanks @herrodius)
It enables the MXMLApplicationContext to inject a number of Application properties into its managed objects. The following properties are available:


  • application.frameRate
  • application.historyManagementEnabled
  • application.pageTitle
  • application.resetHistory
  • application.scriptRecursionLimit
  • application.scriptTimeLimit
  • application.url
  • application.url.protocol
  • application.url.host
  • application.url.port
  • application.usePreloader
  • application.viewSourceURL
And besides those, any application parameters will be added by name as well. So if the a parameter called myAppVar is passed into the application it will be available as an external property by the name of application.myAppVar.
To inject these values into an object add them into the configuration like this:

 <sas:Object id="myClass" clazz="{MyClass}">  
  <sas:Property name="frameRate" value="$(application.frameRate)"/>  
 </sas:Object>  

Default Definition Properties
Object definitions have, hopefully, sensible defaults. But we've added some shortcuts to enable you to change those without having to set these properties on every definition in the configuration.
The <sas:SASObjects/> element now has a number of the same properties as the IObjectDefinition which will be inherited by any definition within that config:
  • autoWireMode
  • childContextAccess
  • dependencyCheck
  • destroyMethod
  • factoryMethod
  • factoryObjectName
  • initMethod
  • isAutoWireCandidate
  • isLazyInit
  • parentName
  • scope
  • skipMetadata
  • skipPostProcessors
For now this is only implemented in the MXML configuration, but naturally this will also be implemented in the XML and metadata versions.

In Conclusion
Those are the newest features (I hope I haven't forgotten any actually...), apart from those, there have been quite a number of bugfixes and optimizations. The autowiring has been sped up quite a bit, as well as the dependency checker. Furthermore, my colleague @bertvandamme fixed a particularly nasty bug in the popup injection logic which would screw up the FocusManager for modal popups. Good times! :)

I haven't gotten round to updating the Spring Actionscript 2.0 documentation yet, but hopefully I'll be able to add some more to that in the near future.

New snapshots have been deployed to the maven repository as per usual.

Here are the forums if you'd like to discuss anything in public:
Spring Actionscript forum

You can follow me on twitter: @mechhead
Or follow Spring Actionscript: @springas

Our JIRA bugbase can be reached here:
SpringSource JIRA

And that's all folks, until next time, happy coding!

cheers,

Roland

Tuesday, December 13, 2011

Spring Actionscript 2.0 Progress Report - Part V

Its been quite a while since the last progress report, I'm sorry to admit that I haven't been able to spend as much time working on Spring Actionscript 2.0 as I had hoped. Sadly, work and life in general got in the way.
Nevertheless there have been some exciting changes to the code base. Not a lot of extra features, but more a refinement of the existing stuff.

Multiple root views

An application context used to be only tied to one root view. I was, wrongfully, under the impression that a context will always be wiring one module or sub application.
Until I ran into a situation during my own current project where a tab navigator was managed by a parent context with child contexts managing the actual screens in each tab. Only it was possible for multiple tabs to be managed by the same child context.
So, to support this the application context now receives an optional Vector of DisplayObjects as a constructor parameter. After context creation its also to possible to add root views at runtime using the new addRootView() method on the application context. So the views do not necessarily need to be known at the time of creation of the context.

MXMLApplicationContext cleaned up
Admittedly, the MXMLApplicationContext had turned into a bit of a mess. The MXML component acted as a sort of wrapper for an internal DefaultApplicationContext, which somehow seemed like a good idea at the time but lead to nasty issues in practice. (Thanks to this forum post I realized the error of my ways: Spring Actionscript forum link)
So, the MXMLApplicationContext got refactored heavily and while fine-tuning the multi-module support I added some nifty extra possibilities for child contexts.
Originally, as described in Progress Report Part III, the addChildContext() method signature looked like this:
function addChildContext(childContext:IApplicationContext, shareDefinitions:Boolean=true, shareSingletons:Boolean=true, shareEventBus:Boolean=true):void;
This now has changed to a slightly more readable form:
function addChildContext(childContext:IApplicationContext, settings:ContextShareSettings=null):IApplicationContext;
As you'll see the most interesting parameter here is the one called settings. This parameter is of type ContextShareSettings and this can describe the various ways that a parent context will share its data with a child context. This class has four properties:
  1. shareDefinitions - If true all definitions that do not have their childContextAccess set to NONE or SINGLETON will be cloned and added to the child context.
  2. shareProperties - If true all the external properties will be added to the child context
  3. shareSingletons - If true all of the singletons in the parent's cache will be added to the child's cache, provided that an object with the same name doesn't already exist in the child context. Using this also explicitly added singleton can be shared (an explicit singleton means a cached object that doesn't have a corresponding object definition)
  4. eventBusShareSettings - This property is of type EventBusShareSettings, which describes the way that the context eventbuses will be linked to each other.
An EventBusShareSettings instance has these properties:
  1. shareRegularEvents - If true, all regular events, so events that are dispatched without a topic will be shared.
  2. sharedTopics - A Vector of topics whose events will be shared.
  3. shareKind - This property is of type EventBusShareKind as described below.
The  EventBusShareKind enumeration has these values:
  • NONE - The eventbuses will not be connected.
  • BOTH_WAYS - Events dispatched by the parent will be routed to the child's eventbus, and vice versa, events dispatched by the child will be routed to the parent.
  • CHILD_LISTENS_TO_PARENT - Events dispatched by the parent will be routed to the child's eventbus.
  • PARENT_LISTENS_TO_CHILD - Events dispatched by the child will be routed to the parent's eventbus.
Some events were added to this process as well, the application context now dispatches four types of ChildContextEvents:

  1. AFTER_CHILD_CONTEXT_REMOVE
  2. BEFORE_CHILD_CONTEXT_REMOVE
  3. BEFORE_CHILD_CONTEXT_ADD
  4. AFTER_CHILD_CONTEXT_ADD
The names speak for themselves, but the most interesting ones are the BEFORE_CHILD_CONTEXT_ADD and BEFORE_CHILD_CONTEXT_REMOVE.
These events are cancelable, so when preventDefault() is called on them the specified logic will not be executed. So in these cases the child will not be added, or not removed.


Multi-module support and automatic child context detection
The Flex extensions for Spring Actionscript have been further fleshed out in the multi-module support department.
The MXMLApplicationContext has a new property called modulePolicy that determines what a context will do when it encounters a Flex module on the stage. This modulePolicy is an enum with two values:
  • AUTOWIRE - Try to autowire the module
  • IGNORE - Do nothing
By default this property has a value of ModulePolicy.AUTOWIRE, so if your application just needs one context and configuration, but loads its UI in parts there is nothing to be changed. Just add an MXMLApplicationContext and you're good to go.
However, when modules are loaded with their own context that is responsible for wiring the module, set this property to ModulePolicy.IGNORE.

Also new in this drop of Spring Actionscript 2.0 is the fact that MXML based contexts now automatically can detect the creation of child contexts. So all that is needed is to add a context to your module and things will get sorted automatically.
When a new context is detected it will be automatically added to the parent context. The way that an application context determines whether it is a parent context or a child context is by checking the systemManager's isTopLevelRoot property of one of its root views. If this property is true then it assumes its the parent, if not, it assumes its a child.
When a parent adds the child it, naturally, invokes its own addChildContext() method. To specify the ContextShareSettings instance for this call it is possible to do so using the defaultShareSettings property on the MXMLApplicationContext.

If different settings are needed for different childcontexts there is the ChildContextEvents, when listening for the BEFORE_CHILD_CONTEXT_ADD event it is possible to assign a ContextShareSettings instance to the ChildContextEvent.shareSettings property,
If the ContextShareSettings instance is not capable of describing the way that the contexts ought to be shared there is event the possibility to completely override the sharing logic.
This is done by assigning a Function to the ChildContextEvent.customAddChildFunction property, this function needs to have this signature:
function(parentContext:IApplicationContext, childContext:IApplicationContext, settings:ContextShareSettings);
 A sample application that demonstrates the functionality described above here can be viewed here:

Cafe Townsend - Multi-module implementation

The application has 'view source' enabled so its implementation can be checked out easily.

Oh, and before I forget, this functionality can be turned off completely by setting the autoAddChildren property on the MXML context to false.

Popup and tooltip wiring
The MXML based contexts are now able to automatically detect popups and tooltips for wiring purposes. So it is no longer necessary to register a popup after creation, it is automatically picked by the regular stagewiring.
There was some dirty hacking needed to get this working, if you're interested in the nasty details, then check out the PopupAndTooltipWireManager class.

Logging
The framework now reports its internal behavior much more elaborately than before, its not completely finished yet, but there is already an enormous slew of statements waiting for you to be checked out.
Internally we use the mighty as3commons-logging library by Martin Heidegger which, as it should, is turned off by default.
To see the log statements turn up in your trace log all you need to do is add this line of code before the context gets initialized:

LOGGER_FACTORY.setup = new SimpleTargetSetup(new TraceTarget());
 (Don't forget to add the as3commons-logging .swc to your project of course)
The as3commons-logging library offers a host of other logging targets as well, check out its documentation for more details on that.

In conclusion
The documentation has been added to steadily, you can check this out at the usual location:
Spring Actionscript 2.0 - Beta docs

New snapshots have been deployed to the maven repository, so using the 2.0-SNAPSHOT artifact will get updated automatically, should you be using that.

If you have any questions or suggestions, check out the user forums:
Spring Actionscript forum

You can follow me on twitter: @mechhead
Or follow Spring Actionscript: @springas

Our JIRA bugbase can be reached here:
SpringSource JIRA

Thanks for taking the time again to plow through this pile of text, until next time, happy coding!

Roland

Monday, September 19, 2011

Spring Actionscript v2.0 Progress Report - part IV

So, after the release of as3commons-bytecode v1.0 (by the way, v1.1 is nearing completion already hehe), it was time to focus back on Spring Actionscript v2.0

I've been mostly busy re-setting up the site generation. We are building our documentation in the Docbook format. Its has a bit of a learning curve, but once you get the hang of it, and especially the extension points of the transformation classes, Docbook is a great choice to encode technical documentation in. For me it was important to be able to simply enclose a class name with a <literal/> element and have a custom XSLT sheet transform this to a <a href="...">Classname</a> result. With the href containing a valid link to the correct ASDoc page.
Luckily the intermittent XML format that is being spat out by the ASDoc compiler helps out here, so that saves me quite a bit of typing. We used to already have a system in place but this still required me to copy/paste the fully qualified into an xlink:href attribute. Which sucks if you have hundreds of class names strewn throughout the reference docs. But now that pain is gone :)

Anyways, once that was out of the way I added some custom xslthl extensions, so now we have some nicely highlighted code snippets as well.

And then the writing started... I've tried to re-organize the old reference docs into something with a little bit better of an overview. I hope I've succeeded...

But besides writing documentation there *have* been some small additions to the library since the last progress report. Let's see what they are.

MXML EventBus Custom Configuration

For XML configuration we described the Eventbus namespace handler to easily configure eventhandlers, interceptor, listenerinterceptors and event routers in the second progress report. In the third one we described the ICustomObjectDefinitionComponentinterface.
Using this interface we now offer some Eventbus configuration extensions for the MXML configuration.
So, to configure an Eventhandler in MXML use this MXML markup in your configuration:

<sas:EventHandler instance="metadataHandler">
    <sas:EventHandlerMethod name="handleEvent" eventName="complete"/>
</sas:EventHandler>

Where instance is the object name whose handleEvent method will be used as the eventhandler for events with the name complete.
To add a topic or topics, use the topics property:
<sas:EventHandler instance="metadataHandler">
    <sas:EventHandlerMethod name="handleEvent" eventName="complete" topics="topic1,topic2"/>
</sas:EventHandler>

For an event interceptor, add this MXML markup:
<sas:EventInterceptor instance="eventInterceptor">
    <sas:InterceptionConfiguration eventName="complete"/>
</sas:EventInterceptor>
Same applies here for topics, or topic properties, or if you want to intercept an event class instead of an event by name:
<sas:EventInterceptor instance="eventInterceptor">
    <sas:InterceptionConfiguration eventClass="{MyCustomEvent}" topics="topic1" topicProperties="myProperty,myOtherProperty"/>
</sas:EventInterceptor>
And event listener interceptor is almost the same as an interceptor, configuration-wise:
<sas:EventListenerInterceptor instance="eventListenerInterceptor">
    <sas:InterceptionConfiguration eventName="complete" topics="topic1"/>
</sas:EventListenerInterceptor>
And lastly, there is the RouteEvents markup, used to automatically send one or more specified events dispatched by a specified object through the EventBus. To configure this in MXML, use this markup:
<sas:EventRouter instance="eventRouterInstance">
    <sas:EventRouterConfiguration eventNames="busy,progress,ready" topics="topic1"/>
</sas:EventRouter>
And that's it!

Factory objects

Spring Actionscript v1.x offered the IFactoryObject to perform complex object creation and configuration for cases where XML or MXML markup was simply to verbose or unwieldy. Now Spring Actionscript v2.0 doesn't require you to implement the interface any more, you can simply add this metadata to your class:
[Factory(factoryMethod="createNewInstance")]
public class IncrediblyComplicatedObjectFactoryThatDoesNotImplementIFactoryObject {

    public function createNewInstance():* {
        var instance:IncrediblyComplicatedObject = new IncrediblyComplicatedObject();
        //creation logic ommitted
        return instance;
    }

}

Now all you have to do is add this class as an object definition to your configuration and it'll be automatically picked as a factory object by the container.

If you don't want to litter your classes with metadata, you can also use the XML configuration, to achieve this, first add the util namespace handler to your XMLApplicationContext:

xmlApplicationContext.addNamespaceHandler(new UtilNamespaceHandler());

Then add this namespace to your XML configuration:
xmlns:util='http://www.springactionscript.org/schema/util'

And finally, add this markup to the XML itself:
<util:factory
    factory-method="createNewInstance"
    class="com.myclasses.factories.IncrediblyComplicatedObjectFactoryThatDoesNotImplementIFactoryObject"
    id="incrediblyComplicatedObject"/>

Naturally, there is also the possibility to do the same in MXML configuration, use this MXML markup instead:
<sas:FactorObjectDefinition
    factoryMethod="createNewInstance"
    clazz="{IncrediblyComplicatedObjectFactoryThatDoesNotImplementIFactoryObject}"
    id="incrediblyComplicatedObject"/>

Metadata configuration

One of the disadvantages of the metadata configuration used to be that you can only add the [Component] metadata to classes that you have source code access to. It was impossible to add object definitions for Flex classes, or any other third party libraries for that matter.
Or maybe you simply dislike having all of the [Component] metadata strewn around your code base. Certainly in larger projects this might become a handicap.
Therefore I have added the [Configuration] metadata tag. This can be added to a class that functions as nothing more than a placeholder for object definition specific metadata.

Here's an example of what this class might look like:
[Configuration]
public class MyConfiguration {

    [Constructor(args="ref=objectName2")]
    [Invoke(name="someMethodName",args="ref=objectName1, value=10")]
    [Property(name="wireOnlyOnce",value="true")]
    [Component(id="processor",isLazyInit="true")]
    public var defaultAutowiringStageProcessor:DefaultAutowiringStageProcessor;
}

What this does is add an object definition for the class DefaultAutowiringStageProcessor, with object name 'processor'. It will inject the object with name objectName2 into its constructor, it will set its wireOnlyOnce property to true, it will invoke it someMethodName with two arguments: an instance of the object with name objectName1 and a value of 10. And finally, it will set is lazyInit property to true.

Just make sure that this class will get compiled into your resulting SWF by declaring it somewhere, otherwise the MetadataApplicationContext won't be able to detect it.

There will be an extension point for this as well, to be able to add custom metadata to these configurations that can add extra configuration logic to specific object definitions. But that is for the next progress report :)

Beta site is online!

And finally I am happy to annoucne that the beta site for Spring Actionscript v2.0 is now online! As you will see the reference documentation is far from complete. This is VERY much a work in progress, but as I mention this is a BETA site, with BETA software. So bear with me :)

So please, anything you download from there, please do not be surprised if it crashes, explodes or doesn't work like it says on the box. Do however play around with it, poke holes in it, and contact us with questions, suggestions, criticism and ideas.

You can find the beta site at this address: http://beta.springactionscript.org

I believe that's it for now, until the next time, happy coding!

Wednesday, September 14, 2011

Released: AS3Commons-Bytecode version 1.0!

So, its been more than a year in the making. If I check the changelog, the first commit of as3commons-bytecode was done at the 27th of June 2010.


I've decided to call this release v1.0. I could think of another thousand things to be tweaked and improved but at a certain moment there needs to be a first final release :)
This certainly doesn't mean the library is now finished, I will keep on tweaking and improving the library. Hopefully users of the library will join in the discussion and suggest new features or improvements.

So, now perhaps is the time to look back, reflect and tell a little about the history of as3commons-bytecode :)

I started as3commons-bytecode after taking over the Loom project from Maxim Porges (http://code.google.com/p/loom-as3/). I had begun implementing an AOP solution for Spring Actionscript, first focusing on the pointcut scanning logic because I was following Maxim's progress with Loom and thought this would be an ideal library to use as its foundation.
Sadly, before the library was finished Maxim couldn't offer the personal resources anymore to continue the project. This certainly threw my schedule off :) At first I considered using the FLemit and FLoxy libraries but found that they were too specifically aimed at generating mocks. I need something more generic.

So that's when I started spelunking through the Loom code and step-by-step I actually started to understand what was going on. Before, I was very reluctant since I considered this stuff way beyond my mortal understanding. But I managed to fix some bugs and that's when I contacted Maxim and asked him if it was alright for me take over the project and bring it into the AS3Commons project.
Luckily Maxim was alright with this and so my nightmare begun haha :)

First thing I implemented was the bytecode based reflection. Since it appeared to be relatively simple and was a good way for me to get to know the code base a little. When this was done I started the task of finishing the parsing of all of the opcodes since this hadn't been completed yet. This was when the proverbial shit hit the fan because this is when I started to find out about subtle AVM documentation errors. Or just plain non-existent documentation...Luckily, a trip through the Tamarin source code offered quite a lot of valuable insight as well.
Actually getting the opcode parsing completely to work only got finished a few weeks ago :)

Next step was to generate classes at run-time. I was familiar enough with the ABC format by now to come up with an API to let a developer assemble an ABC file without needing to have any intimate knowledge of 'what lies beneath'. I actually used the .NET System.emit namespace as an inspiration.

Around the time that class generation was implemented, James Ward contacted Maxim Porges to see if he could persuade him to continue his work on Loom since James and Michael Labriola had been hacking away on a mechanism that could intercept SWF loading by the Flash Player.
An ideal hook for AOP and other black magic.
Maxim then forwarded James to me and afterwards Michael and James offered some invaluable help and advice in further developing as3commons-bytecode. Eventually this culminated in their Mixing Loom project (James' blog introduction) and their fantastic session called 'Planet of the AOPs' at the 360|Flex conference in Denver. This was the first true introduction of AOP to the Flash community I guess you could say.

After class generation was working the next step was to provide a generic API for generating dynamic run-time proxies. These are basically subclasses (generated at runtime) that incorporate an interception mechanism for methods and accessors (getters and setters). So when a method gets invoked on the dynamic subclass it will first invoke any registered interceptors, enabling these interceptor to perhaps change or replace the behavior of the underlying functionality. Most mocking libraries (like asmock, mockolate or mockito-flex) are based on this logic.

The API for this is explained in this documentation section on the as3commons site.

Naturally, the most interesting solution that can be created using this proxy API are AOP mechanisms and quite soon after the proxy API became available Marty Pitt went ahead and created Flapper. An AOP extension for the Parsley framework. As if this wasn't enough, he then also created another library called Dynamic Services, also a Parsley extension. This library is able to take an interface that describes a service class and generate this service on-the-fly. This can save you a lot of typing :)

David Arno discovered the library as well and went out to create AS3Introspection, a library that he himself dexcribes as "describeType on steroids". I think that pretty much covers it :)

Jeff Ardillo then went ahead and showcased a technique to create proxies without having to depend on the ProxyFactory to create them in his excellent blog article 'Aspect Oriented Programming in Flex'.

I am very excited to see all of these initiatives take shape as this is exactly the reason why I started as3commons-bytecode. It was its specific aim to be a foundational library and facilitate a platform for other developers to base their own solutions on. Seeing this actually taking place is very satisfying indeed, so kudos to all of you who have taken the library to its next level!

Lately the Flash/Flex twitter- and blogosphere has been buzzing a lot with all sorts of AOP solutions. The Swiz framework just announced their own AOP functionality in their upcoming version 2.0, for instance. This is all great news and opens up all sorts of new and exciting possibilities on the Flash platform.

In that spirit, expect to see a new As3Commons project to be released in the near future as well. It'll be called as3commons-aop and will offer a bunch of standard interfaces and API's that deal with advices and pointcut scanning. Hopefully this will help developers to easily incorporate AOP functionality in other frameworks out there. As we are used to eating our own dogfood, Spring Actionscript will naturally use as3commons-aop as its AOP foundation :)

Yet, I would like to stress, don't focus only on the AOP possibilities of as3commons-bytecode. I believe that projects like Marty Pitt's Dynamic Services show that much more can be achieved with the ability to generate classes at run-time. So be creative and try to come up with some more interesting solutions!

Thank you very much to everyone who has submitted bug reports, feature requests and developed solutions based as3commons-bytecode!

Happy coding!

P.S. If you'd like to get involved with as3commons-bytecode's development or the as3commons project in general, please drop us a line! We always appreciate more help and contributions!

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!

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!

About Me

My Photo

Co-Owner at Stack & Heap (http://www.stackandheap.com)
Lead developer for the Spring Actionscript (http://www.springactionscript.org) and AS3Commons (http://www.as3commons.org) projects.
I like noise.