-
Notifications
You must be signed in to change notification settings - Fork 70
cobigen core_configuration
CobiGen will be configured using a configuration folder containing a context configuration, multiple template folders with a templates configuration per template folder, and a number of templates in each template folder. See some examples here. Thus, a simple folder structure might look like this:
CobiGen_Templates
|- templateFolder1
|- templates.xml
|- templateFolder2
|- templates.xml
|- context.xml
In addition, it is possible to implement more complex template logic by custom Java code since cobigen-core-3.0.0 which is included in the Eclipse and Maven Plugin since version 2.0.0. To enable this feature, you can simply turn the CobiGen_Templates
into a simple maven project (if it is not already) and implement any Java logic in the common maven layout (e.g. in the source folder src/main/java
). Each Java class will be instantiated by CobiGen for each generation process. Thus, you can even store any state within a Java class instance during generation. However, there is currently no guarantee according to the template processing order.
As a consequence, you have to implement your Java classes with a public default (non-parameter) constructor to be used by any template. Methods of the implemented Java classes can be called within templates by the simple standard FreeMarker expression for calling Bean methods: SimpleType.methodName(param1)
. Until now, CobiGen will shadow multiple types with the same simple name indeterministically. So please prevent yourself from that situation.
Finally, if you would like to do some reflection within your Java code accessing any type of the template project or any type referenced by the input, you should load classes by making use of the classloader of the util classes. CobiGen will take care of the correct classloader building including the classpath of the input source as well as of the classpath of the template project. If you use any other classloader or build it by your own, there will be no guarantee, that generation succeeds.
The context configuration (context.xml
) always has the following root structure:
<?xml version="1.0" encoding="UTF-8"?>
<contextConfiguration xmlns="http://capgemini.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<triggers>
...
</triggers>
</contextConfiguration>
The context configuration has a version
attribute, which should match the XSD version the context configuration is an instance of. It should not state the version of the currently released version of CobiGen. This attribute should be maintained by the context configuration developers. If configured correctly, it will provide a better feedback for the user and thus higher user experience. Currently there is only the version v1.0. For further version there will be a changelog later on.
As children of the <triggers>
node you can define different triggers. By defining a <trigger>
you declare a mapping between special inputs and a templateFolder
, which contains all templates, which are worth to be generated with the given input.
<trigger id="..." type="..." templateFolder="..." inputCharset="UTF-8" >
...
</trigger>
-
The attribute
id
should be unique within an context configuration. It is necessary for efficient internal processing. -
The attribute
type
declares a specific trigger interpreter, which might be provided by additional plug-ins. A trigger interpreter has to provide an input reader, which reads specific inputs and creates a template object model out of it to be processed by the FreeMarker template engine later on. Have a look at the plug-in’s documentation of your interest and see, which trigger types and thus inputs are currently supported. -
The attribute
templateFolder
declares the relative path to the template folder, which will be used if the trigger gets activated. -
The attribute
inputCharset
(optional) determines the charset to be used for reading any input file.
A trigger will be activated if its matchers hold the following formula:
!(NOT || … || NOT) && AND && … && AND && (OR || … || OR)
Whereas NOT/AND/OR describes the accumulationType of a matcher (see below) and e.g. NOT
means 'a matcher with accumulationType NOT matches a given input'. Thus additionally to an input reader, a trigger interpreter has to define at least one set of matchers, which are satisfyable, to be fully functional. A <matcher>
node declares a specific characteristics a valid input should have.
<matcher type="..." value="..." accumulationType="...">
...
</matcher>
-
The attribute
type
declares a specific type of matcher, which has to be provided by the surrounding trigger interpreter. Have a look at the plug-in’s documentation, which also provides the used trigger type for more information about valid matcher and their functionalities. -
The attribute
value
might contain any information necessary for processing the matcher’s functionality. Have a look at the relevant plug-in’s documentation for more detail. -
The attribute
accumulationType
(optional) specifies how the matcher will influence the trigger activation. Valid values are:-
OR (default): if any matcher of accumulation type OR matches, the trigger will be activated as long as there are no further matchers with different accumulation types
-
AND: if any matcher with AND accumulation type does not match, the trigger will not be activated
-
NOT: if any matcher with NOT accumulation type matches, the trigger will not be activated
-
Finally, a <matcher>
node can have multiple <variableAssignment>
nodes as children. Variable assignments allow to parametrize the generation by additional values, which will be added to the object model for template processing. The variables declared using variable assignments, will be made accessible in the templates.xml as well in the object model for template processing via the namespace variables.*
.
<?xml version="1.0" encoding="UTF-8"?>
<contextConfiguration xmlns="http://capgemini.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<triggers>
<trigger id="..." type="..." templateFolder="...">
<matcher type="..." value="...">
<variableAssignment type="..." key="..." value="..." />
</matcher>
</trigger>
</triggers>
</contextConfiguration>
-
The attribute
type
declares the type of variable assignment to be processed by the trigger interpreter providing plug-in. This attribute enables variable assignments with different dynamic value resolutions. -
The attribute
key
declares the namespace under which the resolved value will be accessible later on. -
The attribute
value
might declare a constant value to be assigned or any hint for value resolution done by the trigger interpreter providing plug-in.
The <containerMatcher>
node is an additional matcher for matching containers of multiple input objects.
Such a container might be a package, which encloses multiple types or---more generic---a model, which encloses multiple elements. A container matcher can be declared side by side with other matchers:
<?xml version="1.0" encoding="UTF-8"?>
<contextConfiguration xmlns="http://capgemini.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<triggers>
<trigger id="..." type="..." templateFolder="..." >
<containerMatcher type="..." value="..." retrieveObjectsRecursively="..." />
<matcher type="..." value="...">
<variableAssignment type="..." variable="..." value="..." />
</matcher>
</trigger>
</triggers>
</contextConfiguration>
-
The attribute
type
declares a specific type of matcher, which has to be provided by the surrounding trigger interpreter. Have a look at the plug-in’s documentation, which also provides the used trigger type for more information about valid matcher and their functionalities. -
The attribute
value
might contain any information necessary for processing the matcher’s functionality. Have a look at the relevant plug-in’s documentation for more detail. -
The attribute
retrieveObjectsRecursively
(optional boolean) states, whether the children of the input should be retrieved recursively to find matching inputs for generation.
The semantics of a container matchers are the following:
-
A
<containerMatcher>
does not declare any<variableAssignment>
nodes -
A
<containerMatcher>
matches an input if and only if one of its enclosed elements satisfies a set of<matcher>
nodes of the same<trigger>
-
Inputs, which match a
<containerMatcher>
will cause a generation for each enclosed element
The template configuration (templates.xml
) specifies, which templates exist and under which circumstances it will be generated. There are two possible configuration styles:
-
Configure the template meta-data for each template file by template nodes
-
(since cobigen-core-v1.2.0): Configure templateScan nodes to automatically retrieve a default configuration for all files within a configured folder and possibly modify the automatically configured templates using templateExtension nodes
To get an intuition of the idea, the following will intially describe the first (more extensive) configuration style. Such an configuration root structure looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<templatesConfiguration xmlns="http://capgemini.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<templates>
...
</templates>
<increments>
...
</increments>
</templatesConfiguration>
<templatesConfiguration>
mainly specifies one attribute. The attribute version
provides further usability support and will be handled analogous to the version
attribute of the context configuration. The node <templatesConfiguration>
allows two different grouping nodes as children. First, there is the <templates>
node, which groups all declarations of templates. Second, there is the <increments>
node, which groups all declarations about increments.
The <templates>
node groups multiple <template>
declarations, which enables further generation. Each template file should be registered at least once as a template to be considered.
<templates>
<template id="..." destinationPath="..." templateFile="..." mergeStrategy="..." targetCharset="..." />
...
</templates>
A template declaration consist of multiple information:
-
The attribute
id
specifies an unique ID within the templates configuration, which will later be reused in the increment definitions. -
The attribute
destinationPath
specifies the destination path the template will be generated to. It is possible to use all variables defined by variable assignments within the path declaration using the FreeMarker syntax${variables.*}
. While resolving the variable expressions, each dot within the value will be automatically replaced by a slash. This behavior is accounted for by the transformations of Java packages to paths as CobiGen has first been developed in the context of the Java world. Furthermore, the destination path variable resolution provides the following additional built-in operators analogue to the FreeMarker syntax:-
?cap_first
analogue to FreeMarker -
?uncap_first
analogue to FreeMarker -
?lower_case
analogue to FreeMarker -
?upper_case
analogue to FreeMarker -
?replace(regex, replacement)
- Replaces all occurrences of the regular expressionregex
in the variable’s value with the givenreplacement
string. (since cobigen-core v1.1.0) -
?removeSuffix(suffix)
- Removes the givensuffix
in the variable’s value iff the variable’s value ends with the givensuffix
. Otherwise nothing will happen. (since cobigen-core v1.1.0) -
?removePrefix(prefix)
- Analogue to?removeSuffix
but removes the prefix of the variable’s value. (since cobigen-core v1.1.0)
-
-
The attribute
templateFile
describes the relative path dependent on the template folder specified in the trigger to the template file to be generated. -
The attribute
mergeStrategy
(optional) can be optionally specified and declares the type of merge mechanism to be used, when thedestinationPath
points to an already existing file. CobiGen by itself just comes with amergeStrategy
override
, which enforces file regeneration in total. Additional available merge strategies have to be obtained from the different plug-in’s documentations (see here for java, XML, properties, and text). Default: not set (means not mergable) -
The attribute
targetCharset
(optional) can be optionally specified and declares the encoding with which the contents will be written into the destination file. This also includes reading an existing file at the destination path for merging its contents with the newly generated ones. Default: UTF-8
(since cobigen-core-v1.2.0)
The second configuration style for template meta-data is driven by initially scanning all available templates and automatically configure them with a default set of meta-data. A scanning configuration might look like this:
<?xml version="1.0" encoding="UTF-8"?>
<templatesConfiguration xmlns="http://capgemini.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.2">
<templateScans>
<templateScan templatePath="templates" templateNamePrefix="prefix_" destinationPath="src/main/java"/>
</templateScans>
</templatesConfiguration>
<templateScan …>
nodes for different templatePaths
and different templateNamePrefixes
.
-
The
name
can be specified to later on reference the templates found by a template-scan within an increment. (since cobigen-core-v2.1.) -
The
templatePath
specifys the relative path from thetemplates.xml
to the root folder from which the template scan should be performed. -
The
templateNamePrefix
(optional) defines a common id prefix, which will be added to all found and automatically configured templates. -
The
destinationPath
defines the root folder all found templates should be generated to, whereas the root folder will be a prefix for all found and automatically configured templates.
A templateScan
will result in the following default configuration of templates. For each file found, new template will be created virtually with the following default values:
-
id
: file name without.ftl
extension prefixed bytemplateNamePrefix
fromtemplate-scan
-
destinationPath
: relative file path of the file found with the prefix defined bydestinationPath
fromtemplate-scan
. Furthermore,-
it is possible to use the syntax for accessing and modifying variables as described for the attribute
destinationPath
of the template node, besides the only difference, that due to file system restrictions you have to replace all?
-signs (for built-ins) with#
-signs. -
the files to be scanned, should provide their final file-ending by the following file naming convention:
<filename>.<fileending>.ftl
Thus the file-ending.ftl
will be removed after generation.
-
-
templateFile
: relative path to the file found -
mergeStrategy
: (optional) not set means not mergable -
targetCharset
: (optional) defaults to UTF-8
(since cobigen-core-v1.2.0)
Additionally to the templateScan declaration it is easily possible to rewrite specific attributes for any scanned and automatically configured template.
<templates>
<templateExtension idref="prefix_FooClass.java" mergeStrategy="javamerge" />
</templates>
<templateScans>
<templateScan templatePath="foo" templateNamePrefix="prefix_" destinationPath="src/main/java/foo"/>
</templateScans>
Lets assume, that the above example declares a template-scan
for the folder foo
, which contains a file FooClass.java.ftl
in any folder depth. Thus the template scan will automatically create a virtual template declaration with id=prefix_FooClass.java
and further default configuration.
Using the templateExtension
declaration above will reference the scanned template by the attribute idref
and overrides the mergeStrategy
of the automatically configured template by the value javamerge
. Thus we are able to minimize the needed templates configuration.
The <increments>
node groups multiple <increment>
nodes, which can be seen as a collection of templates to be generated. An increment will be defined by a unique id
and a human readable description
.
<increments>
<increment id="..." description="...">
<incrementRef idref="..." />
<templateRef idref="..." />
<templateScanRef ref="..." />
</increment>
</increments>
An increment might contain multiple increments and/or templates, which will be referenced using <incrementRef …>
, <templateRef …>
, resp. <templateScanRef …>
nodes. These nodes only declare the attribute idref
or ref
respectively, which will reference an increment, a template, or a template-scan by its id
or name
.
Disclaimer
If you discover any documentation bugs or would like to request new content, please raise them as an issue or create a pull request. Contributions to this wiki are done through the main repo under the folder documentation.
License
This documentation is licensed under the Creative Commons License (Attribution-NoDerivatives 4.0 International
)