Thursday, August 18, 2011

Spring Actionscript v2.0 Progress Report

For the past several weeks we have been busy working on what will become Spring Actionscript version 2.0. The work is still in the alpha stages, but we thought it might be interesting for people to read about our progress and perhaps give us some criticism or ideas in the process.
The reasons for a complete overhaul were the following:
  • More reliance on composition rather than inheritance internally
  • Less memory consumption
  • Asynchronous ObjectFactoryPostProcessors
  • Complete separation of Actionscript and Flex dependent parts
  • Refocus back to being an IoC container
  • Make sure *everything* lives behind an interface
  • Upgrade of the testing project to Flexunit 4 and the use of a mocking library

Making things smaller.


First of all, the Spring Actionscript core was starting to get bloated. There was the eventbus that got added, the operation API, a micro MVC architecture, etc.
We felt it was needed that the core library should be an IoC container, and nothing else. So in the last few months you may have seen quite few new as3commons projects pop up that seemed familiar. (If you're a Spring Actionscript user of course.)
Well, that's because we have been busy cutting out the bloat :) The following as3commons project have so far been created out of the refactorings in Spring Actionscript:

Of course the as3commons-reflect and -lang projects already originated from the Spring Actionscript v1.x code base.
This comes much closer to the original philosophy of Spring Actionscript which is focused on re-use. All these libraries are autonomous API's that can be used perfectly well on their own, but bundled together with the Spring Actionscript IoC container may be turned into a powerhouse. :)

Breaking things up further.


The new Spring Actionscript core itself is a pure actionscript library that can be used in non-Flex projects. i.e. springactionscript-core.swc
Any Flex specific functionality will be released as a separate .swc. i.e. springactionscript-flex.swc
Any other functionality will be released also as separate projects, that way you can pick and choose what you need for a particular project. i.e. springactionscript-mvc.swc
We will do our best to offer different kinds of packages for different needs. For instance we will release one huge master swc that contains all of the libraries, extensions and dependencies. But there will also be releases in the form of an archive filled with all the necessary .swc files.

Separating concerns in the object factory.


Spring Actionscript 1.x started out only supporting XML configurations, so all of the loading and parsing logic was in the base class of the object factory. When afterwards MXML and annotation based configuration was implemented this lead to an incredibly 'heavy' base class with quite a bit of logic that wasn't always needed in all usage scenario's.

The first thing that had to be done was to split up the object factory in functionally separate classes. The IObjectFactory now is only responsible for what its name indicates: Creating objects. It is composed however of an IInstanceCache, an IObjectDefinitionRegistry, an IDependencyInjector and an IAutowireProcessor. This immediately made unit testing a lot easier since the separation of concerns was a lot clearer by then.

The main entry point for most developers, the IApplicationContext, is now responsible for configuring the IObjectFactory. It serves as a registry for one or more IObjectDefinitionProvider implementations.
An IObjectDefinitionProvider is responsible for creating the IObjectDefinitions (the separate configuration recipes for objects created by the IObjectFactory), in the case of XML this means the loading of XML file(s) (be it external, embedded or explicit), parsing this XML and creating IObjectDefinitions from it. Each IObjectDefinitionProvider is also responsible for reporting any property URI's encountered in the configuration. These property files will afterwards be loaded by an ITextFilesLoader and parsed by an IPropertiesParser which eventually will populate an IPropertiesProvider.

The direct advantage of moving all of this logic into separate object instances is that after the configurations have been processed by their responsible IObjectDefinitionsProviders, these providers can be discarded, freeing up memory.

After the object definitions have been created each IObjectFactoryPostProcessor will be executed. These postprocessors can be used to analyze the registered object definitions and provide some extra configuration.

For instance the StageProcessorFactoryPostprocessor will search the IObjectDefinitionRegistry for implementations of IStageObjectProcessor and registers them with the IStageObjectProcessorRegistry instance that has been assigned to the IApplicationContext.
One of these IStageObjectProcessors is the DefaultAutowiringStageProcessor, which takes care of the autowiring of stage components in Spring Actionscript.

An IObjectFactoryPostProcessor can now also perform its logic asynchronously (this isn't the case in version 1.x), so a server call can be made for instance. Or, in the future, we will probably support some type of AOP system that will generate classes at runtime. These are also asynchronous processes, so the IoC container will be ready for those.

Creating the new contexts.


Now, to make use of an XML configuration the following code would be needed to get the ApplicationContext ready for use:

var applicationContext:IApplicationContext = new ApplicationContext();
var provider:XMLObjectDefinitionsProvider = new XMLObjectDefinitionsProvider();
provider.addLocation("application-context.xml");
applicationContext.addDefinitionProvider(provider);
applicationContext.addEventListener(Event.COMPLETE, onComplete);
applicationContext.load();

 To make life a little easier we will be providing the necessary subclasses of the ApplicationContext for the various types of configuration. For an application context that uses an XML configuration we offer the XMLApplicationContext. This subclass will automatically create the XMLObjectDefinitionsProvider and register it. Creating and loading would only need this bit of code in that case:

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

Note: The location for an XML configuration can be of type String, Class or XML. When the loader encounters a String it will assume it is a URL, in the case of a Class it will assume it is an embedded XML file, and in the case of XML it will directly parse the provided XML object.

Subclasses for MXML, annotation and Actionscript based configuration will each have their own subclass for convenience. Mixing different types of configuration will still be possible, one needs only to add an appropriate IObjectDefinitionsProvider to the context manually. These subclasses are really meant for common usage scenarios.

Tweaking the XML dialect.


The XML configuration dialect has remained largely the same, with some additional new possibilities though.
Properties and method invocations can now be configured for members that live in a custom namespace. The and elements both have a namespace attribute now:

<property name="myProperty" namespace="http://www.mydomain.org/custom" value="myValue"/>

<method-invocation name="myMethod" namespace="http://www.mydomain.org/custom"/>

Static properties may be injected as well:

<property name="myStaticProperty" value="myValue" static="true"/>

For explicit null values the <null/> element already existed, we now also support <undefined/> and <not-a-number/>.
Any suggestions for more additions are welcome of course :)


Taking advantage of your parents.


An ApplicationContext can have another context as its parent. The nice thing about this is that a child context can inject an object that it created with an instance that is managed by its parent context. It is also possible for a child context to override certain objects by registering an object definition with the same name.
This functionality was already in place in Spring Actionscript v1.x, but Spring Actionscript v2.0 now offers a subtle bit of extra flexibility. Should a context have overridden an object, but in a certain case still need to inject the original instance present in the parent factory, the configuration can be set like this:

<property name="myComplexProperty" ref="parent.myValue"/>

In the case where there is a chain of parent/child contexts, this can even be brought higher up the chain like this:

<property name="myComplexProperty" ref="parent.parent.myValue"/>


Wiring stage components.


The way the stage autowiring processor is being added to the XML configuration has changed slightly as well. In version v1.0 you just needed to add a regular object definition like this:

<object class="org.springextensions.actionscript.stage.DefaultAutowiringStageProcessor" id="autowiringStageProcessor"/>

 In version 2.0 we have added a separate XML namespace for autowiring, which makes things slightly easier to read. (Hopefully...):

<objects xmlns="http://www.springactionscript.org/schema/objects"
         xmlns:stage="http://www.springactionscript.org/schema/stageprocessing"
         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">

    <stage:autowiringstageprocessor/>

</objects>

A custom IStageObjectProcessor can be configured like this with a custom IObjectSelector:
<objects xmlns="http://www.springactionscript.org/schema/objects"
         xmlns:stage="http://www.springactionscript.org/schema/stageprocessing"
         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">

          <object id="customSelector" class="com.classes.MyCustumSelector"/>
          <stage:stageprocessor class="com.classes.MyProcessor" object-selector="custumSelector"/>

</objects>

Where do we go from here?


If you're interested in playing around with the new library, you can. Of course we can't stress enough the fact that this is alpha code and should *definitely* not be used in a production environment. But if you're feeling adventurous and want to try things out, go ahead and check out the 2.0 branch in our SVN repository:


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.

So far XML configuration and stage wiring ought to be working. If you encounter any bugs or have any ideas for new functionality, please let us know!
Either leave a comment on this blog or visit our JIRA system:


Thanks a lot for taking the time to read all of this, we will let you know how we progress further!

Happy coding!

Wednesday, December 29, 2010

AS3Commons-Bytecode v0.9.2 released

The last two days two updates to AS3Commons-Bytecode were released, v0.9.1 and today v0.9.2 to be precise.

The most important additions in these two releases have been the support for proxying protected and custom namespace members. I ran into a bunch of issues during development but wanted to get the API out so that people could play around with it and perhaps come up with some constructive criticism. Therefore the first v0.9 release only supported public members, enough for some basic testing and trying out.
Luckily in the past few evenings I've been able to track down the issues I had surrounding generation of protected and custom namespace scoped members.

It came down to a few bugs in the Bytecode reflection and emit.* API, that'll teach me to unit test better I suppose. :)

Another handy addition are a bunch of build cycle events that allow a developer to customize the generation of the method bodies. All of them are explained in this doc section:
Generating the proxy classes

Furthermore, the library now offers an entry point for using an IFactory implementation to take care off the creation of IMethodInvocationInterceptors. How this is hooked up is described in this section:
Instantiating a proxy class

For the next release I'll be focusing on what they call in AOP terms 'introductions', which means that the library will enable you to let proxy classes implement new interfaces at runtime. Handy for when an object needs an 'isDirty' property, for instance.

When that's finished I suppose a version 1.0 should be ready.
Beyond v1.0 will be bytecode weaving based AOP, this is going to introduce its own set of difficulties to overcome which is why I've decided to push it back after the v1.0 release.

Cheers and a happy new year!

Roland

Sunday, December 26, 2010

AS3Commons-Bytecode v0.9 released

Today saw the release of v0.9 of AS3Commons-Bytecode, an ABC bytecode parsing/publishing and bytecode based reflection API for ActionScript 3.0, formerly known as Loom. (http://code.google.com/p/loom-as3/).

It offers bytecode based reflection, giving a developer access to a much richer set of reflection information than that retrieved from the native describeType() method.
Check this link for more information about this feature: Bytecode reflection.

Secondly it offers the emit API, enabling a developer to define, generate and load Actionscript classes at runtime.
Check this link for more information about this feature: Runtime class generation.

And lastly, the library has just added support for runtime dynamic proxy generation in this v0.9 release. Dynamic proxies will bring the first, albeit limited, AOP possibilities to Actionscript.
Check this link for more information about this feature: Dynamic proxy generation.

For the upcoming release support for proxying protected and custom namespace scoped members for dynamic proxies is planned. Along with bytecode weaving AOP support.

Until then, try out the library and report any bugs or ideas here: Issues.

Cheers,

Roland

Monday, September 13, 2010

Spring Actionscript 1.0 released!

As usual Herrodius.com has the complete lowdown:

http://www.herrodius.com/blog/350

Or you can head over to the changelog immediately:

http://www.springactionscript.org/changes-report.html#a1.0

if you have any questions or criticism, please visit the forums:

http://forum.springsource.org/forumdisplay.php?f=60

Cheers!

Monday, March 1, 2010

Released: Spring Actionscript version 1.0 Release Candidate 1 now available!

Finally, Spring Actionscript 1.0 RC1 sees the light of day!

Get all the juicy details over at Herrodius' blog:

http://www.herrodius.com/blog/273

or just read the changelog here:

http://www.springactionscript.org/changes-report.html#a1.0RC1

if you have any questions or criticism, please visit the forums:

http://forum.springsource.org/forumdisplay.php?f=60

Cheers!

Tuesday, September 15, 2009

Spring Actionscript version 0.8.1 released!

Its mainly a maintenance release with a slew of bugfixes, but there's some new functionality in there as well.
Read the full story at Herrodius' blog as per usual:

http://www.herrodius.com/blog/208

Download away:

http://www.springactionscript.org

Here's the changelog:

http://www.springactionscript.org/changes-report.html#a0.8.1

And should you find any bugs or have some feature request, please head on over to JIRA:

http://jira.springframework.org/browse/SESPRINGACTIONSCRIPTAS

cheers!

Friday, July 17, 2009

Spring Actionscript version 0.8 released!

Get the full story at herrodius blog:

herrodius.com

read the new documentation site front to back:

springactionscript.org

For all people upgrading from an older version and haven't done so, make sure you change the namespace declarations in your configuration files! Failing to do so will prevent springactionscript from working properly. (well, it won't work at all actually :))
This is what your XML should look like:

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

