//Artefact:SoftwareComponent/com/sphenon/engines/Generator

Usage/Operation - Manual

How to invoke the generator
The most easiest way to invoke the generator is the command line interface, since no Java programming is needed. When learning how to write templates, this is a good start.
Operation Class
The generator package provides a class named . This class implements the
Operation
interface, which declares an
execute
method.
The class can be used in two ways. First, it provides a
main
method, which can be used from the command line. Simply invoke it without arguments and you get an explanation of it's usage.
Secondly, you can create instances of the class, specify the respective parameters and call the
execute
method. This is what the
main
method also does internally.
And finally, there are some static
execute
methods with several arguments. They are provided simply for convenience. Internally, they create an instance, set the parameters and invoke the non-static
execute
method.
Command Line Invocation
The generator package contains an example bash script that performs the aboveexplained invokation. Just invoke it without arguments and get more information. Basically, it expects the name of a template you want to process.
Emacs Integration
To invoke the generator from emacs dired buffers, you need to include some lisp code provided in the file
generator.el
. Either you copy&paste that code into your emacs.el file, or you load that file with (load "my_generator").
Then, in a dired buffer you just press
hyper-g
(or whatever key you configure in your loadfile) on a template and emacs invokes the command line bash script.
DynamicString Integration
A very convenient and interesting way to embed generator capabilities into your application is the
DynamicString
interface.
In the default configuration, you just create a
DynamicString
instance, with an argument of
"g:..."
, where you replace the dots with a generator template. Then, you can call the
get
method to get the evaluated contents of the dynamic string. Internally, a template is prepared and the generator is invoked, but you aren't bothered with any details of this!
Programming Interface
In many cases the
Operation_Generate
class (see above) is already sufficient to invoke the generator from within your programs.
But there is another API beneath that class, providing more fine grained and exhaustive control over the various generator features. Please refer to the generator API documentation for more details.

Usage - Tutorial

Tutorial
A Simple Template
The following example shows a simple OOGenerator Template.
helloworld.template
  G-2.0-plain_java-1.0

      Hello world!

              
Test Execution
To execute the test, the following command can be used. It is assumed, that the jar- and template-file are located in the current directory.
Testaufruf
  java -classpath oogenerator.jar com.sphenon.engines.generator.operations.Operation_Generate helloworld.template helloworld.out
              
