What is ColdBox?

ColdBox is a proven MVC event-driven CFC based ColdFusion Framework, specifically designed for high availability web applications. ColdBox is a solid software foundation on which you can build your applications on. It provides you with a set of reusable code and tools that you can use to increase your productivity, and it provides you with a development standard that comes in very handy when working in a team environment. The purpose behind ColdBox was to create a fast & stable development methodology that could be shared among several developers. It makes use of an MVC (Model View Controller) design pattern implemented via CFCs and an extensive array of patterns for its operations such as Factories, Helpers, Workers, etc. And since it is based on CFCs it does not rely on an XML dialect.

It uses event handler CFCs, which are CFCs that hold all the code necessary to prepare views (html/JSON/xml), call internal/external Business layers, use ColdBox plugins, and redirect requests. You can consider the event handlers to be all that code you had on top of your templates, but now moved to an Object Oriented pattern.

In this article you will have an overview of the main components of this Object Oriented Framework.

ColdBox Service To Worker Diagram

Features & Capabilities

Please see the Features and Capabilities Guide for an in depth overview.

System Requirements

Below is a quick overview:

Supported CFML Engines are

  • Adobe ColdFusion 6.X and greater
  • BlueDragon 6.X and greater
  • Railo 2.0 and greater

Supported OS

  • Any OS that ColdFusion runs

Please see the System Requirements Guide for an in depth overview.

What are some of ColdBox's Novel Features

Aspect programming

ColdBox comes bundled with a set of plugins that will help you on every day software application tasks like bug reports and notifications, AOP file logging with auto-archiving, a way to sense your environment as either dev or production, storage facilities for cluster environments, object caching, datasource declarations, web services integrations, and internationalization. And this is how ColdBox can be very EXTENSIBLE because they are all plugins that can be loaded on the fly and it allows the developers to have the ability to create small libraries which can be reused on any project.

Coldfusion Controllers instead of XML Controllers

ColdBox doesn't rely on xml declarative logic where you have to define the event and what happens next. You basically expose methods on an event handler cfc by turning their access to public or remote. The framework then will auto-register the handler cfc's and now you are able to use the methods as ColdBox Events. So the declarative logic is now placed within the methods, where you can place method exit points, what business logic to call and what view to render or what event to surrender execution to. This is how ColdBox can help you create multi-layered applications with one single skeleton and configuration file. So instead of working with a long and complex configuration file all the time, you are mostly working with cfc's all the time. You would use the configuration file to setup your project or maybe tweak some settings.

Handler Packages

ColdBox introduces Event Handler packages where you will be able to organize event handlers by application or task and ColdBox will auto register them for you. This means that you can use the same application skeleton for a blog, a forum, a website, etc, without writing any configuration files for each and trying to mesh them all together. There is no need for that, you can gradually make your application grow and extend its functionality just by dropping in more handlers and views to it. Drop and Play baby!!

ColdBox Dashboard

The ColdBox Dashboard application is a visual application that helps you configure your framework installation. It is also a self-documenting application that will help you learn about the framework. You can modify all of the framework configurations, read documentation, it is tightly integrated to this site for you to search the wiki, svn repository, and ticket reports, and much more. (Different License then The ColdBox Framework)

ColdBox Caching

ColdBox cache is new for version 2.0.0 and it just simplifies object and data caching. You have several tuning parameters for the cache and also cache reports in the debugging panel. You can actually see how many objects and what type of objects are in your cache, the efficiency of your cache and the tuning parameters. This feature will help developers save time and actually not have to worry about persistence. 2.5.0 introduces the idea of event caching, in which the HTML output events produce will be cached by the framework and presented to users. This will enhance applications and system stability. The best part of it, is that you use metadata in the cfcomponent and cffunction tags to actually declare caching parameters. That is it!!

//Example, timeouts are in minutes.
<cfcomponent name="myHandler" cache="true" cacheTimeout="40" cacheLastAccessTimeout="15">

