<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<document>

 <properties>
  <title>Getting Started with Torque code generation</title>
 </properties>

 <body>
  <section name="Introduction">
    <p>
      In this introduction, it will be shown how to generate code
      using the Torque generator.
      Maven 2 is used as a build tool (although the example can
      also be run using plain java),
      a properties file is used as input for generation and
      velocity is used as template language.
      In the following section, the necessary steps to set up such a project
      are described; and detailed by a simple example: We have a properties file
      and want to create a java enum which contains the keys as constants.
      The sample files can be found in the src/test/site/gettingStarted
      directory of the torque-generator sources.
    </p>
    <p> 
      In our example, from the source
      <source><![CDATA[
torque.sample.property = sampleValue
torque.some.other.property = someOtherValue
    ]]></source>
      we want produce the output
    <source><![CDATA[
package org.apache.torque.generator.example.gettingstarted;

/**
 * Contains all keys in the property file.
 */
public enum PropertyKeys 
{
    /** Key for torque.sample.property */
    TORQUE_SAMPLE_PROPERTY("torque.sample.property"),

    /** Key for torque.some.other.property */
    TORQUE_SOME_OTHER_PROPERTY("torque.some.other.property");

    /** The property key. */
    private String key;

    /**
     * Constructor.
     *
     * @param key the key of the property. 
     */
    private PropertyKeys(String key)
    {
        this.key = key;
    }

    /**
     * Returns the property key.
     *
     * @return the property key.
     */
    public String getKey() 
    {
        return key;
    }

    @Override
    public String toString()
    {
        return key;
    }
}
      ]]></source>
    </p>
  </section>
  
  <section name="Project setup">
    <p>
      Create a root folder for your project. In the root folder, create a 
      src/main/torque-gen folder. This is where all the files for
      the torque generator go. 
      In the torque-gen folder, create a "conf" subdirectory
      (this is where the main configuration goes), a "templates" subdirectory
      (for the velocity templates), a "outlets" subdirectory 
      (for the definition of the outlets) and a "src" directory 
      (for the source files, they can be anywhere in the project but if
      you do not know a better place for them, torque-gen/src is a reasonable
      default).
    </p> 
  </section>
  
  <section name="Creating a sample source">
    <p>
      As a starting point, create the source file which keeps the information
      you need to generate the output (to MDA addicts, 
      this is known as the "Metamodel instance". There is no explicit metamodel
      needed, it is defined implicitly by the templates.).
      In our example, the source will be the property file listed above.
    </p>
    <p>
      This file will be used to feed the generation process. 
      Name this file "propertiesData.properties" and put it into
      the src subdirectory of the torque-gen directory.
    </p>
    <p>
      Internally, the Torque generator uses a representation similar 
      to a xml file to represent the source: 
      Elements make up a tree or graph structure,
      and each element has a set of named attributes. 
      The internal representation of our property source looks like
      <source><![CDATA[
<properties>
  <entry key="torque.sample.property">sampleValue</entry>
  <entry key="torque.some.other.property">someOtherValue</entry>
</properties>
      ]]></source>
      A text node is represented as the attribute with the key null.
      The internal structure of the source is important because the
      generation process traverses the source tree, and the attribute names
      are used to access the textual information in the source.
    </p>
    <p>
      Other input file formats (currently xml) and input types 
      (currently JDBC metadata) are also supported.
    </p>
  </section>

  <section name="Creating the templates">
    <p>
      Create the templates which produce the generated code in the
      "templates" subdirectory of the "torque-gen" folder. Use at least one
      template per file you want to generate; it is better to use one
      template per logical unit (this improves reusability and readability).
      A good idea is to create some sample output and start putting in
      control structures (variables, loops, includes) as necessary.
    </p>
    <p>
      In our desired output above, we can identify the following logical units:
      <ul>
        <li>The enum class frame</li>
        <li>The constants for the single properties</li>
        <li>The fields of the enum</li>
        <li>The methods of the enum</li>
      </ul>
      So let's create a template for each logical unit.
    </p>
    <p>
      The template for the enum's class frame, classFrame.vm, 
      contains the class outer frame plus mergepoints
      for the constants, fields and methods of the enum:
      <source><![CDATA[
package org.apache.torque.generator.example.gettingstarted;

/**
 * Contains all keys in the property file.
 */
public enum PropertyKeys 
{
$torqueGen.mergepoint("constants")##
$torqueGen.mergepoint("fields")##
$torqueGen.mergepoint("methods")##
}
      ]]></source>
      As mentioned above, <a href="http://velocity.apache.org">velocity</a>
      is used as template language.
      This introduction does not cover the velocity template language itself;
      if you are not familiar with velocity, look at
      <a href="http://velocity.apache.org">the velocity documentation</a>.
      <br/>
      The interesting part in the template is the call of the mergepoint method
      of the torqueGen Object. The torqueGen object is placed into the velocity
      context by the torque generator and contains methods for defining
      mergepoints and accessing the source, options and variables. See
      <a href="../../modules/generator/reports/apidocs/org/apache/torque/generator/template/velocity/TorqueGenVelocity.html">its javadoc</a>
      for the available methods.
    </p>
    <p>
      The template constant.vm, which outputs a constant for each property,
      is also interesting because we need to access information from the
      source file. For outputting simple data, this is simple: 
      The velocity construct "${key}" accesses the object named "key"
      in the velocity context. The "key" object is put in the velocity
      context by the torque generator, which by default puts all attributes
      of the current source element into the velocity context.<br/>
      For the name of the constant, the key would also be used, but it needs
      to be processed in some way (capitalized, underscores added).
      For this processing we will use a built-in java generator, which
      will be plugged into the mergepoint "constantName".<br/>
      Finally, we need a comma after each definition, except for the last
      definition, where we need a semicolon. To decide whether to render the
      comma or the semicolon, we fetch the current source element from 
      torgueGen (${torqueGen.getSourceElement()) and ask it whether it
      has following siblings (i.e. source elements with the same parent
      and the same name) (see
      <a href="../../modules/generator/reports/apidocs/org/apache/torque/generator/source/SourceElement.html">the SourceElement javadoc</a>
      for available methods on a source element).
    </p>
    <source><![CDATA[
    /** Key for ${key} */
    $torqueGen.mergepoint("constantName")("${key}")#if(${torqueGen.getSourceElement().hasFollowingSibling()}),#else;#end


    ]]></source>
    <p>
      There is nothing new in the other templates: 
    </p>
    <p>
      keyField.vm outputs the key field of the enum:
    </p>
    <source><![CDATA[
    /** The property key. */
    private String key;
    ]]></source>
    <p>
      There are three methods; each has its own template:
    </p>
    <p>
      constructor.vm renders the constructor method:
    </p>
    <source><![CDATA[
    /**
     * Constructor.
     *
     * @param key the key of the property. 
     */
    private PropertyKeys(String key)
    {
        this.key = key;
    }
    ]]></source>
    <p>
      getKey.vm renders the constructor method:
    </p>
    <source><![CDATA[
    /**
     * Returns the property key.
     *
     * @return the property key.
     */
    public String getKey() 
    {
        return key;
    }
    ]]></source>
    <p>
      and toString.vm creates the toString method:
    </p>
    <source><![CDATA[
    @Override
    public String toString()
    {
        return key;
    }
    ]]></source>
    
    <p>
      You might ask yourself why we create so many templates and not use a
      single large template (which is, of course, also possible).
      The reason is that smaller templates can be re-used more easily, but
      even more important, they can be re-plugged more easily. For example,
      if you want to create an enum class without the toString() method,
      you do not need to change a single template, but just the way they are
      plugged together (see below).
    </p>
  </section>
  
  <section name="Creating the control file">
    <p>
      The control file contains information about all the files you want to
      create. It is a XML file named "control.xml" and resides in the conf
      directory.
      
      Create this file, and for each file or set of files in the output,
      create a "output" tag in the root "control" tag. 
      An output needs a name by which it can be identified.
      Each output needs a filename, which can be either fixed 
      (then you can use the "filename" attribute of the "output" tag),
      or which is generated (in which case you would use a "filenameGenerator"
      tag inside the "output" tag.
    </p>
    <p>
      Each "output" tag needs a "source" tag which tells the torque generator
      which source files to use.
      If you want to create more than one output file per "output"
      tag and source file, use the "elements" attribute of the "source" tag
      to select the root elements for the different output files.
    </p>
    <p>
      Also, each output tag needs a "outlet" tag which contains the name
      of the outlet to invoke on the root elements. For defining outlets,
      see the next section.
    </p>
    <p>
      In our example, we want to create only one file, thus we have a simple
      control file:
    </p>
    <source><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<control
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://db.apache.org/torque/4.0/generator/configuration http://db.apache.org/torque/4.0/generator/configuration.xsd"
    xmlns="http://db.apache.org/torque/4.0/generator/configuration"
    loglevel="debug">
  <output name="propertyKeys"
      file="org/apache/torque/generator/example/gettingstarted/PropertyKeys.java">
    <source xsi:type="fileSource">
      <include>propertiesData.properties</include>
    </source>
    <outlet name="classFrame"/>
  </output>
</control>
    ]]></source>
    <p>
      The single "output" tag in this file contains the following definitions:
      Its name is "propertyKeys",
      the output is written to the file 
      "org/apache/torque/gf/example/propertyenum/PropertyKeys.java",
      the source is read from "propertiesData.properties" in the src directory,
      and the outlet named "classFrame" (defined below) will be the master
      outlet for the output. 
    </p>
  </section>
    
  <section name="Configuring the outlets">
    <p>
      Now that we have created the templates and defined our input and output,
      we must plug the templates into each other.
      The Torque generator encapsulates each template in a concept named 
      "outlet". Each outlet acts on a source element and produces a 
      String output from it. Also, an outlet can define so-called
      "mergepoints" where it can call insert the output of other outlets.
      To define the outlets, create one or more xml file in the 
      "outlets" subdirectory ending with the suffix ".xml". 
      Into each file, put a root element "outlets".
    </p>
    
    <p>
      You need at least one outlet per template 
      (you might have more than one if you want to fill the mergepoints
      differently).
      For each outlet, create a "outlet" tag in the "outlets" root 
      element. Set the "xsi:type" attribute to "velocityOutlet",
      the "path" attribute to the path to the template
      relative to the "templates" subdirectory,
      and give it an unique name using the "name" attribute.
      For each mergepoint you want to fill in the outlet, create 
      a "mergepoint" tag in the "outlet" tag with the "name" attribute 
      set to the name of the mergepoint in the template.
      Define the action you want to execute 
      (e.g. for calling another generator, use the apply action, 
      or for looping through several elements, use the traverse-all action).
    </p>
    <p>
      In our example, we define the following outlets in the file
      "outlets/enumOutlets.xml":
    </p>
    <source><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<outlets xmlns="http://db.apache.org/torque/4.0/generator/configuration"
    xsi:schemaLocation="http://db.apache.org/torque/4.0/generator/configuration http://db.apache.org/torque/4.0/generator/configuration.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <outlet name="classFrame" xsi:type="velocityOutlet" path="classFrame.vm">
    <mergepoint name="constants">
      <action xsi:type="traverseAllAction" element="entry" outlet="constant"/>
    </mergepoint>
    <mergepoint name="fields">
      <action xsi:type="applyAction" outlet="keyField"/>
      <action xsi:type="applyAction" outlet="newline"/>
    </mergepoint>
    <mergepoint name="methods">
      <action xsi:type="applyAction" outlet="constructor"/>
      <action xsi:type="applyAction" outlet="newline"/>
      <action xsi:type="applyAction" outlet="getKey"/>
      <action xsi:type="applyAction" outlet="newline"/>
      <action xsi:type="applyAction" outlet="toString"/>
    </mergepoint>
  </outlet>
  <outlet name="constant" xsi:type="velocityOutlet" path="constant.vm">
    <mergepoint name="constantName">
      <action xsi:type="applyAction" outlet="constantName"/>
    </mergepoint>
  </outlet>
  <outlet name="constantName" xsi:type="javaOutlet" class="org.apache.torque.generator.outlet.java.ConstantNameOutlet">
    <inputSourceElement>.</inputSourceElement>
    <sourceElementAttribute>key</sourceElementAttribute>
  </outlet>
  <outlet name="keyField" xsi:type="velocityOutlet" path="keyField.vm"/>
  <outlet name="constructor" xsi:type="velocityOutlet" path="constructor.vm"/>
  <outlet name="getKey" xsi:type="velocityOutlet" path="getKey.vm"/>
  <outlet name="toString" xsi:type="velocityOutlet" path="toString.vm"/>
  <outlet name="newline" xsi:type="javaOutlet" class="org.apache.torque.generator.outlet.java.NewlineOutlet"/>
