The Model-Driven System Builder
JeeWiz Architect's Guide
2.7 Rendering Inheritance
We use the term 'rendering inheritance' to indicate that there are multiple
levels used in rendering, and higher levels can make use of the lower levels - similar to inheritance in Java.
2.7.1 The Backbone|
For example, here are the lowest three levels in a J2EE application system build.
This backbone is used for a range of features in JeeWiz.
It consists of an ordered of sequence of "template directories".
Each part of the backbone is a template directory, holding rendering information.
These are specified by the "templateDir" property at start-up.
This can contain a complete list of the template directories - which is now the preferred approach.
Alternatively, it can be deduced as follows:
- The 'templateDir' configuration parameter only defines the first - top-most - directory in the chain.
- Template directories must have a file named 'model.properties' which defines key characteristics for this
templating level, such as the default inheritance structure
(via the 'parent' property described next) and the package for compiling meta-model classes into.
This is a typical Java properties file.
- To continue the default inheritance chain,
the 'parent' property must be defined.
Its value is points to the next template directory in the chain.
- The chain ends when the there is no 'parent' property in the 'model.properties' file.
The chain of renderings can be as long as necessary. Six levels of rendering is common,
but customer implementations have used many more.
The following diagram shows the actual directories and values used to construct to create the three-level example above.
Directories are given relative to the JeeWiz installation directory.
In fact, the "parent" property has the ability to point to multiple parents, creating a tree of template directories.
This is only used occasionally - details are given in the
Template Directory section.
This section describes overall (per-rendering-level) features.
2.7.2 Part 1: Overall Features|
126.96.36.199 Referencing Meta-Models|
The meta-models are attached to the backbone by including the Jar of the Java classes for the meta-model
(as created by building the meta-model) in the 'components.jar' file.
The 'components.jar' file is optional. In our example, all levels have a components.jar file, but rendering-only (no-meta-model) template directories are allowed.
188.8.131.52 Other Attachments|
There are other files that are attached to the backbone, by placing them in the template directory.
Briefly, these are
- system.properties - default configuration properties for this level of the rendering
- VM_global_library.vm - Velocity macros that are global to the rendering
- control/meta-class/* - a directory holding per-meta-class information for the rendering.
- control/*.control - controls for this template directory.
The individual system.properties and VM_global_library.vm files are aggregated by JeeWiz before the build starts,
to create a composite file.
This is useful because it allows the different levels to be built in a modular way.
It turns out this is also quite natural:
different rendering layers have different concerns, reflecting the different things being modeled.
Allowing them to be defined separately but then aggregated for the build is the most convenient approach.
Just like inheritance in object-oriented programming languages, the aggregation allows
files from higher-level template directories to use and override features from the lower-level ones.
'Higher-level' means template directories encountered earlier in the search.
The highest-level template directory is the top-most direct -
the one named in the 'templateDir' build configuration parameter;
the lowest-level template directory is the last in the chain.
This section describes features that apply to each meta-class.
2.7.3 Part 2: Per-Model-Object Features|
What we are doing in this section is combining rendering inheritance with meta-class inheritance.
This is necessary because typically we want to render model objects according to their inherent characteristics.
This points to searching for meta-class renderings based on the meta-class's inheritance structure.
This way an entity can reuse some of the rendering of a business-object, which in turn can re-use parts of a normal class's rendering.
However, there are two good reasons why we need to consider the vector of renderings - the backbone described above.
What we have describe here may seem to be overly complex or unnecessary.
This is one of the areas of JeeWiz where the original, simpler, approach has been enhanced in the face of real-world requirements.
Our experience shows that it makes it possible to quickly build complex rendering structures.
- Overriding: for customer-specific builds or technology add-ins, we want to override individual files or properties in a standard rendering
- Logical/physical re-use: when we have an abstract meta-model such as the Business Object Meta-Model,
it needs to work in conjunction with one or more platform- or technology-specific meta-models.
For example, much of the complex logic behind entity-relations and data-view mappings is implemented in
the Business Object Meta-Model, but to map it into real code and configuration,
we need to use part of the J2EE rendering.
The way we tie these together is by rendering inheritance.
The key to combining these two dimensions is as follows:
Other system generation tools often have a similar feature to the search capability,
but restricted to a two-level facility: the basic template plus specially marked variation points,
where local variations can be merged in.
JeeWiz generalises this facility to be multi-level, and to add the dimension for meta-model inheritance.
In a sense, we are added the benefits of object-oriented technology - inheritance and overriding - to system generation.
- The outer loop of the search (usually) follows the meta-model inheritance chain.
For example, we will first search for entity renderings, and failing that business-object renderings, and so on.
- The inner loop follows the backbone.
This makes it possible to place an overlay file to replace a very specific piece of the rendering.
This is why the inner loop follows the backbone.
This section applies to all the files that JeeWiz looks up for a meta-class. These are:
2.7.4 Searching For Files|
- build.xml - the Ant build script for the meta-class
- uptodate.xml - an Ant build script that tells the engine whether a meta-class is up to date
- component.properties - the meta-class equivalent of component.properties, described in more detail in the next page
- *.vm/*.inc etc. - all template and pattern files, and included (e.g. for #parse()) that are processed by Velocity.
184.108.40.206 Directory Structure|
The rendering files for a particular meta-class are stored in the following way:
$templateDirectory / $metaClassXMLName / $filename
|$templateDirectory ||is the template directory for this level of rendering
|$metaClassXMLName ||is the XML version of the meta-class class (e.g. 'ejb-jar' or 'business-object')
|$filename ||is the name of the file being looked up, such as 'build.xml' or .includeSpec.vm'.
220.127.116.11 Adding Model Object Inheritance|
In essence, we add meta-class inheritance to this chain.
We will give examples here using a more realistic typical template directory chain for building J2EE applications,
which adds onto the three lower levels we used above:
|resources/demo/control ||implements look for JeeWiz demonstrations
|resources/jboss3/control ||application-server specific renderings for JBoss 3.0
|resources/j2ee/control ||the (physical) J2EE level
|resources/screen/control ||the (logical) screen/pageflow level
|resources/bizobject/control||the (logical) service level
|resources/java/control ||the (physical) Java language level
|resources/base/control ||the base.
Say we are looking for build.xml for an application model object.
This search looks through the directories in order until the first file is found.
The actual file lookups done are
If we compare this to the general algorithm given above, we see that the $templateDirectory part is
moving in order down the template directories,
but the other two parts are fixed: $metaClassXMLName = 'application' and $filename = 'build.xml'.
The search for build.xml is only looking for a single file, so it stops when the j2ee/control/build.xml file is found.
The search example showed no variation in the meta-class directory used - the required file was found using the original meta-class name.
Now let's look at what happens when we lookup 'build.xml' for an attribute.
The attribute meta-model class extends the field meta-model class.
As attribute has no 'build.xml' file of its own, the search continues, using 'field' for the $elementXMLName.
The file is finally found down in the Java ('object') rendering level.
The complete list of files searched here therefore is
Note that we arrived at a different meta-model, from bizobject (Business Object) to object (Java),
as well as at a different meta-class, from attribute to field.
This shows how the two dimensions of this inheritance work:
we want to reuse rendering information from lower meta-classes and/or different template directories.
18.104.22.168.1 The Mechanism|
The mechanism by which we add the meta-class is not simple meta-model class inheritance.
Although the effect is the same in almost always all cases,
there may be parts of a rendering that we need to mix in.
For example, when rendering EJBs in the J2EE meta-model,
there are aspects of the rendering that are common to all the EJB types - entities, sessions and message-driven beans.
To allow for this, there is a special file named 'template.properties'.
This file normally contains just one line:
This redirects the search: it stops the search down the rendering inheritance chain,
and restarts the search with the top-most rendering directory, using the next meta-class name.
(The XML format of the name is recommended but not required;
you can use the equivalent Java name 'nextMetaClass'.)
In the example in the previous section,
this is how the bizobject/control/attribute switched to using the 'field' directory.
Note that the last example showed how the search down the rendering inheritance chain stopped.
To include parts of the rendering from another directory,
the template.properties file has an 'include' property, e.g.:
This includes the ejb directory as an additional search, before continuing with the normal search;
the effect is to add the 'ejb' aspects as a 'mix-in' into the inheritance chain.
We should stress that this is rarely used:
normally the search order follows the meta-class inheritance chain.
At this point, you may be having concerns about performance.
If we have a long search chain - 10 levels of rendering inheritance - and a long inheritance chain,
then potentially there is a long search path to file a file.
To reduce the overhead of the search, all files found are cached,
so the search process is only executed once for a given meta-class/template-file type combination.
This means that you should not let the length of the search path for template files deter you from using long renering chains.
In practice, the length of this search chain does not make an appreciable difference to performance in normal use (10 levels of template directory).
Copyright (c) 2001-2008 New Technology/enterprise Ltd.