By Peter Bell

Mixing Hand Written and Generated Code

If you want to create an active application generator, one of the first problems you have to solve is how to mix hand written code with generated code.

An active generator needs to be able to re-generate its files at any time. Because of this you need to find a way that regenerating the generated files won’t wipe out any hand written modifications. It is possible to write files with “protected” areas of code and other areas for adding custom comments and up to a couple of years ago that seemed to be the most common approach.

I never really liked that approach as ColdFusion isn’t a great tool for writing a parser and I’m not that good at Regular Expressions! It also seemed to be a little fragile. It would break if a developer accidentally deleted one line too many and removed just one of the “protected code markers”.

When I saw Hal Helms presentation on mixins back at cf.objective() this year, at first I thought I’d seen a better solution. With mixins, you can take advantage of the flexibility of ColdFusion to put a cfinclude statement within your classes. This means that you can generate the classes somewhere safe and allow programmers to write any custom methods to extend the core generated methods.

Unfortunately, mixins don’t allow you to overload generated methods with custom methods (which is a pretty common requirement). You get a huffy “Routines cannot be declared more than once” from ColdFusion, so that was that for mixins to separate hand written and generated code (they are still interesting in their own right). Then I had a look at Doug Hughes excellent ORM generator (Reactor) and saw a beautifully elegant solution (which I have since seen on a commercial .NET generator as well) – inheritance.

Let’s say you want to generate a set of DAO’s and you name them %EntityName%DAO.cfc. Create two directories – one for generated code and another for custom code and create two script templates – customEntityDAO.cft and generateEntityDAO.cft (CF Templates).

They should both create cfc’s with the same name, so for the user entity you might have %applicationname%.com.custom.model.dao.UserDAO.cfc and %applicationname%.com.generated.model.dao.UserDAO.cfc. Now just make sure that the custom DAO extends the generated DAO and always call the custom DAO. That way if you want to overload or extend a method or property, you can just manually set it in the custom DAO and it’ll overload/extend the generated class while keeping hand code and generated code nicely separated.

Comments
BlogCFC was created by Raymond Camden. This blog is running version 5.005.