devxlogo

Creating Portable Applications with Code Generation

Creating Portable Applications with Code Generation

I don’t know about you but when I think about writing applications I think about all of the things I want the application to do for myself or for the customer. What I don’t think about is all of the little details that turn an elegant design into a workable implementation, because so often the beauty of the design gets lost during the implementation process.

Alleviating this loss of design integrity is the main reason I’m so enamored with code generation. By using a program to translate an abstract model of my design into code I can maintain the design and also gain a measure of portability that no single implementation language can provide. While code generation provides many benefits, it’s the portability aspect that I want to analyze in this article.

For those not familiar with the software engineering technique of code generation, I’ll run through a brief introduction. Code generation is the technique of using a program to write production code for you. There are many models of code generator. The example in this article uses an abstract model of the design as input, and it outputs one or more implementation files.

There are four primary benefits to code generation; quality, consistency, productivity, and abstraction. Generated code is of high quality because it is being built using a set of templates. When bugs are found the templates are modified and the bugs are fixed across all of the generated code. Because it uses templates, generated code has consistent naming conventions across all of the output. The technique increases productivity by letting developers spend more of their time on the design and the unique aspects of the code.

Part of the design of the application is abstracted into the generator’s input files; this abstract model can then be ported to other platforms and technologies simply by altering the templates of the code generator.

But it’s the abstraction benefit that is the primary focus of this article, because abstraction is what gives our applications portability. Part of the design of the application is abstracted into the generator’s input files; this abstract model can then be ported to other platforms and technologies simply by altering the templates of the code generator.

To demonstrate this I will use a code generator to build the data access layer of an application with two very different implementation technologies. I’ll begin by defining the design of the database that I am going to generate.

My project is to model a small book collection. This is a valuable tutorial because it contains multiple tables and is realistic enough to serve as a foundation for larger data model and data access layer development. I will first generate the SQL to build this database and then generate C# and PHP database access layers for the database.

C# and PHP are proven application development technologies and they are representative of both a latently-typed scripting language and a strongly-typed system languages. With this example in hand you will be able to generate your database application layer in the language of your choice; you will not be bound to the technology that you begin with.

The model should include the name of the book, the author, and the publisher. Using a normalized relational model, I will need one table for each of those fields. These tables relate to each other as shown in Figure 1.

Figure 1. Tables: You’ll need three tables to hold the information for the book database.

Listing 1 shows a model of Figure 1 in XML.

For simplicity I’ve combined the table definition, the connection information for the database, and the test data, into one file.

More detail about different types of XML nodes is provided in the following table:

Node

Description

The database node includes attributes which describe the connection to the database.

A table node defines a table in the database. It must include a node for each field in the table. This node has the name of the field and it’s type.

If anode is included then this node defines a query that should be associated with the table. Thenode must include a node that defines the SQL for the query, and a set of

nodes for each run-time parameter.

A data node defines a row of test data. It includes the name of the table to insert the data into, as well as a set of nodes which include the data for each field in the row.

Your application may require more information to properly model your database layer. You can easily add this to the code generation templates in this article.

With the data model and test data in hand I can start building the code generators that will turn the design into reality. I’ve chosen PHP and C# as my generation targets, but I’ll also generate SQL for the physical model so that the database schema always remains in sync with the database access layer sitting above it. For the generator I have chosen to use XSLT.

Generating Code with XSLT
XSLT is not just about converting one XML form to another or converting XML to HTML?it can also be used for code generation by building source code as text.

The value of XSLT is that it is a standard and has implementations in a number of languages, making it very accessible. There are a number of books and articles on XSLT. It also helps that with version 1.1 you can create multiple output files with a single XSL template. I’ll start with a simple example stylesheet called ‘simple.xsl’:

    CREATE TABLE ( );  

For this article I’ve used the Saxon XSLT processor (v.6.5.3). To run ‘simple.xsl’ on the ‘schema.xml’ input file the command is:

> java jar saxon.jar schema.xml simple.xsl 

The output looks like this:

CREATE TABLE Book( ); CREATE TABLE Author( ); CREATE TABLE Publisher( ); 

In the process above, the XSL processor searches the templates against each of the nodes it encounters in the input XML. In this case it matches against

