From fb334bca9f4f4cba73ca4ab0f3726a2e87eb23d3 Mon Sep 17 00:00:00 2001 From: wolandscat Date: Tue, 5 Mar 2024 00:25:42 -0700 Subject: [PATCH 1/3] Initial changes working as previous. --- .../archetype_tool/gui_definition_control.e | 4 +- .../archetype_tool/gui_description_controls.e | 67 ++--- .../gui/schema_tool/gui_rm_information_tool.e | 8 +- .../src/validator/aom_post_parse_processor.e | 4 +- components/aom_profile/src/aom_profile.e | 113 +++++---- .../src/library/arch_lib_archetype.e | 8 +- .../src/library/archetype_library.e | 2 +- .../statistics/archetype_statistical_report.e | 18 +- .../src/am/archetype/authored_archetype.e | 32 +-- .../constraint_model/c_instance_generator.e | 23 +- .../terminology/archetype_terminology.e | 7 +- .../am/persistence/p_archetype_terminology.e | 15 +- .../src/am/persistence/p_authored_archetype.e | 22 +- .../src/am/persistence/p_authored_resource.e | 10 +- .../rm/common/resource/authored_resource.e | 35 +-- .../resource/authored_resource_validator.e | 23 +- .../common/resource/language_translations.e | 5 +- .../rm/common/resource/resource_description.e | 228 ++++++++---------- .../support/identification/hier_object_id.e | 2 +- 19 files changed, 304 insertions(+), 322 deletions(-) diff --git a/apps/adl_workbench/src/gui/archetype_tool/gui_definition_control.e b/apps/adl_workbench/src/gui/archetype_tool/gui_definition_control.e index 593e4ade5..4a1117323 100755 --- a/apps/adl_workbench/src/gui/archetype_tool/gui_definition_control.e +++ b/apps/adl_workbench/src/gui/archetype_tool/gui_definition_control.e @@ -474,9 +474,9 @@ feature {NONE} -- Implementation if aom_profiles_access.has_profile_for_rm_schema (ref_model.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (ref_model.model_id) - if attached aom_profile.archetype_parent_class then + if not aom_profile.archetype_parent_class.is_empty then visualise_descendants_class := aom_profile.archetype_parent_class - elseif attached aom_profile.archetype_visualise_descendants_of then + elseif not aom_profile.archetype_visualise_descendants_of.is_empty then visualise_descendants_class := aom_profile.archetype_visualise_descendants_of end end diff --git a/apps/adl_workbench/src/gui/archetype_tool/gui_description_controls.e b/apps/adl_workbench/src/gui/archetype_tool/gui_description_controls.e index ac59662bb..c640fe671 100755 --- a/apps/adl_workbench/src/gui/archetype_tool/gui_description_controls.e +++ b/apps/adl_workbench/src/gui/archetype_tool/gui_description_controls.e @@ -46,7 +46,7 @@ feature {NONE} -- Initialisation -- lifecycle state control - single line combo text-selection field create evx_lifecycle_state_combo.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_lifecycle_state_label_text), get_text ({ADL_MESSAGES_IDS}.ec_lifecycle_state_label_tooltip), - agent : detachable STRING do Result := source_archetype.description.lifecycle_state end, + agent : STRING do Result := source_archetype.description.lifecycle_state end, resource_lifecycle_states, agent (a_str: STRING) do source_archetype.description.set_lifecycle_state (a_str) end, Void, undo_redo_chain, 18) @@ -59,12 +59,7 @@ feature {NONE} -- Initialisation ev_governance_tab_vbox.extend (evx_package_frame.ev_root_container) ev_governance_tab_vbox.disable_item_expand (evx_package_frame.ev_root_container) create evx_resource_package.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_packages_label_text), - agent :detachable STRING - do - if attached source_archetype.description.resource_package_uri as rpi then - Result := rpi.out - end - end, + agent : STRING do Result := source_archetype.description.resource_package_uri.out end, agent (a_str: STRING) do source_archetype.description.set_resource_package_uri (a_str) end, agent do source_archetype.description.clear_resource_package_uri end, undo_redo_chain, 0, True) @@ -78,12 +73,7 @@ feature {NONE} -- Initialisation -- custodian namespace - String create evx_custodian_namespace_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_custodian_namespace_label_text), - agent : detachable STRING - do - if attached source_archetype.description.custodian_namespace as rpi then - Result := rpi - end - end, + agent : STRING do Result := source_archetype.description.custodian_namespace end, agent (a_str: STRING) do source_archetype.description.set_custodian_namespace (a_str) end, agent do source_archetype.description.clear_custodian_namespace end, undo_redo_chain, 0, True) @@ -92,12 +82,7 @@ feature {NONE} -- Initialisation -- custodian organisation - String create evx_custodian_organisation_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_custodian_organisation_label_text), - agent : detachable STRING - do - if attached source_archetype.description.custodian_organisation as rpi then - Result := rpi - end - end, + agent : STRING do Result := source_archetype.description.custodian_organisation end, agent (a_str: STRING) do source_archetype.description.set_custodian_organisation (a_str) end, agent do source_archetype.description.clear_custodian_organisation end, undo_redo_chain, 0, True) @@ -112,12 +97,7 @@ feature {NONE} -- Initialisation -- original namespace - String create evx_original_namespace_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_original_namespace_label_text), - agent : detachable STRING - do - if attached source_archetype.description.original_namespace as rpi then - Result := rpi - end - end, + agent : STRING do Result := source_archetype.description.original_namespace end, agent (a_str: STRING) do source_archetype.description.set_original_namespace (a_str) end, agent do source_archetype.description.clear_original_namespace end, undo_redo_chain, 0, True) @@ -126,12 +106,7 @@ feature {NONE} -- Initialisation -- original publisher - String create evx_original_publisher_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_original_publisher_label_text), - agent : detachable STRING - do - if attached source_archetype.description.original_publisher as rpi then - Result := rpi - end - end, + agent : STRING do Result := source_archetype.description.original_publisher end, agent (a_str: STRING) do source_archetype.description.set_original_publisher (a_str) end, agent do source_archetype.description.clear_original_publisher end, undo_redo_chain, 0, True) @@ -145,7 +120,7 @@ feature {NONE} -- Initialisation -- copyright - multi-line text create evx_copyright_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_copyright_label_text), - agent : detachable STRING do Result := source_archetype.description.copyright end, + agent : STRING do Result := source_archetype.description.copyright end, agent (a_str: STRING) do source_archetype.description.set_copyright (a_str) end, agent do source_archetype.description.clear_copyright end, undo_redo_chain, 0, 0, True) @@ -154,7 +129,7 @@ feature {NONE} -- Initialisation -- licence - multi-line text create evx_licence_text.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_licence_label_text), - agent : detachable STRING do Result := source_archetype.description.licence end, + agent : STRING do Result := source_archetype.description.licence end, agent (a_str: STRING) do source_archetype.description.set_licence (a_str) end, agent do source_archetype.description.clear_licence end, undo_redo_chain, 0, 0, True) @@ -163,7 +138,7 @@ feature {NONE} -- Initialisation -- ip_acknowledgements control - Hash create evx_ip_acknowledgements.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_ip_acknowledgements_label_text), - agent : detachable HASH_TABLE [STRING, STRING] do if attached source_archetype.description.ip_acknowledgements as ack then Result := ack end end, + agent : HASH_TABLE [STRING, STRING] do Result := source_archetype.description.ip_acknowledgements end, agent (a_key, a_val: STRING) do source_archetype.description.put_ip_acknowledgements_item (a_key, a_val) end, agent (a_key: STRING) do source_archetype.description.remove_ip_acknowledgements_item (a_key) end, undo_redo_chain, @@ -184,9 +159,9 @@ feature {NONE} -- Initialisation -- conversion_details control - Hash create evx_conversion_details.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_conversion_details_label_text), - agent : detachable HASH_TABLE [STRING, STRING] do if attached source_archetype.description as desc and then attached desc.conversion_details as cd then Result := cd end end, - agent (a_key, a_val: STRING) do if attached source_archetype.description as desc then desc.put_conversion_details_item (a_key, a_val) end end, - agent (a_key: STRING) do if attached source_archetype.description as desc then desc.remove_conversion_details_item (a_key) end end, + agent : HASH_TABLE [STRING, STRING] do Result := source_archetype.description.conversion_details end, + agent (a_key, a_val: STRING) do source_archetype.description.put_conversion_details_item (a_key, a_val) end, + agent (a_key: STRING) do source_archetype.description.remove_conversion_details_item (a_key) end, undo_redo_chain, 0, 0, True, Void) gui_controls.extend (evx_conversion_details) @@ -203,18 +178,18 @@ feature {NONE} -- Initialisation -- original_author control - Hash create evx_original_author.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_auth_orig_auth_label_text), - agent : detachable HASH_TABLE [STRING, STRING] do if attached source_archetype.description as desc then Result := desc.original_author end end, - agent (a_key, a_val: STRING) do if attached source_archetype.description as desc then desc.put_original_author_item (a_key, a_val) end end, - agent (a_key: STRING) do if attached source_archetype.description as desc then desc.remove_original_author_item (a_key) end end, + agent : HASH_TABLE [STRING, STRING] do Result := source_archetype.description.original_author end, + agent (a_key, a_val: STRING) do source_archetype.description.put_original_author_item (a_key, a_val) end, + agent (a_key: STRING) do source_archetype.description.remove_original_author_item (a_key) end, undo_redo_chain, 0, min_entry_control_width_in_chars, False, Void) gui_controls.extend (evx_original_author) evx_auth_frame.extend (evx_original_author.ev_root_container, True) -- contributors - list create evx_auth_contrib_list.make_linked (get_text ({ADL_MESSAGES_IDS}.ec_auth_contrib_label_text), - agent : detachable DYNAMIC_LIST [STRING] do if attached source_archetype.description as desc and then attached desc.other_contributors as oc then Result := oc end end, - agent (a_str: STRING; i: INTEGER) do if attached source_archetype.description as desc then desc.add_other_contributor (a_str, i) end end, - agent (a_str: STRING) do if attached source_archetype.description as desc then desc.remove_other_contributor (a_str) end end, + agent : DYNAMIC_LIST [STRING] do Result := source_archetype.description.other_contributors end, + agent (a_str: STRING; i: INTEGER) do source_archetype.description.add_other_contributor (a_str, i) end, + agent (a_str: STRING) do source_archetype.description.remove_other_contributor (a_str) end, undo_redo_chain, 0, min_entry_control_width_in_chars, False) gui_controls.extend (evx_auth_contrib_list) evx_auth_frame.extend (evx_auth_contrib_list.ev_root_container, True) @@ -232,11 +207,9 @@ feature {NONE} -- Initialisation -- translation languages selector create evx_trans_languages_combo.make (get_text ({ADL_MESSAGES_IDS}.ec_trans_languages_label_text), Void, - agent : detachable DYNAMIC_LIST [STRING] + agent : DYNAMIC_LIST [STRING] do - if source_archetype.has_translations then - Result := create {ARRAYED_LIST [STRING]}.make_from_array (source_archetype.translations.current_keys) - end + Result := create {ARRAYED_LIST [STRING]}.make_from_array (source_archetype.translations.current_keys) end, Void, 6, True) ev_lang_original_trans_hbox.extend (evx_trans_languages_combo.ev_root_container) gui_controls.extend (evx_trans_languages_combo) diff --git a/apps/adl_workbench/src/gui/schema_tool/gui_rm_information_tool.e b/apps/adl_workbench/src/gui/schema_tool/gui_rm_information_tool.e index 216f887fd..db082d175 100755 --- a/apps/adl_workbench/src/gui/schema_tool/gui_rm_information_tool.e +++ b/apps/adl_workbench/src/gui/schema_tool/gui_rm_information_tool.e @@ -58,11 +58,11 @@ feature {NONE} -- Implementation create rm_stats_class_list.make (0) if aom_profiles_access.has_profile_for_rm_schema (safe_source.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (safe_source.model_id) - if attached aom_profile.archetype_parent_class as apc then - rm_stats_class_list.extend (apc) + if not aom_profile.archetype_parent_class.is_empty then + rm_stats_class_list.extend (aom_profile.archetype_parent_class) end - if attached aom_profile.archetype_data_value_parent_class as advpc then - rm_stats_class_list.extend (advpc) + if not aom_profile.archetype_data_value_parent_class.is_empty then + rm_stats_class_list.extend (aom_profile.archetype_data_value_parent_class) end end diff --git a/components/adl_compiler/src/validator/aom_post_parse_processor.e b/components/adl_compiler/src/validator/aom_post_parse_processor.e index 7f60a73c9..a1d3682d5 100755 --- a/components/adl_compiler/src/validator/aom_post_parse_processor.e +++ b/components/adl_compiler/src/validator/aom_post_parse_processor.e @@ -142,8 +142,8 @@ feature {NONE} -- Implementation -- find out if any mappings exist in an AOM_PROFILE do if attached aom_profile as att_ap then - if attached att_ap.aom_rm_type_mappings as aom_tm and then aom_tm.has (bare_type_name (({TERMINOLOGY_CODE}).name)) then - c_terminology_code_type_mapping := aom_tm.item (bare_type_name (({TERMINOLOGY_CODE}).name)) + if att_ap.aom_rm_type_mappings.has (bare_type_name (({TERMINOLOGY_CODE}).name)) then + c_terminology_code_type_mapping := att_ap.aom_rm_type_mappings.item (bare_type_name (({TERMINOLOGY_CODE}).name)) else clear end diff --git a/components/aom_profile/src/aom_profile.e b/components/aom_profile/src/aom_profile.e index ba066b546..b8dbef842 100755 --- a/components/aom_profile/src/aom_profile.e +++ b/components/aom_profile/src/aom_profile.e @@ -44,7 +44,6 @@ feature -- Initialisation create profile_name.make_from_string (Default_aom_profile_name) create rm_aom_primitive_type_mappings.make (0) rm_aom_primitive_type_mappings.merge (c_primitive_subtypes) - create rm_schema_pattern.make_empty create matched_model_ids.make (0) create file_path.make_empty end @@ -61,38 +60,56 @@ feature -- Access (attributes from file) -- This is used to match the 'schema_id' generated in BMM_SCHEMA class based on model -- publisher, model name, model release found in .bmm files. -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file + attribute + create Result.make_empty + end terminology_profile: detachable AOM_TERMINOLOGY_PROFILE -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file - archetype_visualise_descendants_of: detachable STRING + archetype_visualise_descendants_of: STRING -- The effect of this attribute in visualisation is to generate the most natural tree or -- grid-based view of an archetype definition, from the semantic viewpoint. -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file + attribute + create Result.make_empty + end - archetype_parent_class: detachable STRING + archetype_parent_class: STRING -- name of a parent class used within the schema to provide archetype capability, -- enabling filtering of classes in RM visualisation. If empty, 'Any' is assumed -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH RM SCHEMA + attribute + create Result.make_empty + end - archetype_data_value_parent_class: detachable STRING + archetype_data_value_parent_class: STRING -- name of a parent class of logical 'data types' used within the schema to provide archetype capability, -- enabling filtering of classes in RM visualisation. If empty, 'Any' is assumed -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH RM SCHEMA + attribute + create Result.make_empty + end - aom_rm_type_mappings: detachable HASH_TABLE [AOM_TYPE_MAPPING, STRING] + aom_rm_type_mappings: HASH_TABLE [AOM_TYPE_MAPPING, STRING] -- mappings from AOM built-in types to actual types in RM: whenever -- the type name is encountered in an archetype, it is mapped to a specific RM type -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file + attribute + create Result.make(0) + end - aom_rm_type_substitutions: detachable HASH_TABLE [STRING, STRING] + aom_rm_type_substitutions: HASH_TABLE [STRING, STRING] -- allowed type substitutions: Actual RM type names keyed by AOM built-in types which can -- substitute for them in an archetype. E.g. means -- that if RM property TYPE.some_property is of type String, an ISO8601_DATE is allowed at that -- position in the archetype. -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file + attribute + create Result.make (0) + end - rm_primitive_type_equivalences: detachable HASH_TABLE [STRING, STRING] + rm_primitive_type_equivalences: HASH_TABLE [STRING, STRING] -- Equivalences of RM primitive types to in-built set of primitive types -- Used to determine which AOM C_PRIMITIVE_OBJECT descendant is used for a primitive type -- Typical entries: @@ -100,16 +117,22 @@ feature -- Access (attributes from file) -- "Real" "Double" -- "Integer" "Integer64" -- DO NOT RENAME OR OTHERWISE CHANGE THIS ATTRIBUTE EXCEPT IN SYNC WITH profile file + attribute + create Result.make(0) + end - aom_lifecycle_mappings: detachable HASH_TABLE [STRING, STRING] + aom_lifecycle_mappings: HASH_TABLE [STRING, STRING] -- list of mappings of lifecycle state names used in archetypes to AOM lifecycle state -- names. value = AOM lifecycle state; key = source lifecycle state + attribute + create Result.make(0) + end aom_lifecycle_mapping (a_state_name: STRING): STRING require has_lifecycle_state_mapping (a_state_name) do - check attached aom_lifecycle_mappings as att_ls and then attached att_ls.item (a_state_name.as_lower) as map_state then + check attached aom_lifecycle_mappings.item (a_state_name.as_lower) as map_state then Result := map_state end end @@ -165,20 +188,20 @@ feature -- Status Report has_any_type_substitution (an_aom_type: STRING): BOOLEAN -- is there any type substitution for `an_aom_type'? do - Result := attached aom_rm_type_substitutions as att_type_subs and then att_type_subs.has (an_aom_type) + Result := aom_rm_type_substitutions.has (an_aom_type) end has_lifecycle_state_mapping (a_state_name: STRING): BOOLEAN -- is there an AOM lifecycle state for `a_state_name'? do - Result := attached aom_lifecycle_mappings as att_ls and then att_ls.has (a_state_name.as_lower) + Result := aom_lifecycle_mappings.has (a_state_name.as_lower) end has_rm_aom_primitive_type_mapping (an_rm_type, an_aom_type: STRING): BOOLEAN -- is there a type equivalence for `an_aom_type', `an_rm_type'? do Result := attached rm_aom_primitive_type_mappings.item (an_rm_type.as_upper) as att_type_eq_type and then - att_type_eq_type.is_case_insensitive_equal (an_aom_type) + att_type_eq_type.is_case_insensitive_equal (an_aom_type) end has_aom_primitive_type_mapping_for_rm_type (an_rm_type: STRING): BOOLEAN @@ -216,24 +239,22 @@ feature -- Validation if matched_model_ids.is_empty then add_error (ec_ARP_no_matching_schemas, <>) else - if attached aom_rm_type_mappings as aom_tm then - -- check that all type mappings are found in all mentioned schemas - across matched_model_ids as models_csr loop - if has_bmm_model (models_csr.item) then - bm := bmm_model (models_csr.item) - across aom_tm as type_mappings_csr loop - rm_class_name := type_mappings_csr.item.target_class_name - if not bm.has_class_definition (type_mappings_csr.item.target_class_name) then - add_error (ec_ARP_invalid_class_mapping, <>) - else - if attached type_mappings_csr.item.property_mappings as prop_mappings then - across prop_mappings as property_mappings_csr loop - if not bm.has_property (rm_class_name, property_mappings_csr.item.target_property_name) then - add_error (ec_ARP_invalid_property_mapping, <>) - end + -- check that all type mappings are found in all mentioned schemas + across matched_model_ids as models_csr loop + if has_bmm_model (models_csr.item) then + bm := bmm_model (models_csr.item) + across aom_rm_type_mappings as type_mappings_csr loop + rm_class_name := type_mappings_csr.item.target_class_name + if not bm.has_class_definition (type_mappings_csr.item.target_class_name) then + add_error (ec_ARP_invalid_class_mapping, <>) + else + if attached type_mappings_csr.item.property_mappings as prop_mappings then + across prop_mappings as property_mappings_csr loop + if not bm.has_property (rm_class_name, property_mappings_csr.item.target_property_name) then + add_error (ec_ARP_invalid_property_mapping, <>) end end end @@ -243,11 +264,9 @@ feature -- Validation end -- check lifecycle state mappings - if attached aom_lifecycle_mappings as att_ls then - across att_ls as ls_csr loop - if not Resource_lifecycle_states.has (ls_csr.item) then - add_error (ec_ARP_invalid_lifecycle_state_mapping, <>) - end + across aom_lifecycle_mappings as ls_csr loop + if not Resource_lifecycle_states.has (ls_csr.item) then + add_error (ec_ARP_invalid_lifecycle_state_mapping, <>) end end end @@ -281,25 +300,21 @@ feature {DT_OBJECT_CONVERTER} -- Persistence end -- merge default RM/AOM primitive type mappings into those found in AOM profile - if attached rm_primitive_type_equivalences as att_rm_prim_type_eqs then - across att_rm_prim_type_eqs as rm_prim_types_csr loop - default_rm_type_key := rm_prim_types_csr.item.as_upper - if rm_aom_primitive_type_mappings.has (default_rm_type_key) and then - attached rm_aom_primitive_type_mappings.item (default_rm_type_key) as aom_type - then - rm_aom_primitive_type_mappings.put (aom_type, rm_prim_types_csr.key.as_upper) - end + across rm_primitive_type_equivalences as rm_prim_types_csr loop + default_rm_type_key := rm_prim_types_csr.item.as_upper + if rm_aom_primitive_type_mappings.has (default_rm_type_key) and then + attached rm_aom_primitive_type_mappings.item (default_rm_type_key) as aom_type + then + rm_aom_primitive_type_mappings.put (aom_type, rm_prim_types_csr.key.as_upper) end end -- convert lifecycle states table to all lower case - if attached aom_lifecycle_mappings as aom_ls_mappings then - create lc_aom_lifecycle_mappings.make (0) - across aom_ls_mappings as state_mappings_csr loop - lc_aom_lifecycle_mappings.put (state_mappings_csr.item.as_lower, state_mappings_csr.key.as_lower) - end - aom_lifecycle_mappings := lc_aom_lifecycle_mappings + create lc_aom_lifecycle_mappings.make (0) + across aom_lifecycle_mappings as state_mappings_csr loop + lc_aom_lifecycle_mappings.put (state_mappings_csr.item.as_lower, state_mappings_csr.key.as_lower) end + aom_lifecycle_mappings := lc_aom_lifecycle_mappings end get_regex_matches (a_regex: STRING) diff --git a/components/archetype_repository/src/library/arch_lib_archetype.e b/components/archetype_repository/src/library/arch_lib_archetype.e index 0badf4a4c..a40d6a2b7 100755 --- a/components/archetype_repository/src/library/arch_lib_archetype.e +++ b/components/archetype_repository/src/library/arch_lib_archetype.e @@ -524,8 +524,8 @@ feature -- Artefacts locatable_class_name := ref_model.any_type_name if aom_profiles_access.has_profile_for_rm_schema (ref_model.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (ref_model.model_id) - if attached aom_profile.archetype_parent_class as advpc then - locatable_class_name := advpc + if not aom_profile.archetype_parent_class.is_empty then + locatable_class_name := aom_profile.archetype_parent_class end end Result := select_archetype (differential_view, editing_enabled).paths_matching_rm_type (agent ref_model.type_conforms_to (?, locatable_class_name)) @@ -552,8 +552,8 @@ feature -- Artefacts locatable_class_name := ref_model.any_type_name if aom_profiles_access.has_profile_for_rm_schema (ref_model.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (ref_model.model_id) - if attached aom_profile.archetype_parent_class as advpc then - locatable_class_name := advpc + if not aom_profile.archetype_parent_class.is_empty then + locatable_class_name := aom_profile.archetype_parent_class end end Result := select_archetype (differential_view, editing_enabled).locatable_descriptions (a_language, a_segment_delimiter, agent ref_model.type_conforms_to (?, locatable_class_name)) diff --git a/components/archetype_repository/src/library/archetype_library.e b/components/archetype_repository/src/library/archetype_library.e index 6d446ea3c..07e11f8f2 100755 --- a/components/archetype_repository/src/library/archetype_library.e +++ b/components/archetype_repository/src/library/archetype_library.e @@ -946,7 +946,7 @@ feature {NONE} -- Implementation bm := models_csr.item if aom_profiles_access.has_profile_for_rm_schema (bm.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (bm.model_id) - archetype_parent_class := if attached aom_profile.archetype_parent_class as apc then apc else Any_type_name end + archetype_parent_class := if not aom_profile.archetype_parent_class.is_empty then aom_profile.archetype_parent_class else Any_type_name end else archetype_parent_class := Any_type_name end diff --git a/components/archetype_repository/src/statistics/archetype_statistical_report.e b/components/archetype_repository/src/statistics/archetype_statistical_report.e index 809c012fa..b1565e447 100755 --- a/components/archetype_repository/src/statistics/archetype_statistical_report.e +++ b/components/archetype_repository/src/statistics/archetype_statistical_report.e @@ -44,13 +44,13 @@ feature -- Initialisation -- no 'LOCATABLE' or equivalent class declared, create a default table. Additionally create a -- primitive types table (for nodes that archetype RM types like String, Integer etc), since this can -- always be detected - if attached archetype_parent_class as apc then - rm_grouped_class_table.put (default_rm_class_table, apc) + if not archetype_parent_class.is_empty then + rm_grouped_class_table.put (default_rm_class_table, archetype_parent_class) else rm_grouped_class_table.put (default_rm_class_table, "Any") end - if attached archetype_data_value_parent_class as advpc then - rm_grouped_class_table.put (create {HASH_TABLE [RM_CLASS_STATISTICS, STRING]}.make(0), advpc) + if not archetype_data_value_parent_class.is_empty then + rm_grouped_class_table.put (create {HASH_TABLE [RM_CLASS_STATISTICS, STRING]}.make(0), archetype_data_value_parent_class) end rm_grouped_class_table.put (create {HASH_TABLE [RM_CLASS_STATISTICS, STRING]}.make(0), Rm_primitive_group_key) end @@ -89,9 +89,15 @@ feature -- Access ref_model: BMM_MODEL - archetype_data_value_parent_class: detachable STRING + archetype_data_value_parent_class: STRING + attribute + create Result.make (0) + end - archetype_parent_class: detachable STRING + archetype_parent_class: STRING + attribute + create Result.make (0) + end feature -- Modification diff --git a/libraries/openehr/src/am/archetype/authored_archetype.e b/libraries/openehr/src/am/archetype/authored_archetype.e index 35d4ee237..f6bb8ef77 100755 --- a/libraries/openehr/src/am/archetype/authored_archetype.e +++ b/libraries/openehr/src/am/archetype/authored_archetype.e @@ -93,7 +93,6 @@ feature -- Initialisation an_annotations: like annotations) -- make from all possible items require - Translations_valid: attached a_translations as att_trans implies not att_trans.is_empty Rules_valid: attached a_rules as att_rules implies not att_rules.is_empty do make (an_adl_version, an_rm_release, an_id, an_original_language, a_uid, a_build_uid, a_description, a_definition, a_terminology) @@ -133,19 +132,19 @@ feature -- Initialisation build_uid := att_other_uid.twin end set_original_language (other.original_language) - if attached other.other_metadata as att_omd then - other_metadata := att_omd.deep_twin + if not other.other_metadata.is_empty then + other_metadata := other.other_metadata.deep_twin end - if attached other.translations as other_trans then - translations := other_trans.deep_twin + if not other.translations.is_empty then + translations := other.translations.deep_twin end description := other.description.deep_twin if attached other.annotations as other_annots then annotations := other_annots.deep_twin end ensure then - Other_metadata_copied: attached other_metadata as att_omd implies (attached other.other_metadata as att_other_omd and then att_omd.is_deep_equal (att_other_omd)) - Translations_copied: attached translations as att_trans implies (attached other.translations as att_other_trans and then att_trans.is_deep_equal (att_other_trans)) + Other_metadata_copied: not other_metadata.is_empty implies (other.other_metadata.is_deep_equal (other_metadata)) + Translations_copied: not translations.is_empty implies (other.translations.is_deep_equal (translations)) Description_copied: description.is_deep_equal (other.description) Annotations_copied: attached annotations as att_ann implies (attached other.annotations as att_other_ann and then att_ann.is_deep_equal (att_other_ann)) end @@ -194,8 +193,11 @@ feature -- Access -- be valid with respect to multiple releases of a reference model. Conformance is captured -- outside of the archetype. - other_metadata: detachable HASH_TABLE [STRING, STRING] + other_metadata: HASH_TABLE [STRING, STRING] -- other top-level meta-data + attribute + create Result.make (0) + end feature -- Modification @@ -242,18 +244,10 @@ feature -- Modification put_other_metadata_value (a_key, a_value: STRING) -- add the pair `a_key' / `a_value' to `other_metadata', overwriting any value -- with the same key if necessary. - local - o_metadata: HASH_TABLE [STRING, STRING] do - if attached other_metadata as omd then - o_metadata := omd - else - create o_metadata.make (0) - other_metadata := o_metadata - end - o_metadata.force (a_value, a_key) + other_metadata.force (a_value, a_key) ensure - attached other_metadata as att_omd and then attached att_omd.item (a_key) as att_omd_item and then att_omd_item = a_value + attached other_metadata.item (a_key) as att_omd_item and then att_omd_item = a_value end put_other_metadata_flag (a_key: STRING) @@ -262,7 +256,7 @@ feature -- Modification do put_other_metadata_value (a_key, (True).out) ensure - attached other_metadata as att_omd and then attached att_omd.item (a_key) as att_md_item and then att_md_item.is_equal ((True).out) + attached other_metadata.item (a_key) as att_md_item and then att_md_item.is_equal ((True).out) end add_language (a_lang_tag: STRING) diff --git a/libraries/openehr/src/am/archetype/constraint_model/c_instance_generator.e b/libraries/openehr/src/am/archetype/constraint_model/c_instance_generator.e index 81db3d73d..16eb44701 100644 --- a/libraries/openehr/src/am/archetype/constraint_model/c_instance_generator.e +++ b/libraries/openehr/src/am/archetype/constraint_model/c_instance_generator.e @@ -55,17 +55,17 @@ feature -- Initialisation c_attribute_completed.wipe_out c_object_ignore.wipe_out - aom_profile := Void + create aom_profile.make_dt (Void) -- wipe out from previous run archetype_parent_class := {BMM_DEFINITIONS}.any_type_name archetype_data_value_parent_class := {BMM_DEFINITIONS}.any_type_name if aom_profiles_access.has_profile_for_rm_schema (ref_model.model_id) then aom_profile := aom_profiles_access.profile_for_rm_schema (ref_model.model_id) - if attached aom_profile.archetype_parent_class as aop_loc then - archetype_parent_class := aop_loc + if not aom_profile.archetype_parent_class.is_empty then + archetype_parent_class := aom_profile.archetype_parent_class end - if attached aom_profile.archetype_data_value_parent_class as aop_dt then - archetype_data_value_parent_class := aop_dt + if not aom_profile.archetype_data_value_parent_class.is_empty then + archetype_data_value_parent_class := aom_profile.archetype_data_value_parent_class end end end @@ -313,7 +313,10 @@ feature {NONE} -- Implementation Result := model_for_archetype_id (archetype_id) end - aom_profile: detachable AOM_PROFILE + aom_profile: AOM_PROFILE + attribute + create Result.make_dt (Void) + end language: STRING attribute @@ -470,8 +473,8 @@ feature {NONE} -- Implementation is_ignored (rm_type, attr_name: STRING): BOOLEAN do - if ignored_attributes.has (rm_type) then - Result := ignored_attributes.item (rm_type).has(attr_name) + if ignored_attributes.has (rm_type) and then attached ignored_attributes.item (rm_type) as attr_list then + Result := attr_list.has(attr_name) end end @@ -484,8 +487,8 @@ feature {NONE} -- Implementation is_required (rm_type, attr_name: STRING): BOOLEAN do - if required_attributes.has (rm_type) then - Result := required_attributes.item (rm_type).has(attr_name) + if required_attributes.has (rm_type) and then attached required_attributes.item (rm_type) as attr_list then + Result := attr_list.has (attr_name) end end diff --git a/libraries/openehr/src/am/archetype/terminology/archetype_terminology.e b/libraries/openehr/src/am/archetype/terminology/archetype_terminology.e index 7c4816b40..dcbc3975e 100755 --- a/libraries/openehr/src/am/archetype/terminology/archetype_terminology.e +++ b/libraries/openehr/src/am/archetype/terminology/archetype_terminology.e @@ -142,8 +142,11 @@ feature -- Access (Stored) create Result.make (0) end - terminology_extracts: detachable HASH_TABLE [HASH_TABLE [ARCHETYPE_TERM, STRING], STRING] + terminology_extracts: HASH_TABLE [HASH_TABLE [ARCHETYPE_TERM, STRING], STRING] -- table of {code, description} keyed by terminology_id containing extracted concepts from external terminologies + attribute + create Result.make (0) + end feature -- Access (computed) @@ -273,7 +276,7 @@ feature -- Access (computed) Terminology_valid: has_terminology_extract (a_terminology) Term_code_valid: has_terminology_extract_code (a_terminology, a_code) do - check attached terminology_extracts as att_tex and then attached att_tex.item (a_terminology) as att_ex_terms and then attached att_ex_terms.item (a_code) as term then + check attached terminology_extracts.item (a_terminology) as att_ex_terms and then attached att_ex_terms.item (a_code) as term then Result := term end end diff --git a/libraries/openehr/src/am/persistence/p_archetype_terminology.e b/libraries/openehr/src/am/persistence/p_archetype_terminology.e index 7602c2e99..200576c7e 100755 --- a/libraries/openehr/src/am/persistence/p_archetype_terminology.e +++ b/libraries/openehr/src/am/persistence/p_archetype_terminology.e @@ -59,14 +59,23 @@ feature -- Access create Result.make (0) end - term_bindings: detachable HASH_TABLE [HASH_TABLE [STRING, STRING], STRING] + term_bindings: HASH_TABLE [HASH_TABLE [STRING, STRING], STRING] -- tables of bindings of external terms to internal codes, keyed by external terminology id + attribute + create Result.make (0) + end - value_sets: detachable HASH_TABLE [VALUE_SET, STRING] + value_sets: HASH_TABLE [VALUE_SET, STRING] -- table of value set relationships keyed by ac-code + attribute + create Result.make (0) + end - terminology_extracts: detachable HASH_TABLE [HASH_TABLE [ARCHETYPE_TERM, STRING], STRING] + terminology_extracts: HASH_TABLE [HASH_TABLE [ARCHETYPE_TERM, STRING], STRING] -- table of {code, description} keyed by terminology_id containing extracted concepts from external terminologies + attribute + create Result.make (0) + end feature -- Factory diff --git a/libraries/openehr/src/am/persistence/p_authored_archetype.e b/libraries/openehr/src/am/persistence/p_authored_archetype.e index 60f78179d..4278b8fd2 100755 --- a/libraries/openehr/src/am/persistence/p_authored_archetype.e +++ b/libraries/openehr/src/am/persistence/p_authored_archetype.e @@ -28,8 +28,6 @@ feature -- Initialisation make_dt (make_args: detachable ARRAY[ANY]) -- basic make routine to guarantee validity on creation do - create adl_version.make_empty - create rm_release.make_empty create description.make_dt (make_args) end @@ -50,15 +48,27 @@ feature -- Initialisation feature -- Access - other_metadata: detachable HASH_TABLE [STRING, STRING] + other_metadata: HASH_TABLE [STRING, STRING] + attribute + create Result.make (0) + end adl_version: STRING -- ADL version of this archetype + attribute + create Result.make_empty + end rm_release: STRING -- RM release on which definition of this archetype is based + attribute + create Result.make_empty + end - build_uid: detachable STRING + build_uid: STRING + attribute + create Result.make_empty + end feature -- Factory @@ -77,8 +87,8 @@ feature -- Factory if attached uid as att_uid then create o_uid.make_from_string (att_uid) end - if attached build_uid as att_uid then - create o_build_uid.make_from_string (att_uid) + if not build_uid.is_empty then + create o_build_uid.make_from_string (build_uid) end create arch_terminology.make_differential (original_language.code_string, o_definition.node_id) diff --git a/libraries/openehr/src/am/persistence/p_authored_resource.e b/libraries/openehr/src/am/persistence/p_authored_resource.e index 6eb15ee5e..0bda8ba73 100755 --- a/libraries/openehr/src/am/persistence/p_authored_resource.e +++ b/libraries/openehr/src/am/persistence/p_authored_resource.e @@ -26,14 +26,20 @@ feature {P_AUTHORED_ARCHETYPE} -- Initialisation feature -- Access - uid: detachable STRING + uid: STRING + attribute + create Result.make (0) + end original_language: TERMINOLOGY_CODE attribute create Result.default_create end - translations: detachable HASH_TABLE [TRANSLATION_DETAILS, STRING] + translations: HASH_TABLE [TRANSLATION_DETAILS, STRING] + attribute + create Result.make (0) + end description: RESOURCE_DESCRIPTION diff --git a/libraries/openehr/src/rm/common/resource/authored_resource.e b/libraries/openehr/src/rm/common/resource/authored_resource.e index 6451e6172..0a05e6e81 100755 --- a/libraries/openehr/src/rm/common/resource/authored_resource.e +++ b/libraries/openehr/src/rm/common/resource/authored_resource.e @@ -57,10 +57,13 @@ feature -- Access create Result.default_create end - translations: detachable HASH_TABLE [TRANSLATION_DETAILS, STRING] + translations: HASH_TABLE [TRANSLATION_DETAILS, STRING] -- List of details for each natural translation made of this resource, keyed by -- language tag. For each translation listed here, there must be corresponding -- sections in all language-dependent parts of the resource. + attribute + create Result.make (0) + end description: RESOURCE_DESCRIPTION -- Description and lifecycle information of the resource. @@ -127,7 +130,7 @@ feature -- Status Report has_translations: BOOLEAN -- True if there are translations do - Result := attached translations + Result := not translations.is_empty end has_revision_history: BOOLEAN @@ -191,16 +194,8 @@ feature -- Modification -- add a translation for a_lang require Translation_valid: not has_language(a_trans.language.code_string) - local - trans: attached like translations do - if attached translations as att_trans then - trans := att_trans - else - create trans.make(0) - translations := trans - end - trans.put (a_trans, a_trans.language.code_string) + translations.put (a_trans, a_trans.language.code_string) ensure has_language (a_trans.language.code_string) end @@ -272,12 +267,7 @@ feature {ARCHETYPE} -- Flattening do across languages_available as langs_csr loop if not a_langs.has (langs_csr.item) then - if attached translations as trans then - trans.remove (langs_csr.item) - if trans.is_empty then - translations := Void - end - end + translations.remove (langs_csr.item) description.remove_language (langs_csr.item) if attached annotations as annots then annots.remove_language (langs_csr.item) @@ -291,12 +281,7 @@ feature {ARCHETYPE} -- Flattening require has_language (a_lang) do - if attached translations then - translations.remove (a_lang) - if translations.is_empty then - translations := Void - end - end + translations.remove (a_lang) description.remove_language (a_lang) if attached annotations then annotations.remove_language (a_lang) @@ -324,9 +309,9 @@ feature {ARCHETYPE} -- Flattening -- remove translations meta-data structure; -- leaves any translation languages in description intact do - translations := Void + translations.wipe_out ensure - not attached translations + translations.is_empty end feature {ADL_2_ENGINE, ADL_14_ENGINE} -- Implementation diff --git a/libraries/openehr/src/rm/common/resource/authored_resource_validator.e b/libraries/openehr/src/rm/common/resource/authored_resource_validator.e index 3c42d2cca..bc6ae0cdc 100755 --- a/libraries/openehr/src/rm/common/resource/authored_resource_validator.e +++ b/libraries/openehr/src/rm/common/resource/authored_resource_validator.e @@ -61,19 +61,20 @@ feature {NONE} -- Implementation validate_translations -- True if `translations' structures obey their invariants + local + tgt_trans: HASH_TABLE [TRANSLATION_DETAILS, STRING] do -- check that AUTHORED_RESOURCE.translations items match their Hash keys - if attached target.translations as tgt_trans then - from - tgt_trans.start - until - tgt_trans.off or not tgt_trans.key_for_iteration.is_equal (tgt_trans.item_for_iteration.language.code_string) - loop - tgt_trans.forth - end - if not tgt_trans.off then - add_error ({ADL_MESSAGES_IDS}.ec_VTRLA, <>) - end + tgt_trans := target.translations + from + tgt_trans.start + until + tgt_trans.off or not tgt_trans.key_for_iteration.is_equal (tgt_trans.item_for_iteration.language.code_string) + loop + tgt_trans.forth + end + if not tgt_trans.off then + add_error ({ADL_MESSAGES_IDS}.ec_VTRLA, <>) end end diff --git a/libraries/openehr/src/rm/common/resource/language_translations.e b/libraries/openehr/src/rm/common/resource/language_translations.e index 43d4eb728..05d211cd1 100755 --- a/libraries/openehr/src/rm/common/resource/language_translations.e +++ b/libraries/openehr/src/rm/common/resource/language_translations.e @@ -43,10 +43,13 @@ feature -- Access create Result.default_create end - translations: detachable HASH_TABLE [TRANSLATION_DETAILS, STRING] + translations: HASH_TABLE [TRANSLATION_DETAILS, STRING] -- List of details for each natural translation made of this resource, keyed by -- language. For each translation listed here, there must be corresponding -- sections in all language-dependent parts of the resource. + attribute + create Result.make (0) + end feature -- Modification diff --git a/libraries/openehr/src/rm/common/resource/resource_description.e b/libraries/openehr/src/rm/common/resource/resource_description.e index fd815c2e2..3b8681c1a 100755 --- a/libraries/openehr/src/rm/common/resource/resource_description.e +++ b/libraries/openehr/src/rm/common/resource/resource_description.e @@ -83,30 +83,54 @@ feature -- Access Result.put (Default_original_author, "name") end - original_namespace: detachable STRING + original_namespace: STRING -- Original namespace of this archetype as a reverse domain name + attribute + create Result.make_empty + end - original_publisher: detachable STRING + original_publisher: STRING -- Original publisher of this archetype as a string name + attribute + create Result.make_empty + end - custodian_namespace: detachable STRING + custodian_namespace: STRING -- Namespace of current custodian organisation of this archetype as a reverse domain name + attribute + create Result.make_empty + end - custodian_organisation: detachable STRING + custodian_organisation: STRING -- Current custodian organisation of this archetype as a string name + attribute + create Result.make_empty + end - copyright: detachable STRING + copyright: STRING -- Rights over the archetype as a knowledge resource; -- usually copyright and/or license to use. + attribute + create Result.make_empty + end - licence: detachable STRING + licence: STRING -- Licence for this archetype if any, typically a short phrase with embedded URL + attribute + create Result.make_empty + end - ip_acknowledgements: detachable HASH_TABLE [STRING, STRING] + ip_acknowledgements: HASH_TABLE [STRING, STRING] -- list of IP acknowledgments, keyed by tag name of IP being mentioned + attribute + create Result.make (0) + end - conversion_details: detachable HASH_TABLE [STRING, STRING] + conversion_details: HASH_TABLE [STRING, STRING] -- tagged list of conversion information, where applicable + attribute + create Result.make (0) + end details: HASH_TABLE [RESOURCE_DESCRIPTION_ITEM, STRING] -- list of translatable descriptive details, keyed by language @@ -114,18 +138,31 @@ feature -- Access create Result.make (0) end - other_contributors: detachable ARRAYED_LIST [STRING] + other_contributors: ARRAYED_LIST [STRING] -- Other contributors to the resource, probably listed in “name ” form + attribute + create Result.make (0) + Result.compare_objects + end - references: detachable HASH_TABLE [STRING, STRING] + references: HASH_TABLE [STRING, STRING] + attribute + create Result.make (0) + end - other_details: detachable HASH_TABLE [STRING, STRING] + other_details: HASH_TABLE [STRING, STRING] + attribute + create Result.make (0) + end parent_resource: detachable AUTHORED_RESOURCE -- Reference to owning resource. - resource_package_uri: detachable URI + resource_package_uri: URI -- URI of archetype package + attribute + create Result + end languages: ARRAYED_SET [STRING] -- list of all languages in details @@ -155,22 +192,22 @@ feature -- Status Report has_details: BOOLEAN -- True if there are any details do - Result := attached details and not details.is_empty + Result := not details.is_empty end has_ip_acknowledgements (a_key: STRING): BOOLEAN do - Result := attached ip_acknowledgements as att_ack and then att_ack.has (a_key) + Result := ip_acknowledgements.has (a_key) end has_conversion_details (a_key: STRING): BOOLEAN do - Result := attached conversion_details as att_cd and then att_cd.has (a_key) + Result := conversion_details.has (a_key) end has_other_contributors (a_key: STRING): BOOLEAN do - Result := attached other_contributors as att_oc and then att_oc.has (a_key) + Result := other_contributors.has (a_key) end feature -- Comparison @@ -207,7 +244,7 @@ feature -- Modification clear_original_author -- wipeout current items in original_author list do - create original_author.make(0) + original_author.wipe_out ensure original_author.is_empty end @@ -221,9 +258,9 @@ feature -- Modification clear_original_namespace do - original_namespace := Void + original_namespace.wipe_out ensure - not attached original_namespace + original_namespace.is_empty end set_original_publisher (a_name: STRING) @@ -235,9 +272,9 @@ feature -- Modification clear_original_publisher do - original_publisher := Void + original_publisher.wipe_out ensure - not attached original_publisher + original_publisher.is_empty end set_custodian_namespace (a_namespace: STRING) @@ -249,9 +286,9 @@ feature -- Modification clear_custodian_namespace do - custodian_namespace := Void + custodian_namespace.wipe_out ensure - not attached custodian_namespace + custodian_namespace.is_empty end set_custodian_organisation (a_name: STRING) @@ -263,9 +300,9 @@ feature -- Modification clear_custodian_organisation do - custodian_organisation := Void + custodian_organisation.wipe_out ensure - not attached custodian_organisation + custodian_organisation.is_empty end set_copyright (a_copyright: STRING) @@ -280,9 +317,9 @@ feature -- Modification clear_copyright do - copyright := Void + copyright.wipe_out ensure - not attached copyright + copyright.is_empty end set_licence (a_text: STRING) @@ -294,9 +331,9 @@ feature -- Modification clear_licence do - licence := Void + licence.wipe_out ensure - not attached licence + licence.is_empty end put_ip_acknowledgements_item (a_key, a_value: STRING) @@ -304,43 +341,28 @@ feature -- Modification require Key_valid: not a_key.is_empty Value_valid: not a_value.is_empty - local - ipa: attached like ip_acknowledgements do - if attached ip_acknowledgements as att_ipa then - ipa := att_ipa - else - create ipa.make (0) - ip_acknowledgements := ipa - end - ipa.force (a_value, a_key) + ip_acknowledgements.force (a_value, a_key) ensure - Item_added: attached ip_acknowledgements as att_ipa and then att_ipa.item (a_key) = a_value + Item_added: ip_acknowledgements.item (a_key) = a_value end remove_ip_acknowledgements_item (a_key: STRING) -- remove the key, value pair from `ip_acknowledgements' require Key_valid: has_ip_acknowledgements (a_key) - Ip_acknowledgements_exists: attached ip_acknowledgements do - if attached ip_acknowledgements as att_ipa then - att_ipa.remove (a_key) - if att_ipa.is_empty then - ip_acknowledgements := Void - end - end + ip_acknowledgements.remove (a_key) ensure - Item_removed: not has_ip_acknowledgements (a_key) - If_last_then_removed: attached old ip_acknowledgements as att_old_ipa and then att_old_ipa.count = 1 implies not attached ip_acknowledgements + Item_removed: not ip_acknowledgements.has (a_key) end clear_ip_acknowledgements -- wipeout current items in `ip_acknowledgements' list do - ip_acknowledgements := Void + ip_acknowledgements.wipe_out ensure - not attached ip_acknowledgements + ip_acknowledgements.is_empty end put_conversion_details_item (a_key, a_value: STRING) @@ -348,18 +370,10 @@ feature -- Modification require Key_valid: not a_key.is_empty Value_valid: not a_value.is_empty - local - cd: attached like conversion_details do - if attached conversion_details as att_cd then - cd := att_cd - else - create cd.make (0) - conversion_details := cd - end - cd.force (a_value, a_key) + conversion_details.force (a_value, a_key) ensure - Item_added: attached conversion_details as att_cd and then att_cd.item (a_key) = a_value + Item_added: conversion_details.item (a_key) = a_value end remove_conversion_details_item (a_key: STRING) @@ -367,49 +381,35 @@ feature -- Modification require Key_valid: has_conversion_details (a_key) do - if attached conversion_details as att_cd then - att_cd.remove (a_key) - if att_cd.is_empty then - conversion_details := Void - end - end + conversion_details.remove (a_key) ensure - Item_removed: not has_conversion_details (a_key) - If_last_then_removed: attached old conversion_details as att_old_cd and then att_old_cd.count = 1 implies not attached conversion_details + Item_removed: not conversion_details.has (a_key) + If_last_then_removed: old conversion_details.count = 1 implies conversion_details.is_empty end clear_conversion_details -- wipeout current items in `conversion_details' list do - conversion_details := Void + conversion_details.wipe_out ensure - not attached conversion_details + conversion_details.is_empty end add_other_contributor (a_contributor: STRING; at_pos: INTEGER) -- add a_contributor to `add_other_contributor' at position `at_pos', or end if i is 0 require Contributor_valid: not a_contributor.is_empty - Valid_max_index: attached other_contributors as att_oc implies at_pos <= att_oc.count - local - oc: attached like other_contributors + Valid_max_index: at_pos <= other_contributors.count do - if attached other_contributors as att_oc then - oc := att_oc - else - create oc.make(0) - oc.compare_objects - other_contributors := oc - end if at_pos > 0 then - oc.go_i_th (at_pos) - oc.put_left (a_contributor) + other_contributors.go_i_th (at_pos) + other_contributors.put_left (a_contributor) else - oc.extend (a_contributor) + other_contributors.extend (a_contributor) end ensure - attached other_contributors as att_oc and then (att_oc.has (a_contributor) and - at_pos > 0 implies att_oc.i_th (at_pos) = a_contributor) + other_contributors.has (a_contributor) and + at_pos > 0 implies other_contributors.i_th (at_pos) = a_contributor end remove_other_contributor (a_contributor: STRING) @@ -417,19 +417,17 @@ feature -- Modification require Contributor_valid: has_other_contributors (a_contributor) do - if attached other_contributors as att_oc then - att_oc.prune_all (a_contributor) - end + other_contributors.prune_all (a_contributor) ensure - Other_contributor_set: not has_other_contributors (a_contributor) + Other_contributor_set: not other_contributors.has (a_contributor) end clear_other_contributors -- wipeout current items in other_contributors list do - other_contributors := Void + other_contributors.wipe_out ensure - not attached other_contributors + other_contributors.is_empty end set_resource_package_uri (a_uri: STRING) @@ -439,15 +437,15 @@ feature -- Modification do create resource_package_uri.make_from_string (a_uri) ensure - Archetype_package_uri_set: attached resource_package_uri as att_rpu and then att_rpu.out.is_equal (a_uri) + Archetype_package_uri_set: resource_package_uri.out.is_equal (a_uri) end clear_resource_package_uri -- clear `resource_package_uri' do - resource_package_uri := Void + resource_package_uri.wipe_out ensure - not attached resource_package_uri + resource_package_uri.is_empty end set_lifecycle_state (a_lifecycle_state: STRING) @@ -498,7 +496,7 @@ feature -- Modification clear_details -- wipeout current items in details list do - create details.make(0) + details.wipe_out end put_other_details_item (a_key, a_value: STRING) @@ -506,19 +504,10 @@ feature -- Modification -- existing value for the same key require Key_valid: not a_key.is_empty - local - dets: attached like other_details do - if attached other_details as att_od then - dets := att_od - else - create dets.make (0) - other_details := dets - end - - dets.force (a_value, a_key) + other_details.force (a_value, a_key) ensure - other_details_attached: attached other_details as od and then od.item (a_key) = a_value + other_details_added: other_details.item (a_key) = a_value end remove_other_details_item (a_key: STRING) @@ -526,11 +515,9 @@ feature -- Modification require Key_valid: not a_key.is_empty do - if attached other_details as att_od then - att_od.remove (a_key) - end + other_details.remove (a_key) ensure - key_removed: attached other_details as od and then not od.has (a_key) + key_removed: other_details.has (a_key) end put_references_item (a_key, a_value: STRING) @@ -538,19 +525,10 @@ feature -- Modification -- existing value for the same key require Key_valid: not a_key.is_empty - local - dets: attached like references do - if attached references as att_od then - dets := att_od - else - create dets.make (0) - references := dets - end - - dets.force (a_value, a_key) + references.force (a_value, a_key) ensure - references_attached: attached references as od and then od.item (a_key) = a_value + references_added: references.item (a_key) = a_value end remove_references_item (a_key: STRING) @@ -558,11 +536,9 @@ feature -- Modification require Key_valid: not a_key.is_empty do - if attached references as att_od then - att_od.remove (a_key) - end + references.remove (a_key) ensure - key_removed: attached references as od and then not od.has (a_key) + key_removed: references.has (a_key) end set_parent_resource (a_res: AUTHORED_RESOURCE) @@ -604,8 +580,6 @@ invariant Parent_resource_valid: attached parent_resource as att_pr implies att_pr.description = Current Language_valid: attached parent_resource as att_pr implies details.linear_representation.for_all (agent (rdi: RESOURCE_DESCRIPTION_ITEM; auth_res: AUTHORED_RESOURCE): BOOLEAN do Result := auth_res.languages_available.has (rdi.language.code_string) end (?, att_pr)) - Copyright_valid: attached copyright as att_copyright implies not att_copyright.is_empty - Ip_acknowledgements_valid: attached ip_acknowledgements as att_ipa implies not att_ipa.is_empty end diff --git a/libraries/openehr/src/rm/support/identification/hier_object_id.e b/libraries/openehr/src/rm/support/identification/hier_object_id.e index f939eee3f..e9a96c998 100755 --- a/libraries/openehr/src/rm/support/identification/hier_object_id.e +++ b/libraries/openehr/src/rm/support/identification/hier_object_id.e @@ -18,7 +18,7 @@ inherit UID_BASED_ID create - make, make_from_string + make, make_from_string, default_create feature {NONE} -- Initialization From 616fd94f4b529645298db9d5d638b5c69cf5aab4 Mon Sep 17 00:00:00 2001 From: wolandscat Date: Mon, 11 Mar 2024 09:29:10 -0600 Subject: [PATCH 2/3] Void safety improvements --- .../archetype_ui_graph_state.e | 20 ++--- .../archetype_editor/c_attribute_ui_node.e | 46 +++++----- .../gui/archetype_editor/c_object_ui_node.e | 90 +++++++++---------- .../rm/common/resource/authored_resource.e | 14 +-- 4 files changed, 85 insertions(+), 85 deletions(-) diff --git a/apps/adl_workbench/src/gui/archetype_editor/archetype_ui_graph_state.e b/apps/adl_workbench/src/gui/archetype_editor/archetype_ui_graph_state.e index 0e5580d3c..faecea256 100755 --- a/apps/adl_workbench/src/gui/archetype_editor/archetype_ui_graph_state.e +++ b/apps/adl_workbench/src/gui/archetype_editor/archetype_ui_graph_state.e @@ -31,11 +31,11 @@ feature -- Initialisation archetype := aca.select_archetype (differential_view_flag, False) flat_archetype := source.flat_archetype flat_terminology := flat_archetype.terminology - if aom_profiles_access.has_profile_for_rm_schema (an_rm.model_id) then - aom_profile := aom_profiles_access.profile_for_rm_schema (an_rm.model_id) - archetype_parent_class := aom_profile.archetype_parent_class - archetype_data_value_parent_class := aom_profile.archetype_data_value_parent_class - archetype_visualise_descendants_of := aom_profile.archetype_visualise_descendants_of + if aom_profiles_access.has_profile_for_rm_schema (an_rm.model_id) and then attached aom_profiles_access.profile_for_rm_schema (an_rm.model_id) as att_ap then + aom_profile := att_ap + archetype_parent_class := att_ap.archetype_parent_class + archetype_data_value_parent_class := att_ap.archetype_data_value_parent_class + archetype_visualise_descendants_of := att_ap.archetype_visualise_descendants_of end end @@ -50,11 +50,11 @@ feature -- Initialisation flat_archetype := source.flat_archetype flat_terminology := archetype.terminology undo_redo_chain := an_undo_redo_chain - if aom_profiles_access.has_profile_for_rm_schema (an_rm.model_id) then - aom_profile := aom_profiles_access.profile_for_rm_schema (an_rm.model_id) - archetype_parent_class := aom_profile.archetype_parent_class - archetype_data_value_parent_class := aom_profile.archetype_data_value_parent_class - archetype_visualise_descendants_of := aom_profile.archetype_visualise_descendants_of + if aom_profiles_access.has_profile_for_rm_schema (an_rm.model_id) and then attached aom_profiles_access.profile_for_rm_schema (an_rm.model_id) as att_ap then + aom_profile := att_ap + archetype_parent_class := att_ap.archetype_parent_class + archetype_data_value_parent_class := att_ap.archetype_data_value_parent_class + archetype_visualise_descendants_of := att_ap.archetype_visualise_descendants_of end if attached aca.specialisation_parent as par_aca then parent_archetype := par_aca.flat_archetype diff --git a/apps/adl_workbench/src/gui/archetype_editor/c_attribute_ui_node.e b/apps/adl_workbench/src/gui/archetype_editor/c_attribute_ui_node.e index e43e78704..4449af633 100755 --- a/apps/adl_workbench/src/gui/archetype_editor/c_attribute_ui_node.e +++ b/apps/adl_workbench/src/gui/archetype_editor/c_attribute_ui_node.e @@ -70,8 +70,8 @@ feature -- Access path: STRING -- path of this node with respect to top of archetype do - if attached arch_node then - Result := arch_node.path + if attached arch_node as a_n then + Result := a_n.path elseif parent.is_root then Result := parent.path + rm_property.name else @@ -135,26 +135,26 @@ feature -- Display do precursor (ui_settings) - if attached arch_node then + if attached arch_node as a_n then -- RM attr name / path - if arch_node.has_differential_path then + if a_n.has_differential_path then create attr_str.make_empty if display_settings.show_technical_view then - attr_str.append (arch_node.rm_attribute_path) + attr_str.append (a_n.rm_attribute_path) else - attr_str.append (ui_graph_state.flat_archetype.annotated_path (arch_node.rm_attribute_path, display_settings.language, True)) + attr_str.append (ui_graph_state.flat_archetype.annotated_path (a_n.rm_attribute_path, display_settings.language, True)) end attr_str.replace_substring_all ({OG_PATH}.segment_separator_string, "%N" + {OG_PATH}.segment_separator_string) attr_str.remove_head (1) evx_grid.update_last_row_label_col_multi_line (Definition_grid_col_rm_name, attr_str, node_tooltip_str, Void, c_attribute_colour, c_pixmap) else - evx_grid.update_last_row_label_col (Definition_grid_col_rm_name, arch_node.rm_attribute_name, node_tooltip_str, c_node_font, c_attribute_colour, c_pixmap) + evx_grid.update_last_row_label_col (Definition_grid_col_rm_name, a_n.rm_attribute_name, node_tooltip_str, c_node_font, c_attribute_colour, c_pixmap) end -- existence c_col := c_attribute_colour create ex_str.make_empty - if attached arch_node.existence as att_ex then + if attached a_n.existence as att_ex then if not att_ex.is_prohibited then ex_str.append (att_ex.as_string) else @@ -169,7 +169,7 @@ feature -- Display -- cardinality create card_str.make_empty c_col := c_attribute_colour - if attached arch_node.cardinality as att_card then + if attached a_n.cardinality as att_card then card_str := att_card.as_string c_col := c_constraint_colour elseif not ui_graph_state.in_differential_view and display_settings.show_rm_multiplicities and then attached {BMM_CONTAINER_PROPERTY} rm_property as bmm_cont_prop then @@ -178,7 +178,7 @@ feature -- Display evx_grid.update_last_row_label_col (Definition_grid_col_card_occ, card_str, Void, Void, c_col, Void) -- any allowed - if arch_node.any_allowed then + if a_n.any_allowed then evx_grid.update_last_row_label_col (Definition_grid_col_constraint, Archetype_any_constraint, Void, Void, c_constraint_colour, Void) end @@ -270,8 +270,8 @@ feature -- Modification Not_already_child: not has_child (a_ui_node) Coherence: not a_ui_node.is_rm implies not is_rm do - if attached arch_node and attached a_ui_node.arch_node as child_a_n then - arch_node.put_child (child_a_n) + if attached arch_node as a_n and attached a_ui_node.arch_node as child_a_n then + a_n.put_child (child_a_n) end attach_child_and_display (a_ui_node) ensure @@ -305,8 +305,8 @@ feature -- Modification if is_rm then convert_to_constraint end - check attached arch_node then - arch_node.set_prohibited + if attached arch_node as a_n then + a_n.set_prohibited end if is_displayed then display_in_grid (display_settings) @@ -318,8 +318,8 @@ feature -- Modification if is_rm then convert_to_constraint end - check attached arch_node then - arch_node.set_mandated + if attached arch_node as a_n then + a_n.set_mandated end if is_displayed then display_in_grid (display_settings) @@ -330,8 +330,8 @@ feature -- Modification require not is_rm do - check attached arch_node then - arch_node.set_optional + if attached arch_node as a_n then + a_n.set_optional end if is_displayed then display_in_grid (display_settings) @@ -626,7 +626,7 @@ feature {NONE} -- Context menu end -- only offer addition of new nodes if current node existence is not prohibited - if attached arch_node and then not arch_node.is_prohibited then + if attached arch_node as a_n and then not a_n.is_prohibited then create types_sub_menu.make_with_text (get_text ({ADL_MESSAGES_IDS}.ec_attribute_context_menu_add_child)) -- make a menu item with the base class of the property @@ -655,12 +655,12 @@ feature {NONE} -- Context menu end -- add menu item for copying path to clipboard - if attached arch_node and attached archetype_tool_agents.path_select_action_agent then + if attached arch_node as a_n and attached archetype_tool_agents.path_select_action_agent then create an_mi.make_with_text_and_action (get_text ({ADL_MESSAGES_IDS}.ec_object_context_menu_copy_path), agent (path_str: STRING) do archetype_tool_agents.path_copy_action_agent.call ([path_str]) - end (arch_node.path) + end (a_n.path) ) context_menu.extend (an_mi) end @@ -762,8 +762,8 @@ feature {NONE} -- Implementation apa: ARCHETYPE_PATH_ANALYSER ca_path_in_flat: STRING do - if attached arch_node and attached ui_graph_state.parent_archetype as parent_arch then - create apa.make (arch_node.og_path) + if attached arch_node as a_n and attached ui_graph_state.parent_archetype as parent_arch then + create apa.make (a_n.og_path) if not apa.is_phantom_path_at_level (parent_arch.specialisation_depth) then ca_path_in_flat := apa.path_at_level (parent_arch.specialisation_depth) if parent_arch.has_attribute_path (ca_path_in_flat) then diff --git a/apps/adl_workbench/src/gui/archetype_editor/c_object_ui_node.e b/apps/adl_workbench/src/gui/archetype_editor/c_object_ui_node.e index 9c08ba95d..2c67aeb61 100755 --- a/apps/adl_workbench/src/gui/archetype_editor/c_object_ui_node.e +++ b/apps/adl_workbench/src/gui/archetype_editor/c_object_ui_node.e @@ -56,8 +56,8 @@ feature -- Access path: STRING -- path of this node with respect to top of archetype do - if attached arch_node then - Result := arch_node.path + if attached arch_node as a_n then + Result := a_n.path else Result := parent.path end @@ -115,10 +115,10 @@ feature -- Display precursor (ui_settings) if attached evx_grid then - if attached arch_node then + if attached arch_node as a_n then -- RM name & meaning columns if display_settings.show_technical_view then - evx_grid.update_last_row_label_col (Definition_grid_col_rm_name, arch_node.rm_type_name, node_tooltip_str, c_node_font, c_object_colour, c_pixmap) + evx_grid.update_last_row_label_col (Definition_grid_col_rm_name, a_n.rm_type_name, node_tooltip_str, c_node_font, c_object_colour, c_pixmap) evx_grid.update_last_row_label_col (Definition_grid_col_meaning, node_id_text, node_tooltip_str, c_node_font, c_meaning_colour, Void) else evx_grid.update_last_row_label_col (Definition_grid_col_rm_name, node_display_text, node_tooltip_str, c_node_font, c_object_colour, c_pixmap) @@ -128,27 +128,27 @@ feature -- Display -- card/occ column create s.make_empty c_occ_colour := c_constraint_colour - if attached arch_node.occurrences as att_occ then + if attached a_n.occurrences as att_occ then if not att_occ.is_prohibited then s.append (att_occ.as_string) else s.append (get_text ({ADL_MESSAGES_IDS}.ec_occurrences_removed_text)) end elseif not ui_graph_state.in_differential_view and display_settings.show_rm_multiplicities and not is_root then - s := arch_node.effective_occurrences (agent (ui_graph_state.ref_model).property_object_multiplicity).as_string + s := a_n.effective_occurrences (agent (ui_graph_state.ref_model).property_object_multiplicity).as_string c_occ_colour := c_attribute_colour end evx_grid.set_last_row_label_col (Definition_grid_col_card_occ, s, Void, Void, c_occ_colour, Void) -- sibling order column - if ui_graph_state.in_differential_view and then attached arch_node.sibling_order then + if ui_graph_state.in_differential_view and then attached a_n.sibling_order as a_n_so then create s.make_empty - if arch_node.sibling_order.is_after then + if a_n_so.is_after then s.append ("after") else s.append ("before") end - s.append ("%N" + local_term_string (arch_node.sibling_order.sibling_node_id)) + s.append ("%N" + local_term_string (a_n_so.sibling_node_id)) evx_grid.set_last_row_label_col_multi_line (Definition_grid_col_sibling_order, s, Void, Void, c_constraint_colour, Void) end @@ -229,7 +229,7 @@ feature -- Modification require is_specialised and not is_rm do - if attached arch_node then + if attached arch_node as a_n then -- if AOM type has changed, need to remove current node from flat and replace -- with a node of the new type if not co_create_params.aom_type.same_string (arch_node.generator) then @@ -238,9 +238,9 @@ feature -- Modification -- setup undo/redo ui_graph_state.undo_redo_chain.add_link_simple (evx_grid.ev_grid, -- undo - agent do_refine_existing_constraint (arch_node.rm_type_name, arch_node.occurrences.as_string, - ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id).text, - ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id).description), + agent do_refine_existing_constraint (a_n.rm_type_name, a_n.occurrences.as_string, + ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id).text, + ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id).description), -- redo agent do_refine_existing_constraint (co_create_params.rm_type, co_create_params.occurrences, co_create_params.node_id_text, co_create_params.node_id_description) @@ -257,26 +257,26 @@ feature -- Modification local new_occ: MULTIPLICITY_INTERVAL do - if attached arch_node then + if attached arch_node as a_n then -- RM type - if not arch_node.rm_type_name.same_string (new_rm_type) then - arch_node.set_rm_type_name (new_rm_type) - arch_node.set_specialisation_status_redefined + if not a_n.rm_type_name.same_string (new_rm_type) then + a_n.set_rm_type_name (new_rm_type) + a_n.set_specialisation_status_redefined end -- occurences new_occ := create {MULTIPLICITY_INTERVAL}.make_from_string (new_occurrences) if attached arch_node.occurrences as occ and then not occ.is_equal (new_occ) then - arch_node.set_occurrences (new_occ) - arch_node.set_specialisation_status_redefined + a_n.set_occurrences (new_occ) + a_n.set_specialisation_status_redefined end -- node id - if not new_node_text.same_string (ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id).text) then - ui_graph_state.flat_terminology.replace_term_definition_item (display_settings.language, arch_node.node_id, {ARCHETYPE_TERM}.text_key, new_node_text) + if not new_node_text.same_string (ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id).text) then + ui_graph_state.flat_terminology.replace_term_definition_item (display_settings.language, a_n.node_id, {ARCHETYPE_TERM}.text_key, new_node_text) end - if not new_node_description.same_string (ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id).description) then - ui_graph_state.flat_terminology.replace_term_definition_item (display_settings.language, arch_node.node_id, {ARCHETYPE_TERM}.description_key, new_node_description) + if not new_node_description.same_string (ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id).description) then + ui_graph_state.flat_terminology.replace_term_definition_item (display_settings.language, a_n.node_id, {ARCHETYPE_TERM}.description_key, new_node_description) end end end @@ -295,15 +295,15 @@ feature {NONE} -- Implementation -- show node_id text either as just rubric, or as node_id|rubric|, depending on `show_codes' setting do create Result.make_empty - if attached arch_node then - if not arch_node.node_id.is_equal (Primitive_node_id) then - if ui_graph_state.flat_terminology.has_id_code (arch_node.node_id) then - Result := ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id).text.twin + if attached arch_node as a_n then + if not a_n.node_id.is_equal (Primitive_node_id) then + if ui_graph_state.flat_terminology.has_id_code (a_n.node_id) then + Result := ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id).text.twin if display_settings.show_codes then - Result := annotated_code (arch_node.node_id, Result, " ") + Result := annotated_code (a_n.node_id, Result, " ") end elseif display_settings.show_codes then - Result := arch_node.node_id + Result := a_n.node_id end else -- nothing special to do @@ -315,8 +315,8 @@ feature {NONE} -- Implementation -- show `node_id_text' unless empty, in which case show `rm_type_name' do Result := node_id_text - if Result.is_empty and then attached arch_node then - Result := "(" + arch_node.rm_type_name + ")" + if Result.is_empty and then attached arch_node as a_n then + Result := "(" + a_n.rm_type_name + ")" end end @@ -350,25 +350,25 @@ feature {NONE} -- Implementation pixmap_key, pixmap_cand_key, c_type_occ_str: STRING do create pixmap_key.make_empty - if attached arch_node then + if attached arch_node as a_n then if not display_settings.show_technical_view then pixmap_key := rm_type_pixmap_key (rm_type.defining_class) end if pixmap_key.is_empty then - if attached {C_PRIMITIVE_OBJECT} arch_node then + if attached {C_PRIMITIVE_OBJECT} a_n then c_type_occ_str := bare_type_name (({C_PRIMITIVE_OBJECT}).name) else - c_type_occ_str := arch_node.generating_type.name + c_type_occ_str := a_n.generating_type.name end c_type_occ_str.append ("." + - arch_node.effective_occurrences (agent (ui_graph_state.ref_model).property_object_multiplicity).as_quantifier_text) + a_n.effective_occurrences (agent (ui_graph_state.ref_model).property_object_multiplicity).as_quantifier_text) pixmap_key := Icon_am_dir + resource_path_separator + "added" + resource_path_separator pixmap_cand_key := pixmap_key + c_type_occ_str if has_icon_pixmap (pixmap_cand_key) then pixmap_key := pixmap_cand_key else - pixmap_key.append (arch_node.generating_type.name) + pixmap_key.append (a_n.generating_type.name) end end @@ -409,13 +409,13 @@ feature {NONE} -- Context menu an_mi.set_pixmap (get_icon_pixmap ("tool/class_tool_new")) context_menu.extend (an_mi) - if attached arch_node then + if attached arch_node as a_n then -- if this node is addressable, add menu item to show node_id in terminology create an_mi.make_with_text_and_action (get_text ({ADL_MESSAGES_IDS}.ec_menu_option_display_code), agent (node_id_str: STRING) do archetype_tool_agents.id_code_select_action_agent.call ([node_id_str]) - end (arch_node.node_id) + end (a_n.node_id) ) context_menu.extend (an_mi) @@ -426,13 +426,13 @@ feature {NONE} -- Context menu agent (path_str: STRING) do archetype_tool_agents.path_select_action_agent.call ([path_str]) - end (arch_node.path) + end (a_n.path) ) context_menu.extend (an_mi) end else - if not arch_node.is_root then - if arch_node.specialisation_status /= ss_added then + if not a_n.is_root then + if a_n.specialisation_status /= ss_added then -- add menu item to refine constraint create an_mi.make_with_text_and_action (get_text ({ADL_MESSAGES_IDS}.ec_object_context_menu_refine), agent ui_offer_refine_constraint) context_menu.extend (an_mi) @@ -503,8 +503,8 @@ feature {NONE} -- Context menu arch_node_aom_type, rm_type.type_name, def_occ, ui_graph_state.archetype, anc_arch_node, display_settings) - if attached arch_node and then is_valid_code (arch_node.node_id) then - a_term := ui_graph_state.flat_terminology.term_definition (display_settings.language, arch_node.node_id) + if attached arch_node as a_n and then is_valid_code (a_n.node_id) then + a_term := ui_graph_state.flat_terminology.term_definition (display_settings.language, a_n.node_id) dialog.set_term (a_term.text, a_term.description) end @@ -536,8 +536,8 @@ feature {NONE} -- Context menu apa: ARCHETYPE_PATH_ANALYSER co_path_in_flat: STRING do - if attached arch_node and attached ui_graph_state.parent_archetype as parent_arch then - create apa.make (arch_node.og_path) + if attached arch_node as a_n and attached ui_graph_state.parent_archetype as parent_arch then + create apa.make (a_n.og_path) if not apa.is_phantom_path_at_level (parent_arch.specialisation_depth) then co_path_in_flat := apa.path_at_level (parent_arch.specialisation_depth) if parent_arch.has_object_path (co_path_in_flat) then diff --git a/libraries/openehr/src/rm/common/resource/authored_resource.e b/libraries/openehr/src/rm/common/resource/authored_resource.e index 0a05e6e81..4c23cfa39 100755 --- a/libraries/openehr/src/rm/common/resource/authored_resource.e +++ b/libraries/openehr/src/rm/common/resource/authored_resource.e @@ -234,8 +234,8 @@ feature -- Modification -- merge annotations, if any found in `other' to current do if attached other.annotations as other_anns then - if attached annotations then - annotations.merge (other_anns) + if attached annotations as att_annot then + att_annot.merge (other_anns) else annotations := other_anns.deep_twin end @@ -283,8 +283,8 @@ feature {ARCHETYPE} -- Flattening do translations.remove (a_lang) description.remove_language (a_lang) - if attached annotations then - annotations.remove_language (a_lang) + if attached annotations as att_annot then + att_annot.remove_language (a_lang) end ensure not has_language (a_lang) @@ -295,14 +295,14 @@ feature {ARCHETYPE} -- Flattening local trans_langs: ARRAYED_LIST [STRING] do - if attached translations as trans then - create trans_langs.make_from_array (trans.current_keys) + if not translations.is_empty then + create trans_langs.make_from_array (translations.current_keys) across trans_langs as trans_langs_csr loop remove_language (trans_langs_csr.item) end end ensure - not attached translations + translations.is_empty end remove_translations From f96ddd7a4cc1ea5ebc13e091e19dbc9d31c019e8 Mon Sep 17 00:00:00 2001 From: wolandscat Date: Mon, 11 Mar 2024 09:30:18 -0600 Subject: [PATCH 3/3] Add specialisation graph report; improve id_codes report by adding in new use_archetype reference column. --- .../src/interface/Archetype_library_report.e | 2 +- .../src/interface/Id_code_report.e | 38 +++++---- .../interface/Loinc_archetype_map_report.e | 84 +++++-------------- .../src/interface/arch_id_to_tpl_id_report.e | 2 +- .../src/interface/archetype_reporter.e | 6 +- .../interface/specialization_graph_report.e | 76 +++++++++++++++++ .../src/interface/value_sets_report.e | 2 +- .../src/library/arch_lib_archetype.e | 16 ++++ .../openehr/src/am/archetype/archetype.e | 29 ++++++- 9 files changed, 167 insertions(+), 88 deletions(-) create mode 100644 components/adl_compiler/src/interface/specialization_graph_report.e diff --git a/components/adl_compiler/src/interface/Archetype_library_report.e b/components/adl_compiler/src/interface/Archetype_library_report.e index 26c0fc22c..add5c3014 100644 --- a/components/adl_compiler/src/interface/Archetype_library_report.e +++ b/components/adl_compiler/src/interface/Archetype_library_report.e @@ -64,7 +64,7 @@ feature {ARCHETYPE_REPORTER} -- Processing do end - process_archetype (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) + process_archetype (auth_ara: ARCH_LIB_ARCHETYPE) require auth_ara.is_valid deferred diff --git a/components/adl_compiler/src/interface/Id_code_report.e b/components/adl_compiler/src/interface/Id_code_report.e index c689ed4a2..6d5c58492 100644 --- a/components/adl_compiler/src/interface/Id_code_report.e +++ b/components/adl_compiler/src/interface/Id_code_report.e @@ -42,14 +42,14 @@ feature -- Access Result := "Id-codes in library" end - output_table: ARRAYED_LIST[TUPLE [arch_id, id_code, path, description, loinc_code: STRING]] + output_table: ARRAYED_LIST[TUPLE [arch_id, id_code, path, use_ref, description, loinc_code: STRING]] once create Result.make(0) end feature {ARCHETYPE_REPORTER} -- Processing - process_archetype (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) + process_archetype (auth_ara: ARCH_LIB_ARCHETYPE) -- Generate serialised output under `output_dir' from `ara', optionally building it first if necessary. local id_code, loinc_code: STRING @@ -59,9 +59,9 @@ feature {ARCHETYPE_REPORTER} -- Processing finished: BOOLEAN locatable_descriptions: HASH_TABLE [STRING, STRING] concept_desc: IMMUTABLE_STRING --- save_flag: BOOLEAN + use_ref: STRING do - if not attached {ARCH_LIB_TEMPLATE} auth_ara then + if not (attached {ARCH_LIB_TEMPLATE} auth_ara or attached {ARCH_LIB_TEMPLATE_OVERLAY} auth_ara) then terminology := auth_ara.differential_archetype.terminology create concept_desc.make_from_string (terminology.term_definition (Default_language, terminology.concept_code).text) @@ -71,9 +71,9 @@ feature {ARCHETYPE_REPORTER} -- Processing locatable_descriptions := auth_ara.locatable_descriptions (True, False, Default_language, Text_field_delimiter) -- create a report row for each path, of the form: archetype_id, path, meaning - across auth_ara.locatable_paths (True, False) as path_csr loop + across auth_ara.locatable_path_map (True, False) as path_csr loop -- first work out if the path terminal node has a terminology defined code; if not, ignore it - create path.make_from_string (path_csr.item) + create path.make_from_string (path_csr.key) if path.is_root then id_code := terminology.concept_code else @@ -87,8 +87,8 @@ feature {ARCHETYPE_REPORTER} -- Processing create binding_key.make_empty if terminology.has_term_binding (loinc_terminology_id, id_code) then binding_key := id_code - elseif terminology.has_term_binding (loinc_terminology_id, path_csr.item) then - binding_key := path_csr.item + elseif terminology.has_term_binding (loinc_terminology_id, path_csr.key) then + binding_key := path_csr.key end if not binding_key.is_empty then @@ -98,24 +98,26 @@ feature {ARCHETYPE_REPORTER} -- Processing -- build the text: start with archetype concept create item_text.make_from_string (concept_desc) if not path.is_root then - if attached locatable_descriptions.item (path_csr.item) as desc then + if attached locatable_descriptions.item (path_csr.key) as desc then item_text.append (Text_field_delimiter + desc) else item_text.append (Text_field_delimiter + "(ITEM NOT FOUND}") end end - output_table.extend ([auth_ara.id.as_string, id_code, path_csr.item, text_quote_agent.item([item_text]), loinc_code]) ---if not loinc_code.is_empty then --- terminology.remove_term_binding (binding_key, loinc_terminology_id) --- terminology.put_term_binding (create {URI}.make_from_string (loinc_code), loinc_terminology_id, id_code) --- save_flag := True ---end + -- if it is a C_ARCHETYPE_ROOT node, get the reference + create use_ref.make_empty + if attached {C_ARCHETYPE_ROOT} path_csr.item as car then + if attached current_library.archetype_matching_ref (car.archetype_ref) as att_ala then + use_ref.append (att_ala.id.as_string) + else + use_ref.append ("ERR: unmatched use_reference") + end + end + + output_table.extend ([auth_ara.id.as_string, id_code, path_csr.key, use_ref, text_quote_agent.item([item_text]), loinc_code]) end end ---if save_flag then --- auth_ara.save_differential_text ---end end end diff --git a/components/adl_compiler/src/interface/Loinc_archetype_map_report.e b/components/adl_compiler/src/interface/Loinc_archetype_map_report.e index 5e05659b4..d5fc2293c 100644 --- a/components/adl_compiler/src/interface/Loinc_archetype_map_report.e +++ b/components/adl_compiler/src/interface/Loinc_archetype_map_report.e @@ -42,14 +42,14 @@ feature -- Access Result := "LOINC to Archetype id map" end - output_table: ARRAYED_LIST [TUPLE [loinc_code, arch_id, id_code, path, description: STRING]] + output_table: ARRAYED_LIST [TUPLE [loinc_code, arch_id, id_code, path, use_ref, description: STRING]] once create Result.make(0) end feature {ARCHETYPE_REPORTER} -- Processing - process_archetype (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) + process_archetype (auth_ara: ARCH_LIB_ARCHETYPE) -- Generate serialised output under `output_dir' from `ara', optionally building it first if necessary. local id_code, loinc_code: STRING @@ -59,8 +59,9 @@ feature {ARCHETYPE_REPORTER} -- Processing finished: BOOLEAN locatable_descriptions: HASH_TABLE [STRING, STRING] concept_desc: IMMUTABLE_STRING + use_ref: STRING do - if not attached {ARCH_LIB_TEMPLATE} auth_ara then + if not (attached {ARCH_LIB_TEMPLATE} auth_ara or attached {ARCH_LIB_TEMPLATE_OVERLAY} auth_ara) then terminology := auth_ara.differential_archetype.terminology create concept_desc.make_from_string (terminology.term_definition (Default_language, terminology.concept_code).text) @@ -70,9 +71,9 @@ feature {ARCHETYPE_REPORTER} -- Processing locatable_descriptions := auth_ara.locatable_descriptions (True, False, Default_language, Text_field_delimiter) -- create a report row for each path, of the form: archetype_id, path, meaning - across auth_ara.locatable_paths (True, False) as path_csr loop + across auth_ara.locatable_path_map (True, False) as path_csr loop -- first work out if the path terminal node has a terminology defined code; if not, ignore it - create path.make_from_string (path_csr.item) + create path.make_from_string (path_csr.key) if path.is_root then id_code := terminology.concept_code else @@ -85,8 +86,8 @@ feature {ARCHETYPE_REPORTER} -- Processing create loinc_code.make_empty if terminology.has_term_binding (loinc_terminology_id, id_code) then binding_key := id_code - elseif terminology.has_term_binding (loinc_terminology_id, path_csr.item) then - binding_key := path_csr.item + elseif terminology.has_term_binding (loinc_terminology_id, path_csr.key) then + binding_key := path_csr.key end if not binding_key.is_empty then @@ -95,72 +96,27 @@ feature {ARCHETYPE_REPORTER} -- Processing -- build the text: start with archetype concept create item_text.make_from_string (concept_desc) if not path.is_root then - if attached locatable_descriptions.item (path_csr.item) as desc then + if attached locatable_descriptions.item (path_csr.key) as desc then item_text.append (Text_field_delimiter + desc) else item_text.append (Text_field_delimiter + "(ITEM NOT FOUND}") end end - output_table.extend ([loinc_code, auth_ara.id.as_string, id_code, path_csr.item, text_quote_agent.item([item_text])]) + -- if it is a C_ARCHETYPE_ROOT node, get the reference + create use_ref.make_empty + if attached {C_ARCHETYPE_ROOT} path_csr.item as car then + if attached current_library.archetype_matching_ref (car.archetype_ref) as att_ala then + use_ref.append (att_ala.id.as_string) + else + use_ref.append ("ERR: unmatched use_reference") + end + end + + output_table.extend ([loinc_code, auth_ara.id.as_string, id_code, path_csr.key, use_ref, text_quote_agent.item([item_text])]) end end end end - process_archetype2 (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) - -- Generate serialised output under `output_dir' from `ara', optionally building it first if necessary. - local - flat_terminology: ARCHETYPE_TERMINOLOGY - binding_key, binding_text: STRING - binding_path: OG_PATH - locatable_descriptions: HASH_TABLE [STRING, STRING] - do - flat_terminology := auth_ara.flat_archetype.terminology - - -- find the language key - check flat_terminology.languages_available.has (Default_language) end - - locatable_descriptions := auth_ara.locatable_descriptions (True, False, Default_language, Text_field_delimiter) - - -- process any LOINC codes inside terminology - across flat_terminology.term_bindings_for_terminology (Loinc_terminology_id) as bindings_csr loop - - -- we ignore at-codes --- if not is_value_code (binding_key) then - --- -- here we figure out which id-code the binding key corresponds to. There are 3 possibilities: --- -- * an id-code --- -- * the root path '/', which means the code is the concept code from the terminology --- -- * a path containing one or more id-codes --- binding_key := bindings_csr.key --- if is_id_code (binding_key) then --- binding_text := flat_terminology.term_definition (Default_language, bindings_csr.key).text - --- -- assume path --- else --- create binding_path.make_from_string (binding_key) --- if binding_path.is_root then --- binding_text := flat_terminology.term_definition (Default_language, flat_terminology.concept_code).text --- else --- create binding_text.make_empty --- across binding_path as path_csr loop --- if is_id_code (path_csr.item.object_id) then --- if flat_terminology.has_code (path_csr.item.object_id) then --- binding_text.append (flat_terminology.term_definition (Default_language, path_csr.item.object_id).text) --- else --- binding_text.append (path_csr.item.attr_name) --- end --- end --- if not path_csr.is_last then --- binding_text.append ("/") --- end --- end --- end --- end --- output_table.extend ([bindings_csr.item.as_string, auth_ara.id.as_string, bindings_csr.key, text_quote_agent.item([binding_text])]) --- end - end - end - end diff --git a/components/adl_compiler/src/interface/arch_id_to_tpl_id_report.e b/components/adl_compiler/src/interface/arch_id_to_tpl_id_report.e index dccc3d0f7..efad5780a 100644 --- a/components/adl_compiler/src/interface/arch_id_to_tpl_id_report.e +++ b/components/adl_compiler/src/interface/arch_id_to_tpl_id_report.e @@ -49,7 +49,7 @@ feature -- Access feature {ARCHETYPE_REPORTER} -- Processing - process_archetype (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) + process_archetype (auth_ara: ARCH_LIB_ARCHETYPE) -- Generate serialised output under `output_dir' from `ara', optionally building it first if necessary. local arch_id: STRING diff --git a/components/adl_compiler/src/interface/archetype_reporter.e b/components/adl_compiler/src/interface/archetype_reporter.e index 8aa83889b..df3814f7f 100644 --- a/components/adl_compiler/src/interface/archetype_reporter.e +++ b/components/adl_compiler/src/interface/archetype_reporter.e @@ -63,6 +63,7 @@ feature -- Access report2: ID_CODE_REPORT report3: ARCH_ID_TO_TPL_ID_REPORT report4: VALUE_SETS_REPORT + report5: SPECIALIZATION_GRAPH_REPORT once create Result.make(0) @@ -80,6 +81,9 @@ feature -- Access create report4.make Result.put (report4, report4.title) + + create report5.make + Result.put (report5, report5.title) end feature -- Commands @@ -206,7 +210,7 @@ feature {NONE} -- Implementation do if not exception_encountered then if not is_interrupted then - if attached {ARCH_LIB_AUTHORED_ARCHETYPE} ara as auth_ara and then auth_ara.is_valid then + if attached {ARCH_LIB_ARCHETYPE} ara as auth_ara and then auth_ara.is_valid then report.process_archetype (auth_ara) update_progress end diff --git a/components/adl_compiler/src/interface/specialization_graph_report.e b/components/adl_compiler/src/interface/specialization_graph_report.e new file mode 100644 index 000000000..415204fec --- /dev/null +++ b/components/adl_compiler/src/interface/specialization_graph_report.e @@ -0,0 +1,76 @@ +note + component: "openEHR ADL Tools" + description: "Id-code extractor" + keywords: "export, archetype, ADL" + author: "Thomas Beale " + support: "openEHR AWB project " + copyright: "Copyright (c) 2024- openEHR International" + license: "Apache 2.0 License " + +class SPECIALIZATION_GRAPH_REPORT + +inherit + ARCHETYPE_LIBRARY_REPORT + export + {NONE} all + redefine + output_table + end + + SHARED_ARCHETYPE_LIBRARIES + export + {NONE} all + end + + EXCEPTIONS + export + {NONE} all + end + +create + make + +feature -- Access + + id: STRING + do + Result := "Spec_graph_report" + end + + title: STRING + do + Result := "Specialization graph of archetype library" + end + + output_table: ARRAYED_LIST[TUPLE [arch_id, spec_lineage: STRING]] + once + create Result.make(0) + end + +feature {ARCHETYPE_REPORTER} -- Processing + + process_archetype (ara: ARCH_LIB_ARCHETYPE) + local + arch_csr: ARCH_LIB_ARCHETYPE + parents: STRING + do + create parents.make_empty + + from + arch_csr := ara + until + not attached {ARCH_LIB_ARCHETYPE} arch_csr.parent + loop + if attached {ARCH_LIB_ARCHETYPE} arch_csr.parent as p then + parents.append (p.id.as_string) + arch_csr := p + if attached {ARCH_LIB_ARCHETYPE} arch_csr.parent then + parents.append (", ") + end + end + end + + output_table.extend ([ara.id.as_string, "%"" + parents + "%""]) + end + +end diff --git a/components/adl_compiler/src/interface/value_sets_report.e b/components/adl_compiler/src/interface/value_sets_report.e index e7dbcdcc0..9a70fe74b 100644 --- a/components/adl_compiler/src/interface/value_sets_report.e +++ b/components/adl_compiler/src/interface/value_sets_report.e @@ -49,7 +49,7 @@ feature -- Access feature {ARCHETYPE_REPORTER} -- Processing - process_archetype (auth_ara: ARCH_LIB_AUTHORED_ARCHETYPE) + process_archetype (auth_ara: ARCH_LIB_ARCHETYPE) -- Generate structure of the form: -- { -- id: "Value_sets_report" diff --git a/components/archetype_repository/src/library/arch_lib_archetype.e b/components/archetype_repository/src/library/arch_lib_archetype.e index a40d6a2b7..56e4c2779 100755 --- a/components/archetype_repository/src/library/arch_lib_archetype.e +++ b/components/archetype_repository/src/library/arch_lib_archetype.e @@ -531,6 +531,22 @@ feature -- Artefacts Result := select_archetype (differential_view, editing_enabled).paths_matching_rm_type (agent ref_model.type_conforms_to (?, locatable_class_name)) end + locatable_path_map (differential_view, editing_enabled: BOOLEAN): HASH_TABLE [ARCHETYPE_CONSTRAINT, STRING] + -- path map to Locatable objects + local + aom_profile: AOM_PROFILE + locatable_class_name: STRING + do + locatable_class_name := ref_model.any_type_name + if aom_profiles_access.has_profile_for_rm_schema (ref_model.model_id) then + aom_profile := aom_profiles_access.profile_for_rm_schema (ref_model.model_id) + if not aom_profile.archetype_parent_class.is_empty then + locatable_class_name := aom_profile.archetype_parent_class + end + end + Result := select_archetype (differential_view, editing_enabled).path_map_matching_rm_type (agent ref_model.type_conforms_to (?, locatable_class_name)) + end + primitive_paths (differential_view, editing_enabled: BOOLEAN): ARRAYED_LIST[STRING] -- path map down to primitive leaf nodes do diff --git a/libraries/openehr/src/am/archetype/archetype.e b/libraries/openehr/src/am/archetype/archetype.e index c6c3b9b2e..083068386 100755 --- a/libraries/openehr/src/am/archetype/archetype.e +++ b/libraries/openehr/src/am/archetype/archetype.e @@ -219,7 +219,7 @@ feature -- Access terminology: ARCHETYPE_TERMINOLOGY -feature -- Paths +feature -- Path Maps path_map: HASH_TABLE [ARCHETYPE_CONSTRAINT, STRING] -- get the full path map of the archetype, including paths created by @@ -233,6 +233,31 @@ feature -- Paths end end + path_map_filtered (a_filter: FUNCTION [ANY, TUPLE [ARCHETYPE_CONSTRAINT], BOOLEAN]): HASH_TABLE [ARCHETYPE_CONSTRAINT, STRING] + -- full path map from definition structure filtered by `a_filter'; inclusion if filter + -- returns True + do + create Result.make (0) + across path_map as map_csr loop + if a_filter.item ([map_csr.item]) then + Result.put (map_csr.item, map_csr.key) + end + end + end + + path_map_matching_rm_type (a_bmm_type_matcher_agent: FUNCTION [ANY, TUPLE [STRING], BOOLEAN]): HASH_TABLE [ARCHETYPE_CONSTRAINT, STRING] + -- path map from definition structure + do + Result := path_map_filtered ( + agent (ac: ARCHETYPE_CONSTRAINT; bmm_type_matcher_agent: FUNCTION [ANY, TUPLE [STRING], BOOLEAN]): BOOLEAN + do + Result := attached {C_OBJECT} ac as cco and then bmm_type_matcher_agent.item ([cco.rm_type_name]) + end (?, a_bmm_type_matcher_agent) + ) + end + +feature -- Paths + all_paths: ARRAYED_LIST [STRING] -- all paths from definition structure do @@ -249,7 +274,7 @@ feature -- Paths Result := all_paths_filtered ( agent (ac: ARCHETYPE_CONSTRAINT; bmm_type_matcher_agent: FUNCTION [ANY, TUPLE [STRING], BOOLEAN]): BOOLEAN do - Result := attached {C_COMPLEX_OBJECT} ac as cco and then bmm_type_matcher_agent.item ([cco.rm_type_name]) + Result := attached {C_OBJECT} ac as cco and then bmm_type_matcher_agent.item ([cco.rm_type_name]) end (?, a_bmm_type_matcher_agent) ) ensure