Example0000_Unicode
Example0000_Unicode
  G-2.0-plain_java-1.0

     Maybe the most striking feature of the OOGenerator is it's nice and compact
     unicode syntax. While it is eye-catching, it's just syntactic sugar, and
     besides it is optional. There's an alternative syntax available, which is
     pretty JSP-like. If you don't like both: no problem - just plugin your own
     syntax frontend.

     Since unicode syntax looks best - at least we do think so - it is used in
     the examples here. It is important to use an appropriate unicode font to
     view them correctly. Most moderately recent browsers should have no problem
     with this, while some text editors might need tuning.

     If you prefer to use the ASCII (JSP like) syntax, note that there is a
     converter available, which transforms one syntax into the other in both
     directions.

     -------------------------------------------------------------------------

     Here is a list of correspondences between Unicode and ASCII syntax:

     « java code »                      <% java code %>
     ⊰ comment ⊱                        <%-- comment --%>
     ⊰✉ message ⊱                       <%--#{message} message --%>
     ⊰✏ doclet ⊱                        <%--#{doclet} doclet --%>
     ⊰⚒ work ⊱                          <%--#{work} work --%>
     ◂ print code ▸                     <%= print code %>
     ◂ print code ⌘encoding▸            <%= print code %%encoding%>
     ◂⊙▸                                <%=#{current}()%>
     ◂Ⓘ▸                                <%=#{index}()%>
     ▼ file level code (import) ▼       <%@ file level code (import) %>
     ▲ class level code (declaration) ▲ <%! class level code (declaration) %>
     ⊏ template code ⊐                  <%? template code ?%>
     ⊏ signature(...) ⊐                 <%? signature(...) ?%>
     ⊏ ➜ somepart(...) ⊐                <%? #{insert} somepart(...) ?%>
     ⊏ ⌘ ⊐...⊏ /⌘ ⊐                     <%? %% ?%>...<%? /%% ?%>
     ◂‖"Ⓧ/./path/expression"▸           <%= ::"XPath/./path/expression"%>
     ◂‖"Ⓟ/..."▸                         <%= ::"Property/..."%>
     ◂‖"✦/..."▸                         <%= ::"XModel/..."%>
     ◂ recoded ⌘xml/html▸               <%= recoded %%xml/html%>
     ⊏ ⌘... ⊐ also recoded ⊏ /⌘ ⊐       <%? %%... ?%> also recoded <%? /%% ?%>
     ⊏ Ⓣ somepart(...) ⊐...⊏ /Ⓣ ⊐       <%? #{template} somepart(...) ?%>...<%? /#{template} ?%>
     ⊏ ◧ (...) ⊐...⊏ /◧ ⊐               <%? #{partition} (...) ?%>...<%? /#{partition} ?%>
     ≤ Java Template ≥                  <- Java Template ->
     ≦ Model Template ≧                 <= Model Template =>
     ⑊◂ escaped ⑊▸                      ◂ escaped ▸ (i.e., escapes unicode interpretation)
     ⋖ tag(a,b,c) ⋗                     <@ tag(a,b,c) @>
     ●(...){ ... }/●                    #{select}(...){ ... }/#{select}
     ∃(...){ ... }/∃                    #{exists}(...){ ... }/#{exists}
     ¬∃(...){ ... }/¬∃                  #{notexists}(...){ ... }/#{notexists}
     ⁇(...){ ... }/⁇                    #{isvalid}(...){ ... }/#{isvalid}
     ¬⁇(...){ ... }/¬⁇                  #{isinvalid}(...){ ... }/#{isinvalid}
     ∅(...){ ... }/∅                    #{empty}(...){ ... }/#{empty}
     ¬∅(...){ ... }/¬∅                  #{notempty}(...){ ... }/#{notempty}
     ⇾(...){ ... }/⇾                    #{isa}(...){ ... }/#{isa}
     ∀(...){ ... }/∀                    #{for}(...){ ... }/#{for}
     ∀(...∪...){ ... }/∀                #{for}(...#{union}...){ ... }/#{for}
     ∀(...){ ➀{...}∨{...}/➀ ... }/∀     #{for}(...){ #{first}(){...}#{else}(){...}/#{first} ... }/#{for}
     ∀(...){ ¬➀{...}∨{...}/¬➀ ... }/∀   #{for}(...){ #{notfirst}(){...}#{else}(){...}/#{notfirst} ... }/#{for}
     ➀:(...)                            #{declarepass}(...)
     ➀{ ... }/➀                         #{first}(){ ... }/#{first}
     ➀(...){ ... }/➀                    #{first}(...){ ... }/#{first}
     ➀:                                 #{declarepass}
     ¬➀{ ... }/¬➀                       #{notfirst}(){ ... }/#{notfirst}
     ¬➀(...){ ... }/¬➀                  #{notfirst}(...){ ... }/#{notfirst}
     ⓝ{ ... }/ⓝ                         #{last}(){ ... }/#{last}
     ¬ⓝ{ ... }/¬ⓝ                       #{notlast}(){ ... }/#{notlast}
     ⋈:                                 #{declareduplicates}
     ⋈(...){ ... }/⋈                    #{duplicates}(...){ ... }/#{duplicates}
     ¬⋈(...){ ... }/¬⋈                  #{notduplicates}(...){ ... }/#{notduplicates}
     }∨{                                }#{else}(){
     ¶(...)  /¶                         #{indent}(...)  /#{indent}
     🅁pattern=replacement               ~~~pattern=replacement (at start of line, template preprocessing)
     ⏎                                  \n
     …                                  \
     ⋮                                  <%|
     ⟦ expression ⟧                     {* expression *} (prefixes and disables unicode interpretation)
     ˮ                                  \" (within expression)
     ␀                                  null
     ✔                                  true
     ✘                                  false
     ≡                                  .equals
     ≔                                  define
     ⟜                                  option
     Ⓧ                                  XPath
     Ⓙ                                  JPath
     Ⓟ                                  Property
     ✦                                  XModel
     Ⓕ                                  File
     Ⓢ                                  SQL
     Ⓞ                                  OQL
     ▢                                  Space
     ⁂                                  OCP
     ‖                                  ::
     ┃                                  oorl://
     ∈(...){ ... }/∈                    #{element}(...){ ... }/#{element}
     ¬∈(...){ ... }/¬∈                  #{notelement}(...){ ... }/#{notelement}
     ∉(...){ ... }/∉                    #{notelement}(...){ ... }/#{notelement}
     ⊙                                  #{current}()
     Ⓘ(...)                             #{index}(...)
     Ⓘ                                  #{index}()
     Ⓘ:                                 #{declareindex}
     ⊕                                  #{add}
     ⊖                                  #{remove}
     ⊛                                  #{create}
     ¬                                  #{not}
     ∨                                  ||
     ∧                                  &&
     ⤙ items to join to string ⤚       --( items to join to string )--
     ⚡                                  °° config property
     ★{}                                new java.util.HashMap<String,String>()
     ★[]                                new java.util.ArrayList<String>()
     ★                                  new 
     ⚙                                  (*)
     ‹                                  <
     ›                                  >
     ⎆                                  placeholder
     ❓                                  |?|
     ╏                                  |:|
     ↯                                  catch
     ⌚                                  #{time}
     ⬒⌚                                 #{datetime}
     ⬒                                  #{date}
     ⌾                                  #{format}
     ⌗                                  #{size}
     ⌀                                  #{average}
     ∏                                  #{product}
     ∑                                  #{sum}
     ⤓                                  #{minimum}
     ⤒                                  #{maximum}
     ⇵                                  #{reverse}
     Ⓡ( ... )                           RegularExpression(context, ... )
     Ⓡ                                  RegularExpression
     ≋( ... )                           .tryGetMatches(context, ... )

              
