The spiralcraft.builder subsystem is a facility for declaratively defining an integration layer in an application or framework. The term "integration layer" refers to a part of an application where various application components, often unaware of one another, are assembled into functional units to provide context specific behavior.
This subsystem has the following features:
Spiralcraft.builder assumes the role of a setter and constructor based dependency injection tool, with added extensibility features that go beyond the usual capabilities of "configuration" tools.
While procedural programming code lives in Java classes, usually "parameterized" through the use of bean properties, declarative elements (eg. the initial values of the bean properties and interconnections between objects) tend to fall to a configuration mechanism.
Spiralcraft.builder was created out of the philosophy that declarative elements and the structural composition (ie. dependencies) of an application should be managed in their own flexible, extensible layer, in order to decouple Java classes from compositional specifics and thus maximize their re-use, and to enable the re-use of declarative and structural elements and thus remove complexity from the "configuration" layer.
This subsystem allows an application developer to define pre-wired groups of components through the creation of "scaffolding" objects called Assemblies. Assemblies can be defined using a built-in compact XML format or can be created dynamically, and can extend and include one another.
The spiralcraft.builder subsystem centers around the Assembly construct, and the associated AssemblyClass construct.
An AssemblyClass describes a partial configuration for a Java object (ie. values for the Bean properties of the object as well as other "contents"). It is used to create one or more Assemblies at runtime. An Assembly manufactures (resolves/instantiates and configures) one or more application components (arbitrary Java objects) as defined in its AssemblyClass.
A PropertySpecifier defines the value source and target property for a given injected property. It can take multiple forms- text, other AssemblyClasses, a load-time evaluated spiralcraft.lang Expression, etc. When other AssemblyClasses are used as property values, a natural containership model is realized.
An AssemblyClass can inherit from another AssemblyClass, and can override property settings in the base AssemblyClass. An AssemblyClass that does not inherit from another effectively "inherits" a default set of properties from a POJO (Plain Old Java Object).
An AssemblyClass is bound at load time to the application context (represented by a Focus chain) to resolve dependencies. The bound AssemblyClass is called an Assembly.
The natural containership model created by nested AssemblyClasses provides a Focus chain that is used to bind spiralcraft.lang Expressions at load time.
AssemblyClasses are specified using a Normalized XML Object Notation (NXON). All element names are dynamically mapped to the runtime resource environment, while attributes define functionality specific to spiralcraft.builder.
The following examples build on one another to demonstrate how spiralcraft.builder works.
Define a simple (but not particularly useful) AssemblyClass which instantiates the Java type com.example.test.MyClass
resource: class:/com/example/test/MyClass.assy.xml <test:MyClass xmlns:test="class:/com/example/test/" />
An AssemblyClass which instantiates and configures the Java type com.example.test.MyClass, which has "title" (String) and "active" (boolean) properties. The setTitle(String) and setActive(boolean) methods on the MyClass type are called to inject to property values.
resource: class:/com/example/test/MyClass.assy.xml <test:MyClass xmlns:test="class:/com/example/test/" > <title>My Class</title> <active>true</active> </test:MyClass>
An AssemblyClass which instantiates and configures the Java type com.example.test.MyClass, which has "title" (String), "active" (boolean), "partner" (com.example.test.MyClass), and "children" (com.example.MyClass[]) properties.
resource: class:/com/example/test/MyConfiguredClass.assy.xml
<test:MyClass
xmlns:test="class:/com/example/test/"
>
<title>My Class</title>
<active>true</active>
<partner>
<test:MyClass>
<title>Partner Class</title>
<active>true</active>
</test:MyClass>
</partner>
<children>
<test:MyClass>
<title>Child 1</title>
<active>false</active>
</test:MyClass>
<test:MyClass>
<title>Child 2</title>
<active>true</active>
</test:MyClass>
<test:MyClass>
<title>Child 3</title>
<active>false</active>
</test:MyClass>
</children>
</test:MyClass>
A spiralcraft.lang Expression that will supply the property value.
The Expression is bound against a FocusChain composed of all the containing Assemblies in addition to the FocusChain provided by the container application, if any.
<example:MyClass> <title x="[example:Application].title"/> </example:MyClass>
A boolean value ("true" or "false") which specifies that any whitespace before or after the attribute value should be preserved.
For bean properties that have an interface type that extends java.util.Collection.
Specifies the Java class name of an implementation of java.util.Collection (or the appropriate sub-interface) to use for the property value.
Specifies a URI in the form of "namespace:name" that references a data resource from the spiralcraft.data subsystem that defines the object to be injected in terms of reflective Types.
This attribute is namespace aware and will use the namespaces defined in the xmlns declarations- eg. "myns:MyDataObject.xml". To supply an absolute URI, prefix it with a ":", eg. ":class:/com/example/data/MyDataObject.xml"
Specifies an id for use in object graph assembly and Expression Focus resolution.
Specifies that the resource assemblyURI "." overlayId ".assy.xml" should be used if it exists. This provides a mechanism to use a context-specific resource where applicable.
A common example is to use "local" or "private" as the overlayId, which provides a way to incorporate private data (eg. login credentials) into an application.