</outlets>    ]]></source>

    <p>
      So, e.g. in the "classFrame" outlet, the three mergepoints 
      "constants", "fields" and "methods" are filled. In the "constants"
      mergepoint, the outlet "constant" is invoked for each "entry" 
      child element of the current source element. The output is then
      concatenated and filled into the mergepoint. In the "fields" and
      "methods" mergepoints, a bunch of outlets is invoked on the current
      source element ("properties"), the output is concatenated for each
      mergepoint and inserted into the mergepoint.
    </p>
    <p>
      The "constantName" and the "newline" outlets are a special case.
      The "constantName" outlet generates the name of a java constant
      from an input (e.g. converting to upper case, inserting underscores.)
      The "newline" outlet simply prints a newline (\n) each time it is 
      called, and is used to beautify the output.
      Both outlets are java outlets which are provided 
      by the Torque generator and are referenced by their class name.
      The "constantName" outlet needs some additional configuration
      to know from where to read its input. 
    </p>
  </section>
  
  <section name="Generating the source">
    <p>
      There are currently two ways to run the generation process: Either the
      generation can be integrated into a Maven 2 build process,
      or a simple java program can be used.
    </p>
    
    <subsection name="Using the Torque Maven 2 plugin">
      <p>
        To hook the generation process into your Maven 2 build, you need to
        install Maven 2.
        If you are new to Maven 2, read
        <a href="http://maven.apache.org/run-maven/index.html">the Maven documentation</a>.
        Then, add the following section to your pom.xml:
      </p>
    <source><![CDATA[
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.torque</groupId>
        <artifactId>torque-maven-plugin</artifactId>
        <version>4.0</version>
        <executions>
          <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <!-- The torque generator files are provided in a project directory -->
              <packaging>directory</packaging>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>    
    ]]></source>
      <p>
        Then, run "mvn generate-sources" in your project root dir,
        and the generated sources should show up in the target/generated-sources
        directory of your project.
      </p>
    </subsection>
    
    <subsection name="Using plain java">
      <p>
        As an alternative to Maven, you can also run the generation process
        using plain java. For this, you can use the following small
        program:
      </p>
      <source><![CDATA[
package org.apache.torque.generator.example.gettingstarted;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.torque.generator.configuration.UnitDescriptor;
import org.apache.torque.generator.configuration.paths.DefaultTorqueGeneratorPaths;
import org.apache.torque.generator.configuration.paths.Maven2DirectoryProjectPaths;
import org.apache.torque.generator.control.Controller;

public class GettingStarted
{
    public static void main(String[] argv) throws Exception
    {
        File target = new File("target");
        FileUtils.deleteDirectory(target);
        Controller controller = new Controller();
        List<UnitDescriptor> unitDescriptors = new ArrayList<UnitDescriptor>();
        unitDescriptors.add(new UnitDescriptor(
                UnitDescriptor.Packaging.DIRECTORY,
                new Maven2DirectoryProjectPaths(
                        new File(".")),
                new DefaultTorqueGeneratorPaths()));
        controller.run(unitDescriptors);
    }
}
]]></source>
      <p>
        Add all the dependencies of the torquegenerator into the classpath,
        and start this java program in the root directory of your project.
        The generated source will show up in the target/generated-sources
        subdirectory. 
      </p>
    </subsection>
  </section>
 </body>
</document>