Example0010_HelloWorld
Example0010_HelloWorld
  G-2.0-plain_java-1.0
  ⊰
     This templates creates a text with the famous words "Hello, world!".
  ⊱

      Hello, world!

              
Example0020_Comment
Example0020_Comment
  G-2.0-plain_java-1.0
  ⊰

     This templates does not produce any output, but an empty file.

     It demonstrates the use of template comments.

     These comments do not show up anywhere except in the template source.

  ⊱
              
Example0030_Expression
Example0030_Expression
  G-2.0-plain_java-1.0
  ⊰
     This templates demonstrates the use of embedded java expressions.
  ⊱
  ⊰
     The first example is just another way to say "Hello, world!".
     The placeholder ◂...▸ is replaced by the value of the java expression
     between the filled arrows.
  ⊱

      Hello, ◂"world"▸!

  ⊰
     So, any valid java expression is usable.
  ⊱

      Hello, ◂"w"+"o"+"r"+"l"+"d"▸!
      2 * 21 = ◂2*21▸

              
Example0040_Argument
Example0040_Argument
  G-2.0-plain_java-1.0
  ⊰
     This templates allows to greet arbitrary planets (not just worlds).

     It demonstrates the use of template arguments.

     When invoked, this templated receives an argument named "my_arg".
     E.g., if the actual invocation argument is "Mars", it creates the text
     "Hello, Mars!"
  ⊱
  ⊏ signature(String my_arg) ⊐

      Hello, ◂my_arg▸!

  ⊰
     Note the special characters "⊏" and "⊐" around the signature. These are
     socalled "template code delimiters". The code inside them is processed by
     the template parser, in contrast to java code inside "«" and "»". The
     latter - Java code - is passed directly to the created intermediate Java
     generator class.

     It is useful to keep these different processing levels in mind.
  ⊱
              
