By Peter Bell

Want to Get Started with Code Generation?

There are a number of specific code generation tools in the CF world, but there isn't a general purpose code generation tool.

Over the next couple of days I'll be re-building and republishing CF Gen as a general purpose tool for code generation projects in CF. This posting introduces the steps required to implement a general purpose code generator and would be useful for anyone interested in getting started with code generation . . .

A Overview of Code Generation
The purpose of a (Model to Text) code generator is to take some kind of metadata, apply it to a set of templates and use those to generate a number of files. To build a specific generator, you need metadata, templates and a workflow.

ColdFusion allows you to take data and generate files using cfml templates. For example, you might take product data from a database and run that through a product.cfm display template to display the product detail pages for all of the products in a commerce store.

Code generation is pretty similar, only instead of the output being HTML that is sent to a browser, you use some kind of metadata together with a template (usually a .cft or .xslt file in the CF world) to create files that will be saved to the hard drive. Most of the files for a ColdFusion project will usually be .cfc's or .cfm's, although you may well also generate .sql, .xml and other file types as part of the process of generating an entire application.

Metadata
The starting point is the metadata. Most existing projects use database introspection to generate their metadata by looking at a db schema. That is one approach, but a more flexible approach is to allow any kind of metadata so if you want to use a UML modeling tool, write your own external DSL using XML or store metadata statements in the database you could still use them with the generator.

Template
You could use .xslt templates, but I find that CF Template is the easiest way to take advantage of the power and simplicity of ColdFusion for your code generation templating. Templates for code generation just have to support accessing the metadata, looping over collections and conditional statements, although CF template allows you to do anything you can do in CF including calling objects, using UDFs, using CF functions, writing cfscript blocks, etc.

Workflow
There are broadly two ways to implement a code generator. In tools like MetaEdit, it "walks the model", going through the model, generating the necessary code as it goes through.

I've taken the general approach used by openArchitectureWare of having a workflow description as I found that an easier approach to get started with.

If you look at most code generators, you could generalize what they do as follows:

For each step

  • Get Metadata
  • Get template
  • Iterate over iterator
  • Generate one file/snippet per instance
So, for example, the first step might be to create a DAO for each entity, iterating over a collection of metadata describing the entities in the model and creating a DAO for each one. The next step might be to create a service class for each entity, and then the next step might be to generate a controller class for each controller required by the application.

In practice this fairly simplistic workflow description allows you to solve a pretty wide range of problems - especially when you remember that the collection you iterate over can have 1..* elements, so if you want to generate a single config file, you just "iterate" over a collection with only a single record.

Thoughts? Making sense?

Comments
I've been playing with code generation over the last couple of months, gradually refining and refactoring my code, and it's good to see that I'm mostly on the right track, even though I didn't really research anything...

I started off with some crude meta data (mostly lists) and was just generating chunks of code. But over time you get to see more and more patterns emerging, so you progress to storing more complex metadata (structs, queries) and come up with some meta data to handle edge cases, apply some logic to them, and finally you get to the stage where you can spit out complete .cfm files that just work.

My next step is to refactor the templating, because using skeleton files and evaluated strings is just a little bit messy. I think I should give CFTemplate a try, thanks for the tip :)
# Posted By Justin Carter | 7/15/08 6:13 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.005.