<cffunction name="dspBlog" returntype="void" output="false" cache="True" cacheTimeout="30">

Custom Conventions

With ColdBox you can now define your application layouts and conventions. You can even do this from the ColdBox Dashboard. This gives great flexibility to developers who are used to their own application layouts and conventions. Conventions are also used for registering events, interceptors, plugins and much more.

Event Handler Unit Testing

ColdBox is a framework based on objects and Unit Testing is an integral part of development, then why shouldn't you be able to unit test your handlers? Well, with the introduction of version 2.0.1, Handler Unit Testing is now possible.

ColdBox Proxy: Flex/Air/Remote Integration

The ColdBox proxy enables remote applications like Flex and AIR to communicate with ColdBox and provide an event model for those applications. This feature lets you create an event driven model that can easily be called from within any flex/air application. Not only that, but you can reinitialize the entire application, get settings, and yes, announce custom or core interceptions. You can create custom interceptor chains for your model that can be executed asynchronously when a user hits a save record button for example. You can create a Service Layer with built-in environmental settings, logging, error handling, event interception and chaining, you name it, the possibilities are endless.

Not only that, but this enables you to actually create two front ends using the same reusable ColdBox and model code. The code is the same, you create event handlers, you interact with a request collection, with core and custom plugins, but you don't set views or layouts because the framework is now a remote framework for your model. So what do you do, well, return data, arrays, xml, value objects. Anything, right from withing the event handlers or setup a configuration setting that tells the framework to always return the request collection.

How ColdBox Works?

ColdBox uses both implicit and explicit invocation methods to execute events and render content; ColdBox is an event driven framework. You have one single xml configuration file: coldbox.xml.cfm, from where you can configure your entire application (No logic, just configuration data). You can use ColdSpring, Transfer, Remoting, CRUD, Bean/DAO Factories or any other technology and/or pattern that you can think off with ColdBox. However, ColdBox does make you adhere to an application directory structure based on conventions that are fully customizable. This is done with the purpose of creating a standard for all developers in the same team to share and for ColdBox to find what it needs. Remember that this framework will not solve your problems. It is a standard, a foundation on which to develop on and thanks to its software programming aspects that it provides, this framework can also be a development toolkit. However, it is up to you to create GOOD code, this is not a magical framework that will make your code better. It will help you, but at the end of the day, it is your responsibility.

ColdBox makes use of the Front Controller design pattern as its means of operation. This means that every request comes in through a single template, usually index.cfm. You can choose another file from index.cfm, but that is up to you. Once a request is received by the framework through this front controller, it will parse the request and re-direct appropriately to the correct execution paths.

You are only limited by your ingenuity

Implicit & Explicit Invocations

ColdBox Events can be registered for execution in two different ways. Events can be registered for the following events via the configuration file, which are run implicitly:

  • Request Start Handler (simulates onRequestStart)
  • Request End Handler (simulates onRequestEnd)
  • Application Start Handler (simulates onApplicationStart)
  • Session Start Handler (simulates onSessionStart)
  • Session End Handler (simulates onSessionEnd)
  • defaultEvent (The default event to execute)
  • onException (The event to execute when an exception occurs)
  • onInvalidEvent (The event to execute when an invalid event is detected)

There are also two more implicit convention method declarations that can be executed by just writing the following methods inside of a handler cfc:

preHandler Executes before the requested event (In the same handler cfc)
postHandler Executes after the requested event (In the same handler cfc)

The other method to register events are via explicit declarations in your event handlers, which are CFC's. From these events, you declare what business actions to invoke, what view to render, call/use plugins, and if more events need to be executed (chaining). All these actions are done explicitly, you define them in CF code and not in XML Dialect. The ColdBox controller then implicitly renders layouts/views that where set by the event handlers and finalizes execution.

One thing to note, is that the event handler's events (methods) are very loosely coupled from each other. They interact on their own and do what they need to do and surrender execution to the framework. I believe that you will get a better understanding of Implicit Invocation by reading this great document by Ben Edwards from the Mach-II project.