Example0050_DefaultValue
Example0050_DefaultValue
  G-2.0-plain_java-1.0
  ⊰
     This templates allows to greet arbitrary planets, but by default the world.

     It demonstrates the use of default values for template arguments.

     If invoked without an argument, it prints "Hello, world!".
  ⊱
  ⊏ signature(String my_arg = "world") ⊐

      Hello, ◂my_arg▸!

              
Example0060_PrettySyntax
Example0060_PrettySyntax
  G-2.0-plain_java-1.0
  ⊰
     This template demonstrates how to keep your templates readable.

     There are three tiny syntactic helpers to solve three frequently encountered
     problems. 
  ⊱
  ⊰
     To illustrate the first problem, note that between the first comment and
     the second one (this one) there is a line break. This line break appears
     not only in the template, but in the output, too. You will want your
     template being reasonable layouted, while at the same time having nicely
     layouted results. How to achieve this?

     First, note the three tiny continuation dots '…' behind the following comment
     end delimiter:
  ⊱…
  ⊰
     They simple say: please ignore the line break (they are comparable to the
     use of a backslash in programming languages like C or C++).
  ⊱…
  ⊰
     Another problem often encountered is the indentation depth mismatch between
     template code and result code. E.g.
  ⊱…
                                Hello, world!  
  ⊰
     is of course indented in the output by 30 spaces. How to avoid this,
     without compromising template layout? That's the purpose of the indentation
     character '⋮', like here
  ⊱…
                               ⋮Hello, world!  
  ⊰
     The '⋮' character says: please ignore every whitespace between it and the
     beginning of the line.

     So, if you combine these concepts, you might e.g. write
  ⊱…
                               ⋮Hello, …
                               ⋮◂"world"▸…
                               ⋮!…
  ⊰
     which creates again "Hello, world!", without any additional spaces or line
     breaks before, after of within the output.
  ⊱…
  ⊰
     And finally, sometimes you may need the contrary of the continuation dots:
     a linebreak in the output, but not in the template. This is the purpose of
     the 'Return' sign '⏎'.

     The following code produces 50 emtpy lines in the output:
  ⊱…
  ⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎⏎
              
Example0070_JavaCode
Example0070_JavaCode
  G-2.0-plain_java-1.0
  ⊰
     This templates demonstrates how to embed Java code statements.

     Like in the previous examples, it prints "Hello, world!"
     (if invoked without an argument).
  ⊱…
  ⊏ signature(String my_arg = "world") ⊐…
  ⊰
     The characters '«' and '»' are used as delimimeters for arbitrary
     Java code statements.
  ⊱…
  « String greeting = "Hello, " + my_arg; »…

      ◂greeting▸

              
Example0080_JavaCode2
Example0080_JavaCode2
  G-2.0-plain_java-1.0
  ⊰
     This templates demonstrates the embedding of arbitrary
     types of Java code.
  ⊱…
  « String greeting = "Hello, world!"; »…

      ◂greeting▸

  « if (1 == 2) { » Something is wrong here. « } »…

  Countdown: « for (int i=10; i>=0; i--) { » ◂i▸« } »

              
Example0090_TemplateIsAClass
Example0090_TemplateIsAClass
  G-2.0-plain_java-1.0
  ⊰
     Each template is translated into a Java class with
     the same name and in the same package.

     Therefore, all features of Java classes are available
     from within templates, too.
  ⊱…
  ⊰
     Within two characters '▲...▲' you can define class level
     code. I.e. you can declare variables and define methods.
  ⊱…
  ▲  protected void times(int a, int b) { return a * b; } ▲…

      3 * 7 = ◂times(3, 7)▸

  ⊰
     You can declare class level code multiple times,  and at
     arbitrary locations within your template.
  ⊱…
  ▲  static final protected float pi = 3.14159265; ▲…
  «  floar r = 1.0; »…

     area : ◂ pi * r * r ▸

              
