ZJSON4ABAP
ZJSON4ABAP
internal table) TYPE-POOLS sydes. *----------------------------------------------------------------------* * CLASS json4abap DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS json4abap DEFINITION. PUBLIC SECTION. TYPES: ty_oname TYPE string, BEGIN OF ty_sydes_nameinfo, index TYPE sy-tabix, name TYPE ty_oname, END OF ty_sydes_nameinfo, ty_sydes_nameinfos TYPE HASHED TABLE OF ty_sydes_nameinfo WITH UNIQUE KEY index, BEGIN OF ty_sydes_desc, types TYPE sydes_typeinfos, names TYPE ty_sydes_nameinfos, END OF ty_sydes_desc. CLASS-METHODS class_constructor. METHODS json IMPORTING abapdata TYPE any name TYPE string RETURNING value(json) TYPE string. PROTECTED SECTION. CLASS-DATA: a_allowed TYPE string, a_start TYPE string. DATA: a_td TYPE ty_sydes_desc. METHODS describe_dataobject IMPORTING abapdata TYPE any RETURNING value(is_ok) TYPE flag. METHODS fname2json IMPORTING fname TYPE string RETURNING value(jname) TYPE string. METHODS get_replace IMPORTING val TYPE c RETURNING value(rval) TYPE string. METHODS data2json IMPORTING abapdata TYPE any type_idx TYPE i RETURNING value(json) TYPE string. METHODS data2json_stru IMPORTING abapdata TYPE any typ TYPE sydes_typeinfo RETURNING value(json) TYPE string. METHODS data2json_atom IMPORTING abapdata TYPE any typ TYPE sydes_typeinfo RETURNING value(value) TYPE string. METHODS data2json_tab IMPORTING abapdata TYPE any typ TYPE sydes_typeinfo RETURNING value(json) TYPE string. METHODS value2string IMPORTING abapdata TYPE any typ TYPE sydes_typeinfo RETURNING value(value) TYPE string. METHODS value2string_num IMPORTING abapdata TYPE any typ TYPE sydes_typeinfo RETURNING value(value) TYPE string. METHODS value2string_date IMPORTING abapdata TYPE any RETURNING value(value) TYPE string. METHODS value2string_time IMPORTING abapdata TYPE any RETURNING value(value) TYPE string. PRIVATE SECTION. METHODS remove_trail IMPORTING val TYPE string RETURNING value(rval) TYPE st ring. ENDCLASS. "json4abap DEFINITION *----------------------------------------------------------------------* * CLASS json4abap IMPLEMENTATION
*----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS json4abap IMPLEMENTATION. METHOD json. DATA: l_oname TYPE oname, l_value TYPE string. describe_dataobject( abapdata ). l_value = data2json( abapdata = abapdata type_idx = 1 ). IF name IS NOT INITIAL. l_oname = fname2json( name ). CONCATENATE '{ "' l_oname '": ' l_value ' }' INTO json. ELSE. json = l_value. ENDIF. ENDMETHOD. "json METHOD data2json. DATA l_typ TYPE sydes_typeinfo. READ TABLE a_td-types INDEX type_idx INTO l_typ. CASE l_typ-type. WHEN 'h'. json = data2json_tab( abapdata = abapdata typ = l_typ ). WHEN 'u' OR 'v'. json = data2json_stru( abapdata = abapdata typ = l_typ ). WHEN OTHERS. json = data2json_atom( abapdata = abapdata typ = l_typ ). ENDCASE. ENDMETHOD. "data2json METHOD data2json_stru. DATA: l_typ TYPE sydes_typeinfo, j TYPE sy-tabix, n TYPE i, l_name TYPE ty_sydes_nameinfo, l_oname TYPE ty_oname, l_json TYPE string. FIELD-SYMBOLS <comp> TYPE ANY. LOOP AT a_td-types INTO l_typ FROM typ-from TO typ-to. j = sy-tabix. ADD 1 TO n. CHECK: l_typ-type NA 'lr'. ASSIGN COMPONENT n OF STRUCTURE abapdata TO <comp>. CHECK sy-subrc = 0. READ TABLE a_td-names WITH TABLE KEY INDEX = l_typ-idx_name INTO l_name TRANSPORTING name. l_oname = l_name-name. l_json = data2json( abapdata = <comp> type_idx = j ). CONCATENATE l_oname ':' l_json INTO l_json . "separated by space. IF json IS INITIAL. json = l_json. ELSE. CONCATENATE json ',' l_json INTO json . "separated by space. ENDIF. ENDLOOP. CONCATENATE '{' json '}' INTO json . "separated by space. ENDMETHOD. "data2json_stru METHOD data2json_atom. CHECK: typ-type NA 'lr' OR NOT abapdata IS INITIAL. value = value2string( abapdata = abapdata typ = typ ). ENDMETHOD. "data2json_atom
METHOD value2string. DATA l TYPE i. CASE typ-type. WHEN 'C' OR 'g' OR 'V'. CONCATENATE '"' abapdata '"' INTO value. WHEN 'I' OR 's' OR 'b' OR 'P'. value = value2string_num( abapdata = abapdata typ = typ ). WHEN 'D'. value = value2string_date( abapdata = abapdata ). WHEN 'T'. value = value2string_time( abapdata = abapdata ). WHEN 'X'. * PERFORM Hex_value_to_string USING dataobject typ-LENGTH * CHANGING value attval. WHEN 'y'. * l = XSTRLEN( dataobject ). * PERFORM Hex_value_to_string USING dataobject l * CHANGING value attval. WHEN OTHERS. " 'N' OR 'F' value = abapdata. ENDCASE. ENDMETHOD. "value2string METHOD value2string_date. DATA: c(10) TYPE c, l TYPE i, lv_in(8) TYPE c. lv_in = abapdata. c(4) = lv_in(4). c+5(2) = lv_in+4(2). c+8(2) = lv_in+6(2). c+4(1) = c+7(1) = '-'. value = c. l = 10 - STRLEN( value ). DO l TIMES. CONCATENATE value ' ' INTO value SEPARATED BY space. ENDDO. "add trailing blank IF value(8) = ' - -'. value = '0000-00-00'. ENDIF. CONCATENATE '"' value '"' INTO value. ENDMETHOD. "value2string_date METHOD value2string_time. DATA: c(8) TYPE c, l TYPE i, lv_in(6) TYPE c. lv_in = abapdata. c(2) = lv_in(2). c+3(2) = lv_in+2(2). c+6(2) = lv_in+4(2). c+2(1) = c+5(1) = ':'. value = c. l = 8 - STRLEN( value ). DO l TIMES. CONCATENATE value ' ' INTO value SEPARATED BY space. ENDDO. "add trailing blank CONCATENATE '"' value '"' INTO value. ENDMETHOD. "value2string_date METHOD value2string_num. DATA p TYPE sy-fdpos. FIELD-SYMBOLS <dataobject> TYPE ANY. IF abapdata < 0. "#EC PORTABLE
value = <dataobject> * -1. CONCATENATE '-' value INTO value. ELSE. value = abapdata. value = remove_trail( value ). ENDIF. CHECK typ-decimals > 0 AND value CA '.'. p = sy-fdpos. WHILE value+p CN '0.'. p = p + sy-fdpos + 1. ENDWHILE. value = value(p). ENDMETHOD. "value2string_num METHOD remove_trail. DATA: i TYPE i, l TYPE i. i = STRLEN( val ) - 1. WHILE i >= 0 AND val+i(1) CO ' '. SUBTRACT 1 FROM i. ENDWHILE. ADD 1 TO i. l = STRLEN( val ) - i. rval = val(i). ENDMETHOD. "remove_trail METHOD describe_dataobject. DATA: l_td TYPE sydes_desc, l_name TYPE ty_sydes_nameinfo, l_jname TYPE string. FIELD-SYMBOLS: <typeinfo> TYPE sydes_typeinfo, <name> LIKE LINE OF l_td-names. DESCRIBE FIELD abapdata INTO l_td. a_td-types = l_td-types. CLEAR a_td-names. LOOP AT l_td-types ASSIGNING <typeinfo> WHERE idx_name > 0. l_name-index = <typeinfo>-idx_name. CLEAR l_jname. LOOP AT l_td-names ASSIGNING <name> FROM <typeinfo>-idx_name. CONCATENATE l_jname <name>-name INTO l_jname. IF <name>-continue IS INITIAL. EXIT. ENDIF. ENDLOOP. l_name-name = fname2json( l_jname ). IF l_jname IS INITIAL. EXIT. ENDIF. INSERT l_name INTO TABLE a_td-names. ENDLOOP. is_ok = 'X'. ENDMETHOD. "Describe_dataobject METHOD fname2json. DATA: l_parts TYPE STANDARD TABLE OF string, l_part TYPE string, l TYPE i, rep(5) TYPE c, c(1) TYPE c, m TYPE i.
IF fname CA '-'. SPLIT fname AT '-' INTO TABLE l_parts. rep = get_replace( '-' ). LOOP AT l_parts INTO l_part. IF sy-tabix = 1. jname = l_part. ELSE. CONCATENATE jname rep l_part INTO jname. ENDIF. ENDLOOP. l = STRLEN( fname ) - 1. IF fname+l(1) = '-'. CONCATENATE jname rep INTO jname. ENDIF. ELSE. jname = fname. CHECK NOT fname IS INITIAL. ENDIF. IF jname(1) CA a_start. l = 1. ELSE. c = jname(1). rep = get_replace( c ). IF rep IS INITIAL. CLEAR jname. EXIT. ENDIF. l = STRLEN( rep ). REPLACE c WITH rep(l) INTO jname. ENDIF. WHILE jname+l CN a_allowed. ADD sy-fdpos TO l. c = jname+l(1). rep = get_replace( c ). IF rep IS INITIAL. CLEAR jname. EXIT. ENDIF. m = STRLEN( rep ). ADD m TO l. REPLACE c WITH rep(m) INTO jname. ENDWHILE. ENDMETHOD. METHOD get_replace. DATA: x(1) TYPE x, l_rval TYPE char5. IF val = '/'. rval = '_-'. ELSE. l_rval(3) = '_--'. CALL FUNCTION 'SCP_TRANSLATE_CHARS' EXPORTING inbuff = val outcode = '1100' csubst = ' ' IMPORTING outbuff = x EXCEPTIONS
"fname2json
OTHERS = 5. IF sy-subrc <> 0. EXIT. ENDIF. l_rval+3(2) = x. rval = l_rval. ENDIF. ENDMETHOD. "get_replace METHOD class_constructor. DATA: l_small TYPE string. l_small = sy-abcde. TRANSLATE l_small TO LOWER CASE. "#EC SYNTCHAR CONCATENATE sy-abcde '_' l_small INTO a_start. CONCATENATE sy-abcde '_0123456789-.' l_small INTO a_allowed. ENDMETHOD. "CLASS_CONSTRUCTOR METHOD data2json_tab. data: l_json type string. FIELD-SYMBOLS <line> TYPE ANY. FIELD-SYMBOLS <table> TYPE ANY TABLE. ASSIGN abapdata TO <table>. IF sy-subrc = 0. LOOP AT <table> ASSIGNING <line>. l_json = data2json( abapdata = <line> type_idx = typ-from ). if json is initial. json = l_json. else. concatenate json ',' l_json into json. endif. ENDLOOP. ENDIF. CONCATENATE '[' json ']' INTO json. ENDMETHOD. "data2json_tab ENDCLASS. "json4abap IMPLEMENTATION