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.
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.
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.
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
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?