A outlet generates String output from sources. An example for an outlet is a VelocityOutlet, which uses a velocity template to create the output. An outlet may be used in several generation processes. The output of an outlet can be used as file name or (part of a) generated file.
Sources are the input of the generation process. They can be read from different formats, e.g. properties files, XML files, or jdbc metadata. For each generation process, a directed weighted graph (which is usually, but not necessarily, a tree) is constructed from the sources. The graph may then be fed into the outlets, or it may be transformed in an intermediate step. Each outlet can access the transformed graph to produce its output.
The graph is represented similarly to the structure which is normally
used to represent XML files:
The nodes are called "elements", and each element has a list of children
and a list of parents (i.e. parents and children are ordered).
Elements without parents
are also allowed, but usually there will be only one such element
Each element can also have attributes. Each attribute has a name and a value. There can be at most one attribute with a given name for each element.
Additionally to the attributes, each element also has a name.
In the simplest generation projects, it suffices to pass the sources directly to the outlets. But in more complex projects, it makes sense to transform the source before generating output from it. A transformer performs the transformation from an input graph to an output graph. The output graph is then used for generation.
A typical example is that different source elements reference each other (e.g. by name, or by even more complex relations), and one would like to have this reference resolved before the generation phase. E.g. the source looks (in XML representation) like
<root> <element name="element1"> <related name="element2"> </element> <element name="element2"/> <element name="element3"/> </root>
<root> <element name="element1"> <related name="element2"> <relatedElements> <element name="element2"/> <-- This is typically element2 itself, not a copy </relatedElements> </element> <element name="element2"/> <element name="element3"/> </root>
<database> <table name="FIRST_TABLE" /> </database>
<database> <table name="FIRST_TABLE" javaName="FirstTable"/> </database>
SkipDeciders do what their name promise, they decide whether the generation of certain files is skipped. E.g. a SkipDecider could read an option value and skip the generation of a file if the option is not set. SkipDeciders are java classes which implement the SkipDecider interface.
The Controller makes sure that the configuration files are read, reads the source and options, performs possible transformations on the source and feeds the result into the generators.
Options can be used in the generation process to influence the output. Note that sometimes, there might be an ambiguity between sources and options. The difference is more of a philosophical nature: Sources are the data to be processed, whereas options influence the way the data is processed.
To ease communication between outlets, the concept of a variable is also known outside of the single outlets. This makes it possible e.g. to pass a variable from a Java outlet to a Velocity template in the same generation process.
Variables have different scopes. The scope defines where a certain variable is visible. The current scopes are "OUTLET" (the variable is only visible in this outlet), "CHILDREN" (the variable is visible to the current outlet and all outlets called by it), "FILE" (the variable is visible during the generation of the current file), and "GLOBAL" (the variable is always visible).
Note that scopes and namespaces are orthogonal concepts, i.e. a variable is visible only if it has a sufficient scope and the correct namespace.
The Torque generator encourages to use modularized outlets, in order to reuse them or drop, replace or add parts into the generation process. To connect one outlet to another, mergepoints can be used. A mergepoint is a place where the output of one outlet can be fed into another outlet.
If a mergepoint is encountered during the generation process, one or more actions may be performed, depending of the configuration of the current outlet. Typically, these actions describe how to traverse the source tree. An example would be "invoke the outlet xyz for all children of the current element and insert the output here".
If no action is defined at a mergepoint, it is left unused. This should be used to insert extension points in the outlets, as a placeholder for additional output. E.g. if you write a velocity template which generates a java class, it makes sense to create unused extension points where additional methods can be inserted (without changing the template).
If outlets are created in a modular manner, it is desirable that some options and variables are visible only to one outlet, while others should be visible to all outlets. To support this, outlets, options and variables can be assigned a namespace. Namespace elements are separated by dots. Generators see only options and variables which live in their namespace or in parent namespaces.
For example, the outlet with the fully qualified name "org.apache.torque.generator.classnameToFilename" lives in the namespace "org.apache.torque.generator" and will only see variables and options set in that namespace or in the parent namespaces "org.apache.torque", "org.apache", "org" and "". The namespace "" is also called the root namespace, variables and options therein are visible to all outlets.
You do not need to use namespaces; if you do not prefix any name with a namespace, every option and variable will be seen by every template.
The configuration of the Torque generator tells the Controller which option files are read, which output files are produced from which Outlets and Sources, which SkipDeciders and which Transformers should be used, and which Outlets are connected to which Mergepoints. The configuration of the Torque generator is described in detail in the configuration section of the Torque generation documentation.
The Torque generator offers overriding via a parent-child mechanism. A generator configuration can inherit from another generator configuration; and settings can be overridden or added. This can be used to customize the generation output. A common way to change the output is to add or change Outlets which are used by the generation mechanism. E.g. one can replace a template in all places by overriding an Outlet definition in a child configuration, or one can disable the use of an outlet in a place by overriding a Mergepoint definition.