32
CHAPTER 2
C
ODE
GENERATION
BASICS
2.1.5
Tier or layer generation
In this model, the generator takes responsibility for building one complete tier of an n-
tier system. The case study in chapter 1 included examples of tier generators.
An example of tier generation is model-driven generation, wherein a UML author-
ing application is used in conjunction with a generator and an input definition file
(often in XML) to output one or more tiers of a system.
As figure 2.6 shows, the input and output flow of a tier generator is the same as
with a partial-class generator. The tier generator reads a definition file and then uses
templates to build output classes to implement the specifications in the definition
file. Figure 2.7 shows a tier generator building the data access layer for a three-tier
web application.
Figure 2.5 5 A partial-class generator can be used in a web application architecture.
Figure 2.6
The input and output flow 
for a tier generator
Pdf page size - Compress reduce PDF size in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
C# Code & .NET API to Compress & Decompress PDF Document
pdf change page size; change paper size pdf
Pdf page size - VB.NET PDF File Compress Library: Compress reduce PDF size in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
VB.NET PDF Document Compression and Decompression Control SDK
pdf change font size; pdf compress
T
HE
VARIOUS
FORMS
OF
ACTIVE
CODE
GENERATION
33
The big difference between tier and partial-class generation is that in the tier model the
generator builds all of the code for a tier. In the partial-class model, the generator builds
the base classes but derived classes are still required to finish off the code for the tier.
The primary advantage of partial-class generation is speed of implementation.
The most common difficulty in building a tier generator is designing for special cases,
but with a partial-class generator, you can build a relatively simple generator and
then implement the special cases with custom code. You should think of moving from
partial-class generation to tier generation as a migration path. When the requirements
and design are loose, you may still be able to develop a partial-class generator; after the
problem space is well known—by the second or third release—you can upgrade the
partial generator to a tier generator by migrating the special cases and custom code.
In chapter 4 we describe a simple tier generator, and chapters 6 and 9 present
complete examples.
2.1.6
Full-domain language
full-domain language is a Turing complete language customized to allow engineers to
represent the concepts in the domain more easily. A Turing complete language is a
general-purpose computer language that supports all of the variable management,
logic, branching, functional, and object decomposition abilities included with today’s
programming languages.
Code generation, as the term is used in this book, is about generating large
amounts of high-level language production code based on descriptive requirements.
The end of the spectrum of descriptive requirements is a Turing complete language.
So it follows that the end of the spectrum of code generation is a Turing complete
domain-specific language.
It is outside the scope of this book to describe the implementation of a domain-
specific language. However, let’s look at the pros and cons of taking this route.
The advantage is that you have a very high-level functional description of the
semantics of your solution that can be compiled into almost any high-level language.
As for disadvantages, your team is buying into supporting a new language that you
Figure 2.7  A tier generator builds a full tier of an n-tier web application.
C# PDF File Split Library: Split, seperate PDF into multiple files
Divide PDF file into multiple files by outputting PDF file size. control, C# developers can easily and accurately disassemble multi-page PDF document into two
change font size in pdf fillable form; reader compress pdf
C# PDF Thumbnail Create SDK: Draw thumbnail images for PDF in C#.
public override Bitmap ConvertToImage(Size targetSize). Description: Convert the PDF page to bitmap with specified size. Parameters:
adjust size of pdf file; adjust pdf size
34
CHAPTER 2
C
ODE
GENERATION
BASICS
must maintain and document. In addition, you must train your colleagues in the use
of this language. Also, with a fully functional language it is difficult to generate derived
products (e.g., documentation or test cases). With a tier or partial-class model, the
generator understands the structure and purpose of the class being built from the
abstract definition. With a Turing complete language, the generator will not under-
stand the semantics of the code at a high level, so automatically generating documen-
tation or test cases will not be possible.
The case study in chapter 12, “Generating business logic,” presents a limited exam-
ple of a full-domain language.
An example of Turing complete domain-specific language is the math language
used by Mathematica, a language that supports matrix math in a simple manner.
Using matrix math is difficult in traditional languages such as C, C++, or Java.  Having
a domain-specific language in a product like Mathematica allows the language users
to spend more time concentrating on their problem by enabling them to present their
code in familiar domain-specific terms.
2.2
C
ODE
GENERATION
WORKFLOW
As shown in figure 2.8, the classic workflow for developing and debugging code is
“edit, compile, and test.” Figure 2.8 shows the edit, compile, and test workflow that
cycles between the three states. Code generation adds a few new workflow elements, as
shown in figure 2.9. The edit, compile, and test phase still applies for all of the custom
code that is either used by or makes use of the generated code.
Figure 2.8 8 The edit, compile, 
and test workflow
VB.NET PDF File Split Library: Split, seperate PDF into multiple
Separate source PDF document file by defined page range in VB.NET class application. Divide PDF file into multiple files by outputting PDF file size.
change page size of pdf document; adjusting page size in pdf
VB.NET PDF Thumbnail Create SDK: Draw thumbnail images for PDF in
Program.RootPath + "\\" 1.pdf" Dim doc As PDFDocument = New PDFDocument(inputFilePath) Dim page As PDFPage = doc.GetPage(0) ' Define the size of the
best way to compress pdf files; change font size on pdf text box
C
ODE
GENERATION
CONCERNS
35
The left-hand side of figure 2.9 shows the generation workflow. First, you edit the tem-
plates and definition files (or the generator itself) and then run the generator to create
the output files. The output files are then compiled along with the custom code and the
application is tested.
If your target language is not a compiled language, then simply disregard the
compile phase in the diagrams.
2.2.1
Editing generated code
Unless you are using the inline-code expander model (in which the output files are
used in the generation cycle), you should never edit the output files of the generator
directly. Generators completely replace the output files so that any revisions to the out-
put files created by the previous generation will be lost. For this reason, we recommend
that you bracket in comments the implementation files that are output, to specifically
warn the user not to edit them.
There is one exception to this rule. When you are debugging the code in the tem-
plates it is easier to edit the output files, diagnose the problem, and then integrate the
fix back into the templates.
2.3
C
ODE
GENERATION
CONCERNS
No technique is without drawbacks, and code generation is no different. In the follow-
ing sections, we describe some of the issues you may encounter when proposing, build-
ing, and deploying code generators. 
Some of these are fear of the unknown, others are an unwillingness to change, and
still others are well-founded technical concerns. All of these issues will need to be
addressed at some level and at some time during the deployment of a generator. We
list them here to help you with some counterpoints to the criticism.
Figure 2.9
The coding workflow when 
a code generator is involved
C# PDF Convert to Jpeg SDK: Convert PDF to JPEG images in C#.net
Using this C#.NET PDF to JPEG conversion library component toolkit, C# developers can easily and quickly convert a large-size multi-page PDF document to a
change font size in fillable pdf form; pdf page size
C# PDF Convert to Tiff SDK: Convert PDF to tiff images in C#.net
zoomValue, The magnification of the original PDF page size. 0.1f
reader shrink pdf; pdf edit text size
36
CHAPTER 2
C
ODE
GENERATION
BASICS
2.3.1
Nobody on my team will accept a generator
Creating a tool that builds in minutes what would take months to write by hand will
have a dramatic effect on the development team, particularly if no one on the team has
experience with automatic code generation. With a small engineering team or one that
has had generator experience, there probably won’t be any reticence toward adopting
generation. With larger teams you may experience problems. Some engineers may dig
in their heels and swear that they won’t use generators; they may try to influence other
team members as well. Here are suggestions for handling these problems:
• Start small—Take a small section of the code base that requires maintenance and
replace it with a generated version. Ideally, this will be a section of code that
could become larger over time so that the investment in building the generator
has a high payoff. Start with a small section of code so that engineers and
management can see how code generation works and understand the benefits for
the organization.
• Integrate with the architecture—When building a new generator, people often sug-
gest changing the architecture of the application in conjunction with building the
generator. The idea is to kill two birds with one stone. The first goal is to fix the
architecture and the second is to speed up the development process. These find-
ings are welcome of course, but coding more quickly and changing to a better
architecture are two separate issues. Our recommendation for your first code gen-
eration project is to tackle building code in the existing framework. Once you’ve
finished the generator and tested and stabilized the output code, you can alter the
templates to move to a new architectural model.
• Solve one problem—The ideal generator can solve a number of problems in the
architecture and the implementation of a product, as well as accelerate the sched-
ule. If this is the first generator going into a project, you should concentrate on
the schedule issue alone. Taking on several tasks in the first release of a generator
can open up too many issues at once and muddle the decision making. You
should focus your effort on solving one or two key problems.
2.3.2
Engineers will ignore the “do not edit” comments
One of the most common problems with a generated code base is that engineers will
ignore the plentiful warnings in the comments of the file indicating that the code
should not be edited.
I can’t stress enough that your first reaction to someone breaking the “do not edit”
rule should be sympathy. Engineers break the rule because they want to get something
done and either they don’t understand how to run the generator or the generator sim-
ply could not do what they needed. In both cases, you need to educate your team and
perhaps alter the function of the generator to address their reasons for ignoring the
comments. The important thing is not the infraction, but the fact that a team member
C# PDF Convert to Word SDK: Convert PDF to Word library in C#.net
zoomValue, The magnification of the original PDF page size. 0.1f
advanced pdf compressor; pdf page size dimensions
C# Convert: PDF to Word: How to Convert Adobe PDF to Microsoft
Support fast Word and PDF conversion with original document page size remained. Microsoft Office Word 2003 (.doc) and 2007 (.docx) versions are available.
pdf compressor; change paper size in pdf document
C
ODE
GENERATION
CONCERNS
37
was using the code and possibly using the generator—which is a great starting point
for the deployment of the generator.
If engineers continue to violate the “do not edit” rule, you may need to go back
to the drawing board with the generator, the deployment, or both. Engineers who are
conscious of the value of the generator and who understand how the generator works
should not alter the output by hand and expect that their changes will be maintained.
2.3.3
If the generator can’t build it, the feature 
will take weeks to build
Suppose you’ve developed a generator for a user interface builds assembly code from a
set of high-level UI definitions. It builds everything: the window drawing code, the
message handling, the button drawing—everything, right down to the machine code.
What happens when you need to add a dialog box to your UI that cannot be built
with this generator? In the worst-case scenario, you get out your assembly language
manual and go for it.
This is an unrealistic and extreme example, but it proves the point that you always
want your generator building code that sits on a powerful framework. An example is
the Qt cross-platform UI toolkit. Figure 2.10 shows a generator for Qt code.
Should a generator replace the functionality of Qt? No. It should generate code for
Qt from high-level UI definitions: the same high-level UI definitions that can be used
to build the web interfaces that Qt can’t build. There is also nothing wrong with hav-
ing the generator write code that makes use of your own libraries, which sit on top of
powerful frameworks.
As with any software engineering project, you will want to spend the time
picking an appropriate and powerful architecture and development environment.
Using code generation techniques in combination with the right development tools
can significantly enhance the quality and reduce the development time of your appli-
cation development.
Figure 2.10 0 Generating code for the Qt framework
38
CHAPTER 2
C
ODE
GENERATION
BASICS
Figure 2.11 shows a generator that builds to both Qt and a company-specific interface
library. Including code to manage the interface can make the generator run more
smoothly, as well as make it much easier for an implementer to build the dialog boxes
that cannot be created by the generator.
2.4
C
ODE
GENERATION
SKILLS
In this section, we discuss the specific technical skills you’ll need to build generators. If
you are unfamiliar with some of these skills, consider using them in practical code gen-
eration projects as an ideal opportunity to learn them.
2.4.1
Using text templates
Generating code programmatically means building complex structured text files en
masse. To maintain your sanity and the simplicity of the generator, you should use a
text-template tool such as HTML::Mason, JSP, ASP, or ERb. Using a text template
means that you can keep the formatting of the code separate from the logic that deter-
mines what should be built. This separation between the code definition logic and the
code formatting logic is an ideal abstraction, which we maintain in the generators pre-
sented in this book as case studies.
2.4.2
Writing regular expressions
Regular expressions are a tool for searching and replacing within a block of text. Read-
ing in configuration files or scanning source files is greatly simplified by using regular
expressions. Regular expressions allow you to specify a format for text, and then check
to see whether the text matches in addition to extracting any information you require
from the text.
If you have always thought of regular expressions as indecipherable line noise, now
is the time to learn them. The regular expressions used in this book are fairly simple,
and you should be able to learn from the examples in the text through context.
Figure 2.11 1 Generating code for a combination of Qt 
and a company-specific interface library
C
ODE
GENERATION
SKILLS
39
For an immersion course in regular expressions, I recommend the book Mastering
Regular Expressions, by Jeffrey Friedl (O’Reilly, 2002). This excellent book gives you
a solid grounding in the art of regular expression construction. Many people learn to
use regular expressions as invocations of black magic; they use them without knowing
precisely why they work. Regular expressions are an invaluable tool and worth your
time to learn thoroughly. Once you have mastered them, the idea of writing string
parsing code by hand will be forever dashed from your mind.
Appendix F shows examples of regular expressions implemented in Ruby, Perl,
Python, Java, C#, and C.
2.4.3
Parsing XML 
XML is an ideal format for configuration and abstract definition files. In addition,
using schema or Document Type Definition (DTD) validation on the XML can save
you from building elaborate error handling into the file-reading code.
There are two styles of XML parsers: 
• Streaming—Streaming parsers (e.g., Simple API for XML-SAX) send the XML to
handlers in the host code as the file is being read. The advantage is that the mem-
ory footprint is low and the performance is good, allowing for very large XML
files to be read. 
• DOM—DOM parsers read the entire XML stream, apply validation, and then
return a set of in-memory objects to the host code. The memory footprint is
much larger than a streaming parser, and the performance is significantly lower.
The advantage of using a DOM parser is that the host code is much less complex
than the corresponding host code for a streaming parser.
The case studies in this book use a DOM parser because the overall complexity of the
code is much lower with DOM. Performance is usually not an issue because the code
generator is run during development on fast machines.
2.4.4
File and directory handling
Code generators do a lot of file reading and writing as well as directory handling. If you
have had experience only with the Win32 API or the standard C library for file and
directory handling, you may be rolling your eyes at the concept of lots of directory
access. Now is an ideal time to learn the joy of simple and portable file and directory
handling available in Perl, Python, or Ruby.
The most common scripting languages have built-in, easy-to-use APIs for direc-
tory construction, directory traversal, and pathname munging, which work on any
operating system without code alteration or special cases. The same is also true of file
I/O, which is implemented in the core libraries of these languages.
40
CHAPTER 2
C
ODE
GENERATION
BASICS
2.4.5
Command-line handling
Code generators are usually command-line based. They are invoked either directly, as
part of a check-in or build process, or from an IDE. The example code generators
shown in this book are run off the command line.
On Macintosh OS X and other Unix derivatives (e.g., Linux or FreeBSD), the
command line is accessible through terminal emulators. On Windows you may want
investigate Cygwin, which is a Unix emulator that runs on top of Windows. 
2.5
C
HOOSING
A
LANGUAGE
FOR
YOUR
CODE
GENERATOR
One of the advantages of separating the code writing from the production code itself is
that you don’t have to use the same language for both tasks. In fact, it is often a good
idea to use a different language for each task if only to distinguish the generator code
from the code being generated.
Code generators are text processing-intensive applications. A generator reads a
number of text files (such as configuration or template files), uses these files to create
the output code, and stores the output code in production files.
So what makes a good language for building a generator?
• The ability to easily read, parse, and search text files is critical.
• Text templating is fundamental to code generation, which means support for
easy-to-use and powerful text-template tools is important.
• Native handling for XML would be handy, though support through an external
library is acceptable. Today a number of high-quality XML authoring and valida-
tion tools are available. For that reason alone, XML is a good choice for a config-
uration file format. The ability to read and manipulate XML data structures is
therefore essential.
• Easy and portable file and directory maintenance and searching is necessary; it
will be the job of the code generator to find and read input files and manage the
output files for the generated code.
On the other hand, some language factors are not important for code generation:
• Language performance is not a high priority because the code generator itself is
not in production. It is the generated code that must match the performance met-
rics of the project.
• Memory space efficiency is also of little concern because the generator is run off-
line during development.
On the whole, you need a language that is efficient to develop and easy to maintain,
and that supports the range of programming models—from simple scripts to advanced
object-oriented designs. 
C
HOOSING
A
LANGUAGE
FOR
YOUR
CODE
GENERATOR
41
2.5.1
Comparing code generator languages
Table 2.1 shows the pros and cons of using various computer languages for code gener-
ation. The differences in each of these languages make them good for some applica-
tions and not so good for others. 
2.5.2
Using Ruby to write code generators
I have chosen Ruby as the programming language for the example code generators in
this book for the following reasons:
• Ruby has built-in support for regular expressions. Regular expressions are critical
for parsing, searching, and modifying text.
• Ruby has portable file and directory I/O constructs.
• Ruby supports several robust text-template tools, including ERb and ERuby.
• Ruby is easy to read and understand.
• Ruby programmers have access to two superb XML libraries in rexml and
ruby-libxml.
Table 2.1 1 Using computer languages for code generation
Language
Pros
Cons
C
C++
• If the generator is shipped 
to customers, they will not be able 
to read or alter the source.
• The languages are suited to text
parsing tasks.
• Strong typing is not ideal 
for text processing applications.
• The exceptional execution speed 
of C is not that important.
• Directory I/O is not portable.
• XML and regular expression tools 
are difficult to use.
Java
• If the generator is shipped 
to customers, they will not be able 
to read or alter the source.
• The code is portable to a number 
of different operating systems.
• XML tools are available.
• Text-template tools are available.
• Java is not ideal for text parsing.
• Strong typing is not ideal for text 
processing applications.
• The implementation overhead 
is large for small generators.
Perl
Ruby
Python
• The code is portable to a number 
of different operating systems.
• The languages scale from small 
to large generators.
• Text parsing is easy.
• You can use built-in regular expressions.
• The XML APIs are easy to use.
• Text-template tools are available.
• Other engineers will need to learn 
how to create and maintain code in 
these languages.
Documents you may be interested
Documents you may be interested