</objects>

That's the most important part to check.

Here's a quick glance at the changelog:

Changes in version 0.8 (16.07.2009)
-----------------------------------

General
* new website at www.springactionscript.org
* factored out common functionality into the AS3Commons projects (http://www.as3commons.org)
* major update to the documentation
* added autowire support
* added custom namespace handler support
* restructured subversion repository
* updated samples
* various performance improvements

Package org.springextensions.actionscript.cairngorm
* added IDataTranslator and IDataTranslatorAware interfaces
* added AbstractDataTranslatorAwareBusinessDelegate base class
* added 'batch command' support to CairngormFrontController

Package org.springextensions.actionscript.context.support.mxml
* added entire package for MXML support for application contexts

Package org.springextensions.actionscript.domain
* moved Enum to AS3Commons-Lang
* moved ICloneable to AS3Commons-Lang
* moved IEquals to AS3Commons-Lang

Package org.springextensions.actionscript.errors
* moved IllegalArgumentError to AS3Commons-Lang
* moved IllegalStateError to AS3Commons-Lang
* removed RuntimeError

Package org.springextensions.actionscript.ioc
* added "factoryObjectName" property to IObjectDefinition and ObjectDefinition

Package org.springextensions.actionscript.ioc.factory
* added ObjectDefinitionStoreError

Package org.springextensions.actionscript.ioc.factory.config
* added StageComponentInterceptionPostProcessor
* fixed e4x query to select nodes with Required metadata in RequiredMetadataObjectPostProcessor
* changed "getObject" and "getObjectType" so we can also return Function references from methods in FieldRetrievingFactoryObject
* added "getObjectDefinition" in IConfigurableListableObjectFactory

Package org.springextensions.actionscript.ioc.factory.config.flex
* added ApplicationPropertiesResolver

Package org.springextensions.actionscript.ioc.factory.support
* removed "allowObjectDefinitionOverriding" getter and setter from IObjectDefinitionRegistry
* error is now thrown when overriding an object definition while it is not allowed in DefaultListableObjectFactory
* added support for retrieving factory objects and autowiring in AbstractObjectFactory
* added ObjectDefinitionBuilder
* fixed bug with caching of factory objects in AbstractObjectFactory

Package org.springextensions.actionscript.ioc.factory.xml
* added StageInterceptionNamespaceHandler
* added spring-actionscript-stageinterception-1.0.xsd
* added spring_actionscript_stageinterception namespace
* added RPCNamespaceHandler
* added spring-actionscript-rpc-1.0.xsd
* added spring_actionscript_rpc namespace
* added UtilNamespaceHandler
* added spring-actionscript-util-1.0.xsd
* added spring_actionscript_util namespace
* added MessagingNamespaceHandler
* added spring-actionscript-messaging-1.0.xsd
* added spring_actionscript_messaging namespace
* added "resolveID" to AbstractObjectDefinitionParser method that allow object name lookup and generation

Package org.springextensions.actionscript.ioc.factory.xml.parser.support
* fixed XMLObjectDefinitionsParser so that abstract definitions are no longer parsed
* fixed XMLObjectDefinitionsParser to support nested custom nodes

Package org.springextensions.actionscript.ioc.factory.xml.parser.support.nodeparsers
* fixed ObjectNodeParser to support nested custom nodes

Package org.springextensions.actionscript.ioc.factory.xml.parser.support.nodeparsers.stageinterception
* added StageInterceptorNodeParser

Package org.springextensions.actionscript.ioc.factory.xml.preprocessors
* fixed parent properties not being overridden by child properties in ParentAttributePreprocessor
* fixed bug with properties replacement

Package org.springextensions.actionscript.mvcs
* removed AbstractService
* added IApplicationController
* added AbstractApplicationController
* added ApplicationEvent
* added ApplicationEventDispatcher
* added IApplicationEventListener

Package org.springextensions.actionscript.utils
* added ApplicationUtils
* moved ArrayUtils to AS3Commons-Lang
* moved Assert to AS3Commons-Lang
* moved DictionaryUtils to AS3Commons-Lang
* moved ObjectUtils to AS3Commons-Lang
* moved StringUtils to AS3Commons-Lang
* moved XMLUtils to AS3Commons-Lang
* removed TypedProxy

Samples
* added object-definition-parser-builder project

Go get it while its hot!