Domain model

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.

table

A table definition can have the following attributes :

  • name : name of the table. This is expected to start with a capital to adhere to the Java naming convention.
  • file : when this is specified, the specified file will replace the table definition. The file is searched on the filesystem, relative to the location of the main file. However, when the value starts with "classpath://" then the file is retrieved using the classloader.
  • dir : when this is specified, the given wildcard expession is used to find all the files which contain the table definitions. The locatio is relative with the location of the main file.
  • type : this is a code of up to four characters which is used to discriminate tables which are part of the same hierarchy (as specified using the "template" tags). This is typically not specified on the root table, but only on the children (this is merely a convention, it is not enforced). The value needs to be unique within the inheritance tree.
  • expected-amount : an indication of the number of records which are expected to be in this table. Allowed values are "small", "medium" and "large" ("large" is the default). This can be used by the templates as a hint to make the user interface more intuitive. For example when expected-amount is "small". links could be rendered as a combo box. When it is "large" then displaying a list of all items may be unpractical.
  • category : category key which is used for gicing a categorisation of tables. The value specified on the root tables can for example be used for grouping the tables in a menu structure.
  • proxy-interface : extra interfaces (comma separated) which should be applied to the proxy. This allows you to have dependencies on the proxies' accessors.
  • internal : when a table is marked internal (by passing a value which is different from "false"), then it cannot be instantiated. The table is only provided to have a common parent in the inheritance tree.

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 :

  • parent : the name of the parent table.

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.

field

A field definition can have the following attributes :

  • name : name of the field. This is expected to start with a capital to adhere to the Java naming convention.
  • singular : when the field is multiple, you can define the singular name here. When this is not specified, the singular name is assumed to be the same as the name, after removal of a trailing "s".
  • type : field type. There are a few builtin types "string", "int", "double", "boolean", "date", "timestamp", "blob", "clob". Also allowed are any table name (in which case the type starts with a capital and the field is interpretted as a link) or custom types (which start with a lower case letter).
  • length : lengh of the field. This is only applicable for string fields. The default length is 50 characters. String which are longer than this will be truncated.
  • display-length : width for the field in number of characters. This is a hint for the generated user interface. Default value for strings is 50. Default value for dates and timestamps is 10. Default value for int and double is 5.
  • renderer : indication of the renderer (and parameters) which should be used to render this fields. This overwrites the defaults.
  • priority : priority for setting this field. When the proxies set/update the field values, this is by default done in an order based on the priority and the order in which the fields are declared in the domain model. Priority is a value between "1" and "9", with fields at priority "1" updated first and "9" updated last.

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.

  • link-name : the name given to the link. If on the linked table there is a link back to this one with the same name, then the link is considered bidirectional.
  • owner : indicates that this side of the relationship is owner. Only allowed for bidirectional links. For 1-N and N-1 this defaults to the 1 side. For 1-1 and N-N it is recommended that this is specified (defaults to the table which comes first in alfabetic order).
  • embedded : indicates that the linked record is considered "embedded". It requires a bidirectional link and removes the posibility to have an unlinked record on the other side of the link.
  • other-side-multiple, other-side-single : all links are 1-N or N-1 by default. This allows you to specify the multiplicity on the other side. Only needed when the link is not bidirectional.
  • use-relation-table, use-relation-field : allows forcing the use of a realtion table. Not recommended.
  • cascade-delete : Indicates that if this record is deleted, that the linked records should also be deleted. When table A has a link to table B which is marked as cascade-keep, then attempts to delete a record from B which is linked in A will fail.
  • cascade-keep : Indicates deleting records which are linked to is not allowed when there is a link.
  • allow-delete : Allow deletion of linked records. The link will be nulled if this is the case. This is the default behaviour.

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 :

  • unique : all not-null values in the field have to be different.
  • required : at least one value should be set for the field, null is not allowed.
  • immutable : the field value can only be set on the first save. The field is immutable aftwerards.
  • immutable-if : set the field to immutable when another field has value "true".
  • mutable-even-if : allows overwriting the immutable-if when another field is (also) "true".
  • compare : set some range checks on the field value.
  • value-when-null : value to return when this field is null. Allows setting defaults.
  • value-when-zero : value to return when this field is zero. Allows setting defaults.

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.

