The Configure tool uses a "script" to tell it what configuration options to capture, how to capture them and where to put them. Here is a simple example illustrating the basic structure of a script file:
<configureScript> <type name="integer.type" pattern="[0-9]+"/> <type name="yesno.type"> <alt value="yes"/> <alt value="no"/> </type> <propFile name="test.properties"> <property name="prop1" type="integer.type" description="Enter an integer" default="0"/> <property name="prop2" type="yesno.type" description="Do you want to?" default="no"/> </propFile> <screen title="Testing set 1"> <item property="prop1"/> <item property="prop2"/> </screen> </configureScript>
The main elements of a script are "types", "property sets" and "screens". Lets describe these in that order.
A "type" element introduces a property type which defines a set of allowed values for properties specified later in the script file. A property type's value set can be defined using a regular expression (pattern) or by listing the value set. For more details refer to the "Specifying property types" page.
A "propFile" element introduces a property set consisting of the properties to be written to a given property file. Each property in the property set is specified in terms of a property name and a previously defined type, together with a (one line) description and an optional default value. For more details refer to the "Specifying property files" page.
A "screen" element defines the dialog sequence that is used to request configuration properties from the user. The screen consists of a list of properties, together with (multi-line) explanations to be displayed to the user. For more details refer to the "Specifying property screens" page.
Finally, the "Advanced features" page describes the control properties and the import mechanism.
Configuration property types define sets of allowable values that can be used in values defined elsewhere in a script file. A property type can be defined either using a regular expression or by listing the set of allowable values. For example:
<type name="integer.type" pattern="[0-9]+"/> <type name="yesno.type"> <alt value="yes"/> <alt value="no"/> </type>
The first "type" element defines a type whose values are unsigned integer literals. The second one defines a type that can take the value "yes" or "no".
In both cases, the value sets are modeled in terms of the "token" character sequences that are entered by the user and the "value" character sequences that are written to the property files. For a property types specified using regular expressions, the "token" and "value" sequences are the same, with one exception. The exception is that a sequence of zero characters is not a valid input token. So if the "pattern" could match an empty token, you must define an "emptyToken" that the user will use to enter this value. For example, the following defines a variant of the previous "integer.type" in which the token "none" is used to specify that the corresponding property should have an empty value:
<type name="optinteger.type" pattern="[0-9]*" emptyToken="none"/>
For property types specified by listing the values, you can make the tokens and values different for any pair. For example:
<type name="yesno.type"> <alt token="oui" value="yes"/> <alt token="non" value="no"/> </type>
Type values and tokens can contain just about any printable character (modulo the issue of zero length tokens). Type names however are restricted to ASCII letters, digits, '.', '-' and '_'.
A "propFile" element in a script file specifies details about a file to which configuration properties will be written. In the simplest case, a "propFile" element specifies a file name and a set of properties to be written. For example:
<propFile fileName="jnode.properties"> <property name="jnode.vm.size" type="integer.type" description="Enter VM size in Mbytes" default="512"/> <property name="jnode.vdisk.enabled" type="yesNo.type" description="Configure a virtual disk" default="no"/> </propFile<
This specifies a classic Java properties file called "jnode.properties" which will contain two properties. The "jnode.vm.size" property will have a value that matches the type named "integer.type", with a default value of "512". The "jnode.vdisk.enabled" will have a value that matches the "yesno.type", defaulting to "no".
The Configure tool will act as follows for the example above.
Attributes of a "property" element
Each "property" element can have the following attributes:
Attributes of a "propFile" element
The Configure tool will read and write properties in different ways depending on the "propFile" element's attributes:
Alternative file formats
As described above, the Configure tool supports five different file types: more if you use plugin classes. These are as follows:
The file types "xml", "java" and "text" require the use of a template file, and do not permit properties to be loaded.
Template file expansion
If Configure uses a java.util.Properties.saveXXX method to write properties, you do not have a great deal of control over how the file is generated. For example, you cannot include comments for each property, and you cannot control the order of the properties.
The alternative is to create a template of a file that you want the Configure tool to add properties to. Here is a simple example:
# This file contains some interesting properties # The following property is interesting interesting=@interesting@ # The following property is not at all interesting boring=@boring@
If the file above is specified as the "templateFile" for a property set that includes the "interesting" and "boring" properties, the Configure tool will output the property set by expanding the template to replace "@interesting@" and "@boring@" with the corresponding property values.
The general syntax for @...@ sequences is:
at_sequence ::= '@' name [ '/' modifiers ] '@' name ::= ... # any valid property name modifiers ::= ... # one or more modifier chars
The template expansion process replaces @...@ sequences as follows:
The template expansion is aware of the type of the file being expanded, and performs file-type specific escaping of properties before writing them to the output stream:
The "dialog" between the Configure tool and the user is organized into sequences of questions called screens. Each screen is a described by a "screen" element in the configuration script. Here is a typical example:
<screen title="Main JNode Build Settings"> <item property="jnode.virt.platform"> The JNode build can generate config files for use with various virtualization products. </item> <item property="expert.mode"> Some JNode build settings should only be used by experts. </item> </screen>
When the Configure tool processes a screen, it first outputs the screen's "title" and then iterates over the "item" elements in the screen. For each item, the tool outputs the multi-line content of the item, followed by a prompt formed from the designated property's description, type and default value. The user can enter a value, or just hit ENTER to accept the default. If the value entered by the user is acceptable, the Configure tool moves to the next item in the screen. If not, the prompt is repeated.
Conditional Screens
The screen mechanism allows you to structure the property capture dialog(s) independently of the property files. But the real power of this mechanism is that screens can be made conditional on properties captured by other screens. For example:
<screen title="Virtualization Platform Settings" guardProp="jnode.virt.platform" valueIsNot="none"> <item property="jnode.vm.size"> You can specify the memory size for the virtual PC. We recommended a memory size of least 512 Mbytes. </item> <item property="jnode.virtual.disk"> Select a disk image to be mounted as a virtual hard drive. </item> </screen>
This screen is controlled by the state of a guard property; viz the "guardProp" attribute. In this case, the "valueIsNot" attribute says that property needs to be set to some value other than "none" for the screen to be acted on. (There is also a "valueIs" attribute with an analogous meaning.)
The Configuration tool uses an algorithm equivalent to the following one to decide which screen to process next:
The "changed" attribute
The "item" element of a screen can take an attribute called "changed". If present, this contains a message that will be displayed after a property is captured if the new value is different from the previous (or default) value. For example, it can be used to remind the user to do a full rebuild when critical parameters are changed.