I have finished coding my application for my hands-on session at 360:Flex Atlanta. The goal of the session is to walk attendees through building a simple application. You may download the source code for Surfing Stats using the download link.

The Flex framework is very powerful and offers lots of powerful functionality. I had trouble limiting myself in scope. I only have 4 hours to teach so I want to make sure I leave the students with a functional and instructive application.

Without futher ado, I want to introduce Surfing Stats. This application consumes XML data from my BlogCFC installation at www.nodans.com and displays the data in table, bar chart and pie chart format. Each dataset is represented as a tab. Clicking on the tab enables the relevant display options.

In the next few weeks I'll wrap up the course materials of the session. I'll probably blog some to finalize my thinking on the session. I do not expect to trim any base functionality of Surfing Stats, though there are several fancy add-ons in the current version we will cover should the class progress at a quick pace.

As a reminder, 360:Flex Atlanta will be held February 25-27, 2008 in Atlanta, GA. If you would like to learn how to build an XML fed charting application with the Flex Platform, attend my hands on session.

Dzone.com is a great resource for developer related content. As a clever way to share interesting links, anyone can submit content to be voted up or down. I've recently added all my tutorials to date on dzone.com

Using Transfer with MG:U is quite different than hand coding all the data access instructions so I separated out the new Transfer enabled code from the old hand coded bits to help compare similar operations between the two styles.
This means the ContactOMatic is not an example of Architectural Purity! Shock! Horror! Gasp!

To make the separation, I added another ModelGlue configuration file, named ContactAction.xml, to the main ModelGlue.xml file through the use of the include tag as follows:

Today we will install the Transfer ORM inside our Contact-O-Matic application.
To complete this tutorial, you should have the Contact-O-Matic installed and running.
If you have not completed this step, please create the database described at the bottom of Series 6 and install the files at Series 10 download link.
Test the application by manually adding several ContactTypes to the ContactType table in your database (I chose Co-Worker, Enemy, Friend). Then use the Contact Form in the ContactOMatic application to enter a few contacts.

I am going to continue the 'So You Wanna Create a Model Glue Application series. (Thanks Lola ;)
For those just tuning in, the Contact-O-Matic is a simple example of a mini-application using ModelGlue and ColdSpring.
The tutorials on the Contact-O-Matic go through the code line by line showing how to perform such tasks as:

Set up the frameworks

Build a View

Place your CSS and JS files

Create a form

Validate a submitted form and persist the data

Return success/error messages

Resolve CFC dependancies with ColdSpring

Create Instance Objects with factories

Refactor, as needed

The Contact-O-Matic is not an example of a Best Practices- Enterprise application.
This is due to the simple nature of the program.
We simply have a list of contacts, a mechanism to add and edit contacts, and a way to remove contacts.
As Object Models grow complex in complex applications, it is important to note that there is no perfect Object Model, only the least annoying set of tradeoffs.
I want the code in the Contact-O-Matic to remain simple, and so it shall.

Our next move is to integrate Transfer ORM into our application.
The next set of posts will cover installation and testing of the Transfer ORM Framework, the inclusion of another 'Contact-O-Feature' in our application as well as some Architectural Techniques.

Sean Corfield pointed out that using ColdSpring to make instance (throwaway) components is quite a heavyweight approach for a simple form bean. He is, of course, correct. Our ContactFormBean is currently created by ColdSpring. In this series, we will add a factory object that will make our instance beans for us. The factory itself will be configured through ColdSpring as well as the configuration for our objects.

This is a very simple factory. It has three methods, GetConfig, SetConfig and getBean. In turn:

Next, open the Controller.cfc file and change each instance (getContactForm, handleContactForm and removeContact) of getModelGlue().getBean("ContactFormBean") to getModelGlue().getBean("InstanceFactory").getBean("ContactFormBean") .

Finally, reinitialize your application and click on the ContactForm tab. You should see your form as before.

A factory might seem like overkill right now, since this is a simple application. However, Factory objects are a good pattern to learn. Our motivation for the factory in this case was to reduce the amount of unnecessary processing incurred by using ColdSpring to make a simple form bean. We could however, expand our factory to take additional parameters and create all sorts of dynamic objects for us.

In our last segment we built the functionality to store our contacts to the database. Now we need a way to edit the information because after all, friends can become enemies, and enemies can become co-workers. We have a good structure in place and these changes will be simple.

In our last series, we moved the ContactTypes from a ColdSpring configured struct, to a database table. This set the stage to move the rest of our persisted data to the database.

As we begin this series our main goal is to have our contacts and lists of contacts stored in our database. Originally, we used in-memory storage as it allowed us a functional application without a database.

In this series, we will introduce two new files, ContactDAO and ContactGW (GW = Gateway). Both components will reside in the *ContactManagerMG.model directory. The ContactDAO will handle the DB work for Creating, Reading, Updating and Deleting our Contacts. Incidentally, this group of functionality is commonly referred to as C.R.U.D. The ContactGW will handle the database work for pulling queries of Contacts. We'll have a function called getContactQuery().

Here is a look at the ContactDAO. Note: we reference the AppConfig inside our ContactDAO so we can use the Application Configuration defined in ColdSpring. While we mostly care about the DSN for now, the flexibility to pull other configuration parameters will come in handy later.

