The main design goal of Spine is to create an extensible, easy to integrate java application framework which will make the task of creating transposable applications much easier.The framework is packaged as a jar file which is added to your application library and requires minimum configuration using XML and java properties files.

There are a few key rules that have been imposed in the architecture of the Spine Framework, they are:

  • Application logic components need never know about the presentation components.
  • Business objects and configuration data are assumed to be completely persistent. Almost nothing else is persistent, i.e., it does not save sessions.
  • Data interchange is bidirectional. The system gets sent a data transfer object from a suitable MVC framework, processes the object and returns a data transfer assembler using the command design pattern.
    Various objects are packaged in this data transfer assembler which can then be unwrapped to obtain the results of the invocation.
  • Security is not established by configuration,Spine recognizes roles,principals and objects which declare themselves to be SpineBean extensions.
Spine Components

The diagram shown represents the main layers or tiers of the spine framework. The system will usually receive DataTransferObject from the View Connectors, which in turn will be sent to the Business tier in a DataTransferAssembler, which then invokes any one of several DataProxies that is used to instantiate a DataAccessObject.

The DataProxy types are directly related to the DataStore which the DataAccessObject will use to access or retrieve data from the datastore.

These objects, which are never invoked from code are made available by the Dependency Injection Controller within a container that imposes Object and Role based security on the entity objects been used in the system.

The main components of this system are listed below: Some of these components are listed below and perform the following activites:

Presentation/UI Connectors

There is no presentation logic in Spine. What we have are two objects whose primary function is to serve as a connector for the framework from which other MVC or presentation tier code can invoke and extend spine to perform business functions.

These objects also call on the configuration engine to determine which set of objects will be used to perform processing(Inversion of Control). The objects used for this logic are:

ViewProcessorFactory Used to create the specific type of ViewProcessor
ViewProcessor Contains the core logic to facilitate connectivity. While default objects are available, developers are encouraged to extend ViewProcessors and perform generic presentation processing in this object.

Business Layer Components

These components initialize and close connectors to datastores and contain the core business logic used for processing.

All business rules and processing are expected to be performed here to facilitate ease of transposing business logic from one presentation style to the other. The two major objects used here are:

BusinessDelegate This must be extended and must contain the business rules and application logic for any process flow.
DataTranferAssembler A transport object used to faciliate the flow of information across the different tiers of the framework.

Data Storage Components

Spine allows the developer to use different types of data stores at the same time, all of which can be accessed by using a combination of a DataProxy subclass and an implementation of a DataAccessObject. For every DataStore type, DataAbstract objects have been defined or may need to be defined by the client developer.Client developers can use the DataAbstract as a template for creating a DataAccessObject specifically meant for that type of data store.

E.g. a database will require a DAO(data access object) which must be a subclass of DataBaseAbstract.All the data access logic can be placed in the data access object which is capable of intercepting the data in the DataTransferObject sent to the ViewProcessor that invoked its present activity. The major components in use within the Data Layer are:

DataProxy This contains the logic used to instantiate, operate and close DataAccessObjects (i.e life cycle methods) for all kinds of data stores.
DataAccessObject All data retrieval and persistence logic must reside here.Implementation classes may not need to write generic methods if using a subclass of the abstract implementation.
DataAbstract Subclasses of this object provide generic implementations of a DataAccessObject. Developers should extend DataAbstract subclasses (avoiding the overhead of rewriting code implementing a DAO) or write new ones for data stores that are not implemented in the framework.
DAOInput The is an object which can be used to decorate a DataAccessObject (null when not needed). Developers must provide an implementation in order to use this capability.
Data Store This is not packaged with the framework but represents any kind of persistence engine. eg database, filesystem and/or LDAP.

Initialization and Configuration/Dependency Injection Engine Components

Initialization in Spine is used to add user defined files and variables to the framework. This is done via the spine-init.xml file, which also allows the user to add configuration for a user plugin object called SpinePlugin.

A SpinePlugin extension is an object which can be configured at framework initialization via xml properties in the spine-init.xml file. The plugin is created by the framework's ApplicationConfigurator which will put the defined properties in a map which is passed to the process method of the plugin.

The PluginServiceLocator also keeps a reference to this plugin throughout the life time of the application making it possible for the application to have a handle to the user created plugin.

Inversion of control is available in Spine via a configuration file spine.xml. This file is read at initialization and its contents rendered in object form as a map accessible by a singleton ( SpineConfiguration).

Developers will usually not need to use this singleton as Spine has provided a generic means of invoking the injection engine via the ViewProcessor. All the client developer need do is define the process flow for the the particular invocation. The main objects in use by this engine are:

SpineConfiguration The singleton which provides the objects used by the dependency injection engine.
ApplicationConfigurator The initialization object for the spine application.
spine.xml The configuration file where the process flows used by an application is defined

Security and Identity Components

Spine provides a set of security objects based on Identity recognition and Object identity association. The default identity scheme assumes that any entity object which extends the spine bean is owned by a principal who specifies the basic unix access control rules at creation time.

This implies that entity objects have a notion of owner,group and public access that entirely mimics the access control rules of a unix resource.

Identity objects provided in the framework also define as much information as is needed to recognize an individual/principal, but go on to define the concept of administrators and users.