http://www.mach-ii.com/downloads/docs/Intro%20to%20Implicit%20Invocation.pdf

As you can see, due to the nature of event handler's written in ColdFusion, you have explicit declarations that would otherwise be implicit if done in an XML based dialect. Thus, the cohesion between implicit and explicit. At the end of the day, ColdBox is based on events and cannot function without them.

Below is a quote by Oscar Arevalo concerning ColdBox's functionality:

ColdBox takes a more direct approach to determine what gets called and when; yes, this adds some coupling between the views and the event handlers, but the benefit is that the amount of indirection and obfuscation is reduced; resulting in what I think is one of the biggest benefits of ColdBox: that you actually program in coldfusion, and not in some XML dialect. This results in applications that are very easy to follow, even if the framework is not there." by Oscar Arevalo

The request lifecyle

This section describes how the framework executes an incoming request. This will give you a roadmap of where you would like to place interceptors, module calls, security, etc.

For each request, the following cycle occurs:

  1. Is the framework initialized?
    1. False: Initialize framework (Creates controller, internal structures, and prepares for requests) then Goto step 4.
    2. True : Goto step 4
  2. Is the config auto reload flag set to true?
    1. True : Initialize Framework then Goto step 4
    2. False : Goto step 4
  3. Is the handler index auto reload flag set to true?
    1. True : Register handlers index then Goto step 4
    2. False : Goto step 4
  4. Capture Request and create request context
  5. Does the Application Start Handler exist and has it not fired yet?
    1. True : Execute Application Start Handler then Goto step 6
    2. False : Goto step 6
  6. Execute the preProcess Interceptors
  7. Execute the Request Start Handler if it exists
  8. Execute the preEvent Interceptors
  9. Execute the handler.preHandler() event if it exists
  10. Execute the handler.event()
  11. Execute the handler.postHandler() event if it exists
  12. Execute the postEvent Interceptors
  13. Execute the Request End Handler if it exists
  14. Execute the preView Interceptors
  15. Render the View/Layout Combinations
  16. Execute the postView Interceptors
  17. Execute the postProcess Interceptors
  18. Are we in debug mode?
    1. True : Render the debugging panel
  19. END

Configuration File (coldbox.xml)

ColdBox is configured for operation via a single xml file. You can define the major settings for your application, what features to use, etc. You need to read the following guide to understand much better the possibilities with ColdBox