Example0100_Encoding
Example0100_Encoding
  G-2.0-plain_java-1.0
  ⊰
     Templates produce output. Such output might be just plain
     ASCII, plain Unicode or might be encoded somehow, say HTML.

     Furthermore, templates process input, which may or may not
     be written in the same encoding.

     And finally, the normal template text might have a third
     encoding.

     Let's assume you want to create a Java properties file
     based on XML input. Then

     - in the input we have '&lt;', '&gt;' and '&amp;'.
     - in our template text we just want to write normal Unicode.
     - in the properties file everything non-ASCII (e.g. german
       umlauts) must be escaped '\uXXXX'

     In templates, such a situation is rather the rule then
     an exception.

     Instead of writing conversion calls each and everyplace,
     we just can use the recoding operator '⌘':
  ⊱…
  «  String xml_input = " immer und überall gilt: 17 &lt; 23 "; »…

     ◂xml_input⌘XML/JAVAPROP▸

  ⊰
     You get the output

     " immer und \u00FCberall gilt: 17 < 23 "

     The '⌘...' sequence is called a 'recoding'.
     It consists of a sequence of encoding names. The above
     example reads 'convert XML to JAVAPROP'.

     The encoding names are defined in an enumeration class
     named 'Encoding'. You can use this class also from normal
     Java code.

     If we have many such expressions in our template, we can
     define a default recoding:
  ⊱…
  ⊏ ⌘XML/JAVAPROP ⊐…

     ◂xml_input▸

  ⊏ /⌘ ⊐…
  ⊰
     This yields the same result as above.

     Default encodings can be nested (they apply to included
     and subtemplates, too, but we do not know yet what these are).
  ⊱…
  ⊏ ⌘DOCBOOK/JAVAPROP ⊐…
     ⋮⊏ ⌘XML/JAVAPROP ⊐…

         ◂xml_input▸

     ⋮⊏ /⌘ ⊐…
  ⊏ /⌘ ⊐…
  ⊰
     This again yields the same result as above.

     Encodings need not be complete, they will be combined.
  ⊱…
  ⊏ ⌘XML/ ⊐…

     ◂xml_input⌘/JAVAPROP▸

  ⊏ /⌘ ⊐…
  ⊰
     This again yields the same result as above.

     Note, that a default encoding applies to embedded Java expressions
     as well as normal template text. What if they are different, as
     within our example?

     Then you can apply a different default encoding to these
     categories.
  ⊱…
  ⊏ ⌘[x]XML/JAVAPROP ⊐…
  ⊏ ⌘[t]UTF8/JAVAPROP ⊐…

     ◂xml_input▸

     This '&lt;' is not translated, since we're here in normal
     template text, not in an expression.

     ◂"But this '&lt;' is translated, since we're an expression"▸

  ⊏ /⌘ ⊐…
  ⊏ /⌘ ⊐…
  ⊰
     As you might have guessed, 'x' stands for 'expression' and
     't' for 'template text'.
  ⊱…
              
Example0110_TemplateTypes
Example0110_TemplateTypes
  G-2.0-plain_java-1.0
  ⊰
     Up to now, all templates begun with this cryptic line:

       G-2.0-plain_java-1.0

     It reads like this:

       G-2.0                this template requires "Generator, Version 2.0"
       plain_java-1.0       it is a template of type "plain_java, Version 1.0"

     The generator version is specified for compatibility reasons. If the
     generator behaviour changes in future versions, it is used to support old
     templates, or at least issue a warning about possible problems.

     The template type specifies the context within which the template is
     interpreted and executed. "plain_java" means: there's nothing but plain
     Java available.

     Some common contexts are:

       plain_java-1.0                       nothing special, just plain Java

       plain_java_jspstyle-1.0              same, but enabling ASCII (JSP like) syntax

       java_jpp-1.0                         plain Java with a special preprocessor enabled

       xml-1.0                              for processing xml files

       xml_string-1.0                       for processing xml, passed as Strings

     These contexts will be introduced in more detail in following examples.
  ⊱…
              