select

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 :

  • name : name of the field. This is expected to start with a capital to adhere to the Java naming convention.
  • type : type of the selector, possible values are "single" and "multiple". Defaults to "multiple".
  • operator : operator which determines how to combine child subselect objects, which act like brackets in your query. It defaults to "AND", other allowed values are "OR", "TRY" and "ADD". "AND" and "OR" are directly applied in the query. When "TRY" is used it attempts each of the selector children in turn. First one which has a result is returned. When the operator is add then the results of all child selector queries are combined.
  • order : order for sorting the results. You can list the fieldnames, separated by comma. Sort order for a specific field can be reverted by prepending "-". You can also use the meta fieldname "EQUANDA_CREATION", "EQUANDA_MODIFIED" for the creation and last modification timestamps respectively.
  • limit : when set to "yes" an extra parameter is added in the select which allows you to specify the maximum number of records to return.

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 :

  • field : field to select on. Should not be a link or calculated field.
  • table : the (root) table this field is part of, defaults to the table in which the selector is defined.
  • path : the path which is used to get from the current table to the other table, defaults to the table attribute.
  • name : variable name for the parameter on the selector method (defaults to the fields name).
  • from : a possible extra part for the from clause in the EJB-QL statement
  • base : base object which is added before the path (default "o")
  • test : can be one of "=", "!=", "<", ">", "<=", ">=", "is null", "is not null", "like". The "is null", "is not null" tests are not allowed for int, boolean and double fields. "like" is (partially) supported. For strings only, you can use an expression "like _?%" (with wildcard), as test. For the rest of types, the substring after "like" is currently neglected.
  • skip-parameter : when this is set to "true" the parameter is not added to the select method. This allows you to reuse a parameter more than once.

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).

build

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 :

  • type : parameter type. You should use the fully qualified class name when this is not a simple java type.
  • name : name which should be given to the parameter.

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.

action

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 :

  • name : method name. According to the java naming convention, this should start with a lower case character. You should assure there are no builds with the same name. It is recommended there are no fields with the same name (though this is allowed).
  • return : return type for the action. Default is "void". Note that you should use the fully qualified class name when not returning a simple java type.

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 :

  • type : parameter type. You should use the fully qualified class name when this is not a simple java type.
  • name : name which should be given to the parameter.

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.

type

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 :

  • name : name of the type. This is expected to start with a lower to make a visual distuinction between links and types in the domain model.
  • type : base type. Can be one of the builtin types "string", "int", "double", "boolean", "date", "timestamp", "blob", "clob" or any table name (in which case the type starts with a capital). Other types are not allowed here.
  • length : default lengh of the field. This is only applicable for string fields.
  • display-length : default width for the field in number of characters.
  • renderer : indication of the default renderer (and parameters) which should be used to render this fields.

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 :

  • unique : all not-null values in the field have to be different.
  • required : at least one value should be set for the field, null is not allowed.
  • immutable : the field value can only be set on the first save. The field is immutable aftwerards.
  • compare : set some range checks on the field value.

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".

include-data

Included files normally have a include-data root tag. This can contain the following :

  • group : a group of fields. Applies when using include in a table, page or group.
  • field : a field definition. Applies when using include in a table, page or group.
  • choice : some choice values. Applies when using include in a field.
  • hide : whether the table or field is hidden. Applies when using include inside a table or field.
  • 1. Domain model
  • 1.1. table
  • 1.2. field
  • 1.3. select
  • 1.4. build
  • 1.5. action
  • 1.6. type
  • 1.7. include-data