Event Handlers (cfc's)

ColdBox Event handlers are cfc's that act as your application controllers. Most of this topic is covered in the Event Handlers Guide. Here is a brief introduction:

  • First of all, these cfc's must extend the coldbox eventhandler base cfc: coldbox.system.eventhandler
  • If they implement an init method, then they must call the base class constructor using the super method. Remember that if you implement an init method in an event handler. All the methods executed from this handler will run the constructor code. Below is the format as of version 2.0.0 of how an init method (IF USED) should be written.
<cffunction name="init" access="public" returntype="any" output="false">
  <cfargument name="controller" type="any" required="true">
  <cfset super.init(arguments.controller)>
  <!--- Your constructor code below--->
  <cfreturn this>
</cffunction>

  • The cfc's must be placed in the handlers directory under your application. See cbDirectoryStructure
    • Since version 2.0.0 you can now create handler package directories and organize your handlers into packages.
  • Then you need to create methods that will respond to events. ColdBox uses the event action variable on form submits and url parameters to determine what event to execute.
  • Handlers will be cached by the framework and cache metadata can be attached to their cfcomponent declaration.

The format of this event variable is {event_handler cfc}.{method}

This looks very similar to a java/cfc method call, example: String.getLength(), but without the parenthesis. The framework on initialization will read your handler directory and register the available handlers. Once an event is detected to execute, the framework will validate both the handler and the method. Therefore, in order to expose an event to the framework, just create a method in your cfc with public or remote access. This allows for using the framework with remote interfaces.

Anatomy of a Handler Method

Below you can see the anatomy of an event handler method:

Each method receives the request context object which holds the framework's request collection data structure, explained below. This data structure is where all form/URL and set variables go into. It is what defines a specific user request. (More below in the next section) So in order to interact with the request collection, you would do it via the request context. (See ColdBox API). For example, I want to extract a variable I would use something like:

<cfset var myName = Event.getValue("myname")>
<!--- Alternative method --->

<!--- I get a local reference to the collection, easier to type --->
<cfset var rc = Event.getCollection()>
<cfset var myName = rc.myName>
<cfset rc.myLastName = "Majano">
<!--- Or long syntax --->
<cfset Event.setValue("myLastName","Majano")>

As you can see from the code samples above, there are several ways a developer can interact with the request collection. I usually use the local reference and then use the local rc scope. Easier to read and type. (I am lazy) See cbDirectoryStructure cbEventHandlersGuide

Request Collection

ColdBox also uses a request collection data structure where all variables can be stored and shared among an execution request. The Request Collection is a central repository of information that is refreshed on every user request with the request's information. This is how data gets moved around from event handlers to views and layouts to plugins and anything running inside of the framework. The object containing the request collection is the request context object found at coldbox.system.beans.requestContext.(See ColdBox API). Not only can you use the request context object but you can decorate it! You can expand its functionality according to your needs with the introduction of ColdBox 2.5.0, please read the Request Context Decorator Guide to help you learn more.

Plugins

Another important ColdBox feature is the use of a plugin library of CFC's that extend the normal usage of ColdBox to application specific tasks but without hindering system performance. These plugins are reusable components that your applications can use and can be loaded on demand via a Plugin Factory. Some samples are: i18n, resource bundles, refresh a webservice stub, Bug Reports, java file utilities, etc. This is a major difference between ColdBox and any other framework, in that it gives you a set of reusable on-demand components for tedious or repeatable application-specific tasks. Thus, the toolkit aspect of ColdBox.

Also, not only can you use and modify the plugins that come with every ColdBox installation, but you can create your own. You are not limited anymore, you can extend the framework to your needs. You can create as many plugins as you want and build a plugins library that can be located by just specifying it on the configuration file or loaded up via conventions. You will then be able to get the plugin and use it on any of your ColdBox applications. The best part of it all, is that the plugin will inherit all of the framework's functionality, so you have everything that you need to be able to code.

How easy is it? well, you just do the following:

  • Make your plugin cfc extend coldbox.system.plugin
  • Create an init method with the following standard code:
<cffunction name="init" access="public" returntype="coldbox.system.plugin" output="false" cache="{true or false}" cachetimeout="{x in minutes}">
        <cfargument name="controller" type="any" required="true">
        <cfscript>
        //Set controller reference
        super.Init(arguments.controller);
        //Plugin Name
        setpluginName("Name of the plugin");
        //Version of the plugin
        setpluginVersion("1.0");
        //Small description
        setpluginDescription("I am a simple bean factory");
        return this;
        </cfscript>
</cffunction>
  • Create your methods and WALLAH!!! You are done and you can call any of the inherited methods from coldbox.system.plugin.cfc
  • You can also declare caching metadata in the cfcomponent declaration, so ColdBox will persist your plugins.

An interesting side of plugins is that they do not get injected with the request context, so how do they interact with it? Well, very simple, by going to the Request Service. The Request Service is an integral part of ColdBox, in that it abstracts interaction with the request context and collection. So in order to get a reference to the current running request context all you would do is the following:

<cfset var myContext = controller.getRequestService().getContext()>

That's it! By looking at the ColdBox API you can see all the methods for the Request Service. This technique would also apply to handlers, where you can get the context from the service. A good example, would be by using it on a private method.

Please see the Creating My First Plugin Guide for more information

Interceptors

ColdBox interceptors increase functionality for applications and framework alike, without touching the core functionality, and thus encapsulating logic into separate objects. This pattern wraps itself around a request in specific execution points in which it can process, pre-process, post-process and redirect requests. These interceptors can also be stacked to form interceptor chains that can be executed implicitly. The chaining is all about positioning in the configuration file. The order of declaration is very important. These stacked interceptor chains form a chain of separate, declaratively-deployable services to an existing web application or framework without incurring any changes to the main application or framework source code. This is a powerful feature that can help developers and framework contributors share and interact with their work.

Interceptors are a great compliment to ColdBox plugins, in which now they can be used alongside of them and implicitly add functionality to a ColdBox application. Another important aspect to note is that Interceptors have full access to a request's lifecycle and the framework. Thus, they can get application settings, redirect control, execute events, use the cache manager, get plugins, transform views, adapt views for certain protocols and much much more. Please read the full Interceptor's Guide for an in-depth tutorial.

Interceptor Class Diagram

Interceptor Sequence Diagram

For what can I use them

Below are just a few applications of ColdBox Interceptors:

  • Security
  • Event based Security
  • Method Tracing
  • AOP Interceptions
  • Publisher/Consumer operations
  • Implicit chain of events
  • Content Appending or Pre-Pending
  • View Manipulations
  • Custom SES support
  • Cache advices on insert and remove
  • Much much more...

Much more than Interceptors

However, we went a step further with interception points and created the hooks necessary in order to implement an observer/observable pattern into the entire interceptor service. Ok ok, what does this mean? It means, that you are not restricted to the pre-defined interception points that ColdBox provides, you can create your own! WOW! Really? Yes, you can very easily declare execution points via the configuration file, create your interceptors with the execution point you declared (Conventions baby!!) and then just announce interceptions in your code via the interception API. The power of conventions. However, not only can you intercept at an execution point, but you can actually send a structure of intercepted data right into the interceptor.

Core Interception Points

As you can see from the diagram, there are several core interception points that you can tap into. Below is a simple chart for you to understand these interception points.

Interception Point Description
afterConfigurationLoad This occurs after the framework loads and your applications' configuration file is read and loaded. An important note here is that your application aspects have not been configured yet: bug reports, ioc plugin, logging, and internationalization. This is a great interception point to load custom configuration settings per tier. Tier control plugins should tap into this point.
afterAspectsLoad This occurs after the configuration loads and the aspects have been configured. This is a great way to intercept on application start. You can also use the application start handler setting and point to an event. However, if you want to have separation and even chaining, this is the way to do it.
preProcess This occurs after a request is received and made ready for processing. This simulates an on request start interception point. Please note that this interception point occurs before the request start handler.
preEvent This occurs before ANY event execution, whether it is the current event or called via the run event method. It is important to note that this interception point occurs before the preHandler convention. (See Event Handler Guide)
postEvent This occurs after ANY event execution, whether it is the current event or called via the run event method. It is important to note that this interception point occurs after the postHandler convention (See Event Handler Guide)
preRender This occurs before the main set view/layout combination is rendered. A great way to transform output or inject output.
postRender This occurs after the main set view/layout combination is rendered. A great way to finalize output transformations or inject your own output.
postProcess This occurs after rendering, usually the last step in an execution. This simulates an on request end interception point.
sessionStart This occurs only when using an Application.cfc application, because it models the onSessionStart method
sessionEnd This occurs only when using an Application.cfc application, because it models the onSessionEnd method
afterCacheElementInsert This occurs when a new element is inserted into the coldbox cache.
afterCacheElementRemoved This occurs when an element is removed or expunged from the coldbox cache.
afterPluginCreation This occurs right after a plugin gets created by coldbox
afterHandlerCreation This occurs right after a handler gets created by coldbox

Conclusion

I hope that this overview gave you an insight into how powerful ColdBox is for building your web applications. It is a new generation framework based on conventions that will increase your productivity and adaptability in a team environment. So download it and give it a shot.


Copyright 2006 ColdBox Framework by Luis Majano