Model Overview
The model described here is a pure object-oriented model that can be used with archetype parsers and software that manipulates archetypes and templates in memory. It is typically the output of a parser of any serialised form of archetypes.
Used BASE Component Packages
The AOM is dependent on various packages from the openEHR BASE component. The first of these is the base.foundation_types package, which defines the various 'leaf' types assumed by the AOM as well as other utility types and basic data structures, such as the Interval<T> type. These types are documented in the openEHR Foundation Types specification and reproduced below for convenience.
base.foundation_types - 'leaf' typesbase.foundation_types.interval Package| the above types do not constitute a formal part of this specification. Any implementation of the AOM will typically have to use concrete versions of these types found within languages and/or libraries. |
In addition, various definitions from the base.base_types.definitions package are reused, which are shown below.
base.base_types.definitions PackageThe enumeration type VALIDITY_KIND is provided in order to define standard values representing mandatory, optional, or disallowed in any model. It is used in this model in classes such as C_DATE , C_TIME and C_DATE_TIME. The VERSION_STATUS enumeration type serves a similar function within various AOM types.
Other classes used from the BASE Component include the base.resource package, which includes the class AUTHORED_RESOURCE and subordinate classes. These are shown by inclusion in the AOM Archetype package diagram below.
Finally, classes from the BASE Component base.expressions package is used by the rules part of the AOM. This is documented in the relevant section below.
AOM2 Package Structure
The Archetype Object Model is defined by the package am.aom2 and subordinate packages, as illustrated in Package Overview.
Definition and Utility Classes
Overview
Various definitional constants are used in the AOM. These are defined in the aom2.definitions package from the AM component and are shown below.
ADL_CODE_DEFINITIONS Class
-
Definition
-
Effective
-
BMM
-
UML
Class |
ADL_CODE_DEFINITIONS |
|
|---|---|---|
Description |
Definitions relating to the internal code system of archetypes. |
|
Constants |
Signature |
Meaning |
1..1 |
Id_code_leader: |
String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes. |
1..1 |
Value_code_leader: |
String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members. |
1..1 |
Value_set_code_leader: |
String leader of ‘value set’ codes, i.e. codes used to identify value sets. |
1..1 |
Specialisation_separator: |
Character used to separate numeric parts of codes belonging to different specialisation levels. |
1..1 |
Code_regex_pattern: `String = "(0 |
[1-9][0-9]*)(\.(0 |
[1-9]))"` |
Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes. |
1..1 |
Root_code_regex_pattern: |
Regex pattern of the root id code of any archetype. Corresponds to codes of the form |
1..1 |
Primitive_node_id: |
Code id used for |
Functions |
Signature |
Meaning |
1..1 |
codes_conformant ( |
True if |
1..1 |
is_adl_code ( |
True if |
1..1 |
is_id_code ( |
True if |
1..1 |
is_value_code ( |
True if |
1..1 |
is_value_set_code ( |
True if |
1..1 |
A code has been specialised if there is a non-zero code index anywhere above the last index e.g.
|
1..1 |
|
| ADL_CODE_DEFINITIONS | |
|---|---|
Definitions relating to the internal code system of archetypes. |
|
Constants |
|
Id_code_leader: |
String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes. |
Value_code_leader: |
String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members. |
Value_set_code_leader: |
String leader of ‘value set’ codes, i.e. codes used to identify value sets. |
Specialisation_separator: |
Character used to separate numeric parts of codes belonging to different specialisation levels. |
Code_regex_pattern: `String = "(0 |
[1-9][0-9]*)(\.(0 |
[1-9]))"` [1..1] |
Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes. |
Root_code_regex_pattern: |
Regex pattern of the root id code of any archetype. Corresponds to codes of the form |
Primitive_node_id: |
Code id used for |
Functions |
|
codes_conformant ( |
True if |
is_adl_code ( |
True if |
is_id_code ( |
True if |
is_value_code ( |
True if |
is_value_set_code ( |
True if |
A code has been specialised if there is a non-zero code index anywhere above the last index e.g.
|
|
code_exists_at_level ( |
Is |
{
"name": "ADL_CODE_DEFINITIONS",
"documentation": "Definitions relating to the internal code system of archetypes.",
"constants": {
"Id_code_leader": {
"name": "Id_code_leader",
"documentation": "String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes.",
"type": "String",
"value": "\"id\""
},
"Value_code_leader": {
"name": "Value_code_leader",
"documentation": "String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members.",
"type": "String",
"value": "\"at\""
},
"Value_set_code_leader": {
"name": "Value_set_code_leader",
"documentation": "String leader of ‘value set’ codes, i.e. codes used to identify value sets.",
"type": "String",
"value": "\"ac\""
},
"Specialisation_separator": {
"name": "Specialisation_separator",
"documentation": "Character used to separate numeric parts of codes belonging to different specialisation levels.",
"type": "Character",
"value": "'.'"
},
"Code_regex_pattern": {
"name": "Code_regex_pattern",
"documentation": "Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes.",
"type": "String",
"value": "\"(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))*\""
},
"Root_code_regex_pattern": {
"name": "Root_code_regex_pattern",
"documentation": "Regex pattern of the root id code of any archetype. Corresponds to codes of the form `id1`, `id1.1`, `id1.1.1` etc..",
"type": "String",
"value": "\"^id1(\\.1)*$\""
},
"Primitive_node_id": {
"name": "Primitive_node_id",
"documentation": "Code id used for `C_PRIMITIVE_OBJECT` nodes on creation.",
"type": "String",
"value": "\"id9999\""
}
},
"functions": {
"codes_conformant": {
"name": "codes_conformant",
"documentation": "True if `_a_child_code_` conforms to `_a_parent_code_` in the sense of specialisation, i.e. is `_a_child_code_` the same as or more specialised than `_a_parent_code_`?",
"parameters": {
"a_child_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_child_code",
"type": "String"
},
"a_parent_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_parent_code",
"type": "String"
}
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"is_adl_code": {
"name": "is_adl_code",
"documentation": "True if `_a_code_` is any kind of ADL archetype local code.",
"parameters": {
"a_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_code",
"type": "String"
}
},
"post_conditions": {
"Post": "Result = is_id_code (a_code) or else is_value_code (a_code) or else is_value_set_code (a_code)"
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"is_id_code": {
"name": "is_id_code",
"documentation": "True if `_a_code_` is an 'id' code.",
"parameters": {
"a_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_code",
"type": "String"
}
},
"post_conditions": {
"Post": "Result = a_code.starts_with (Id_code_leader)"
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"is_value_code": {
"name": "is_value_code",
"documentation": "True if `_a_code_` is an 'at' code, i.e. a code representing a single terminology item.",
"parameters": {
"a_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_code",
"type": "String"
}
},
"post_conditions": {
"Post": "Result = a_code.starts_with (Value_code_leader)"
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"is_value_set_code": {
"name": "is_value_set_code",
"documentation": "True if `_a_code_` is an 'ac' code, i.e. a code referring to a terminology value set.",
"parameters": {
"a_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_code",
"type": "String"
}
},
"post_conditions": {
"Post": "Result = a_code.starts_with (Value_set_code_leader)"
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"is_redefined_code": {
"name": "is_redefined_code",
"documentation": "A code has been specialised if there is a non-zero code index anywhere above the last index e.g. \n\n* `at0.0.1` -> False\n* `at1.0.1` -> True",
"parameters": {
"a_code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_code",
"type": "String"
}
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
},
"code_exists_at_level": {
"name": "code_exists_at_level",
"documentation": "Is `_a_code_` valid at level `_a_level_` or less, i.e. if we remove its trailing specialised part corresponding to specialisation below `_a_level_`, and then any trailing '.0' pieces, do we end up with a valid code? If so it means that the code corresponds to a real node from `_a_level_` or higher.",
"parameters": {
"a-code": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a-code",
"type": "String"
},
"a_level": {
"_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
"name": "a_level",
"type": "Integer"
}
},
"result": {
"_type": "P_BMM_SIMPLE_TYPE",
"type": "Boolean"
}
}
}
}
Utility Algorithms
Useful utility algorithms from the above class, referenced elsewhere in this specification are shown below.
codes_conformant (a_child_code, a_parent_code: String): Boolean
-- True if `a_child_code' conforms to `a_parent_code' in the sense of specialisation, i.e.
-- is `a_child_code' the same as or more specialised than `a_parent_code'
do
Result := is_valid_code (a_child_code) and then a_child_code.starts_with (a_parent_code) and then
(a_child_code.count = a_parent_code.count or else
a_child_code.item (a_parent_code.count + 1) = Specialisation_separator)
end