Customizing the metamodel : Keywords for USRPROPS : KEYED (BY)
  
KEYED (BY)
A KEYED BY clause is optionally used to specify how the key components of referenced objects may be found.
The KEYED BY clause contains a portion for each key component separated by a comma. The KEYED BY clause provides two benefits:
It eliminates the need for the end user to type in the fully qualified name of a reference value (with periods separating qualifiers). For example, for a property that references a class attribute named email of the class Customer of the package "Order System", instead of typing in "Order System".Customer.email, the end user simply types in email.
It can be used to ensure that all key components of a reference value are the same. For example, the LISTOF "Class Attribute" property in a Class definition contains a list of attributes that all belong to the same class and to the same package.
Example
For example, the KEYED BY clause of the Class’s "Class Attribute" property could be as follows:
DEFINITION "Class"
{
...
PROPERTY "Attributes" { ... LISTOF "Class Attribute"KEYED BY {Package:Package, "Class Name":Name, Name:* } ... }
In the example above, the three key components (separated by commas) are Package:Package, "Class Name":Name, and Name:*. These components refer to the three parts needed to identify the referenced Class Attribute definitions – the Package name, the Class name, and the Class Attribute name. Taking them in reverse order, it states that:
The name of the Class Attribute will be found in this property (* means "here"), hence: Name:*
The value of the key property "Class Name" in the Class Attribute definition will be found in this object’s name, hence: "Class Name":Name
The value of the key property Package in the Class Attribute definition will be found in this object’s Package property, hence: Package:Package
The following schematic diagram shows how the KEYED BY clause is used in the example above, and may be useful in understanding the KEYED BY clause generally.
The schematic shows what we have said above – in the definition of a class, a class attribute is entered by specifying its package (stored in the class attribute’s Package property and obtained from the Package value of the class you are in), its class name (stored in the class attribute’s "Class Name" property and obtained from the class’s actual name), and name (stored in the class attribute’s "Name" property and obtained from itself).
In summary:
1 For each key component of the reference object, the KEYED BY clause has a component.
2 The components of the KEYED BY clause are separated by commas.
3 Each component has two parts:
The first part identifies the key component of the reference object.
The second part states where the value of that component is to be found.
The two parts are separated by a colon.
However, certain default values may be assumed to simplify the KEYED BY clause. If the two parts of the component are the same, the second may be omitted and if the second part of the last component is omitted, it assumed to be "here" – that is, the asterisk. Thus, in practice the KEYED BY clause of the Class’s "Attributes" property is coded:
KEYED BY {Package, "Class Name":Name, Name }
Naturally, all the properties used in the KEYED BY statement must exist. Thus, System Architect checks that there is a "Package" property and a "Class Name" property in the "Class Attribute" definition and that they are both KEY.
Besides saving all the effort of coding common key components in a LISTOF property like this one, employing a KEYED BY clause using other properties to provide common values ensures the same values are used for each reference. Thus, in the example we have been using, all the Class Attributes referred to in the "Attributes" property of the Class are forced to belong to the same class in the same package – a desirable characteristic in this case.
At other times it is convenient to have the key components of the referenced object separated for reasons of clarity and simplicity. Under such circumstances a KEYED BY clause is used to designate the properties supplying the separate components. Indeed, for these reasons, when a property is KEY and refers to an object with KEY properties, System Architect requires that the components be in separate properties.
Often it is desirable that some key component values besides the names be provided in the reference itself rather than taken from another property. This may happen when there is no suitable property to provide a value or when it is not desirable that the key component be the same value for all references in the property. In this case, the keyword QUALIFIABLE is used. For example, in the class definition there is this property:
PROPERTY "Operations" {Edit ... ParmListOf "Method"
KEYED BY {"Package","Class Name":Name,"Formal Parameters"QUALIFIABLE, Name } ... }
This indicates that although the values of the "Package" and "Class Name" key properties of the Methods referenced should be taken from the Class’s "Package" property and Name respectively, the values of the "Formal Parameters" property of the Methods and their names should be taken from the Class’s "Operations" property itself. Thus each reference will contain two components, the value of the "Formal Parameters" property and the value of the name separated by a period.
Note System Architect requires that KEY properties that have a KEYED BY clause not use the QUALIFIABLE keyword. This is for the reasons of clarity and simplicity mentioned above.