Roles are recognized as either a group or an application, with all identity objects possessing ACL rules which extend the concept defined for norminal SpineBeans. The principal objects used in the security model are:

SpineBean The generic bean defined to be used within spine to guarantee security of entity objects.
SpinePermission The base permission used by this framework to dictate entity object access.
PermissionLevel The collection of unix like security properties used to define the access level granted to a SpineBean.
MemberPermission The object which defines the security properties of a Spine defined role or principal.
Member The base Role/Principal object recognized by the Spine framework.
AccountDetails The object which holds account properties applicable to each principal in the security system.
AccountSecret An object which holds additional security information about the specific principal in consideration.

Error/Message Notification And Exception Components

Spine possesses generic message objects useful for rendering messages and errors back to the invocation mechanism that initiates a process.

Spine messaging possesses the ability to use several java properties files at the same time in a multi lingual,locale based format and allows for parametric replacement of values within the stated properties files.

These properties files are accessible by all exceptions which are types of the SpineMessageException, allowing client developers the chance to use key based parametric string replacement to propage exceptions.

The main objects in use by the error message and exception facility are:

DisplayError This represents a single error (which may be due to various reasons) generated within spine
DisplayMessage This represents a single message generated within spine to be relayed to a user of the system.
DisplayMessages This is a container for collecting messages and errors and provides various details about these messages/errors.
SpineMessageException This is an exception class that allows parametric replacement of keys to fetch strings which can be displayed to the user.
Process Flow Between Spine Components
The flow of information within Spine can categorized into 3 processes.They are:
These individual processes all occur at both initialization and at runtime and determine the manner in which the framework can be used to develop applications.

Configuration and Dependency Injection loading

At initialization, the configuration written in the spine.xml file is read and used to create a map which contains a set of ValueObjects known as DelegateBeans or MultiDelegateBeans.

These value objects contain the data needed to process a single or multiple events sent to the framework by an external process or MVC framework which request data processing, with the contents of this delegateBeans been used to determine our inversion of control references.

Spine itself will know which object to instantiate within the process flow engine and developers do not need to do anything other than to define the objects which are involved in the process flow for a particular operation within the spine.xml file and implement the necessary business delegate and DAO.

For information on how to configure objects used for an operation, please read the user guide, a schema for the spine.xml file can also be downloaded here

Bidirectional information processing through the Spine Framework.

The flow of information for a spine based invocation is simplified for the developer. The flow is characterized in the manner below:

Data is returned back to the invocator using these same objects in reverse order, which the invocator can then send to the display mechanism (View) in use.

The data sent to spine must be packaged in a recognisable manner, and the data received from the framework must also conform to the predefined object type required by the system.

For the input, the object sent to the system must implement the interface DataTransferObject(dto) and the output received from the system may be one of ResultObject or DataTransferAssember.

ResultObject is a concrete implementation of DataTransferAssembler, which will usually fulfill most data requirement needs. It should be noted that in most instances, Spine requires the client developer to create subclasses of some of the objects in the process flow (In some instances, a user defined ViewProcessor or MultiViewProcessor may be needed to service a request).

An additional object whose main purpose is to manage the life cycle of DataAccessObjects (DAO) may also need to be defined, where the data store in use is not a recognizable type to the framework.

This object is known as a DataProxy and subclasses exist within the application to instantiate,run and garbage collect DAOs.
DataProxies provide initialisation properties and other life cycle methods for DAOs. All the developer need do, is implement the DAO interface or extend the base DAO for a data store type and then state which DAO and proxy are in use for a process within the configuration file.( spine.xml).

For additional information on how to create files to service an invocation, please read the user guide.

Data security and identity recognition

Spine does not manage identities but provides predefined principal and role entity objects ( Member and subclasses of Member) which are capable of been used in your applications without a need for extension. These objects all possess accessors useful for storing various entity data with the additional capability to add extensions by means of an adapter( Member objects can save an undefined object).

Member objects also possess the ability to store role and administrative information i.e a user can belong to several Groups(Roles) and possess several Administrators. Each role(Group) also has a super Adminstrator (the group user identified by userName) and all roles are subject to the control of a root administrator.

Each Member is intrinsically tied to a Permission object which stores all security and role/principal information relating to that role/principal and inherits all the properties of the base security object recognised by the Spine framework( SpinePermission).

The core object provided by spine is the SpineBean which possesses minimal auditing and security properties.
It is associated with the SpinePermission and requires that the permission contained within the bean be initialised with the permission object properties belonging to its principal creator.

This ensures that other principals who wish to use an initialized SpineBean merely need to call one of two methods of the SpinePermission to determine if the principal has access to the SpineBean.

Spine does not impose security in any of its processing but leaves the job of invoking security properties of its objects to whichever application requires it. For further reading please consult the user guide.

Architectural mechanisms to ease future extensions or modifications.

Most objects within spine are designed to be extensible, particularly objects which participate in the process flow. Singletons will usually allow for the use of a decorator so client developers can add more features to extend the capability of the object.

Spine is designed to be used as a framework for creating new applications for which it's extensibility  is a major criteria and developers are expected to build applications using a set of objects whose co-existence is based on a varied number of tried and tested design patterns.

Copyright (C) 2008 Zphinx Software Solutions , all rights reserved