Example0120_ParserConfiguration
Example0120_ParserConfiguration
  G-2.0-plain_java-1.0
  ⊰
     This example explains how the parser configuration works.
     It can be safely skipped on a first reading.

     In the previous example template types were introduced. How do they affect
     the generation process?

     When interpreting a template, the first information read is the
     introductory string:

       G-2.0-plain_java-1.0

     This is translated straight forward to the name of a template parser
     configuration by replacing the "G" with "TP":

       TP-2.0-plain_java-1.0

     The parsers are very modularized and consist of several exchangable
     building blocks. A parser configuration is a construction plan for a
     specific parser, made of such components.

     To build the parsers, Object Construction Plans (OCPs) are used. For
     details on OCPs, please refer to <http://www.xocp.org>. Specifically, the
     parser configurations are placed in the ocp package:

       com/sphenon/engines/generator/parsers

     Putting the pieces together, the above parser configuration is found in
     a file in the ocp path at:

       com/sphenon/engines/generator/parsers/TP-2.0-plain_java-1.0.ocp

     In our example, it contains the following plan:

        <?xml version="1.0" encoding="UTF-8"?>
        <parser CLASS="TemplateParser" xmlns="http://xmlns.sphenon.com/com/sphenon/engines/generator">
          <TOMParser>
            <BeginHandler OID="mth" CLASS="TCHMain">
              <SourceHandler CLASS="TCHCompactUnicodeSyntax2ASCII">
                <ASCIISourceHandler CLASS="TCHLanguageDispatcher">
                  <TextHandler CLASS="TCHText"/>
                  <JavaCodeHandler CLASS="TCHJavaCode"/>
                  <JavaExpressionHandler CLASS="TCHJavaExpression"/>
                  <TemplateCommentHandler CLASS="TCHTemplateComment"/>
                  <TemplateCodeHandler CLASS="TCHTemplateCode"/>
                  <TagHandler CLASS="TCHTag"/>
                  <PPTagHandler CLASS="TCHPPTag"/>
                </ASCIISourceHandler>
              </SourceHandler>
            </BeginHandler>
            <SourceHandler OIDREF="mth"/>
            <EndHandler OIDREF="mth"/>
          </TOMParser>
        </parser>

  ⊱…
              
