Wiki
Clone wikiwurbelizer / source-syntax
Source Level Syntax
Java comments, whether single line or block comments, are parsed by the wurbler for wurblet anchors, variables and here-documents. This applies to generated comments as well! Consequently, generated code may include new anchors, variables or documents that in turn are evaluated by the wurbler and so on. This is an important feature because it allows bootstrapping from a rudimentary template similar to a software developer starting with a sketch (you won’t understand until you know how it became). Special significance of a character can be turned off by preceding it with a backslash. A line terminated by a backslash is concatenated with the following line (continuation line). The backslash itself is expressed by a double backslash.
Wurblet Anchor
All generated code, whether a single line or a large block, must be bound to a wurblet and optional variables or resources such as model information. The binding is done by a so-called wurblet anchor. There may be as many anchors in a comment block as desired. The wurblets are applied by the wurbler in the order of their anchors in the source file. The generated output is inserted into the source file right after the comment. Each output block is embraced by special comment lines that uniquely identify the block and allow the wurbler to associate it to the anchor in subsequent wurbelization passes. Once the code is generated, the anchor may be moved in the source file anywhere without losing the binding. Thus, the source file may be edited and anchors or the model information changed between wurbelization passes without getting out of sync.
An anchor is of the form:
@wurblet[(wurbler-directive)] <tag> <wurblet> [<arg1> [... <argN>]]
where:
@wurblet
: starts an anchor(wurbler-directive1 ... N)
: optional directives to the wurbler<tag>
: is a tag uniquely identifying the anchor within the source file-
<wurblet>
: is either the classname of the wurblet. This is either an absolute classname or a basename to which the wurbler will prepend the package names provided by the wurbletPaths configuration. -
<arg1>...
: optional wurblet arguments. Usually, the wurblet arguments carry model information or refer to such.
Anchors that span more than one line must be concatenated by a trailing backslash at the end of the lines to be continued. Arguments are separated by whitespaces. If an argument contains whitespaces, it must be enclosed in double quotes. Such arguments may span more than one line as well. Arguments may contain $-signs denoting a variable. Variables may either be declared in a variable section, can be an ant property, a property from a wurb-file or an environment variable. The variable substitution process is recursive, i.e. variables may contain strings referring to other variables and so on.
Examples:
/** * Principals are cached preloaded with a second index ’code’. * * @wurblet cache PdoCache --preload code */ // @wurblet updateByObjectTypeSerial DbUpdateBy --model=$mapfile \ // processed:=:null objectClassId objectId modType serial:<= | processed
Unnamed Anchor
If the <tag>
in the wurblet anchor does not start with a letter,
it is considered as an unnamed wurblet anchor. Unnamed anchors are useful for
so-called inline wurblets, which are commonly used to inject a small piece
of code into the code block directly preceding or following the anchor. The
code is injected between two consecutive empty block comments /**/
. The
first character of the tag determines whether the preceding or following code
block is targeted by the wurblet.
- The characters
-
or<
refer to the preceding block - all others, including
+
or>
refer to the following block
Example:
@TableName(/**/"modlog"/**/) // @wurblet < Inject --string $tablename
Inject
(which is a
Tentackle wurblet, btw.)
inserts the string "modlog"
into the @TableName
annotation. The value is defined by
the variable $tablename
.
Conditional Anchor
Wurblets may be invoked conditionally.
This is achieved by the test
-directive.
Example:
// @wurblet(test:$planb==yes) runPlanB Didoedeldu
Will invoke the wurblet Didoedeldu
if the variable $planb
equals the string yes
.
Otherwise the comment // condition not met
will be generated.
Currently, only the operators ==
and !=
are supported.
Extra Indentation
The generated code may be indended by extra spaces with the indent wurbler directive. 0 means no extra indent, a negative value is interpreted as smart indent, which is the default for Java sources. Smart indent aligns the generated code with the comment block containing the wurblet anchor.
Example:
// @wurblet(indent=4) someMethod DoIt
Editor Fold
An optional editor fold type for the generated code may be specified. Not all guard types support a fold type. Currently, editor folds are only supported by the Netbeans-IDE. By default, no editor fold will be generated. The following fold types are supported:
collapsed
: the generated code will be collapsedexpanded
: the generated code will be expandednone
: the generated code will get no fold-handle (default)
Example:
// @wurblet(fold=expanded) modelComment ModelComment
Notice that some IDEs automatically fold a guarded block (also known as custom code folding region) by default. IntelliJ does so, for example.
Here Documents
Here-Documents are an elegant way to provide model information to the wurblets
or to create files in general. Whenever the wurbler detects a document
section within a comment block, it creates a file either on heap or in the
filesystem depending on the file’s name. Document sections start with @>
and terminate with @<
.
Example (from the Wurbelizer tutorial):
/* * @> .$filename * String name the name * long id the unique ID * boolean enabled whether enabled or not * @< */
Notice that the filename may be a variable again. If the filename starts with a dot, it will not be saved to the filesystem but instead kept in memory only. Furthermore, such heap files must be unique within the wurbler instance. If the wurbler is invoked from within maven (which usually is the case), the file is available during the whole wurbel lifecycle phase, to all wurblets in all files. This feature allows running wurblets in distinct phases, each phase creating some information for the next phase.
Variables
Maven (or Ant) properties and environment variables are automatically declared
as variables by the wurbler. Additional variables may be declared either in extra
property-files (extension .wurb
) or directly at the source level within any
comment block. Such a declaration section starts with @{
and ends with @}
.
Example (from the Tentackle tutorial):
/* * @{ * tablename = md.orgunit * mapping = $model/$tablename.map * @} */
Variables can be used in comments or other variable definitions in two ways:
$<variable>
: e.g.$tablename.map
where the dot automatically ends the variable name${<variable>}
: e.g.${tablename}xx
to add the stringxx
to the tablename's value
Updated