![]()
CLASS zcl_afl_utilities DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS re_process
IMPORTING
!guid TYPE guid .
CLASS-METHODS is_prd
RETURNING
VALUE(result) TYPE abap_bool .
CLASS-METHODS get_distinct_count
IMPORTING
!tab_data TYPE ANY TABLE
!field_name TYPE clike
RETURNING
VALUE(count) TYPE int4 .
CLASS-METHODS fm_authority_check
IMPORTING !fm_name TYPE rs38l_fnam
!buffer TYPE abap_bool DEFAULT abap_true
RETURNING VALUE(pass) TYPE abap_bool.
PROTECTED SECTION.
PRIVATE SECTION.
TYPES: BEGIN OF ty_auth_result,
fname TYPE zafl_config-fname,
pass TYPE abap_bool,
END OF ty_auth_result.
CLASS-DATA: auth_results_list TYPE HASHED TABLE OF ty_auth_result WITH UNIQUE KEY fname.
ENDCLASS.
CLASS ZCL_AFL_UTILITIES IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AFL_UTILITIES=>FM_AUTHORITY_CHECK
* +-------------------------------------------------------------------------------------------------+
* | [--->] FM_NAME TYPE RS38L_FNAM
* | [--->] BUFFER TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [<-()] PASS TYPE ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD fm_authority_check.
DATA: auth_result LIKE LINE OF auth_results_list.
IF buffer = abap_true.
auth_result = VALUE #( auth_results_list[ fname = fm_name ] OPTIONAL ).
IF auth_result IS NOT INITIAL.
pass = auth_result-pass.
RETURN.
ENDIF.
ENDIF.
IF auth_result IS INITIAL.
DELETE auth_results_list WHERE fname = fm_name.
SELECT SINGLE no_auth_check FROM zafl_config WHERE fname = @fm_name
INTO @DATA(no_auth_check) BYPASSING BUFFER.
IF no_auth_check = abap_true.
auth_result = VALUE #( fname = fm_name pass = abap_true ).
ELSE.
DATA: wa_tadir TYPE tadir,
area TYPE sobj_name.
SELECT SINGLE area FROM enlfdir WHERE funcname = @fm_name INTO @area.
IF sy-subrc <> 0.
RETURN.
ENDIF.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_test_modus = ' '
wi_read_only = 'X'
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = 'FUGR'
wi_tadir_obj_name = area
IMPORTING
new_tadir_entry = wa_tadir
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0 OR wa_tadir-devclass IS INITIAL.
AUTHORITY-CHECK OBJECT 'S_DEVELOP'
ID 'DEVCLASS' DUMMY
ID 'OBJTYPE' FIELD 'FUGR'
ID 'OBJNAME' FIELD area
ID 'P_GROUP' DUMMY
ID 'ACTVT' FIELD '16'.
ELSE.
AUTHORITY-CHECK OBJECT 'S_DEVELOP'
ID 'DEVCLASS' FIELD wa_tadir-devclass
ID 'OBJTYPE' FIELD 'FUGR'
ID 'OBJNAME' FIELD area
ID 'P_GROUP' DUMMY
ID 'ACTVT' FIELD '16'.
ENDIF.
IF sy-subrc = 0.
auth_result = VALUE #( fname = fm_name pass = abap_true ).
ELSE.
auth_result = VALUE #( fname = fm_name pass = abap_false ).
ENDIF.
ENDIF.
ENDIF.
pass = auth_result-pass.
INSERT auth_result INTO TABLE auth_results_list.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AFL_UTILITIES=>GET_DISTINCT_COUNT
* +-------------------------------------------------------------------------------------------------+
* | [--->] TAB_DATA TYPE ANY TABLE
* | [--->] FIELD_NAME TYPE CLIKE
* | [<-()] COUNT TYPE INT4
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD get_distinct_count.
TYPES: BEGIN OF ty_temp,
field TYPE string,
END OF ty_temp.
DATA: count_table TYPE HASHED TABLE OF ty_temp WITH UNIQUE KEY field,
count_wa LIKE LINE OF count_table.
LOOP AT tab_data ASSIGNING FIELD-SYMBOL(<wa>).
ASSIGN COMPONENT field_name OF STRUCTURE <wa> TO FIELD-SYMBOL(<field>).
IF sy-subrc <> 0.
RETURN.
ELSE.
count_wa-field = <field>.
INSERT count_wa INTO TABLE count_table.
ENDIF.
ENDLOOP.
count = lines( count_table ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AFL_UTILITIES=>IS_PRD
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RESULT TYPE ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD is_prd.
DATA: role TYPE t000-cccategory.
CALL FUNCTION 'TR_SYS_PARAMS'
IMPORTING
system_client_role = role
EXCEPTIONS
no_systemname = 1
no_systemtype = 2
OTHERS = 3.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
IF role = 'P'.
result = abap_true.
ENDIF.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AFL_UTILITIES=>RE_PROCESS
* +-------------------------------------------------------------------------------------------------+
* | [--->] GUID TYPE GUID
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD re_process.
DATA: data_ref TYPE REF TO data.
SELECT SINGLE guid, fname, import, change_in, table_in
FROM zafl_log
WHERE guid = @guid
INTO @DATA(record).
IF sy-subrc <> 0.
RETURN.
ENDIF.
SELECT funcname, paramtype, pposition, parameter, structure
FROM fupararef
WHERE funcname = @record-fname
INTO TABLE @DATA(parameters_tab).
IF sy-subrc <> 0.
RETURN.
ENDIF.
DATA: temp_dd04l TYPE STANDARD TABLE OF dd04l.
LOOP AT parameters_tab ASSIGNING FIELD-SYMBOL(<ptab>).
IF strlen( <ptab>-structure ) > 30.
CONTINUE.
ENDIF.
temp_dd04l = VALUE #( BASE temp_dd04l ( domname = <ptab>-structure ) ).
ENDLOOP.
IF temp_dd04l IS NOT INITIAL.
SELECT domname FROM dd04l
FOR ALL ENTRIES IN @temp_dd04l
WHERE domname = @temp_dd04l-domname
INTO TABLE @DATA(data_elements).
ENDIF.
DATA: func TYPE string,
ptab TYPE abap_func_parmbind_tab,
ptab_line TYPE abap_func_parmbind,
etab TYPE abap_func_excpbind_tab,
etab_line TYPE abap_func_excpbind.
LOOP AT parameters_tab ASSIGNING FIELD-SYMBOL(<parameter>).
CLEAR ptab_line.
ptab_line-name = <parameter>-parameter.
ptab_line-kind = COND #( WHEN <parameter>-paramtype = 'E' THEN abap_func_importing
WHEN <parameter>-paramtype = 'I' THEN abap_func_exporting
WHEN <parameter>-paramtype = 'T' THEN abap_func_tables
WHEN <parameter>-paramtype = 'C' THEN abap_func_changing
ELSE ''
).
DATA(json_field_name) = COND string( WHEN ptab_line-kind = abap_func_exporting THEN 'IMPORT'
WHEN ptab_line-kind = abap_func_tables THEN 'TABLE_IN'
WHEN ptab_line-kind = abap_func_changing THEN 'CHANGE_IN'
ELSE ''
).
IF json_field_name IS INITIAL.
CONTINUE.
ENDIF.
ASSIGN COMPONENT json_field_name OF STRUCTURE record TO FIELD-SYMBOL(<json_raw>).
IF sy-subrc <> 0 OR <json_raw> IS INITIAL.
CONTINUE.
ENDIF.
DATA(json_data) = zcl_afl_json=>generate_new( json = <json_raw> ).
ASSIGN json_data->* TO FIELD-SYMBOL(<json_data>).
ASSIGN COMPONENT <parameter>-parameter OF STRUCTURE <json_data> TO FIELD-SYMBOL(<parameter_val>).
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
IF ptab_line-kind = abap_func_exporting OR ptab_line-kind = abap_func_changing.
CREATE DATA data_ref TYPE (<parameter>-structure).
FIELD-SYMBOLS: <temp> TYPE any.
ASSIGN <parameter_val>->* TO <temp>.
ENDIF.
IF ptab_line-kind = abap_func_tables.
DATA(structure_type) = CAST cl_abap_structdescr( cl_abap_datadescr=>describe_by_name( <parameter>-structure ) ).
DATA(table_type) = CAST cl_abap_tabledescr( cl_abap_tabledescr=>create( structure_type ) ).
CREATE DATA data_ref TYPE HANDLE table_type.
ASSIGN <parameter_val>->* TO <temp>.
ENDIF.
IF data_ref IS BOUND.
ASSIGN data_ref->* TO FIELD-SYMBOL(<data_ref>).
ENDIF.
IF line_exists( data_elements[ domname = <parameter>-structure ] ).
<data_ref> = <temp>.
ELSE.
DATA(json_temp) = zcl_afl_json=>serialize( data = <parameter_val> ).
zcl_afl_json=>deserialize( EXPORTING json = json_temp CHANGING data = <data_ref> ).
ENDIF.
GET REFERENCE OF <data_ref> INTO ptab_line-value.
INSERT ptab_line INTO TABLE ptab.
ENDLOOP.
etab_line-name = 'OTHERS'.
etab_line-value = 2.
INSERT etab_line INTO TABLE etab.
CALL FUNCTION record-fname
PARAMETER-TABLE
ptab
EXCEPTION-TABLE
etab.
ENDMETHOD.
ENDCLASS.
![]()
*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations
DEFINE eat_white.
while_offset_cs sv_white_space.
END-OF-DEFINITION.
DEFINE while_offset_cs.
* >= 7.02 alternative
* pos = find_any_not_of( val = json sub = &1 off = offset ).
* if pos eq -1. offset = length.
* else. offset = pos. endif.
* < 7.02
while offset < length.
find first occurrence of json+offset(1) in &1.
if sy-subrc is not initial.
exit.
endif.
offset = offset + 1.
endwhile.
* < 7.02
END-OF-DEFINITION.
class ZCL_AFL_JSON definition
public
inheriting from /UI2/CL_JSON
final
create public .
public section.
methods GENERATE_INT_NEW
importing
!JSON type JSON
returning
value(RR_DATA) type ref to DATA .
class-methods GENERATE_NEW
importing
!JSON type JSON
!PRETTY_NAME type PRETTY_NAME_MODE default PRETTY_MODE-NONE
!NAME_MAPPINGS type NAME_MAPPINGS optional
returning
value(RR_DATA) type ref to DATA .
protected section.
private section.
ENDCLASS.
CLASS ZCL_AFL_JSON IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_AFL_JSON->GENERATE_INT_NEW
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON TYPE JSON
* | [<-()] RR_DATA TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD generate_int_new.
TYPES: BEGIN OF ts_field,
name TYPE string,
value TYPE json,
END OF ts_field.
DATA: length TYPE i,
offset TYPE i.
DATA: lt_json TYPE STANDARD TABLE OF json WITH DEFAULT KEY,
lv_json LIKE LINE OF lt_json,
lv_comp_name TYPE abap_compname,
lt_fields TYPE SORTED TABLE OF ts_field WITH UNIQUE KEY name,
lo_type TYPE REF TO cl_abap_datadescr,
lt_comp TYPE abap_component_tab,
lt_names TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line,
cache LIKE LINE OF mt_name_mappings_ex,
ls_comp LIKE LINE OF lt_comp.
FIELD-SYMBOLS: <data> TYPE any,
<struct> TYPE any,
<field> LIKE LINE OF lt_fields,
<table> TYPE STANDARD TABLE,
<cache> LIKE LINE OF mt_name_mappings_ex.
length = numofchar( json ).
eat_white.
CASE json+offset(1).
WHEN `{`."result must be a structure
restore_type( EXPORTING json = json length = length CHANGING data = lt_fields ).
IF lt_fields IS NOT INITIAL.
ls_comp-type = cl_abap_refdescr=>get_ref_to_data( ).
LOOP AT lt_fields ASSIGNING <field>.
READ TABLE mt_name_mappings_ex WITH TABLE KEY json = <field>-name ASSIGNING <cache>.
IF sy-subrc IS INITIAL.
ls_comp-name = <cache>-abap.
ELSE.
cache-json = ls_comp-name = <field>-name.
TRANSLATE ls_comp-name USING `/_:_~_._-_`. " remove characters not allowed in component names
IF mv_pretty_name EQ pretty_mode-camel_case OR mv_pretty_name EQ pretty_mode-extended.
REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])` IN ls_comp-name WITH `$1_$2`. "#EC NOTEXT
ENDIF.
TRANSLATE ls_comp-name TO UPPER CASE.
cache-abap = ls_comp-name = lv_comp_name = ls_comp-name. " truncate by allowed field name length
INSERT cache INTO TABLE mt_name_mappings_ex.
ENDIF.
INSERT ls_comp-name INTO TABLE lt_names.
IF sy-subrc IS INITIAL.
APPEND ls_comp TO lt_comp.
ELSE.
DELETE lt_fields.
ENDIF.
ENDLOOP.
TRY.
lo_type = cl_abap_structdescr=>create( p_components = lt_comp p_strict = c_bool-false ).
CREATE DATA rr_data TYPE HANDLE lo_type.
ASSIGN rr_data->* TO <struct>.
LOOP AT lt_fields ASSIGNING <field>.
ASSIGN COMPONENT sy-tabix OF STRUCTURE <struct> TO <data>.
<data> = generate_int_new( <field>-value ).
ENDLOOP.
CATCH cx_sy_create_data_error cx_sy_struct_creation.
ENDTRY.
ENDIF.
WHEN `[`."result must be a table of ref
restore_type( EXPORTING json = json length = length CHANGING data = lt_json ).
CREATE DATA rr_data TYPE TABLE OF REF TO data.
ASSIGN rr_data->* TO <table>.
LOOP AT lt_json INTO lv_json.
APPEND INITIAL LINE TO <table> ASSIGNING <data>.
<data> = generate_int_new( lv_json ).
ENDLOOP.
WHEN OTHERS.
IF json+offset(1) EQ `"`.
CREATE DATA rr_data TYPE string.
ELSEIF json+offset(1) CA `-0123456789.`.
IF json+offset CS '.'.
CREATE DATA rr_data TYPE decfloat34.
ELSEIF length GT 9.
CREATE DATA rr_data TYPE p.
ELSE.
CREATE DATA rr_data TYPE i.
ENDIF.
ELSEIF json+offset EQ `true` OR json+offset EQ `false`.
CREATE DATA rr_data TYPE abap_bool.
ENDIF.
IF rr_data IS BOUND.
ASSIGN rr_data->* TO <data>.
restore_type( EXPORTING json = json length = length CHANGING data = <data> ).
ENDIF.
ENDCASE.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_AFL_JSON=>GENERATE_NEW
* +-------------------------------------------------------------------------------------------------+
* | [--->] JSON TYPE JSON
* | [--->] PRETTY_NAME TYPE PRETTY_NAME_MODE (default =PRETTY_MODE-NONE)
* | [--->] NAME_MAPPINGS TYPE NAME_MAPPINGS(optional)
* | [<-()] RR_DATA TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD generate_new.
DATA: lo_json TYPE REF TO zcl_afl_json,
lv_json LIKE json.
lv_json = json.
REPLACE ALL OCCURRENCES OF `\r\n` IN lv_json WITH cl_abap_char_utilities=>cr_lf.
REPLACE ALL OCCURRENCES OF `\n` IN lv_json WITH cl_abap_char_utilities=>newline.
REPLACE ALL OCCURRENCES OF `\t` IN lv_json WITH cl_abap_char_utilities=>horizontal_tab.
CREATE OBJECT lo_json
EXPORTING
pretty_name = pretty_name
name_mappings = name_mappings
assoc_arrays = c_bool-true
assoc_arrays_opt = c_bool-true.
TRY .
rr_data = lo_json->generate_int_new( lv_json ).
CATCH cx_sy_move_cast_error.
ENDTRY.
ENDMETHOD.
ENDCLASS.
*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations
DEFINE eat_white.
while_offset_cs sv_white_space.
END-OF-DEFINITION.
DEFINE while_offset_cs.
* >= 7.02 alternative
* pos = find_any_not_of( val = json sub = &1 off = offset ).
* if pos eq -1. offset = length.
* else. offset = pos. endif.
* < 7.02
while offset < length.
find first occurrence of json+offset(1) in &1.
if sy-subrc is not initial.
exit.
endif.
offset = offset + 1.
endwhile.
* < 7.02
END-OF-DEFINITION.