The domain model is described in a set of xml files. Everything which is generated is based on the definition of the domain model.
The definition can be split over multiple files. There are a few methods to include extra files in the overall definition.
For starters, the declaration of a table can be done by refering to a file or directory. In the latter case all "*.table" files in that directory are included.
Alternatively, the "include" tag can be used to include xml excepts from a file.
The domain model had the following structure
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE equanda SYSTEM "equanda.dtd">
<equanda>
<type name="externalReferenceString" length="30"/>
<type name="titleString" length="100">
<display/>
<indexed/>
</type>
<table dir="."/>
<table file="shared/Vehicle.xml"/>
<table file="classpath://my/appliction/Airplane.table"/>
</equanda>
This demonstrates the typical structure. The main file contains the "type" definitions which can be applied to the fields in the tables. It also contains the tables themselves. In that case these are defined in separate files. The system will search the current directory (where the main file was found for all files ending ".table", and also include references the "Vehicle.xml" table definition in a subdirectory and an "Airplane" definition which should be available in the classpath.
For notation the description below uses italics for tag names and bold for attribute names.
A table definition can have the following attributes :
Each table can be given a description and semantic annotations using subectory.
The inheritance tree is specified using the template tag. Each template specifies a parent table. Note that it is possible to use multiple inheritance (more than one template tag in a table). In that case all fields from all templates will be available, but the prorammatic constraints need to be repeated (only the programmatic constraints from the first template are automatically applied).
On the template tag, you can put the following attributes :
A template can contain several overwite-default tags which overwrite the default values when the table has this type. There is a field attribute which details the fieldname and the value specifies the new default value.
On a table you can define data-filter information. This only applies to the root table (the root of the inheritance tree). With a data filter, you can narrow the records which are visible in a certain situation. For example, you could define a filter to only include/visualize the active records in a table.
A data-filter has a "name" attribute and contains a filter-query element. This contains the necessary addition in the "from" and "where" parts of the EJB-QL query. In these you can put "${}" which will be replaced by the filter value when the uery is applied. A data query only changes the query itself when the value is not null. In code the SelectorsState class is used to set and clear filter values.
When you create objects without specifying the actual subtype, they are normally created as instances of the root table (when this is not marked as "internal"). However, you can use the default-instance tag to either indicate that this type should be the default (when there is no "class-name" attribute), or specify a class which determines the default type (using the "class-name" attribute, should implement org.equanda.validation.DefaultInstance). The "forced" attribute allows you to determine whether this is the only type which can be instantiated, or whether is is just a normal default which can be overridden.
As enterprise java beans are created, you can specify the roles which are allowed to access the data (all getters/setters and defaults for the select/action/build) and which roles are allowed to remove objects. The can be specified as comma separated lists to the security-role and security-role-remove tags. The defaults (when not specified on the table) come from the configuration file.
On a table you can define the cascade-keep status. When a table is marked as cascade-keep, then all records which have a link to (a record from) this table cannot be deleted.
The actual data in a table is grouped in page and group elements. this nesting is done the enable related items to be displayed together in the user interface.
The fields are split into pages. There are always displayed together on the screen. You can also put fields in the "ALL" page. These fields will allways be displayed, typically at the top of each page.
Inside a pgae, you can either put the fields directly, or grouped in group. Groups can be nested. Normally some visual indication is given to indicated that fields in a group belong together.
See below for a separate section about field elements and their possible content.
The cloneable and not-cloneable tags are used to determine whether records can be cloned (that is copies created for further editing). By default records are not-cloneable. You can still determine on the fields whether they should indeed be cloned or not (default there is cloneable).
The constraints tag allows you to specify some table attributes. At table level, the immutable-if and mutable-even-if constraints can be used. This allows something like the following.
<table>
<field name="Whatever"/>
<field name="Locked" type="boolean"/>
<field name="ExceptionCondition" type="boolean"/>
<constraints>
<immutable-if field="Locked"/>
<mutable-even-if field="Locked" when="ExceptionCondition"/>
</constraints>
</table>
In this table, any change to the fields will be disallowed once the "Locked" field is set. However, when the "ExceptionCondition" is also set, then editing is allowed, irrespective of whether "Locked" is true or not.
The hide tag allows you to tell equanda that the generated user interface should not include this table.
You can add select tags to create selectors (sometimes referred to as finders), build to create new instances with specific calculations and action to create actions on the instances of the table.
A field definition can have the following attributes :
Each field can be given a description and semantic annotations using subectory.
A field can be marked as internal, auto or calculated. Internal fields are not visible to the outside world. They are part of the entity beans and database representation, but have no getters or setters. Auto fields have got getters, but no setters, the values are initialized and maintained in the mediators. A calculated field also has only a getter, but it is calculated when requested, it has no database representation.
For string, int and double type fields, you can limit the set of allowed values by specifying one or more choice values. These can list explicit values (with a name), or allow you to refer to a class which lists the possible values. Note that "null" is also allowed as value for string fields if the required constraint is not set. Normally you should also set a default value for fields with choice tags.
You can determine the multiplicity of the field by using multiple. Normally a field can have only one value (multiplicity 0..1, which becomes 1..1 when the required constraint is used). The multiple tag indicates that more than one value is allowed, giving a 0..N value which can be changed to 1..N by using the required constraint.
When a field is a link to a different table. There are many settings that allow you to control the behaviour of the link.
You can specify a default value wich should be assigned when new instances are created of the record. These can either be specified as explicit values (or the choice name) (note that for strings, a literal value should be enclosed in double quotes), or a class-name can be given which is used to determine the default value at runtime. For date and timestamp fields, some aliases like "NOW", "TODAY", "YESTERDAY" and "TOMORROW" are also allowed.
The clonability of the field can be specified using cloneable and not-cloneable. These are only used when the table is marked as "cloneable". By default all fields in a cloneable table are themselves also cloneable, so you will normally only use not-cloneable when this is not the case.
You can specify several field level constraints :
As user interface hints you can specify display which means that the field will by default be included in record summaries and lists, or hide which means that the field will never be included in the user interface.
If the field is marked as indexed then a database level index will be created by ddltool.
For string fields, it is possible to indicate whether the case for the values is always "upper" or "lower". Using "mixed" means everything is allowed. The value can be calulated is you specify a "class-name".
Using is-reference and is-description you can give hints whether the field is a reference or description field. One of each is allowed to be specified on a table. This is used in the user interface (both are automatically treated as display fields for example) and also affects the selects which are automatically created.
All tables always include at least one select called "EquandaAll" which selects all records in the table, sorted on creation timestamp.
If the table has a Reference of Description field (either fields which is marked as such or else fields which have this exact name), then some selects are added to select based on the start of (reference and description) the field or part of the field (description only).
Apart from these more selects can be added in the domain model.
When you define a select in a table which is not root, then only records of the current type (or children thereof) will be selected.
A select definition can have the following attributes :
Each select can be given a description.
A select or subselect can have either one or more selection child tags or one or more select tags, not a combination of both. On a subselect you can again specify the operator but only "AND" and "OR" are allowed in this case.
A selection can have the following attributes :
You can also specify the EJBQL query directly using the query tag.
The security-role which is allowed to call this select can also be specified. This defaults to the security-role for the table, but you can replace this by a different set of comma separated roles.
When hide is set, the select will not be included in the list of selects in the user interface.
You can also specify a view-filter, which allows a runtime selection whether the select is visible. The value is a comma separated list of filter names. The select is only visible in gui if NONE of these filters has a value (they can be set using the SelectorsState class).
A build allows you to have some special code executed when creating objects. The default way is to just consider the default values for the fields, but using build you can have extra parameters and specific calculations.
A build has a name attribute which determines the method to create the instsance. According to the java naming convention, this should start with a lower case character. You should assure there are no actions with the same name. It is recommended there are no fields with the same name (though this is allowed).
Each build can be given a description.
You can specify as many parameter tags as needed for the build. They can all have a description and the following attributes :
You can also specify a specific set of default values which should be used for this build (possibly making it unnecessary to provide code). This can be sone using set tags. The value is used as default value which is assigned to the given field (attribute).
The security-role which is allowed to call this build can also be specified. This defaults to the security-role for the table, but you can replace this by a different set of comma separated roles.
An action allows you to define a method which can be called on a instance from the table in which the action is defined. The actual work which is executed has to be coded in the mediator class.
A action can have the following attributes :
Each action can be given a description.
You can specify as many parameter tags as needed for the action. They can all have a description and the following attributes :
The security-role which is allowed to call this action can also be specified. This defaults to the security-role for the table, but you can replace this by a different set of comma separated roles.
When hide is set, the action will not be included in the list of actions in the user interface.
A type is a field template. A type definition allows a subset of the information to be specified which is possible for a field. Field can then be given a type's name and the definitions from the type will then be pulled in when not overriden at the field level.
A type can have the following attributes :
Each type can be given a description.
A type can be marked as internal. The fields of this type is not visible to the outside world. They are part of the entity beans and database representation, but have no getters or setters.
For string, int and double type fields, you can limit the set of allowed values by specifying one or more choice values. These can list explicit values (with a name), or allow you to refer to a class which lists the possible values. Note that "null" is also allowed as value for string fields if the required constraint is not set. Normally you should also set a default value for fields with choice tags.
You can determine the multiplicity of the fields of this type by using multiple. Normally a field can have only one value (multiplicity 0..1, which becomes 1..1 when the required constraint is used). The multiple tag indicates that more than one value is allowed, giving a 0..N value which can be changed to 1..N by using the required constraint.
When the type indicates a link to a different table, you can marked that it should be implemented as embedded link.
You can specify a default value wich should be assigned when new instances are created of the record. These can either be specified as explicit values (or the choice name) (note that for strings, a literal value should be enclosed in double quotes), or a class-name can be given which is used to determine the default value at runtime. For date and timestamp fields, some aliases like "NOW", "TODAY", "YESTERDAY" and "TOMORROW" are also allowed.
You can specify several field level constraints :
As user interface hints you can specify display which means that the field will by default be included in record summaries and lists, or hide which means that the field will never be included in the user interface.
If the field is marked as indexed then a database level index will be created by ddltool.
For string fields, it is possible to indicate whether the case for the values is always "upper" or "lower". Using "mixed" means everything is allowed. The value can be calulated is you specify a "class-name".
Included files normally have a include-data root tag. This can contain the following :