Now we add each component to our ColdSpring configuration. Each component takes one Property, the AppConfig object. Add both beans as new property tags to the existing ContactService bean definition. We will also remove the references to the old Array based ContactList. Let's do a little housecleaning on our ColdSpring file shall we?

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<property name="ContactList"> <list></list></property>1<property name="ContactList">2<list></list>3</property>

Once complete, ColdSpring will run setContactDAO() and setContactGW() on the ContactService component and stuff the proper object in our service for us. We need to change the service a little now to account for this new functionality. Open up the ContactService and make the following changes:

Remove the getContactList() and setContactList() functions. These functions used to manage our Array based contact list from ColdSpring, with our new Database driven Contact-O-Matic, we won't need them any longer.

Now add in the get/set functions for each component. While we are in here, also add in a new function to get our ContactList from our new ContactGW. The function on the ContactGW is called getContactQuery(). When complete, you'll have removed two functions and added five. Examples of the new functions are below:

Now our service has references to the ContactDAO and the ContactGW, in turn both the ContactDAO and ContactGW have references to our AppConfig. All the plumbing for the database interaction is complete.

Previously, we stored the ContactType in our ContactFormBean. This was acceptable when referential integrity was not on our list. Now, we need to modify the Contact Form and the Contact Form Bean to refer to the ContactTypeID instead of simply the ContactType. In the form itself, all we need to do is switch the reference. Inside the Bean there is a tiny bit more to it. We will start with the form.

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<cfcomponent displayname="ContactFormBean" output="false" hint="A bean which models the ContactFormBean form.">

Finally, we need to change how the contacts are saved. In the beginning, we simply appended the ContactFormBean object into an Array of ContactFormBean object and iterated over the array for our ContactList. Now, we need to change the controller function to call the service. We will let the service decide how to handle the save. In the controller located at *ContactManagerMG.controller modify the isvalid branch to call a ContactService method called saveContact()

Now add the saveContact() function into your ContactService. This function will accept a Contact object, being our ContactFormBean, and check to see if the ContactID has been assigned. If so, we will update the record, if not, we will create the record. Your saveContact() function should look like this:

Reset your application and run your new Database Powered Contact-O-Matic. If you've followed all the steps, (and I haven't left any out) you now have a proper application.

We touched a good chunk of the application and I trust this has been a good refresher into the inner workings of our Contact-O-Matic. In our next series, we will include the mechanics to delete contacts from the database.

We are going to break this up into phases starting with the contact types. At the end of this series, our contact types will come from the database and we will have an even greater appreciation for ModelGlue and ColdSpring.

The last article gave the spec for your database tables, Contact and ContactType. Add in 3 dummy records to the ContactType table. I used Friend, Enemy and Co-worker.

Set up your datasource in the ColdFusion administrator. I used the data source name of 'ContactOMatic'. Test the connection and move on.

Now we will need this datasource name inside of our cfqueries. Can anyone guess where we will keep the DSN? Thats right, in ColdSpring. Give yourself a cookie if you got that one right.

Before we begin, change the ColdSpring.xml ModelGlueConfiguration reload setting to true.

ModelGlue has a standard component called a SimpleConfig. The purpose of the simple config is to hold on to a collection of values and this component is easily configured in ColdSpring. The path for SimpleConfig is ModelGlue.bean.CommonBeans.SimpleConfig, so add a configuration to ColdSpring for this. We will refer to this as AppConfig and it will hold our DSN and an AppTitle.

Note for the DSN we used 'getAppConfig().getConfig().dsn', when we want to access the AppTitle later, we'll use 'getAppConfig().getConfig().AppTitle'. (If you haven't seen this syntax before, getAppConfig() returns a reference to the AppConfig Object, which has a getConfig() function returning a struct. Then we access a property of the struct using dot notation.)

Now, adjust the ContactService to call ContactTypeGW. Remove the following functions: init, getContactTypes and setContactTypes. Add get and set functions for our ContactTypeGW. Then add the proper function for getContactTypes. It should return a query so be sure to adjust the returntype to 'query'

Now adjust ColdSpring to account for the new gateway functionality. Configure the bean definition for ContactTypeGW and add the AppConfig property. Replace the ContactType map with the ContactTypeGW bean The changed lines should look like this:

ColdFISH is developed by Jason Delmore. Source code and license information available at coldfish.riaforge.org<cfloop query="ContactTypes"> <option value="#ContactType#" <cfif ContactFormBean.getContactType() IS ContactType>selected</cfif>>#ContactTypes.ContactType#</option></cfloop>1<cfloop query="ContactTypes">2<option value="#ContactType#"<cfif ContactFormBean.getContactType() IS ContactType>selected</cfif>>#ContactTypes.ContactType#</option>3</cfloop>

Remember to reinitialize your application and now run your code. You should now see the ContactTypes defined in your database

It seems like we touched a few files to make this change. We altered the ColdSpring.xml file to have an application configuration object, added in our ContactTypeGW and then stitched them together. We also had to adjust our form to account for a query in place of the struct. Note we did not touch our Controller nor our ModelGlue.xml file. Since the flow of the application did not change, those files remain the same and happily work with the new functionality of the application. This is an example of the benefits of compartmentalized, or encapsulated, code.

A zip of all files is included with this article.

Next, we will create the contact persistance and write our contacts to the database