abap2UI5/src/00/z2ui5_cl_fw_binding.clas.abap
oblomov 6951a7fe5f
binding update (#518)
* update

* update

* update binding

* update xml view

* title_set method

* update binding
2023-08-30 21:55:43 +02:00

455 lines
11 KiB
ABAP

CLASS z2ui5_cl_fw_binding DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS:
BEGIN OF cs_bind_type,
one_way TYPE string VALUE `ONE_WAY`,
two_way TYPE string VALUE `TWO_WAY`,
one_time TYPE string VALUE `ONE_TIME`,
END OF cs_bind_type.
CONSTANTS cv_model_edit_name TYPE string VALUE `EDIT`.
TYPES:
BEGIN OF ty_s_attri,
name TYPE string,
name_front TYPE string,
type_kind TYPE string,
type TYPE string,
bind_type TYPE string,
data_stringify TYPE string,
data_rtti TYPE string,
check_ready TYPE abap_bool,
check_dissolved TYPE abap_bool,
check_temp TYPE abap_bool,
END OF ty_s_attri.
TYPES ty_t_attri TYPE SORTED TABLE OF ty_s_attri WITH UNIQUE KEY name.
CLASS-METHODS factory
IMPORTING
app TYPE REF TO object OPTIONAL
attri TYPE ty_t_attri OPTIONAL
type TYPE string OPTIONAL
data TYPE data OPTIONAL
check_attri TYPE data OPTIONAL
RETURNING
VALUE(r_result) TYPE REF TO z2ui5_cl_fw_binding.
METHODS main
RETURNING
VALUE(result) TYPE string.
DATA mo_app TYPE REF TO object.
DATA mt_attri TYPE ty_t_attri.
DATA mv_type TYPE string.
DATA mr_data TYPE REF TO data.
DATA mv_check_attri TYPE abap_bool.
CLASS-METHODS update_attri
IMPORTING
t_attri TYPE ty_t_attri
app TYPE REF TO object
RETURNING
VALUE(result) TYPE ty_t_attri.
PROTECTED SECTION.
METHODS bind_local
RETURNING
VALUE(result) TYPE string.
METHODS get_t_attri_by_dref
IMPORTING
val TYPE clike
RETURNING
VALUE(result) TYPE ty_t_attri.
METHODS get_t_attri_by_struc
IMPORTING
val TYPE clike
RETURNING
VALUE(result) TYPE ty_t_attri.
METHODS get_t_attri_by_oref
IMPORTING
val TYPE clike OPTIONAL
PREFERRED PARAMETER val
RETURNING
VALUE(result) TYPE ty_t_attri.
METHODS bind
IMPORTING
bind TYPE REF TO ty_s_attri
RETURNING
VALUE(result) TYPE string.
METHODS dissolve_init.
METHODS dissolve_struc.
METHODS dissolve_dref.
METHODS search_binding
RETURNING
VALUE(result) TYPE string.
METHODS dissolve_oref.
METHODS set_attri_ready
IMPORTING
t_attri TYPE REF TO ty_t_attri
RETURNING
VALUE(result) TYPE REF TO ty_s_attri.
METHODS name_front_create
IMPORTING
val TYPE clike
RETURNING
VALUE(result) TYPE string.
PRIVATE SECTION.
ENDCLASS.
CLASS z2ui5_cl_fw_binding IMPLEMENTATION.
METHOD bind.
FIELD-SYMBOLS <attri> TYPE any.
DATA(lv_name) = `MO_APP->` && bind->name.
ASSIGN (lv_name) TO <attri>.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE z2ui5_cx_fw_error
exporting val = `BINDING_ERROR_ATTRIBUTE_NOT_FOUND_WITH_NAME__` && bind->name.
ENDIF.
DATA lr_ref TYPE REF TO data.
GET REFERENCE OF <attri> INTO lr_ref.
IF mr_data <> lr_ref.
RETURN.
ENDIF.
IF bind->bind_type <> mv_type AND bind->bind_type IS NOT INITIAL.
RAISE EXCEPTION TYPE z2ui5_cx_fw_error
EXPORTING
val = `<p>Binding Error - Two different binding types for same attribute used (` && bind->name && `).`.
ENDIF.
bind->bind_type = mv_type.
bind->name_front = name_front_create( bind->name ).
result = COND #( WHEN mv_type = cs_bind_type-two_way THEN `/` && cv_model_edit_name && `/` ELSE `/` ) && bind->name_front.
IF strlen( result ) > 30.
bind->name_front = z2ui5_cl_fw_utility=>func_get_uuid_22( ).
result = COND #( WHEN mv_type = cs_bind_type-two_way THEN `/` && cv_model_edit_name && `/` ELSE `/` ) && bind->name_front.
ENDIF.
ENDMETHOD.
METHOD bind_local.
FIELD-SYMBOLS <any> TYPE any.
ASSIGN mr_data->* TO <any>.
DATA(lv_id) = z2ui5_cl_fw_utility=>func_get_uuid_22( ).
INSERT VALUE #( name = lv_id
data_stringify = z2ui5_cl_fw_utility=>trans_json_any_2( mr_data )
bind_type = cs_bind_type-one_time )
INTO TABLE mt_attri.
result = |/{ lv_id }|.
ENDMETHOD.
METHOD dissolve_dref.
DATA(lt_dissolve) = VALUE ty_t_attri( ).
LOOP AT mt_attri REFERENCE INTO DATA(lr_bind)
WHERE type_kind = cl_abap_classdescr=>typekind_dref
AND check_dissolved = abap_false.
DATA(lt_attri) = get_t_attri_by_dref( lr_bind->name ).
IF lt_attri IS INITIAL.
CONTINUE.
ENDIF.
lr_bind->check_dissolved = abap_true.
INSERT LINES OF lt_attri INTO TABLE lt_dissolve.
ENDLOOP.
* set_attri_ready( REF #( lt_dissolve ) ).
INSERT LINES OF lt_dissolve INTO TABLE mt_attri.
ENDMETHOD.
METHOD dissolve_init.
IF mt_attri IS INITIAL.
mt_attri = get_t_attri_by_oref( ).
ENDIF.
ENDMETHOD.
METHOD dissolve_oref.
DATA(lt_dissolve) = VALUE ty_t_attri( ).
LOOP AT mt_attri REFERENCE INTO DATA(lr_bind)
WHERE type_kind = cl_abap_classdescr=>typekind_oref
AND check_dissolved = abap_false.
DATA(lt_attri) = get_t_attri_by_oref( val = lr_bind->name ).
IF lt_attri IS INITIAL.
CONTINUE.
ENDIF.
lr_bind->check_dissolved = abap_true.
INSERT LINES OF lt_attri INTO TABLE lt_dissolve.
ENDLOOP.
* set_attri_ready( REF #( lt_dissolve ) ).
INSERT LINES OF lt_dissolve INTO TABLE mt_attri.
ENDMETHOD.
METHOD dissolve_struc.
DATA(lt_dissolve) = VALUE ty_t_attri( ).
LOOP AT mt_attri REFERENCE INTO DATA(lr_attri)
WHERE ( type_kind = cl_abap_classdescr=>typekind_struct1
OR type_kind = cl_abap_classdescr=>typekind_struct2 )
AND check_dissolved = abap_false.
lr_attri->check_dissolved = abap_true.
DATA(lt_attri) = get_t_attri_by_struc( lr_attri->name ).
INSERT LINES OF lt_attri INTO TABLE lt_dissolve.
ENDLOOP.
* set_attri_ready( REF #( lt_dissolve ) ).
INSERT LINES OF lt_dissolve INTO TABLE mt_attri.
ENDMETHOD.
METHOD factory.
r_result = NEW #( ).
r_result->mo_app = app.
r_result->mt_attri = attri.
r_result->mv_type = type.
r_result->mv_check_attri = check_attri.
IF z2ui5_cl_fw_utility=>rtti_check_type_kind_dref( data ).
RAISE EXCEPTION TYPE z2ui5_cx_fw_error
EXPORTING
val = `BINDING_WITH_REFERENCES_NOT_ALLOWED`.
ENDIF.
r_result->mr_data = REF #( data ).
ENDMETHOD.
METHOD get_t_attri_by_dref.
DATA(lv_name) = `MO_APP->` && val && `->*`.
FIELD-SYMBOLS <data> TYPE any.
ASSIGN (lv_name) TO <data>.
IF <data> IS NOT ASSIGNED.
RETURN.
ENDIF.
DATA(lo_descr) = cl_abap_datadescr=>describe_by_data( <data> ).
DATA(ls_new_bind) = VALUE ty_s_attri(
name = val && `->*`
type_kind = lo_descr->type_kind
type = lo_descr->get_relative_name( )
check_ready = abap_true
check_temp = abap_true
).
INSERT ls_new_bind INTO TABLE result.
ENDMETHOD.
METHOD get_t_attri_by_oref.
DATA(lv_name) = COND #( WHEN val IS NOT INITIAL THEN `MO_APP` && `->` && val ELSE `MO_APP` ).
FIELD-SYMBOLS <obj> TYPE any.
ASSIGN (lv_name) TO <obj>.
IF sy-subrc <> 0 OR <obj> IS NOT BOUND.
RETURN.
ENDIF.
DATA(lt_attri2) = z2ui5_cl_fw_utility=>rtti_get_t_attri_by_object( <obj> ).
LOOP AT lt_attri2 INTO DATA(ls_attri2)
WHERE visibility = cl_abap_classdescr=>public
AND is_interface = abap_false.
DATA(ls_attri) = CORRESPONDING ty_s_attri( ls_attri2 ).
IF val IS NOT INITIAL.
ls_attri-name = val && `->` && ls_attri-name.
ls_attri-check_temp = abap_true.
ENDIF.
INSERT ls_attri INTO TABLE result.
ENDLOOP.
ENDMETHOD.
METHOD get_t_attri_by_struc.
DATA(lv_name) = `MO_APP->` && val.
FIELD-SYMBOLS <attribute> TYPE any.
ASSIGN (lv_name) TO <attribute>.
z2ui5_cl_fw_utility=>x_check_raise( xsdbool( sy-subrc <> 0 ) ).
DATA(lt_comp) = z2ui5_cl_fw_utility=>rtti_get_t_comp_by_struc( <attribute> ).
DATA(lv_attri) = z2ui5_cl_fw_utility=>c_replace_assign_struc( val ).
LOOP AT lt_comp REFERENCE INTO DATA(lr_comp).
DATA(lv_element) = lv_attri && lr_comp->name.
IF lr_comp->as_include = abap_true
OR lr_comp->type->type_kind = cl_abap_classdescr=>typekind_struct2
OR lr_comp->type->type_kind = cl_abap_classdescr=>typekind_struct1.
DATA(lt_attri) = get_t_attri_by_struc( lv_element ).
INSERT LINES OF lt_attri INTO TABLE result.
ELSE.
DATA(ls_attri) = VALUE ty_s_attri(
name = lv_element
type_kind = lr_comp->type->type_kind ).
INSERT ls_attri INTO TABLE result.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD main.
"step 0 / MO_APP->MV_VAL
dissolve_init( ).
IF mv_type = cs_bind_type-one_time.
result = bind_local( ).
RETURN.
ENDIF.
result = search_binding( ).
IF result IS NOT INITIAL.
RETURN.
ENDIF.
"step 1 / MO_APP->MS_STRUC-COMP
dissolve_struc( ).
"step 2 / MO_APP->MR_DATA->*
dissolve_dref( ).
"step 3 / MO_APP->MR_STRUC->COMP
dissolve_struc( ).
"step 4 / MO_APP->MO_OBJ->MV_VAL
dissolve_oref( ).
"step 5 / MO_APP->MO_OBJ->MR_STRUC-COMP
dissolve_struc( ).
"step 6 / MO_APP->MO_OBJ->MR_VAL->*
dissolve_dref( ).
"step 7 / MO_APP->MO_OBJ->MR_STRUC->COMP
dissolve_struc( ).
result = search_binding( ).
IF result IS NOT INITIAL.
RETURN.
ENDIF.
RAISE EXCEPTION TYPE z2ui5_cx_fw_error
EXPORTING
val = `BINDING_ERROR - No class attribute for binding found - Please check if the binded values are public attributes of your class`.
ENDMETHOD.
METHOD name_front_create.
result = replace( val = val sub = `*` with = `_` occ = 0 ).
result = replace( val = result sub = `>` with = `_` occ = 0 ).
result = replace( val = result sub = `-` with = `_` occ = 0 ).
ENDMETHOD.
METHOD search_binding.
set_attri_ready( REF #( mt_attri ) ).
LOOP AT mt_attri REFERENCE INTO DATA(lr_bind)
* WHERE ( bind_type = `` OR bind_type = mv_type )
where check_ready = abap_true.
result = bind( lr_bind ).
IF result IS NOT INITIAL.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD set_attri_ready.
LOOP AT t_attri->* REFERENCE INTO result
WHERE check_ready = abap_false and
bind_type <> cs_bind_type-one_time.
CASE result->type_kind.
WHEN cl_abap_classdescr=>typekind_iref
OR cl_abap_classdescr=>typekind_intf.
DELETE t_attri->*.
WHEN cl_abap_classdescr=>typekind_oref
OR cl_abap_classdescr=>typekind_dref
OR cl_abap_classdescr=>typekind_struct2
OR cl_abap_classdescr=>typekind_struct1.
WHEN OTHERS.
result->check_ready = abap_true.
ENDCASE.
ENDLOOP.
ENDMETHOD.
METHOD update_attri.
DATA(lo_bind) = NEW z2ui5_cl_fw_binding( ).
lo_bind->mo_app = app.
lo_bind->mt_attri = t_attri.
lo_bind->dissolve_init( ).
lo_bind->dissolve_oref( ).
lo_bind->dissolve_oref( ).
lo_bind->dissolve_dref( ).
result = lo_bind->mt_attri.
ENDMETHOD.
ENDCLASS.