Example0130_Locators
Example0130_Locators
  G-2.0-java_jpp-1.0
  ⊰
     This example is a bit lengthy, but it's worth reading.

     One of the major issues with generator templates is their tendency to
     become clumsy over time, and often plain unreadable. The purpose of
     templates is to write the desired target output easily and concise -
     unfortunately, this interferes with controlling code.

     We've already seen how unicode syntax (Example0000_Unicode) and tiny syntax
     helpers (Example0060_PrettySyntax) help to keep templates tidy. Another
     means is of course moving longer code sequences into helper classes. Here's
     a fourth possibility.

     A very common type of template code is navigation code. I.e., given some
     instance, the programmer invokes a sequence of methods to navigate to a
     target instance. A simple example is:

         « Person person = ...; 
           Address address = person.getAddress();
           Vector<Phone> phones = address.getPhones();
           Phone phone = phones.get(2);
           Prefix prefix = phone.getPrefix();
         »

     If we just want to print the prefix, we can abbreviate like this:

         The prefix is: ◂person.getAddress().getPhones().get(2).getPrefix()▸

     The brackets and "gets" still look a bit clumsy, it looks better with
     pathes:

         The prefix is: ◂‖[person]"Ⓟ/Address/Phones/2/Prefix"▸

     This is in fact a valid expression that can be used in templates of an
     appropriate type.

     Pathes are not directly built into the template parser - this is where
     "Locators" come into play. The above statement is translated into an
     invocation of a locator, which handles the path at runtime. The translated
     code looks similar to this:

         Locator.resolve("//Property/Address/Phones/2/Prefix", person);

         (note the translation of the unicode "Ⓟ" into "//Property")

     At runtime, the locator then translates this into a sequences of "gets",
     like we've seen before. Admittedly, in this example, the syntactic
     difference is not too big. But locators are much more powerful than this!

     In fact, there's a universal concept behind them (you may want to
     check out <http://www.oorl.org>, too). With pluggable locator extensions,
     locators can be used to navigate through arbitrary structured
     data. Instances and their relations are just an example. Other's are:

         ‖"//File//home/me/myfile.txt"               a file in the file system
         ‖"//Space/company/workplace"                a space
         ‖"//XPath/article/section/title"            an element in a xml file
         ‖"//JavaResource/com/sphenon/basics"        a resource in your classpath
         ‖"//Artefact/org/oomodels"                  a resource in a project
         ‖"//Model/org/uml/stereotypes"              an element of a UML model
         ‖"//Address/Germany/Hamburg//Barkenkoppel"  a street in a city

     Moreover, locators can be concatenated

         ‖"//File//home/me/mytext.dbk/,//XPath/article/title"

     The last example reads a file in your home directory, parses it with an xml
     parser and retrieves it's title.

     In addition to properties, the following unicode abbreviations are
     predefined in the default preprocessor (CUS2ASCII):

        Ⓟ   Property (Java POJO property access)
        Ⓧ   XPath (navigation in xml, see www.w3c.org and xerces.apache.org)
        Ⓕ   File (navigation in file system)
        ✦   XModel (UML XModel extension property access)

     To supported different locator syntaxes, several delimiters are supported:

        ‖'...'
        ‖"..."
        ‖(...)
        ‖{...}
        ‖§...§

     To use locators, the parser has to know a little bit about the objects that
     are retrieved. For simple cases like property access, it's enough to
     declare the template type like we've done in this example:

         G-2.0-java_jpp-1.0

     The associated parser configuration enables the Java preprocessor, and
     declares the default object type for locators as "Object". For property
     access this is sufficient.

     To complete this example here's some more working code.

     First, we declare two test classes:
  ⊱…
  ▲
    public class Planet {
      public String getName() { return "world"; }
    }
    public class SolarSystem {
      public Planet getPlanet() { return new Planet(); }
    }
  ▲
  ⊰
     Then, we create a SolarSystem and use a property to access it's sole
     planet's name:
  ⊱…
  « SolarSystem solar_system = new SolarSystem(); »…

      Hello, ◂‖[solar_system]"Ⓟ/Planet/Name"▸!

  ⊰
    This, of course, prints "Hello, world!" again.
  ⊱…
              
Example0140_LocatorTargets
Example0140_LocatorTargets
  G-2.0-java_jpp-1.0
  ⊰
     As mentioned in the previos example, the parser sometimes needs to know
     something about the instances a locator returns. This is done by declaring
     a socalled "locator target":
  ⊱…

      ⋮⊏ locatortarget Object = (Object object) ⊐…

  ⊰
     The above statement is a declaration. It delares a locator target named
     "Object" with an instance type of "Object" and a variable name of "object".

     To switch between locator targets, the following selector can be used:
  ⊱…

      ⋮⊏ locatortarget Object ⊐…

  ⊰
     Note that the declaration of a locator target also implicitly selects
     it. Therefore, it is not necessary to write:
  ⊱…

      ⋮⊏ locatortarget Object = (Object object) ⊐…
      ⋮⊏ locatortarget Object ⊐…
              
Example0150_ParserInclusion
Example0150_ParserInclusion
  G-2.0-inclusion_test-1.0
  ⊰
     Now that we know how the parser configuration works, and how a template
     type selects a configuration, we can define our own template type.

     Let's assume we want to make a value magically available in all our
     templates of this new type:
  ⊱…

       The magic value is ◂magic_value▸ !

  ⊰
     First, we define a template type, in our example this is

        G-2.0-inclusion_test-1.0

     As we know now, this type points to a configuration in this OCP file

       com/sphenon/engines/generator/parsers/TP-2.0-inclusion_test-1.0.ocp

     This OCP file contains:

        <?xml version="1.0" encoding="UTF-8"?>
        <parser CLASS="TemplateParser" xmlns="http://xmlns.sphenon.com/com/sphenon/engines/generator">
          <TOMParser>

            ...

            <IncludeModules>
              <Module>com.sphenon.engines.generator.test.Example0150_ParserInclusion_MagicValueDefinition</Module>
            </IncludeModules>
          </TOMParser>
        </parser>

     This configuration specifies an include module Example0150_ParserInclusion_MagicValueDefinition.
     Modules have the file extension ".template.module" to distinguish them from
     normal templates. Syntactically, they are normal templates.

     The next example shows the content of this module.
  ⊱…
              
