Customizing Illudium CFCGenerator XSL to fit your needs

Aaron and I are about to start work on a super-top-secret project (oops! Man I suck at secrets) in which we will be making use of Amazon ec2 and SimpleDB platforms using an Apache/Tomcat/OpenBD setup. Considering the fact that in spite of the coolness of amazon services in production, it seems to be somewhat of a problematic platform to develop on.

So, until we have a a somewhat functional alpha release, we probably will do all the development that we can on local setups. One of the immediate questions was in regards to how we would set up our CFC data model. We tend to be fans of the Service/Bean/DAO/Gateway approach, but things change a bit when it comes to using Amazon SimpleDB. We came to a decision that our best bet would be to have abstract DAO/Gateway classes that would in turn call the appropriate specific DAO/Gateway classes, so if we are working in development the path would be: Service–> AbstractDAO–> MySQL-DAO and in production it would be Service–> AbstractDAO–> Amazon-DAO. To make the change only need to alter a ColdSpring property “databasetype” from “mysql” to “amazonbd”. Notice the “BD” at the end of Amazon? That is because this is not only an Amazon data object, but one that is actually designed for use with OpenBD to make use of the <cfquery dbtype=”amazon” /> functionality! Down the line we may add other specific subclasses as well as we need.

One other approach that Aaron and I live and die by in our objects is to steer clear of custom code into our generated CFCs. If you ever make changes to your database or objects in general that require you to re-generate them, it can be a real pain in the ass to make sure that you don’t overwrite custom code that you spent precious hours on. Our solution to this is to have all of our Bean/DAO/Gateway/Objects extend base classes so that if you have a UserDAO.cfc there would also be a BaseUserDAO.cfc which would be generated as an empty object. We can then safely stuff all sorts of custom functionality in that base object, such as hasMany relationships/methods, etc, and then later regenerate the DAO itself on a whim, typically without repercussions whatsoever.

With all of this functionality, we now end up with a ton of CFCs in each package, but the flexibility gained is well worth it. Just how many? Well in the example of a User, we would have:

  • User
  • BaseUser
  • UserService
  • BaseUserService
  • UserDAOAbstract
  • BaseUserDAO
  • UserDAOMySQL
  • UserDAOAmazonBD
  • UserGatewayAbstract
  • BaseUserGateway
  • UserGatewayMySQL
  • UserGatewayAmazonBD

For those that have used and know Illudium, you know that the templates it comes with don’t fit these patterns!  I decided that I would set out to *make* it fit.

Of course I took the first tool I could grab in my toolbox – my sledgehammer – and started hacking into the Flex code trying to figure out what exactly I could change to make this work.  After more investigative work than I would like to admit, I realized I didn’t need my sledgehammer at all!

Brian Rinaldi has written such a flexible tool that I needed to do no more than create a new set of XSL templates to fit my needs and the rest would all fall in place.  If you look in the illudium code under cfcgenerator/xsl, you will find a folder named “projects”.  For some reason it never hit me previously what populated the “Template:” dropdown in the UI, but this list is generated from directories that lie under “projects”.  I then took a copy of the default XSL templates and put them in a new directory named “subclassed_data” since that is kind of the general goal of this.  By adding new XSL docs,  modifying the existing ones, and then making sure all the files I wanted to generate were listed in yac.xml, I easily acheived what I was after.  Here is the end product of XSL…

Really the only limitation I came across is that I was never happy with the casing that I ended up with.  We typically use camel casing in our objects like UserDaoMysql.  Given the way that Illudium works it would come out as UserDaomysql.  Considering that fact, I opted for making the end products of my CFCs all lower case.  Thankfully with ColdSpring I never actually see the casing of my filenames, so I think I can live with that.  To make this happen, I ended up changing the only line of the Illudium codebase so that it would force lowercase to the filenames that it saved.

At this point, the only remaining thing that I may do is alter the Illudium UI.  Why?  Take a look at this!