diff --git a/zsaplink_bopf.clas.abap b/zsaplink_bopf.clas.abap new file mode 100644 index 000000000..2e09c9d2b --- /dev/null +++ b/zsaplink_bopf.clas.abap @@ -0,0 +1,41 @@ +class ZSAPLINK_BOPF definition + public + inheriting from ZSAPLINK_GENERIC_OBJ + final + create public . + +*/---------------------------------------------------------------------\ +*| This file is part of SAPlink. | +*| | +*| SAPlink is free software; you can redistribute it and/or modify | +*| it under the terms of the GNU General Public License as published | +*| by the Free Software Foundation; either version 2 of the License, | +*| or (at your option) any later version. | +*| | +*| SAPlink is distributed in the hope that it will be useful, | +*| but WITHOUT ANY WARRANTY; without even the implied warranty of | +*| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | +*| GNU General Public License for more details. | +*| | +*| You should have received a copy of the GNU General Public License | +*| along with SAPlink; if not, write to the | +*| Free Software Foundation, Inc., | +*| 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +*\---------------------------------------------------------------------/ +public section. +protected section. + + methods GETOBJECTTYPE + redefinition . +private section. +ENDCLASS. + + + +CLASS ZSAPLINK_BOPF IMPLEMENTATION. + + +METHOD getobjecttype. + objecttype = 'BOBF'. + ENDMETHOD. +ENDCLASS. \ No newline at end of file diff --git a/zsaplink_bopf.clas.locals_imp.abap b/zsaplink_bopf.clas.locals_imp.abap new file mode 100644 index 000000000..78d6bd56d --- /dev/null +++ b/zsaplink_bopf.clas.locals_imp.abap @@ -0,0 +1,1814 @@ +*"* use this source file for the definition and implementation of +*"* local helper classes, interface definitions and type +*"* declarations + +CLASS lcl_map DEFINITION INHERITING FROM /bobf/cl_conf_model_api_map. + PUBLIC SECTION. + METHODS map_action_for_create REDEFINITION. + + PROTECTED SECTION. + METHODS map_action_data + IMPORTING + !is_action_api TYPE /bobf/s_conf_model_api_action + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_node_key TYPE /bobf/obm_node_key + RETURNING + VALUE(rr_action_data) TYPE REF TO /bobf/s_conf_act_list . +ENDCLASS. + +CLASS lcl_map IMPLEMENTATION. + + METHOD map_action_data. + + "the node key must be supplied also for create scenarios in order to + "maintain parent - child node relationships + CREATE DATA rr_action_data. + + "create node + rr_action_data->* = VALUE #( + origin_bo_key = is_action_api-origin_bo_key + act_cat = SWITCH #( is_action_api-act_cat + WHEN '' THEN /bobf/if_conf_c=>sc_action_standard + ELSE is_action_api-act_cat ) + node_key = iv_node_key + act_cardinality = is_action_api-act_cardinality + param_data_type = is_action_api-param_data_type + act_name = is_action_api-act_name + description = is_action_api-description + act_class = is_action_api-act_class + extendible = is_action_api-extendible + ). + IF rr_action_data->origin_bo_key IS INITIAL. + rr_action_data->origin_bo_key = iv_bo_key. + ENDIF. + + ENDMETHOD. + METHOD map_action_for_create. + +* BOPF uses node categories in order to differentiate between framework-actions and standard actions +* in addition to the action type => we need to support this as well. + DATA ls_modification TYPE /bobf/s_frw_modification. + DATA lt_node_cat TYPE /bobf/t_conf_node_cat. + DATA ls_action_conf TYPE REF TO /bobf/s_conf_act_conf. + + "create modify container for action + ls_modification = VALUE #( + association = /bobf/if_conf_obj_c=>sc_association-version-action + change_mode = /bobf/if_frw_c=>sc_modify_create + key = is_action-act_key + node = /bobf/if_conf_obj_c=>sc_node-action + source_key = iv_version_key + source_node = /bobf/if_conf_obj_c=>sc_node-version + node_cat = SWITCH #( is_action-act_cat + WHEN /bobf/if_conf_c=>sc_action_adopt_numbers THEN /bobf/if_conf_obj_c=>sc_node_category-action-adopt_foreign_numbers + WHEN /bobf/if_conf_c=>sc_action_archive THEN /bobf/if_conf_obj_c=>sc_node_category-action-archive + WHEN /bobf/if_conf_c=>sc_action_create THEN /bobf/if_conf_obj_c=>sc_node_category-action-create + WHEN /bobf/if_conf_c=>sc_action_delete THEN /bobf/if_conf_obj_c=>sc_node_category-action-delete + WHEN /bobf/if_conf_c=>sc_action_enhancement_post THEN /bobf/if_conf_obj_c=>sc_node_category-action-post_enhancement + WHEN /bobf/if_conf_c=>sc_action_enhancement_pre THEN /bobf/if_conf_obj_c=>sc_node_category-action-pre_enhancement + WHEN /bobf/if_conf_c=>sc_action_handle_bo_events THEN /bobf/if_conf_obj_c=>sc_node_category-action-handle_business_object_events + WHEN /bobf/if_conf_c=>sc_action_lock THEN /bobf/if_conf_obj_c=>sc_node_category-action-lock + WHEN /bobf/if_conf_c=>sc_action_unlock THEN /bobf/if_conf_obj_c=>sc_node_category-action-unlock + WHEN /bobf/if_conf_c=>sc_action_update THEN /bobf/if_conf_obj_c=>sc_node_category-action-update + WHEN /bobf/if_conf_c=>sc_action_save THEN /bobf/if_conf_obj_c=>sc_node_category-action-save + ELSE /bobf/if_conf_obj_c=>sc_node_category-action-standard + ) + data = map_action_data( + is_action_api = is_action + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + ) + ). + + INSERT ls_modification INTO TABLE ct_modification. + + ENDMETHOD. + + +ENDCLASS. + +CLASS lcl_conf_model_api_adt_copy DEFINITION CREATE PUBLIC INHERITING FROM /bobf/cl_conf_model_api_adt. +* @sap: Changes with respect to /BOBF/CL_CONF_MODEL_API_ADT +* constructor injection of dependencies in order to get a custom mapper for framework-action-support +* update_node maps root node key as parent node + + PUBLIC SECTION. + + METHODS constructor + IMPORTING + !io_map TYPE REF TO /bobf/cl_conf_model_api_map OPTIONAL + !io_compare TYPE REF TO /bobf/cl_conf_model_adt_comp OPTIONAL + !iv_package TYPE devclass OPTIONAL + !iv_transport_request TYPE trkorr OPTIONAL . + METHODS update_business_object REDEFINITION. + + PROTECTED SECTION. + DATA mo_map TYPE REF TO /bobf/cl_conf_model_api_map. + DATA mo_compare TYPE REF TO /bobf/cl_conf_model_adt_comp. + + PRIVATE SECTION. + + TYPES: + BEGIN OF gty_bo_name_key . + TYPES name TYPE /bobf/obm_name. + TYPES key TYPE /bobf/obm_bo_key. + TYPES END OF gty_bo_name_key . + TYPES: + gtt_bo_name_key TYPE SORTED TABLE OF gty_bo_name_key WITH UNIQUE KEY name . + + CLASS-DATA gt_bo_locked TYPE gtt_bo_name_key . + + METHODS prepare_modification . + METHODS finalize_nodes + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !it_node_current TYPE /bobf/t_conf_model_adt_node + !it_node_new TYPE /bobf/t_conf_model_adt_node + !it_idx_create_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + EXPORTING + !et_modification TYPE /bobf/t_frw_modification + !ev_success TYPE boole_d . + METHODS process_actions + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_action_current TYPE /bobf/t_conf_model_adt_action + !it_action_new TYPE /bobf/t_conf_model_adt_action + !it_idx_create_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_queries + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_query_current TYPE /bobf/t_conf_model_adt_query + !it_query_new TYPE /bobf/t_conf_model_adt_query + !it_idx_create_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_associations + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !is_source_node TYPE /bobf/s_conf_model_api_node + !it_assoc_current TYPE /bobf/t_conf_model_adt_assoc + !it_assoc_new TYPE /bobf/t_conf_model_adt_assoc + !it_idx_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_node_new TYPE /bobf/t_conf_model_adt_node + !it_alternative_key TYPE /bobf/t_conf_model_adt_alt + CHANGING + !ct_representation_node TYPE /bobf/t_conf_node + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_nodes + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !it_node_current TYPE /bobf/t_conf_model_adt_node + !it_node_new TYPE /bobf/t_conf_model_adt_node + !it_idx_create_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_comp_subentity_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_representation_node TYPE /bobf/t_conf_node + !ct_modification TYPE /bobf/t_frw_modification . + METHODS get_highest_priority_message + IMPORTING + !io_message TYPE REF TO /bobf/if_frw_message + RETURNING + VALUE(ro_message) TYPE REF TO /bobf/cm_frw . + METHODS process_alternative_keys + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_altkey_current TYPE /bobf/t_conf_model_adt_alt OPTIONAL + !it_altkey_new TYPE /bobf/t_conf_model_adt_alt + !is_node_new TYPE /bobf/s_conf_model_api_node + !it_idx_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_altkey_validation + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_altkey_new TYPE /bobf/t_conf_model_adt_alt + !is_node_new TYPE /bobf/s_conf_model_api_node + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_properties + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_prop_current TYPE /bobf/t_conf_model_adt_sprop + !it_prop_new TYPE /bobf/t_conf_model_adt_sprop + !is_node_new TYPE /bobf/s_conf_model_api_node + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_authorizations + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_auth_current TYPE /bobf/t_conf_model_adt_auth + !it_auth_new TYPE /bobf/t_conf_model_adt_auth + !is_node_new TYPE /bobf/s_conf_model_api_node + !it_idx_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_validations + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_val_current TYPE /bobf/t_conf_model_adt_val + !it_val_new TYPE /bobf/t_conf_model_adt_val + !is_node_new TYPE /bobf/s_conf_model_api_node + !it_idx_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS process_determinations + IMPORTING + !iv_bo_key TYPE /bobf/obm_bo_key + !iv_version_key TYPE /bobf/obm_obj_key + !iv_node_key TYPE /bobf/obm_node_key + !it_det_current TYPE /bobf/t_conf_model_adt_det + !it_det_new TYPE /bobf/t_conf_model_adt_det + !is_node_new TYPE /bobf/s_conf_model_api_node + !it_idx_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + !it_idx_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index + CHANGING + !ct_modification TYPE /bobf/t_frw_modification . + METHODS get_dependent_objects + IMPORTING + !it_node TYPE /bobf/t_conf_model_api_node + EXPORTING + et_dependent_object TYPE /bobf/t_conf_model_adt_bo . + METHODS collapse_delegated_nodes + IMPORTING + !is_updated_business_object TYPE /bobf/s_conf_model_adt_bo + !is_current_business_object TYPE /bobf/s_conf_model_adt_bo + EXPORTING + !es_updated_business_object TYPE /bobf/s_conf_model_adt_bo. +ENDCLASS. + +CLASS lcl_conf_model_api_adt_copy IMPLEMENTATION. + METHOD collapse_delegated_nodes. + + " correspondes to method /BOBF/CL_CONF_MODEL_API_MAP->MAP_DELEGATED_NODE_FOR_READ... + " correspondes to method /BOBF/CL_CONF_MODEL_API_MAP->MAP_DELEGATED_ASSOC_FOR_READ... + + " check if there're Delegated Nodes at all. if not, there's nothing to do... + READ TABLE is_updated_business_object-nodes WITH KEY node-node_type = /bobf/if_conf_c=>sc_node_type_do + TRANSPORTING NO FIELDS. + IF sy-subrc <> 0. + es_updated_business_object = is_updated_business_object. + RETURN. " !!!! + ENDIF. + + + CLEAR es_updated_business_object. + + + " >>>>> header... + es_updated_business_object-header = is_updated_business_object-header. + + + " >>>>> adjust nodes and compositions... + LOOP AT is_updated_business_object-nodes INTO DATA(ls_node). + + " skip (remove) all DO nodes (cascading), the exception is the Delegated Node itself... + FIND ALL OCCURRENCES OF '.' IN ls_node-node-node_name MATCH COUNT DATA(lv_count). + IF lv_count = 1. + SPLIT ls_node-node-node_name AT '.' INTO DATA(lv_prefix) DATA(lv_suffix). + IF lv_suffix <> 'ROOT'. + CONTINUE. + ENDIF. + ELSEIF lv_count > 1. + CONTINUE. + ENDIF. + + " adjust Delegated Node... + IF ls_node-node-node_type = /bobf/if_conf_c=>sc_node_type_do. + " >>>>> delete subentities like actions, associations, ... + DATA(ls_delegated_node_node) = ls_node-node. + CLEAR ls_node. + ls_node-node = ls_delegated_node_node. + " clear transient key, description and DDIC fields, otherwise the compare function will mark node as modified... + CLEAR ls_node-node-do_embedding_key. + CLEAR ls_node-node-description. + CLEAR ls_node-node-data_data_type. + CLEAR ls_node-node-data_data_type_t. + CLEAR ls_node-node-data_type. + CLEAR ls_node-node-data_table_type. + CLEAR ls_node-node-database_table. + " >>>>> restore the node key - potentially it's the DO ROOT node key, but has to be the node key of the Delegated Node. + " >>>>> otherwise the subsequent compare function will mark the composition for re-creation. + READ TABLE is_current_business_object-nodes ASSIGNING FIELD-SYMBOL() + WITH KEY node-node_type = ls_node-node-node_type + node-do_embedding_name = ls_node-node-do_embedding_name. + IF sy-subrc = 0. + ls_node-node-node_key = -node-node_key. + ENDIF. + ENDIF. + + " adjust composition to Delegated Node... + LOOP AT ls_node-association ASSIGNING FIELD-SYMBOL() + WHERE assoc_cat = /bobf/if_conf_c=>sc_assoccat_object. + " clear transient key, otherwise the compare function will mark composition as modified... + CLEAR -target_do_embedding_key. + " >>>>> restore the target node key - potentially it's the DO ROOT node key, but has to be the node key of the Delegated Node. + " >>>>> otherwise the subsequent compare function will mark the composition for re-creation. + READ TABLE is_current_business_object-nodes ASSIGNING + WITH KEY node-node_key = -source_node_key. + IF sy-subrc = 0. + READ TABLE -association ASSIGNING FIELD-SYMBOL() + WITH KEY assoc_key = -assoc_key. + IF sy-subrc = 0. + -target_node_key = -target_node_key. + ENDIF. + ENDIF. + ENDLOOP. + + INSERT ls_node INTO TABLE es_updated_business_object-nodes. + + ENDLOOP. + + ENDMETHOD. + + + METHOD constructor. + super->constructor( ). + mv_package = iv_package. + mv_transport = iv_transport_request. + + IF io_compare IS INITIAL. + CREATE OBJECT mo_compare. + ELSE. + mo_compare = io_compare. + ENDIF. + + IF io_map IS INITIAL. + CREATE OBJECT mo_map. + ELSE. + mo_map = io_map. + ENDIF. + + ENDMETHOD. + + + METHOD finalize_nodes. + + CLEAR et_modification. + ev_success = abap_true. + + LOOP AT it_idx_create_new INTO DATA(lv_index). + READ TABLE it_node_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + ev_success = /bobf/cl_conf_model_api_reuse=>create_ext_node_sysadm_trigger( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + iv_parent_node_key = -node-parent_node_key + iv_node_name = CONV #( -node-node_name ) + CHANGING + ct_modification = et_modification ). + IF ev_success = abap_false. + RETURN. + ENDIF. + + ENDLOOP. + + ENDMETHOD. + + + + METHOD get_dependent_objects. + + CLEAR et_dependent_object. + + DATA lt_do_key TYPE STANDARD TABLE OF /bobf/obm_bo_key. + LOOP AT it_node ASSIGNING FIELD-SYMBOL() + WHERE node_type = /bobf/if_conf_c=>sc_node_type_do + AND ref_bo_key IS NOT INITIAL. + APPEND -ref_bo_key TO lt_do_key. + ENDLOOP. + + SORT lt_do_key. + DELETE ADJACENT DUPLICATES FROM lt_do_key. + + + LOOP AT lt_do_key ASSIGNING FIELD-SYMBOL(). + + DATA(lv_do_name) = /bobf/cl_conf_model_api_reuse=>get_bo_name_by_key( ). + CHECK lv_do_name IS NOT INITIAL. + + NEW /bobf/cl_conf_model_api_adt( )->get_business_object( + EXPORTING + iv_business_object_name = lv_do_name + iv_edit_mode = abap_false + iv_expand_dependent_objects = abap_true " a DO may also include a DO... + IMPORTING + es_business_object = DATA(ls_dependent_object) ). + CHECK ls_dependent_object IS NOT INITIAL. + + APPEND ls_dependent_object TO et_dependent_object. + + ENDLOOP. + + ENDMETHOD. + + + METHOD get_highest_priority_message. + IF io_message IS INITIAL. + RETURN. + ENDIF. + + io_message->get_messages( + EXPORTING + iv_severity = /bobf/cm_frw=>co_severity_error + IMPORTING + et_message = DATA(lt_message) + ). + + READ TABLE lt_message INTO DATA(ls_message) INDEX 1. + IF sy-subrc = 0. + ro_message = ls_message-message. + ENDIF. + ENDMETHOD. + + + METHOD prepare_modification. + + /bobf/cl_conf_toolbox=>sv_devclass = mv_package. + /bobf/cl_conf_toolbox=>sv_corr_num = mv_transport. + "suppress transport dialogs: + /bobf/cl_conf_toolbox=>sv_genflag = abap_true. + /bobf/cl_conf_toolbox=>sv_suppress_dialog = abap_true. + + " set active/inactive handling enabled + /bobf/cl_conf_toolbox=>sv_activation_handling = abap_true. + + "cleanup transaction, because modify works stateless + DATA(lo_transaction_manager) = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( ). + lo_transaction_manager->cleanup( ). + + ENDMETHOD. + + + METHOD process_actions. + + DATA lo_map TYPE REF TO /bobf/cl_conf_model_api_map. + DATA lv_index TYPE i. + + CREATE OBJECT lo_map. + + LOOP AT it_idx_create_new INTO lv_index. + + READ TABLE it_action_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_action_for_create( + EXPORTING + is_action = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + LOOP AT it_idx_update_new INTO lv_index. + + READ TABLE it_action_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_action_for_update( + EXPORTING + is_action = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + LOOP AT it_idx_delete_current INTO lv_index. + + READ TABLE it_action_current ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_action_for_delete( + EXPORTING + is_action = + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_alternative_keys. + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + LOOP AT it_idx_create ASSIGNING FIELD-SYMBOL(). + + READ TABLE it_altkey_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + lo_map->map_altkey_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_alternative_key = + iv_node_key = iv_node_key + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_update ASSIGNING . + + READ TABLE it_altkey_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_altkey_subent_keys( + EXPORTING + iv_altkey_key = -altkey_key + IMPORTING + et_ak_field_key_delete = DATA(lt_ak_field_key_delete) ). + + lo_map->map_altkey_for_update( + EXPORTING + is_alternative_key = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + iv_version_key = iv_version_key + it_ak_field_key_delete = lt_ak_field_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_delete ASSIGNING . + + READ TABLE it_altkey_current ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_altkey_subent_keys( + EXPORTING + iv_altkey_key = -altkey_key + IMPORTING + et_ak_field_key_delete = lt_ak_field_key_delete ). + + lo_map->map_altkey_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + is_alternative_key = + it_ak_field_key_delete = lt_ak_field_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + " >>>>> create/remove action validation for altkey uniqueness check... + me->process_altkey_validation( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = iv_node_key + it_altkey_new = it_altkey_new + is_node_new = is_node_new + CHANGING + ct_modification = ct_modification ). + + ENDMETHOD. + + + METHOD process_altkey_validation. + + " >>>>> create/remove action validation for altkey uniqueness check (with library class)... + + " check if the special action validation is needed... + DATA(lv_unique_check_needed) = abap_false. + LOOP AT it_altkey_new TRANSPORTING NO FIELDS + WHERE uniqueness_check = /bobf/if_conf_c=>sc_altkey_uniqcheck_after_mod. "#EC CI_SORTSEQ + lv_unique_check_needed = abap_true. + EXIT. + ENDLOOP. + + " check existence of the special action validation... + DATA(lv_altkey_uniq_check_val_key) = /bobf/cl_conf_model_api_reuse=>get_val_key_altkey_uniq_check( iv_node_key ). + + + IF lv_unique_check_needed = abap_true AND lv_altkey_uniq_check_val_key IS INITIAL. + + " create action validation... + NEW /bobf/cl_conf_model_api_map( )->map_val_act_uniq_for_create( + EXPORTING + is_node = is_node_new + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + CHANGING + ct_modification = ct_modification ). + + ELSEIF lv_unique_check_needed = abap_false AND lv_altkey_uniq_check_val_key IS NOT INITIAL. + + " remove action validation... + /bobf/cl_conf_model_api_reuse=>get_validation_subent_keys( + EXPORTING + iv_val_key = lv_altkey_uniq_check_val_key + IMPORTING + et_val_trigger_key_delete = DATA(lt_val_trigger_key_delete) + et_val_conf_key_delete = DATA(lt_val_conf_key_delete) + et_val_group_conf_key_delete = DATA(lt_val_group_conf_key_delete) ). + NEW /bobf/cl_conf_model_api_map( )->map_val_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + iv_val_key = lv_altkey_uniq_check_val_key + it_val_trigger_key_delete = lt_val_trigger_key_delete + it_val_conf_key_delete = lt_val_conf_key_delete + it_val_group_conf_key_delete = lt_val_group_conf_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDIF. + + ENDMETHOD. + + + METHOD process_associations. + + DATA ls_target_node TYPE /bobf/s_conf_model_adt_node. + + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + LOOP AT it_idx_create ASSIGNING FIELD-SYMBOL(). + + READ TABLE it_assoc_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + CLEAR ls_target_node. + READ TABLE it_node_new WITH KEY node-node_key = -target_node_key INTO ls_target_node. + + lo_map->map_assoc_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_association = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + is_source_node = is_source_node + is_target_node = ls_target_node-node + CHANGING + ct_representation_node = ct_representation_node + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_update ASSIGNING . + + READ TABLE it_assoc_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for subentities... + /bobf/cl_conf_model_api_reuse=>get_association_subent_keys( + EXPORTING + iv_assoc_key = -assoc_key + IMPORTING + et_assoc_binding_key_delete = DATA(lt_assoc_binding_key_delete) ). + + CLEAR ls_target_node. + READ TABLE it_node_new WITH KEY node-node_key = -target_node_key INTO ls_target_node. + + lo_map->map_assoc_for_update( + EXPORTING + is_association = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + it_assoc_binding_key_delete = lt_assoc_binding_key_delete + is_source_node = is_source_node + is_target_node = ls_target_node-node + CHANGING + ct_representation_node = ct_representation_node + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_delete ASSIGNING . + + READ TABLE it_assoc_current ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for subentities... + /bobf/cl_conf_model_api_reuse=>get_association_subent_keys( + EXPORTING + iv_assoc_key = -assoc_key + IMPORTING + et_assoc_binding_key_delete = lt_assoc_binding_key_delete ). + + lo_map->map_assoc_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + is_association = + it_assoc_binding_key_delete = lt_assoc_binding_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_authorizations. + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + LOOP AT it_idx_create ASSIGNING FIELD-SYMBOL(). + + READ TABLE it_auth_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + lo_map->map_auth_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_authorization = + is_node = is_node_new + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_update ASSIGNING . + + READ TABLE it_auth_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_authorization_subent_keys( + EXPORTING + iv_version_key = iv_version_key + iv_node_key = iv_node_key + iv_auth_obj_name = -auth_obj_name + IMPORTING + et_acf_map_key_delete = DATA(lt_acf_map_key_delete) ). + + lo_map->map_auth_for_update( + EXPORTING + is_authorization = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + is_node = is_node_new + iv_version_key = iv_version_key + it_acf_map_key_delete = lt_acf_map_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_delete ASSIGNING . + + READ TABLE it_auth_current ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_authorization_subent_keys( + EXPORTING + iv_version_key = iv_version_key + iv_node_key = iv_node_key + iv_auth_obj_name = -auth_obj_name + IMPORTING + et_acf_map_key_delete = lt_acf_map_key_delete ). + + lo_map->map_auth_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + is_authorization = + it_acf_map_key_delete = lt_acf_map_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_determinations. + + " >>>>> remark: DETERMINATION_CONF and *special handling* regarding DETERMINATION_TRIGGER and DETERMINATION_WRITE is + " >>>>> processed later on in determinations DETERMINATION_PATTERN_CREATE / _UPDATE (@ conf model node DETERMINATION)... + + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + LOOP AT it_idx_create ASSIGNING FIELD-SYMBOL(). + + READ TABLE it_det_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + lo_map->map_det_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_determination = + is_node = is_node_new + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_update ASSIGNING . + + READ TABLE it_det_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_determination_subent_keys( + EXPORTING + iv_det_key = -det_key + IMPORTING + et_det_trigger_key_delete = DATA(lt_det_trigger_key_delete) + et_det_write_key_delete = DATA(lt_det_write_key_delete) + et_det_conf_key_delete = DATA(lt_det_conf_key_delete) + et_det_succ_dep_key_delete = DATA(lt_det_succ_dep_key_delete) + et_det_pred_dep_key_delete = DATA(lt_det_pred_dep_key_delete) ). + + lo_map->map_det_for_update( + EXPORTING + is_determination = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + is_node = is_node_new + iv_version_key = iv_version_key + it_det_trigger_key_delete = lt_det_trigger_key_delete + it_det_write_key_delete = lt_det_write_key_delete + it_det_conf_key_delete = lt_det_conf_key_delete + it_det_succ_dep_key_delete = lt_det_succ_dep_key_delete + it_det_pred_dep_key_delete = lt_det_pred_dep_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_delete ASSIGNING . + + READ TABLE it_det_current ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_determination_subent_keys( + EXPORTING + iv_det_key = -det_key + IMPORTING + et_det_trigger_key_delete = lt_det_trigger_key_delete + et_det_write_key_delete = lt_det_write_key_delete + et_det_conf_key_delete = lt_det_conf_key_delete + et_det_succ_dep_key_delete = lt_det_succ_dep_key_delete + et_det_pred_dep_key_delete = lt_det_pred_dep_key_delete ). + + lo_map->map_det_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + is_determination = + it_det_trigger_key_delete = lt_det_trigger_key_delete + it_det_write_key_delete = lt_det_write_key_delete + it_det_conf_key_delete = lt_det_conf_key_delete + it_det_succ_dep_key_delete = lt_det_succ_dep_key_delete + it_det_pred_dep_key_delete = lt_det_pred_dep_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_nodes. + DATA lv_index TYPE i. + DATA lt_idx_create_action_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_update_action_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_delete_action_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_create_query_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_update_query_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_delete_query_current TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + + + "process new nodes + LOOP AT it_idx_create_new INTO lv_index. + + READ TABLE it_node_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. +* @sap: An business object which has been created with create_business_object might have a different ROOT-node_key, +* as the consumer cannot supply the node_key. +* Thus, lateron, subnodes of the root node refer to the wrong parent_node. + IF it_node_current IS NOT INITIAL. + READ TABLE it_node_current ASSIGNING FIELD-SYMBOL() WITH KEY node-parent_node_key = ''. + ASSERT sy-subrc = 0. "there has to be a root node + + READ TABLE it_node_new ASSIGNING FIELD-SYMBOL() WITH KEY node-node_key = -node-node_key. + IF sy-subrc = 0. + IF -node-parent_node_key IS INITIAL. + " is a subnote of the root-node + -node-parent_node_key = -node-node_key. + ENDIF. + ENDIF. + ENDIF. + + mo_map->map_node_for_create( + EXPORTING + is_node = -node + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification ). + + "collect subentities to be created + "- actions + LOOP AT -action ASSIGNING FIELD-SYMBOL(). + mo_map->map_action_for_create( + EXPORTING + is_action = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification + ). + ENDLOOP. + + "- queries + LOOP AT -query ASSIGNING FIELD-SYMBOL(). + mo_map->map_query_for_create( + EXPORTING + is_query = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification + ). + ENDLOOP. + + "- associations + LOOP AT -association ASSIGNING FIELD-SYMBOL(). + DATA ls_target_node TYPE /bobf/s_conf_model_adt_node. + CLEAR ls_target_node. + READ TABLE it_node_new WITH KEY node-node_key = -target_node_key INTO ls_target_node. + mo_map->map_assoc_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_association = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + is_source_node = -node + is_target_node = ls_target_node-node + CHANGING + ct_representation_node = ct_representation_node + ct_modification = ct_modification + ). + ENDLOOP. + + "- alternative keys + LOOP AT -alternative_key ASSIGNING FIELD-SYMBOL(). + mo_map->map_altkey_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_alternative_key = + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + IF -uniqueness_check = /bobf/if_conf_c=>sc_altkey_uniqcheck_after_mod. + " create action validation for uniqueness check... + mo_map->map_val_act_uniq_for_create( + EXPORTING + is_node = -node + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + ENDIF. + ENDLOOP. + + "- determinations + LOOP AT -determination ASSIGNING FIELD-SYMBOL(). + mo_map->map_det_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_determination = + is_node = -node + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + "- validations + LOOP AT -validation ASSIGNING FIELD-SYMBOL(). + mo_map->map_val_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_validation = + is_node = -node + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + "- static properties + LOOP AT -property ASSIGNING FIELD-SYMBOL(). + mo_map->map_prop_for_create( + EXPORTING + is_property = + is_node = -node + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + "- authorizations + LOOP AT -authorization ASSIGNING FIELD-SYMBOL(). + mo_map->map_auth_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_authorization = + is_node = -node + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = -node-node_key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + ENDLOOP. + + "process updated nodes + LOOP AT it_idx_update_new INTO lv_index. + READ TABLE it_node_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + mo_map->map_node_for_update( + EXPORTING + is_node = -node + iv_bo_key = iv_bo_key + CHANGING + ct_modification = ct_modification ). + + "no handling of subentities; The nodes are redundandly contained in it_idx_comp_subentitiy + ENDLOOP. + + "process deleted nodes + LOOP AT it_idx_delete_current INTO lv_index. + + READ TABLE it_node_current ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + mo_map->map_node_for_delete( + EXPORTING + is_node = -node + CHANGING + ct_modification = ct_modification + ). + "no handling of subentities; BOBF should take care of this automatically + ENDLOOP. + + "process subentities + LOOP AT it_idx_comp_subentity_new INTO lv_index. + + READ TABLE it_node_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + READ TABLE it_node_current ASSIGNING FIELD-SYMBOL() WITH KEY + node-node_key = -node-node_key + node-do_embedding_key = -node-do_embedding_key. + ASSERT sy-subrc = 0. + + "process actions + mo_compare->compare_tables_for_changes( + EXPORTING + it_subentity_new = -action + it_subentity_current = -action + it_update_rel_element = VALUE #( ( |UPDATABLE| ) ) + IMPORTING + et_index_create_new = lt_idx_create_action_new + et_index_update_new = lt_idx_update_action_new + et_index_delete_current = lt_idx_delete_action_current + ). + process_actions( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_action_current = -action + it_action_new = -action + it_idx_create_new = lt_idx_create_action_new + it_idx_update_new = lt_idx_update_action_new + it_idx_delete_current = lt_idx_delete_action_current + CHANGING + ct_modification = ct_modification + ). + + "process queries + mo_compare->compare_tables_for_changes( + EXPORTING + it_subentity_new = -query + it_subentity_current = -query + it_update_rel_element = VALUE #( ( |UPDATABLE| ) ) + IMPORTING + et_index_create_new = lt_idx_create_query_new + et_index_update_new = lt_idx_update_query_new + et_index_delete_current = lt_idx_delete_query_current + ). + process_queries( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_query_current = -query + it_query_new = -query + it_idx_create_new = lt_idx_create_query_new + it_idx_update_new = lt_idx_update_query_new + it_idx_delete_current = lt_idx_delete_query_current + CHANGING + ct_modification = ct_modification + ). + + " process alternative keys + mo_compare->compare_tables_for_changes( + EXPORTING + it_subentity_new = -alternative_key + it_subentity_current = -alternative_key + it_update_rel_element = VALUE #( ( |UPDATABLE| ) ) + IMPORTING + et_index_create_new = DATA(lt_idx_create_altkey) + et_index_update_new = DATA(lt_idx_update_altkey) + et_index_delete_current = DATA(lt_idx_delete_altkey) ). + process_alternative_keys( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_altkey_current = -alternative_key + it_altkey_new = -alternative_key + is_node_new = -node + it_idx_create = lt_idx_create_altkey + it_idx_update = lt_idx_update_altkey + it_idx_delete = lt_idx_delete_altkey + CHANGING + ct_modification = ct_modification ). + + " process associations + mo_compare->compare_associations( + EXPORTING + it_assoc_new = -association + it_assoc_current = -association + IMPORTING + et_index_create = DATA(lt_idx_create_assoc) + et_index_update = DATA(lt_idx_update_assoc) + et_index_delete = DATA(lt_idx_delete_assoc) ). + process_associations( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + is_source_node = -node + it_assoc_current = -association + it_assoc_new = -association + it_idx_create = lt_idx_create_assoc + it_idx_update = lt_idx_update_assoc + it_idx_delete = lt_idx_delete_assoc + it_node_new = it_node_new + it_alternative_key = -alternative_key + CHANGING + ct_representation_node = ct_representation_node + ct_modification = ct_modification ). + + " process determinations + mo_compare->compare_determinations( + EXPORTING + it_det_new = -determination + it_det_current = -determination + IMPORTING + et_index_create = DATA(lt_idx_create_det) + et_index_update = DATA(lt_idx_update_det) + et_index_delete = DATA(lt_idx_delete_det) ). + process_determinations( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_det_current = -determination + it_det_new = -determination + is_node_new = -node + it_idx_create = lt_idx_create_det + it_idx_update = lt_idx_update_det + it_idx_delete = lt_idx_delete_det + CHANGING + ct_modification = ct_modification ). + + " process validations + mo_compare->compare_validations( + EXPORTING + it_val_new = -validation + it_val_current = -validation + IMPORTING + et_index_create = DATA(lt_idx_create_val) + et_index_update = DATA(lt_idx_update_val) + et_index_delete = DATA(lt_idx_delete_val) ). + process_validations( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_val_current = -validation + it_val_new = -validation + is_node_new = -node + it_idx_create = lt_idx_create_val + it_idx_update = lt_idx_update_val + it_idx_delete = lt_idx_delete_val + CHANGING + ct_modification = ct_modification ). + + " process static properties + DATA(lv_properties_are_changed) = mo_compare->compare_properties( + it_prop_new = -property + it_prop_current = -property ). + IF lv_properties_are_changed = abap_true. + process_properties( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_prop_current = -property + it_prop_new = -property + is_node_new = -node + CHANGING + ct_modification = ct_modification ). + ENDIF. + + " process authorizations (no special compare_auth() method needed, since field map table is already sorted) + mo_compare->compare_tables_for_changes( + EXPORTING + it_subentity_new = -authorization + it_subentity_current = -authorization + it_update_rel_element = VALUE #( ( |UPDATABLE| ) ) + IMPORTING + et_index_create_new = DATA(lt_idx_create_auth) + et_index_update_new = DATA(lt_idx_update_auth) + et_index_delete_current = DATA(lt_idx_delete_auth) ). + process_authorizations( + EXPORTING + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + iv_node_key = -node-node_key + it_auth_current = -authorization + it_auth_new = -authorization + is_node_new = -node + it_idx_create = lt_idx_create_auth + it_idx_update = lt_idx_update_auth + it_idx_delete = lt_idx_delete_auth + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_properties. + + " >>>>> remark: adjustment of NODE_CAT will be done later on in determination STATIC_PROPERTY_ADJUST + " >>>>> (@ CONF MODEL node STATIC_PRTY)... + + + CHECK it_prop_new <> it_prop_current. " !!! + + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + " delete current entries upfront... + IF lines( it_prop_current ) > 0. + + DATA(lt_prop_key_delete) = /bobf/cl_conf_model_api_reuse=>get_node_static_property_keys( + iv_version_key = iv_version_key + iv_node_key = iv_node_key ). + + LOOP AT lt_prop_key_delete ASSIGNING FIELD-SYMBOL(). + lo_map->map_prop_for_delete( + EXPORTING + iv_property_key = -key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + ENDIF. + + + " create new entries... + LOOP AT it_prop_new ASSIGNING FIELD-SYMBOL(). + lo_map->map_prop_for_create( + EXPORTING + is_property = + is_node = is_node_new + iv_version_key = iv_version_key + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + CHANGING + ct_modification = ct_modification ). + ENDLOOP. + + ENDMETHOD. + + + METHOD process_queries. + + DATA lo_map TYPE REF TO /bobf/cl_conf_model_api_map. + DATA lv_index TYPE i. + DATA lt_query_new TYPE /bobf/t_conf_model_api_query. + DATA lt_query_current TYPE /bobf/t_conf_model_api_query. + + CREATE OBJECT lo_map. + + lt_query_new = it_query_new. + lt_query_current = it_query_current. + + LOOP AT it_idx_create_new INTO lv_index. + + READ TABLE lt_query_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_query_for_create( + EXPORTING + is_query = + iv_node_key = iv_node_key + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + LOOP AT it_idx_delete_current INTO lv_index. + + READ TABLE lt_query_current ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_query_for_delete( + EXPORTING + is_query = + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + LOOP AT it_idx_update_new INTO lv_index. + + READ TABLE lt_query_new ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + READ TABLE lt_query_current ASSIGNING FIELD-SYMBOL() INDEX lv_index. + ASSERT sy-subrc = 0. + + lo_map->map_query_for_update( + EXPORTING + is_query = + iv_bo_key = iv_bo_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification + ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD process_validations. + + " >>>>> remark: VALIDATION_CONF and *special handling* regarding consistency group (save prevention) is processed + " >>>>> later on in determinations CONSISTENCY_VALIDATION_CREATE / _UPDATE (@ conf model node VALIDATION) for + " >>>>> for consistency validations only (!)... + + " >>>>> remark: adjustment of VALIDATION_CONF for action validations (!) will take place in determination + " >>>>> ACTION_VALIDATION_CREATE / _UPDATE (@ conf model node VALIDATION)... + + + DATA(lo_map) = NEW /bobf/cl_conf_model_api_map( ). + + + LOOP AT it_idx_create ASSIGNING FIELD-SYMBOL(). + + READ TABLE it_val_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + lo_map->map_val_for_create( + EXPORTING + iv_create_with_header = abap_true " !!! + is_validation = + is_node = is_node_new + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + iv_version_key = iv_version_key + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_update ASSIGNING . + + READ TABLE it_val_new ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_validation_subent_keys( + EXPORTING + iv_val_key = -val_key + IMPORTING + et_val_trigger_key_delete = DATA(lt_val_trigger_key_delete) + et_val_conf_key_delete = DATA(lt_val_conf_key_delete) + et_val_group_conf_key_delete = DATA(lt_val_group_conf_key_delete) ). + + lo_map->map_val_for_update( + EXPORTING + is_validation = + iv_bo_key = iv_bo_key + iv_node_key = iv_node_key + is_node = is_node_new + iv_version_key = iv_version_key + it_val_trigger_key_delete = lt_val_trigger_key_delete + it_val_conf_key_delete = lt_val_conf_key_delete + it_val_group_conf_key_delete = lt_val_group_conf_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + + LOOP AT it_idx_delete ASSIGNING . + + READ TABLE it_val_current ASSIGNING FIELD-SYMBOL() INDEX . + ASSERT sy-subrc = 0. + + " get delete keys for all subentities... + /bobf/cl_conf_model_api_reuse=>get_validation_subent_keys( + EXPORTING + iv_val_key = -val_key + IMPORTING + et_val_trigger_key_delete = lt_val_trigger_key_delete + et_val_conf_key_delete = lt_val_conf_key_delete + et_val_group_conf_key_delete = lt_val_group_conf_key_delete ). + + lo_map->map_val_for_delete( + EXPORTING + iv_with_header = abap_true " !!! + iv_val_key = -val_key + it_val_trigger_key_delete = lt_val_trigger_key_delete + it_val_conf_key_delete = lt_val_conf_key_delete + it_val_group_conf_key_delete = lt_val_group_conf_key_delete + CHANGING + ct_modification = ct_modification ). + + ENDLOOP. + + ENDMETHOD. + + + METHOD update_business_object. + + DATA lo_compare TYPE REF TO /bobf/cl_conf_model_adt_comp. + DATA lo_map TYPE REF TO /bobf/cl_conf_model_api_map. + DATA lt_modification TYPE /bobf/t_frw_modification. + DATA lt_idx_node_create TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_node_delete TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_node_update TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lt_idx_node_comp_subs_new TYPE /bobf/cl_conf_model_adt_comp=>gtt_index. + DATA lv_bo_key TYPE /bobf/obm_bo_key. + DATA lo_message_container TYPE REF TO /bobf/if_frw_message. + DATA lo_service_manager TYPE REF TO /bobf/if_tra_service_manager. + DATA lo_transaction_manager TYPE REF TO /bobf/if_tra_transaction_mgr. + DATA lt_representation_node TYPE /bobf/t_conf_node. + + "bo key or bo name must be provided + ASSERT is_business_object-header-bo_key IS NOT INITIAL OR + is_business_object-header-bo_name IS NOT INITIAL. + + ev_success = abap_true. + CLEAR eo_message. + + prepare_modification( ). + IF NOT is_business_object-header-bo_key IS INITIAL. + lv_bo_key = is_business_object-header-bo_key. + ELSE. + lv_bo_key = /bobf/cl_conf_model_api_reuse=>get_bo_key_by_name( iv_bo_name = is_business_object-header-bo_name ). + ENDIF. + + "get version + DATA(lv_version_key) = NEW /bobf/cl_conf_model_vrs_ctrl( )->get_version_for_modify( lv_bo_key ). + + "get current bo data for comparison + get_business_object( + EXPORTING + iv_business_object_name = is_business_object-header-bo_name + iv_edit_mode = abap_true + IMPORTING + es_business_object = DATA(ls_current_bo) + ev_success = ev_success + eo_message = eo_message + ). + + IF ev_success = abap_false. + RETURN. + ENDIF. + + lo_service_manager = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /bobf/if_conf_obj_c=>sc_bo_key ). + "retrieve additional technical bo data not contained in the ADT BO structure + lo_service_manager->retrieve_by_association( + EXPORTING + iv_node_key = /bobf/if_conf_obj_c=>sc_node-version + it_key = VALUE #( ( key = lv_version_key ) ) + iv_association = /bobf/if_conf_obj_c=>sc_association-version-node + iv_fill_data = abap_true + IMPORTING + et_data = lt_representation_node + ). + DELETE lt_representation_node WHERE node_type <> /bobf/if_conf_c=>sc_node_type_bo. "#EC CI_SORTSEQ + + "suppress locking (locking must be done seperately by method lock_business_object) + "This has to come after get_business_object, because get_business_object does cleanup + lo_service_manager->do_action( + EXPORTING + iv_act_key = /bobf/if_conf_obj_c=>sc_action-root-mark_business_object_as_locked + it_key = VALUE #( ( key = lv_bo_key ) ) + IMPORTING + eo_message = lo_message_container + et_failed_action_key = DATA(lt_failed_key) + ). + + IF NOT lt_failed_key IS INITIAL. + ev_success = abap_false. + eo_message = get_highest_priority_message( io_message = lo_message_container ). + RETURN. + ENDIF. + + "process BO header + CREATE OBJECT lo_compare. + CREATE OBJECT lo_map. + + " strip down Delegated Nodes, since they may have subnodes/-entities from last + " GET_BUSINESS_OBJECT( IV_EXPAND_DEPENDENT_OBJECTS = X ) call... + collapse_delegated_nodes( EXPORTING is_updated_business_object = is_business_object + is_current_business_object = ls_current_bo + IMPORTING es_updated_business_object = DATA(ls_business_object) ). + + " determine authorization check relevant flag for header... + lo_compare->compare_nodes_auth_check( + EXPORTING + it_node_new = ls_business_object-nodes + it_node_current = ls_current_bo-nodes + IMPORTING + ev_auth_check_activated = DATA(lv_auth_check_activated) + ev_auth_check_deactivated = DATA(lv_auth_check_deactivated) ). + + IF ls_business_object-header-description <> ls_current_bo-header-description OR + ls_business_object-header-const_interface <> ls_current_bo-header-const_interface OR + lv_auth_check_activated = abap_true OR lv_auth_check_deactivated = abap_true. + + lo_map->map_bo_header_for_update( + EXPORTING + iv_version_key = lv_version_key + is_header = ls_business_object-header + iv_auth_check_relevant = lv_auth_check_activated + CHANGING + ct_modification = lt_modification + ). + + ENDIF. + + "compare nodes + lo_compare->compare_tables_for_changes( + EXPORTING + it_subentity_new = ls_business_object-nodes + it_subentity_current = ls_current_bo-nodes + it_update_rel_element = VALUE #( ( |NODE-UPDATABLE| ) ) + IMPORTING + et_index_create_new = lt_idx_node_create + et_index_update_new = lt_idx_node_update + et_index_delete_current = lt_idx_node_delete + et_index_comp_subentity_new = lt_idx_node_comp_subs_new + ). + + process_nodes( "including subentities + EXPORTING + iv_version_key = lv_version_key + iv_bo_key = lv_bo_key + it_node_new = ls_business_object-nodes + it_node_current = ls_current_bo-nodes + it_idx_update_new = lt_idx_node_update + it_idx_create_new = lt_idx_node_create + it_idx_delete_current = lt_idx_node_delete + it_idx_comp_subentity_new = lt_idx_node_comp_subs_new + CHANGING + ct_representation_node = lt_representation_node + ct_modification = lt_modification + ). + + "apply changes + lo_transaction_manager = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( ). + + IF NOT lt_modification IS INITIAL. + + lo_service_manager->modify( + EXPORTING + it_modification = lt_modification + IMPORTING + eo_change = DATA(lo_change) + eo_message = lo_message_container ). + IF lo_change->has_failed_changes( ) = abap_true. + ev_success = abap_false. + eo_message = get_highest_priority_message( io_message = lo_message_container ). + /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( )->cleanup( ). + RETURN. + ENDIF. + + " process additional steps, which need to read new metadata from buffer. + " therefore this is processed here, after the modify() call... + finalize_nodes( + EXPORTING + iv_version_key = lv_version_key + iv_bo_key = lv_bo_key + it_node_new = ls_business_object-nodes + it_node_current = ls_current_bo-nodes + it_idx_update_new = lt_idx_node_update + it_idx_create_new = lt_idx_node_create + it_idx_delete_current = lt_idx_node_delete + IMPORTING + et_modification = DATA(lt_modification_finalize) + ev_success = ev_success ). + IF ev_success = abap_false. + /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( )->cleanup( ). + RETURN. + ENDIF. + + IF lt_modification_finalize IS NOT INITIAL. + lo_service_manager->modify( + EXPORTING + it_modification = lt_modification_finalize + IMPORTING + eo_change = DATA(lo_change_finalize) + eo_message = DATA(lo_message_finalize) ). + IF lo_change_finalize->has_failed_changes( ) = abap_true. + ev_success = abap_false. + eo_message = get_highest_priority_message( io_message = lo_message_finalize ). + /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( )->cleanup( ). + RETURN. + ENDIF. + ENDIF. + + " remove _lost_ artifacts: e.g. ITEM was deleted, with CHECK_CORRECT_LOST_ELEMENTS the ITEM queries are deleted too... + lo_service_manager->do_action( + iv_act_key = /bobf/if_conf_obj_c=>sc_action-version-check_correct_lost_elements + it_key = VALUE #( ( key = lv_version_key ) ) ). + + lo_transaction_manager->save( + IMPORTING + ev_rejected = DATA(lv_save_rejected) + eo_message = lo_message_container + ). + + IF lv_save_rejected = abap_true. + ev_success = abap_false. + lo_transaction_manager->cleanup( ). + eo_message = get_highest_priority_message( io_message = lo_message_container ). + RETURN. + ENDIF. + ENDIF. + + lo_transaction_manager->cleanup( ). + + ENDMETHOD. +ENDCLASS. + +CLASS lcl_complete_model_api DEFINITION INHERITING FROM lcl_conf_model_api_adt_copy. + PUBLIC SECTION. + METHODS get_business_object REDEFINITION. +ENDCLASS. + +CLASS lcl_complete_model_api IMPLEMENTATION. + METHOD get_business_object. + super->get_business_object( + EXPORTING + iv_business_object_name = iv_business_object_name " Business Object + iv_edit_mode = iv_edit_mode " Data element for domain BOOLE: TRUE (='X') and FALSE (=' ') + iv_expand_dependent_objects = iv_expand_dependent_objects " Data element for domain BOOLE: TRUE (='X') and FALSE (=' ') + IMPORTING + es_business_object = es_business_object " ADT BO + ev_success = ev_success " Data element for domain BOOLE: TRUE (='X') and FALSE (=' ') + eo_message = eo_message " Interface of Message Object + ). + + CHECK ev_success = abap_true. + +* Get BO name by given key + DATA(lv_bo_key) = /bobf/cl_conf_model_api_reuse=>get_bo_key_by_name( iv_bo_name = iv_business_object_name ). + IF lv_bo_key IS INITIAL. + ev_success = abap_false. + eo_message = NEW /bobf/cm_conf_model_api_adt( + textid = /bobf/cm_conf_model_api=>bo_not_found + severity = /bobf/cm_frw=>co_severity_error + symptom = /bobf/if_frw_message_symptoms=>co_bo_inconsistency + mv_bo_name = iv_business_object_name ). + RETURN. + ENDIF. + + /bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( )->cleanup( ). + DATA(lo_service_manager) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /bobf/if_conf_obj_c=>sc_bo_key ). + + DATA(lv_version_key) = NEW /bobf/cl_conf_model_vrs_ctrl( + )->get_version_for_retrieve( + EXPORTING + iv_bo_key = lv_bo_key + iv_bo_name = iv_business_object_name + iv_edit_mode = /bobf/cl_conf_model_api_reuse=>convert_edit_mode( iv_edit_mode ) + ). + +* add framework-actions + /bobf/cl_conf_model_api_reuse=>get_action_tab( + EXPORTING + iv_bo_key = lv_bo_key + iv_version_key = lv_version_key + iv_framework_actions = abap_true + IMPORTING + et_action_tab = DATA(lt_action) + ev_success = ev_success + ). + + LOOP AT es_business_object-nodes ASSIGNING FIELD-SYMBOL(). + LOOP AT lt_action ASSIGNING FIELD-SYMBOL() WHERE node_key = -node-node_key. + READ TABLE -action TRANSPORTING NO FIELDS WITH KEY act_key = -act_key. + IF sy-subrc <> 0. + INSERT INTO TABLE -action. + ASSERT sy-subrc = 0. + ENDIF. + ENDLOOP. + ENDLOOP. + + ENDMETHOD. + +ENDCLASS. \ No newline at end of file diff --git a/zsaplink_bopf.clas.xml b/zsaplink_bopf.clas.xml new file mode 100644 index 000000000..76cd0b4a0 --- /dev/null +++ b/zsaplink_bopf.clas.xml @@ -0,0 +1,53 @@ + + + + ZSAPLINK_BOPF + 1 + E + Saplink adapter for BOPF objects + 00000000000000000000000000000000 + 00 + 2 + 1 + 0 + + 00000000 + + 00000000 + + 00000000 + + + X + X + + X + + X + + + + + + + + 00 + + + + + + + 0 + 0 + + + + + I + 001 + Business object exists in this state in the system. No changes to be made + 73 + + +