Example0160_ParserInclusion_MagicValueDefinition (Module)
Example0160_ParserInclusion_MagicValueDefinition (Module)
  G-2.0-plain_java-1.0
  ⊰
     As described in the previous example, Example0150_ParserInclusion, this is
     a template module. In our example, it defines a magic value, which is now
     available in all our templates of the newly introduced template type.
  ⊱…
  « int magic_value = 42; »…
              
Example0170_ControlBlocks
Example0170_ControlBlocks
  G-2.0-java_jpp-1.0 -*- coding: utf-8; -*-
  ⊰
     As mentioned in the previos example, the parser sometimes needs to know
     something about the instances a locator returns. This is done by declaring
     a socalled "locator target":
  ⊱…
  « Vector friends = new Vector();
    friends.add("Hans");
    friends.add("Willy");
    friends.add("Susi");
  »…
  ⊰

  ⊱…
  «∀(friend:friends){»…
     ◂friend▸
  «}/∀»…
  ⊰

  ⊱…
  «∀(friends){»…
     ◂object▸
  «}/∀»…
  ⊰

  ⊱…
  «∀(friends){»…
     ◂⊙▸
  «}/∀»…
  ⊰

  ⊱…
  « object = vector; »…
  «∀(⊙){»…
     ◂⊙▸
  «}/∀»…
  ⊰

  ⊱…
  «∀(enemies){»…
    ⋮«∀(-friend:friends){»…
       ◂⊙▸ prints current enemy!
       ◂friend⊙▸ prints current friend
    ⋮«}/∀»…
  «}/∀»…
  ⊰

  ⊱…
  «¬∅(⊙){»…
     Nicht leer! (FEHLER)
  «}/¬∅»…
  ⊰

  ⊱…
  «∅(⊙){»…
     Leer!
  «}/∅»…
  ⊰

  ⊱…
     «∀(⊙){»«➀{»My friends: «}∨{», «}/➀»◂⊙▸«}/∀»
  ⊰

  ⊱…
     My friends: «∀(⊙){»«¬➀{», «}/¬➀»◂⊙▸«}/∀»
  ⊰

  ⊱…
     ⋮«➀:(xy)»…
     My friends, 2 times: «∀(⊙){»«¬➀(xy){», «}/¬➀»◂⊙▸«}/∀»«∀(⊙){»«¬➀(xy){», «}/¬➀»◂⊙▸«}/∀»
  ⊰

  ⊱…
  «∀(⊙){»…
     Friend number ◂Ⓘ▸ : ◂⊙▸
  «}/∀»…
  ⊰

  ⊱…
  «Ⓘ:(my_index)»…
  «∀(⊙){»…
     Friend number ◂Ⓘ(my_index)++▸ : ◂⊙▸
  «}/∀»…
  ⊰

  ⊱…
  String friend = "Hans";
  «∃(⊙){»…
     I've got a friend: ◂⊙▸
  «}/∃»…
  ⊰

  ⊱…
  «∃(friend:⊙){»…
     I've got a friend: ◂friend▸
  «}/∃»…
  ⊰

  ⊱…
  String friend = null;
  «¬∃(⊙){»…
     I'm so lonely!
  «}/¬∃»…
  ⊰

  ⊱…
  boolean sun_is_shining = true;
  «⁇(sun_is_shining){»…
     Nice day!
  «}/⁇»…
  ⊰

  ⊱…
  sun_is_shining = false;
  «¬⁇(sun_is_shining){»…
     :-(
  «}/¬⁇»…