nodes within the node. It finds the node because of the match=”schema/table” attribute. Within the template the text is output to standard output. The node tells XSL to output the value of the name attribute into the standard output. The name attribute is specified by use of the select=”@name” attribute. The ‘@’ sign tells XSLT to look for the attribute as opposed to an interior node. The XSL template registers its intention to create text (instead of XML or HTML) by using the method=”text” attribute on the tag.My guess is that the reason that people often find XSL difficult is because it uses an event-driven coding technique rather than an imperative one (e.g. C, Java, etc.). In Java you say, “Open the XML file and find this node then do x,” in XSL you say “when you see this node do x.”The next step is to finish the implementation of the SQL generator.SQL Generation
Finishing off the generation of the SQL for the physical schema means finishing the XSL templates and using the directive to generate two files?one for the SQL for the schema and the other for a file that contains SQL to insert the test data into the database. This is shown in Figure 2.Figure 2. Building SQL: Adding the test data into the schema. Click on each template to see the code. The XSLT files for the SQL generator are <>, the main XSL template, which calls out two helper templates: <> builds the SQL create calls and <> creates the SQL insert commands to add the test data into the schema.With the database schema in place the next step is to lay database access layers on top of it with PHP and C#. I’ll start with the architecture of the PHP solution.PHP Architecture
The PHP architecture that the generation solution supports is a three-tier architecture with the database at the bottom, a second tier of database access, and the user interface in the first tier. This common and well regarded architecture is shown in Figure 3.Figure 3. A Common Plan: The three-tier PHP architecture.The highlighted elements in Figure 3 will be produced with code generation. The database access layer and a set of test pages for that layer will be built by the PHP generator. To finish off the application all that is required is the production user interface on top of the data access layer.Generating the data access layer and the test pages will be done with one XSL style sheet that has four related style sheets.PHP Generation
The relationship between the style sheets is shown in Figure 4. The <> style sheet is the central hub of the code generation system for PHP. <> builds the ssdb.php file, which is a set of functions written on to of Pear::DB to make database access easier. <> contains the code for the database access classes that are created, one per table. <> builds the test pages for the data access classes. <> creates the index.html page that points to all of the test pages.Figure 4. Style: The PHP stylesheets are shown. Click on each template to see the code. Once the style sheets are run on the input schema the phplib directory will contain the data access classes. This directory needs to go somewhere in the PHP path. To finish off, the test pages then need to go into the Apache document root.Now comes the fun part: showing how one abstract design specification can build code in very different technologies.C# Architecture
C# can talk with MySQL through the ODBC interface, so we can reuse the MySQL generator to build the database schema. The XSLT generator for C# only needs to build classes that act as a database access layer and test pages that use these database access classes, as shown in Figure 5.Figure 5. Saving Steps: You only need to build the database access layer.To complete the application you need to add pages to complete the user interface and add any custom business logic that you need.C# Generation
The XSLT generator for C# takes a database schema as input and uses a set of four templates to generate the data access layer. The central template is <>, which calls out to the three other template files (see Figure 6). The <> template builds the C# classes that wrap each database table. The <> page builds the test ASPX page which calls out to each class. The <> template builds the index file that links to all of the test pages.Figure 6. See Schema: These templates each play a role in generating the final ASPX page. Click on each template to see the code. Despite the dramatic differences between the two languages we can use a single generation mechanism and a single schema definition to generate both sets of code and test pagesKeep an Eye Out
There are some drawbacks. For one, XSLT is not Turing complete, so you may need to do some pre-processing on the XML before you send it to the templates. Or you could embed an XSLT processor in your favorite language to handle the shortcomings in XSLT. But in this article I generated code in two different languages with XSLT alone, so don’t be overly gunshy.Another issue is the cumbersome syntax of XSLT and the encoding that must be used in the templates that sometimes obscures the code being generated. Both of these are ameliorated by XSLT tools and by the fact that XSLT is a standard that other engineers can understand and embrace.The abstraction benefits of code generation allow for true cross-technology portability. Other generators, such as ArcStyler, have taken this much further, but the point is the same: XSLT is something that you can use today, right off the shelf, to eliminate redundant coding regardless of what technologies you support.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist