Tuesday, March 25, 2008

Settings, attributes and option default values

The ControlTier 3.1 framework includes a pretty elegant set of rules and conventions for managing the options used in command handlers. Whereas prior to 3.1 the delivery of model data values into a particular command context was fairly unstructured, there is now an ordered set of steps to achieve this that offers the predictability of an established order of precedence.

Reviewing the following excerpt from a module's type XML:
<?xml version="1.0" encoding="UTF-8"?>

<!--
type-xml.generated.date: Wed Mar 07 11:53:24 PST 2007
type-xml.generator.class: com.controltier.shared.cli.ConvertTypeRDFToXML
type-xml.author: $Author$
type-xml.id: $Id$
-->

<types xmlns:cmd="http://open.controltier.com/base/Modules/Commands#" xmlns:module="http://open.controltier.com/base/Modules#" xmlns:type="http://open.controltier.com/base/Types#">
.
.
.

<type role="concrete" uniqueInstances="true" name="HsqldbRdbJavaHome" order="Setting">
<description>JAVA_HOME to use to run a Hypersonic SQL database server instance</description>
<supertype>
<typereference name="HsqldbRdbSetting"/>
</supertype>
<attributes>
<attribute name="hsqldbRdbJavaHome" type-property="settingValue"/>
</attributes>
</type>

.
.
.

<type role="concrete" uniqueInstances="true" name="HsqldbRdb" order="Service">
<description>A Hypersonic SQL database service</description>

<supertype>
<typereference name="Rdb"/>
</supertype>

<attributes>
<attribute-default name="hsqldbRdbJavaHome" value="${env.JAVA_HOME}"/>
.
.
.
</attributes>

<constraints>
<dependency-constraint enforced="false" kind="child">
<allowedtypes>
.
.
.
<typereference name="HsqldbRdbJavaHome"/>
.
.
.
</allowedtypes>
<singletontypes>
.
.
.
<typereference name="HsqldbRdbJavaHome"/>
.
.
.
</singletontypes>
.
.
.
</constraints>
.
.
.
<commands>
.
.
.
<command name="startService" description="Start the Hypersonic SQL database server instance" command-type="AntCommand">
<opts>
.
.
.
<opt parameter="javahome" description="Value of JAVA_HOME" required="false" property="opts.javahome" defaultproperty="entity.attribute.hsqldbRdbJavaHome" default="${env.JAVA_HOME}" type="string"/>
</opts>
</command>
.
.
.
</commands>
</type>
</types>

... starting from the startService command definition:
  • By convention, the goal is to make every configurable property used by a command's implementation available via an option definition.
  • Each option's property (in this case "property=opts.javahome") contains a value potentially provided from one of a number of sources in the following order of precedence:
  1. The value can be provided via the command line when the command is executed, otherwise ...
  2. The value will be initialized from a default property (i.e. defaultproperty="entity.attribute.hsqldbRdbJavaHome") if it is specified and exists, or ...
  3. The default value specified as an option attribute (default="${env.JAVA_HOME}") will be used.
  • If none of these sources are satisfied the option property is left unset, or, if the "required" attribute is set to "true", command execution fails.
This said, note how the default property is assigned using an "entity attribute" property value which arises from the Workbench project (i.e. the type/object model) as follows:
  • The properties intrinsic to each type can be assigned a general attribute name.
  • By convention, a setting type's "value" is assigned such a name (in this case the "HsqldbRdbJavaHome" setting type defines the "hsqldbRdbJavaHome" attribute naming the setting's value.
  • Adding the setting as an allowed singleton resource of the deployment type whose command implementation(s) wish to exploit it makes an attribute value available to objects of that type (see the constraints tab of the type page, and the properties tab of the object page for each module for the list of entity attributes).
Finally, note that entity attribute properties constructed in this fashion can receive values in the following ways:
  1. A resource relationship is setup and the entity attribute value is imported from the setting object.
  2. No such relationship is established and a so called "type level default attribute" value defined directly in the type.xml is used instead (the "attribute-default" value of "${env.JAVA_HOME}" in this case).
So, in summary, the value of "opts.javahome" in the example will come from one of the following sources in order of precedence:
  1. A value provided on the command line when the command is executed.
  2. A HsqldbRdbJavaHome setting value (from a child resource).
  3. The type level attribute default value allowed by the HsqldbRdb type's constraints.
  4. In cases where no type level attribute default value exists, the default value specified on the command's option definition (redundant in this case).
Anthony Shortland.
anthony@controltier.com

No comments: