SAPLink-artifacts added

This commit is contained in:
mrsimpson 2016-02-12 17:52:23 +00:00
parent 6405ac7ab4
commit 35d80083cd
4 changed files with 1438 additions and 0 deletions

View File

@ -0,0 +1,358 @@
* This class is intended to provide generic serialization based on SOBJ-definitions.
* For developers inheriting from this class: BE AWARE: This class will directly insert into
* and delete dynamically from the object's metadata-tables.
* Though this has been tested and is based upon code developed by SAP for a similar purpose,
* this is a risky operation. Please do verify the where-statements generated by the XML-bridge
* for correctness of your dedicated object-type!
* No risk, no fun.
CLASS zsaplink_generic_obj DEFINITION
PUBLIC
INHERITING FROM zsaplink
ABSTRACT
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!name TYPE string .
METHODS checkexists
REDEFINITION .
METHODS createixmldocfromobject
REDEFINITION .
METHODS createobjectfromixmldoc
REDEFINITION .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_s_tlogo_tables,
tabname TYPE ddobjname,
where_clause TYPE string,
data TYPE REF TO data,
END OF ty_s_tlogo_tables .
TYPES:
ty_t_tlogo_tables TYPE SORTED TABLE OF ty_s_tlogo_tables WITH UNIQUE KEY tabname .
METHODS add_table_metadata
IMPORTING
!io_ixmldocument TYPE REF TO if_ixml_document
!io_root_node TYPE REF TO if_ixml_element .
METHODS serialize_table_content
IMPORTING
!io_ixmldocument TYPE REF TO if_ixml_document
!io_root_node TYPE REF TO if_ixml_element
RAISING
zcx_saplink .
METHODS update_db_table_content
IMPORTING
!i_ixmldocument TYPE REF TO if_ixml_document
RAISING
zcx_saplink .
METHODS deleteobject
REDEFINITION .
PRIVATE SECTION.
DATA mo_xml_bridge TYPE REF TO lcl_tlogo_xml_bridge .
CONSTANTS co_xml_metadata TYPE string VALUE 'objMetaData' ##NO_TEXT.
METHODS get_xml_bridge
RETURNING
VALUE(ro_xml_bridge) TYPE REF TO lcl_tlogo_xml_bridge .
METHODS metadata_to_xml
IMPORTING
!it_metadata TYPE lcl_tlogo_xml_bridge=>tt_obj_metadata
RETURNING
VALUE(ro_metadata_element) TYPE REF TO if_ixml_element .
METHODS xml_to_metadata
IMPORTING
!io_metadata_element TYPE REF TO if_ixml_element
RETURNING
VALUE(rt_metadata) TYPE lcl_tlogo_xml_bridge=>tt_obj_metadata .
METHODS validate_metadata
IMPORTING
!it_metadata TYPE lcl_tlogo_xml_bridge=>tt_obj_metadata
RAISING
zcx_saplink .
ENDCLASS.
CLASS ZSAPLINK_GENERIC_OBJ IMPLEMENTATION.
METHOD add_table_metadata.
* add the table's metdata
DATA(lt_metadata) = get_xml_bridge( )->get_table_metadata( CONV #( me->objname ) ).
* encapsulate the simple transformation metadata-table-element to have a fixed name
DATA(lo_md_element) = io_ixmldocument->create_element( co_xml_metadata ).
lo_md_element->append_child( me->metadata_to_xml( lt_metadata ) ).
io_root_node->append_child( lo_md_element ).
ENDMETHOD.
METHOD checkexists.
exists = me->get_xml_bridge( )->exists( CONV #( objname ) ).
ENDMETHOD.
METHOD constructor.
*/---------------------------------------------------------------------\
*| 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 |
*\---------------------------------------------------------------------/
super->constructor( name = name ).
ENDMETHOD.
METHOD createixmldocfromobject.
* convention by saplink: The root element has to be named with the OBJTYPE,
* the first attribute of the root node denotes the objname
DATA lo_root_node TYPE REF TO if_ixml_element.
ixmldocument = ixml->create_document( ).
lo_root_node = ixmldocument->create_element( me->getobjecttype( ) ).
lo_root_node->set_attribute(
name = 'objname' " NAME
value = objname
).
serialize_table_content(
io_ixmldocument = ixmldocument
io_root_node = lo_root_node ).
add_table_metadata(
io_ixmldocument = ixmldocument
io_root_node = lo_root_node ).
ixmldocument->append_child( lo_root_node ).
ENDMETHOD.
METHOD createobjectfromixmldoc.
* validate the metadata of the underlying DB tables
* As insert/update/delete to a table is being performed, the table structure actually
* defines an interface. The compatibility of this interface has to be validated prior
* to consuming it
DATA(lo_obj_metadata_elem) = ixmldocument->get_elements_by_tag_name( name = co_xml_metadata )->get_item( 0 ).
IF lo_obj_metadata_elem IS INITIAL.
BREAK-POINT. "this seems to be an old file-format where no consistency between the tables can be checked.
* => proceed only if you know what you're doing and jump over the next statement.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>error_message
msg = 'Old (unsupported) format'.
ELSE.
DATA(lt_obj_metadata) = me->xml_to_metadata( CAST #( lo_obj_metadata_elem->get_first_child( ) ) ).
me->validate_metadata( lt_obj_metadata ).
ENDIF.
* write the content serialized in the XML document into the DB tables
update_db_table_content( ixmldocument ).
ENDMETHOD.
METHOD deleteobject.
"do not do anything - the update of the object implicitly deletes obsolete entries
ASSERT 1 = 1.
RETURN.
* there is an opportunity to explicitly purge all tables with the corresponding keys,
* but this is actually not necessary (and quite a critical operation).
get_xml_bridge( )->delete_object( CONV #( objname ) ).
ENDMETHOD.
METHOD get_xml_bridge.
IF mo_xml_bridge IS INITIAL.
* can't be called in the constructor as getObjectType is intended to be polymorphic
mo_xml_bridge = NEW lcl_tlogo_xml_bridge( i_tlogo = CONV #( me->getobjecttype( ) ) ).
ENDIF.
ro_xml_bridge = mo_xml_bridge.
ENDMETHOD.
METHOD metadata_to_xml.
DATA(lo_document_md) = ixml->create_document( ).
CALL TRANSFORMATION id
SOURCE metadata = it_metadata
RESULT XML lo_document_md.
ro_metadata_element = lo_document_md->get_root_element( ).
ENDMETHOD.
METHOD serialize_table_content.
* read table content to XML
IF get_xml_bridge( )->exists( CONV #( me->objname ) ) = abap_false.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>not_found.
ENDIF.
get_xml_bridge( )->compose_xml(
EXPORTING
i_objnm = CONV #( me->objname ) " Object name in object directory
IMPORTING
e_string_xml = DATA(lv_string_xml) " XML Data
).
DATA(lo_xml_bridge_document) = convertstringtoixmldoc( xmlstring = lv_string_xml ).
io_root_node->append_child( lo_xml_bridge_document->get_root_element( ) ).
ENDMETHOD.
METHOD update_db_table_content.
* unpack the actual document from the saplink-specific wrapper
DATA(lo_xml_bridge_transport_elem) = i_ixmldocument->get_elements_by_tag_name( name = CONV #( lcl_tlogo_xml_bridge=>p_c_xml_tag_transport ) )->get_item( 0 ).
IF lo_xml_bridge_transport_elem IS INITIAL.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>incorrect_file_format
msg = 'No object data found'.
ELSE.
DATA(lo_xml_bridge_document) = cl_ixml=>create( )->create_document( ).
lo_xml_bridge_document->append_child( lo_xml_bridge_transport_elem ).
ENDIF.
* during existence check, a sanity check is being performed (that not more than one entry in the
* primary table is affected). Thus, issue an existence check without evaluating the result
get_xml_bridge( )->exists( CONV #( me->objname ) ).
get_xml_bridge( )->parse_xml(
EXPORTING
i_objnm = CONV #( me->objname ) " Object name in object directory
i_string_xml = convertixmldoctostring( lo_xml_bridge_document ) " String with XML Data
IMPORTING
e_subrc = DATA(lv_subrc_parsing) " Return Value, Return Value After ABAP Statements
).
IF lv_subrc_parsing IS INITIAL.
get_xml_bridge( )->save(
IMPORTING
e_subrc = DATA(lv_subrc_save)
).
IF lv_subrc_save IS INITIAL.
* perform after import methods
get_xml_bridge( )->activate( ).
ELSE.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>error_message
msg = |An error occurred when saving { objname }. Check Application log Object { cl_rso_repository=>p_c_bal_log_object }|.
ENDIF.
ELSE.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>error_message
msg = 'Object could not be identified in source'.
ENDIF.
ENDMETHOD.
METHOD validate_metadata.
* this method checks whether the metadata of the tables of the transport object
* substantially differ between the object serialized and the current system.
* This is necessary as the DB-table is treated as interface in this tool
* all the tables which are filled in the source need to exist locally with all fields from
* the source system existing with the same technical datatype locally as well
DEFINE exception_metadata.
RAISE EXCEPTION TYPE zcx_saplink
EXPORTING
textid = zcx_saplink=>error_message
msg = 'Database structure differs. Object cannot be imported.'.
END-OF-DEFINITION.
LOOP AT it_metadata ASSIGNING FIELD-SYMBOL(<ls_metadata>) WHERE count > 0. "only the relevant tables need to be validated
DATA lt_dfies TYPE dfies_table.
* get the DDIC info of the local table structure
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = CONV ddobjname( <ls_metadata>-db_table )
TABLES
dfies_tab = lt_dfies
EXCEPTIONS
not_found = 1.
ASSERT sy-subrc = 0.
* compare the fields-information which is relevant to technical compatibility.
LOOP AT <ls_metadata>-fields_definition ASSIGNING FIELD-SYMBOL(<ls_origin_fielddef>).
READ TABLE lt_dfies ASSIGNING FIELD-SYMBOL(<ls_local_fielddef>) WITH KEY fieldname = <ls_origin_fielddef>-fieldname.
IF sy-subrc NE 0.
exception_metadata.
ENDIF.
IF <ls_local_fielddef>-datatype NE <ls_origin_fielddef>-datatype
OR <ls_local_fielddef>-inttype NE <ls_origin_fielddef>-inttype.
exception_metadata.
ENDIF.
IF <ls_local_fielddef>-leng NE <ls_origin_fielddef>-leng.
"<ls_local_fielddef>-intlen NE <ls_origin_fielddef>-intlen. Does not have to be the same when transporting between unicode and non-unicode-systems
exception_metadata.
ENDIF.
IF <ls_local_fielddef>-decimals NE <ls_origin_fielddef>-decimals.
exception_metadata.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
METHOD xml_to_metadata.
DATA(lo_document_md) = ixml->create_document( ).
lo_document_md->append_child( io_metadata_element ).
CALL TRANSFORMATION id
SOURCE XML lo_document_md
RESULT metadata = rt_metadata .
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,147 @@
CLASS lcl_rso_tlogo_xml_bridge DEFINITION
CREATE PUBLIC .
**************************************************************************
* This is slightly modified-copy of CL_RSO_TLOGO_XML_BRIDGE which provides
* features to serialize a logical transport object based on its definition
* in SOBJ. Sadly, the original class hides some information needed in
* private tables. The modification done is to move all this content into
* the protected one.
*"* public components of class CL_RSO_TLOGO_XML_BRIDGE
*"* do not include other source files here!!!
PUBLIC SECTION.
TYPE-POOLS rs .
INTERFACE if_rso_object_xmic LOAD .
INTERFACE if_rso_repository_xml_const LOAD .
CONSTANTS p_c_xml_tag_transport TYPE char40
VALUE 'transport'. "#EC NOTEXT .
CLASS-METHODS class_constructor .
METHODS activate .
METHODS compose_xml
IMPORTING
!i_objnm TYPE sobj_name
!i_objvers TYPE rsobjvers DEFAULT rs_c_objvers-active
EXPORTING
!e_string_xml TYPE string .
METHODS constructor
IMPORTING
!i_tlogo TYPE rstlogo
EXCEPTIONS
tlogo_doesnt_exist .
METHODS parse_xml
IMPORTING
!i_objnm TYPE sobj_name
!i_string_xml TYPE string
!i_detlevel TYPE bal_s_msg-detlevel DEFAULT '1'
EXPORTING
!e_subrc TYPE sysubrc .
METHODS save
IMPORTING
!i_detlevel TYPE bal_s_msg-detlevel DEFAULT '1'
EXPORTING
!e_subrc TYPE sysubrc .
METHODS get_timestmp_of_data
RETURNING
VALUE(r_timestmp) TYPE rstimestmp .
PROTECTED SECTION.
*"* protected components of class CL_RSO_TLOGO_XML_BRIDGE
*"* do not include other source files here!!!
METHODS before_export .
" private section.
*"* private components of class CL_RSO_TLOGO_XML_BRIDGE
*"* do not include other source files here!!!
TYPES:
pt_t_objsl TYPE STANDARD TABLE OF objsl .
TYPES:
pt_ts_objsl TYPE SORTED TABLE OF objsl
WITH UNIQUE KEY objectname objecttype trwcount .
TYPES:
BEGIN OF pt_s_tlogo_tables,
tabname TYPE ddobjname,
where_clause TYPE string,
data TYPE REF TO data,
END OF pt_s_tlogo_tables. .
TYPES:
pt_t_tlogo_tables TYPE STANDARD TABLE OF pt_s_tlogo_tables .
TYPES:
pt_ts_tlogo_tables TYPE SORTED TABLE OF pt_s_tlogo_tables
WITH UNIQUE KEY tabname .
TYPES:
pt_t_objm TYPE STANDARD TABLE OF objm .
TYPES:
pt_ts_objm TYPE SORTED TABLE OF objm
WITH UNIQUE KEY objectname objecttype method .
CONSTANTS p_c_xml_tag_field TYPE char40 VALUE 'field' .
CONSTANTS p_c_xml_tag_key TYPE char40 VALUE 'key' .
CONSTANTS p_c_xml_tag_row TYPE char40 VALUE 'row' .
CONSTANTS p_c_xml_tag_table TYPE char40 VALUE 'table' .
CLASS-DATA p_r_ixml TYPE REF TO if_ixml .
CLASS-DATA p_r_repository TYPE REF TO cl_rso_repository .
CLASS-DATA p_r_stream_factory TYPE REF TO if_ixml_stream_factory .
DATA p_objnm TYPE sobj_name .
DATA p_s_objh TYPE objh .
DATA p_s_tlogoprop TYPE rstlogoprop .
DATA p_tlogo TYPE rstlogo .
DATA p_ts_objm TYPE pt_ts_objm .
DATA p_ts_objsl TYPE pt_ts_objsl .
DATA p_ts_tlogo_tables TYPE pt_ts_tlogo_tables .
DATA p_timestmp TYPE rstimestmp .
METHODS read_tlogo_prop .
ENDCLASS.
CLASS lcl_tlogo_xml_bridge DEFINITION INHERITING FROM lcl_rso_tlogo_xml_bridge
CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ty_obj_metadata,
db_table TYPE tabname,
count TYPE i,
fields_definition TYPE dfies_table,
END OF ty_obj_metadata,
tt_obj_metadata TYPE SORTED TABLE OF ty_obj_metadata WITH UNIQUE KEY db_table.
METHODS
exists
IMPORTING
iv_objname TYPE objname
RETURNING VALUE(rv_object_exists) TYPE abap_bool.
METHODS delete_object
IMPORTING
iv_objname TYPE objname
RETURNING VALUE(rv_deleted) TYPE abap_bool.
METHODS get_table_metadata
IMPORTING
iv_objname TYPE objname
RETURNING
VALUE(rt_metadata) TYPE lcl_tlogo_xml_bridge=>tt_obj_metadata.
PROTECTED SECTION.
METHODS
get_where_clause
IMPORTING
iv_tobj_name TYPE sobj_name
iv_objname TYPE objname
RETURNING VALUE(rv_where_on_keys) TYPE string.
METHODS validate_count_prim_table
IMPORTING
iv_objname TYPE objname
iv_dbcount LIKE sy-dbcnt.
PRIVATE SECTION.
METHODS timestamp_to_xml
IMPORTING iv_timestamp TYPE timestamp
RETURNING VALUE(rv_string) TYPE string.
METHODS get_prim_table_objsl
RETURNING
VALUE(rs_objsl) LIKE line of p_ts_objsl.
ENDCLASS.

View File

@ -0,0 +1,887 @@
CLASS lcl_rso_tlogo_xml_bridge IMPLEMENTATION.
METHOD activate .
FIELD-SYMBOLS: <l_s_tr_prot> TYPE rs_s_tr_prot.
DATA: l_t_tr_prot TYPE rs_t_tr_prot,
l_t_e071 TYPE STANDARD TABLE OF e071,
l_s_e071 TYPE e071,
l_t_e071k TYPE STANDARD TABLE OF e071k.
DATA: l_s_msg TYPE rs_s_msg.
CHECK NOT p_ts_tlogo_tables IS INITIAL.
* start the after import method
l_s_e071-pgmid = rs_c_pgmid_r3tr.
l_s_e071-object = p_tlogo.
l_s_e071-obj_name = p_objnm.
INSERT l_s_e071 INTO TABLE l_t_e071.
CALL FUNCTION 'RS_AFTER_IMPORT'
EXPORTING
i_mode = rs_c_after_import_mode-activate
IMPORTING
e_t_tr_prot = l_t_tr_prot
TABLES
tt_e071 = l_t_e071
tt_e071k = l_t_e071k.
LOOP AT l_t_tr_prot ASSIGNING <l_s_tr_prot>.
l_s_msg-msgid = <l_s_tr_prot>-ag.
l_s_msg-msgno = <l_s_tr_prot>-msgnr.
l_s_msg-msgv1 = <l_s_tr_prot>-var1.
l_s_msg-msgv2 = <l_s_tr_prot>-var2.
l_s_msg-msgv3 = <l_s_tr_prot>-var3.
l_s_msg-msgv4 = <l_s_tr_prot>-var4.
CALL METHOD cl_rso_application_log=>if_rso_application_log~add_message_as_structure
EXPORTING
i_s_msg = l_s_msg.
ENDLOOP.
ENDMETHOD. "
METHOD before_export .
FIELD-SYMBOLS: <l_s_objm> TYPE objm.
DATA: l_t_e071 TYPE STANDARD TABLE OF e071,
l_s_e071 TYPE e071,
l_t_e071k TYPE STANDARD TABLE OF e071k,
l_s_e071k TYPE e071k,
l_client TYPE trclient.
l_client = sy-mandt.
l_s_e071-pgmid = rs_c_pgmid_r3tr.
l_s_e071-object = p_tlogo.
l_s_e071-obj_name = p_objnm.
INSERT l_s_e071 INTO TABLE l_t_e071.
READ TABLE p_ts_objm ASSIGNING <l_s_objm>
WITH TABLE KEY objectname = p_tlogo objecttype = 'L' method = 'BEFORE_EXP'.
IF sy-subrc = 0.
CALL FUNCTION <l_s_objm>-methodname
EXPORTING
iv_client = l_client
TABLES
tt_e071 = l_t_e071
tt_e071k = l_t_e071k.
ENDIF.
ENDMETHOD. "
METHOD class_constructor .
* repository
p_r_repository = cl_rso_repository=>get_repository( ).
* iXML stream factor
p_r_stream_factory = cl_rso_repository=>get_stream_factory( ).
* iXML library
p_r_ixml = cl_ixml=>create( ).
ENDMETHOD. "
METHOD compose_xml .
TYPES: BEGIN OF lt_s_objkey ,
num TYPE numc3,
value TYPE char128,
END OF lt_s_objkey,
lt_ts_objkey TYPE SORTED TABLE OF lt_s_objkey
WITH UNIQUE KEY num.
FIELD-SYMBOLS: <l_s_objsl> TYPE objsl.
FIELD-SYMBOLS: <l_t_data> TYPE STANDARD TABLE,
<l_s_data> TYPE any.
FIELD-SYMBOLS: <l_s_dfies> TYPE dfies.
FIELD-SYMBOLS: <l_fs> TYPE any.
DATA: l_t_dfies TYPE STANDARD TABLE OF dfies,
l_tabname TYPE ddobjname.
DATA: l_s_data TYPE REF TO data,
l_t_data TYPE REF TO data.
DATA: l_where_stmt TYPE string.
DATA: l_n TYPE i,
l_m TYPE i,
l_k TYPE i,
l_len TYPE i.
DATA: l_s_objkey TYPE lt_s_objkey,
l_ts_objkey TYPE lt_ts_objkey,
l_num TYPE numc3.
DATA: l_value128 TYPE char128.
DATA: l_r_document TYPE REF TO if_ixml_document.
DATA: l_r_element_transport TYPE REF TO if_ixml_element,
l_r_element_table TYPE REF TO if_ixml_element,
l_r_element_row TYPE REF TO if_ixml_element,
l_r_element_key TYPE REF TO if_ixml_element,
l_r_element TYPE REF TO if_ixml_element.
DATA: l_value TYPE string,
l_name TYPE string.
DATA: l_rc TYPE i.
DATA: l_r_ostream TYPE REF TO if_ixml_ostream.
DATA: l_r_renderer TYPE REF TO if_ixml_renderer.
DATA: l_r_encoding TYPE REF TO if_ixml_encoding.
DATA: l_r_cdata TYPE REF TO if_ixml_cdata_section.
DATA: l_flag_asterics TYPE rs_bool.
DATA: l_timestmp TYPE rstimestmp.
p_objnm = i_objnm.
* call the before export method
CALL METHOD before_export.
* create the output stream for the output string
CLEAR e_string_xml.
l_r_ostream = p_r_stream_factory->create_ostream_cstring( string = e_string_xml ).
* create the XML document
l_r_document = p_r_ixml->create_document( ).
* set UTF-8 encoding
l_r_encoding = cl_rso_repository=>get_xml_encoding(
i_byte_order = 0 i_character_set = 'latin1' ).
CALL METHOD l_r_document->set_encoding(
encoding = l_r_encoding ).
* XML: <TRANSPORT>
l_name = p_c_xml_tag_transport.
CLEAR l_value.
l_r_element_transport = l_r_document->create_element( name = l_name ).
l_rc = l_r_document->append_child( l_r_element_transport ).
* XML: date (for comparison with object, last changed )
l_name = if_rso_object_xmic=>timestmp.
GET TIME STAMP FIELD l_timestmp.
l_value = cl_rso_repository=>timestamp_to_xml( l_timestmp ).
l_r_element = l_r_document->create_simple_element(
name = l_name value = l_value parent = l_r_element_transport ).
* parse all tables of this TLOGO object
LOOP AT p_ts_objsl ASSIGNING <l_s_objsl>.
CLEAR l_where_stmt.
* XML: <TABLE>
l_name = p_c_xml_tag_table.
CLEAR l_value.
l_r_element_table = l_r_document->create_simple_element(
name = l_name
value = l_value
parent = l_r_element_transport ).
* add attribute: name (ID)
l_name = if_rso_repository_xml_const=>id.
l_value = <l_s_objsl>-tobj_name.
l_rc = l_r_element_table->set_attribute(
name = l_name value = l_value ).
* get the DDIC info of the table structure
l_tabname = <l_s_objsl>-tobj_name.
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = l_tabname
TABLES
dfies_tab = l_t_dfies
EXCEPTIONS
not_found = 1.
IF sy-subrc <> 0.
* message
EXIT.
ENDIF.
* compose the key (table)
CLEAR l_ts_objkey.
CLEAR l_s_objkey.
l_n = 0.
l_num = 1.
l_k = 0.
l_len = strlen( <l_s_objsl>-tobjkey ).
WHILE l_n <= l_len.
l_s_objkey-num = l_num.
* command
IF <l_s_objsl>-tobjkey+l_n(1) = '/'.
IF NOT l_s_objkey-value IS INITIAL.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
ADD 1 TO l_num.
CLEAR l_s_objkey.
l_s_objkey-num = l_num.
ENDIF.
l_m = l_n + 1.
* '*' means all futher key values
IF <l_s_objsl>-tobjkey+l_m(1) = '*'.
l_s_objkey-value = '*'.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
* object name
ELSEIF <l_s_objsl>-tobjkey+l_m(1) = '&'.
l_s_objkey-value = i_objnm.
* #CP-SUPPRESS: FP no risc
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
* language
ELSEIF <l_s_objsl>-tobjkey+l_m(1) = 'L'.
l_s_objkey-value = sy-langu.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
ENDIF.
l_k = 0.
* value
ELSE.
l_s_objkey-value+l_k(1) = <l_s_objsl>-tobjkey+l_n(1).
ADD 1 TO l_k.
ENDIF.
ADD 1 TO l_n.
ENDWHILE.
IF NOT l_s_objkey-value IS INITIAL.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
ENDIF.
* compose the where clause
l_flag_asterics = rs_c_false.
* XML: <KEY>
l_name = p_c_xml_tag_key.
l_r_element_key = l_r_document->create_simple_element(
name = l_name
parent = l_r_element_table ).
l_num = 1.
CLEAR l_where_stmt.
* CONCATENATE '''' i_objvers '''' INTO l_value128.
* CONCATENATE 'OBJVERS' '=' l_value128 INTO l_where_stmt
* SEPARATED BY space.
LOOP AT l_t_dfies ASSIGNING <l_s_dfies>
WHERE NOT keyflag IS INITIAL.
* #CP-SUPPRESS: FP no risc
READ TABLE l_ts_objkey INTO l_s_objkey
WITH TABLE KEY num = l_num.
IF sy-subrc <> 0
OR <l_s_dfies>-fieldname = 'LANGU'.
CLEAR l_s_objkey.
ADD 1 TO l_num.
CONTINUE.
ENDIF.
IF l_s_objkey-value = '*'.
l_flag_asterics = rs_c_true.
ENDIF.
IF l_flag_asterics = rs_c_true.
CONTINUE.
ENDIF.
IF NOT l_where_stmt IS INITIAL.
* #CP-SUPPRESS: FP no risc
CONCATENATE l_where_stmt 'AND' INTO l_where_stmt
SEPARATED BY space.
ENDIF.
* #CP-SUPPRESS: FP no risc
CONCATENATE '''' l_s_objkey-value '''' INTO l_value128.
* #CP-SUPPRESS: FP no risc
CONCATENATE l_where_stmt <l_s_dfies>-fieldname '='
l_value128 INTO l_where_stmt SEPARATED BY space.
ADD 1 TO l_num.
* XML: <FIELD>
l_name = <l_s_dfies>-fieldname.
l_r_element = l_r_document->create_simple_element(
name = l_name parent = l_r_element_key ).
l_value = l_s_objkey-value.
l_r_cdata = l_r_document->create_cdata_section( l_value ).
l_rc = l_r_element->append_child( l_r_cdata ).
ENDLOOP.
* select from database table using the key
CREATE DATA l_s_data TYPE (<l_s_objsl>-tobj_name).
ASSIGN l_s_data->* TO <l_s_data>.
CREATE DATA l_t_data TYPE STANDARD TABLE OF (<l_s_objsl>-tobj_name).
ASSIGN l_t_data->* TO <l_t_data>.
* #CP-SUPPRESS: FP no risc
SELECT * FROM (<l_s_objsl>-tobj_name) INTO TABLE <l_t_data>
WHERE (l_where_stmt).
* write all selected rows
LOOP AT <l_t_data> ASSIGNING <l_s_data>.
* XML: <ROW>
l_name = p_c_xml_tag_row.
CLEAR l_value.
l_r_element_row = l_r_document->create_simple_element(
name = l_name
value = l_value
parent = l_r_element_table ).
* write field/value pairs to to XML stream
LOOP AT l_t_dfies ASSIGNING <l_s_dfies>.
ASSIGN COMPONENT <l_s_dfies>-fieldname OF STRUCTURE <l_s_data> TO <l_fs>.
* XML: <FIELD>
l_name = p_c_xml_tag_field.
l_r_element = l_r_document->create_simple_element(
name = l_name
parent = l_r_element_row ).
IF NOT <l_fs> IS INITIAL.
l_value = <l_fs>.
l_r_element = l_r_document->create_simple_element(
name = l_name
parent = l_r_element_row ).
l_r_cdata = l_r_document->create_cdata_section( l_value ).
l_rc = l_r_element->append_child( l_r_cdata ).
ENDIF.
* add attribute: fieldname name (ID)
l_name = if_rso_repository_xml_const=>id.
l_value = <l_s_dfies>-fieldname.
l_rc = l_r_element->set_attribute(
name = l_name value = l_value ).
ENDLOOP.
ENDLOOP.
ENDLOOP.
* render the DOM tree into an XML document
l_r_renderer = p_r_ixml->create_renderer(
ostream = l_r_ostream document = l_r_document ).
l_rc = l_r_renderer->render( ).
REPLACE 'encoding="sap*"' IN e_string_xml WITH 'encoding="latin1"' . "#EC NOTEXT
ENDMETHOD. "
METHOD constructor .
* read properties of the TLOGO type
p_tlogo = i_tlogo.
CALL METHOD read_tlogo_prop.
ENDMETHOD. "
METHOD get_timestmp_of_data .
r_timestmp = p_timestmp.
ENDMETHOD. "
METHOD parse_xml .
FIELD-SYMBOLS: <l_t_data> TYPE STANDARD TABLE,
<l_s_data> TYPE any.
FIELD-SYMBOLS: <l_s_dfies> TYPE dfies.
FIELD-SYMBOLS: <l_fs> TYPE any.
DATA: l_s_tlogo_tables TYPE pt_s_tlogo_tables.
DATA: l_r_child_table TYPE REF TO if_ixml_node,
l_r_child_row TYPE REF TO if_ixml_node,
l_r_child_field TYPE REF TO if_ixml_node,
l_r_child_key TYPE REF TO if_ixml_node.
DATA: l_r_element_transport TYPE REF TO if_ixml_element,
l_r_element_table TYPE REF TO if_ixml_element,
l_r_element_row TYPE REF TO if_ixml_element,
l_r_element_field TYPE REF TO if_ixml_element,
l_r_element_key TYPE REF TO if_ixml_element.
DATA: l_tagname TYPE string.
DATA: l_dummy TYPE c.
DATA: l_t_dfies TYPE STANDARD TABLE OF dfies,
l_th_dfies TYPE HASHED TABLE OF dfies WITH UNIQUE KEY fieldname.
DATA: l_s_data TYPE REF TO data.
DATA: l_name TYPE string,
l_value TYPE string,
l_fieldname TYPE string.
DATA: l_r_ixml TYPE REF TO if_ixml.
DATA: l_r_document TYPE REF TO if_ixml_document.
DATA: l_r_element TYPE REF TO if_ixml_element.
DATA: l_r_renderer TYPE REF TO if_ixml_renderer.
DATA: l_r_encoding TYPE REF TO if_ixml_encoding.
DATA: l_rc TYPE i.
DATA: l_r_istream TYPE REF TO if_ixml_istream.
DATA: l_returncode TYPE sysubrc.
DATA: l_r_parser TYPE REF TO if_ixml_parser.
DATA: l_r_cdata TYPE REF TO if_ixml_cdata_section.
DATA: l_detlevel TYPE bal_s_msg-detlevel.
DATA: l_detlevel2 TYPE bal_s_msg-detlevel.
CLEAR p_ts_tlogo_tables.
e_subrc = 0.
p_objnm = i_objnm.
l_detlevel = i_detlevel + 1.
l_detlevel2 = l_detlevel + 1.
* create a XML document and parse it
* iXML library
l_r_ixml = cl_ixml=>create( ).
* create an input stream
l_r_istream = p_r_stream_factory->create_istream_cstring( i_string_xml ).
* create the XML document
l_r_document = l_r_ixml->create_document( ).
* create a parser (used to be once only !!!)
l_r_parser = l_r_ixml->create_parser( stream_factory = p_r_stream_factory
istream = l_r_istream
document = l_r_document ).
* parse the document
IF l_r_parser->parse( ) NE 0.
IF l_r_parser->num_errors( ) NE 0.
DATA: parseerror TYPE REF TO if_ixml_parse_error,
str TYPE string,
line TYPE i,
column TYPE i,
count TYPE i,
index TYPE i.
count = l_r_parser->num_errors( ).
IF count > 0.
MESSAGE e207(rsoxml) WITH p_objnm p_tlogo count INTO l_dummy.
CALL METHOD cl_rso_application_log=>if_rso_application_log~add_message_level
EXPORTING
i_probclass = if_rso_application_log=>probclass_high
i_detlevel = l_detlevel.
e_subrc = 12.
index = 0.
WHILE index < count.
parseerror = l_r_parser->get_error( index = index ).
line = parseerror->get_line( ).
column = parseerror->get_column( ).
str = parseerror->get_reason( ).
MESSAGE e202(rsoxml) WITH line column str INTO l_dummy.
CALL METHOD cl_rso_application_log=>if_rso_application_log~add_message_level
EXPORTING
i_probclass = if_rso_application_log=>probclass_high
i_detlevel = l_detlevel2.
ADD 1 TO index.
ENDWHILE.
EXIT.
ENDIF.
ENDIF.
ENDIF.
* parsed OK
CHECK l_returncode = 0.
* get the root element
l_r_element_transport = l_r_document->get_root_element( ).
* the TRANSPORT tag was imported
* get the parameters and references
l_r_child_table = l_r_element_transport->get_first_child( ).
WHILE NOT l_r_child_table IS INITIAL.
l_tagname = l_r_child_table->get_name( ).
l_r_element_table ?= l_r_child_table.
* TIMESTAMP
IF l_tagname = if_rso_object_xmic=>timestmp.
p_timestmp = l_r_element_table->get_value( ).
* TABLE tag
ELSEIF l_tagname = p_c_xml_tag_table.
CLEAR l_s_tlogo_tables.
* get the DDIC info of the table structure
l_name = if_rso_repository_xml_const=>id.
l_s_tlogo_tables-tabname = l_r_element_table->get_attribute( name = l_name ).
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = l_s_tlogo_tables-tabname
TABLES
dfies_tab = l_t_dfies
EXCEPTIONS
not_found = 1.
IF sy-subrc <> 0.
* error message
ELSE.
l_th_dfies = l_t_dfies.
* dynamic creation of tables
CREATE DATA l_s_data TYPE (l_s_tlogo_tables-tabname).
ASSIGN l_s_data->* TO <l_s_data>.
CREATE DATA l_s_tlogo_tables-data TYPE STANDARD TABLE OF (l_s_tlogo_tables-tabname).
ASSIGN l_s_tlogo_tables-data->* TO <l_t_data>.
CLEAR l_s_tlogo_tables-where_clause.
l_r_child_row = l_r_element_table->get_first_child( ).
WHILE NOT l_r_child_row IS INITIAL.
l_tagname = l_r_child_row->get_name( ).
l_r_element_row ?= l_r_child_row.
* KEY tag
IF l_tagname = p_c_xml_tag_key.
l_r_child_key = l_r_element_row->get_first_child( ).
WHILE NOT l_r_child_key IS INITIAL.
l_tagname = l_r_child_key->get_name( ).
l_r_element_key ?= l_r_child_key.
* fields and values
l_fieldname = l_tagname.
l_value = l_r_element_key->get_value( ).
* modify OBJVERS as R3TRANS does
IF l_fieldname = 'OBJVERS'.
IF l_value = rs_c_objvers-active.
l_value = rs_c_objvers-modified.
ENDIF.
ENDIF.
IF NOT l_s_tlogo_tables-where_clause IS INITIAL.
CONCATENATE l_s_tlogo_tables-where_clause 'AND'
INTO l_s_tlogo_tables-where_clause
SEPARATED BY space.
ENDIF.
CONCATENATE '''' l_value '''' INTO l_value.
CONCATENATE l_s_tlogo_tables-where_clause
l_fieldname '=' l_value
INTO l_s_tlogo_tables-where_clause
SEPARATED BY space.
l_r_child_key = l_r_child_key->get_next( ).
ENDWHILE.
* ROW tag
ELSEIF l_tagname = p_c_xml_tag_row.
CLEAR <l_s_data>.
l_r_child_field = l_r_element_row->get_first_child( ).
WHILE NOT l_r_child_field IS INITIAL.
l_tagname = l_r_child_field->get_name( ).
l_r_element_field ?= l_r_child_field.
* FIELD tag
IF l_tagname = p_c_xml_tag_field.
l_name = if_rso_repository_xml_const=>id.
l_fieldname = l_r_element_field->get_attribute( name = l_name )..
READ TABLE l_th_dfies TRANSPORTING NO FIELDS
WITH TABLE KEY fieldname = l_fieldname.
IF sy-subrc = 0.
ASSIGN COMPONENT l_fieldname OF STRUCTURE <l_s_data> TO <l_fs>.
<l_fs> = l_r_element_field->get_value( ).
* modify OBJVERS as R3TRANS does
IF l_fieldname = 'OBJVERS'.
IF <l_fs> = rs_c_objvers-active.
<l_fs> = rs_c_objvers-modified.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
l_r_child_field = l_r_child_field->get_next( ).
ENDWHILE.
INSERT <l_s_data> INTO TABLE <l_t_data>.
ENDIF.
l_r_child_row = l_r_child_row->get_next( ).
ENDWHILE.
INSERT l_s_tlogo_tables INTO TABLE p_ts_tlogo_tables.
ENDIF.
ENDIF.
l_r_child_table = l_r_child_table->get_next( ).
ENDWHILE.
ENDMETHOD. "
METHOD read_tlogo_prop .
* get the BW TLOGO properties
CALL METHOD cl_rso_repository=>if_rso_tlogo_properties~get_tlogoprop
EXPORTING
i_tlogo = p_tlogo
IMPORTING
e_s_tlogoprop = p_s_tlogoprop.
* get the TLOGO properties as stored in transaction SOBJ
* object header (table OBJH)
SELECT SINGLE * FROM objh INTO p_s_objh
WHERE objectname = p_tlogo
AND objecttype = 'L'.
* object tables
SELECT * FROM objsl INTO TABLE p_ts_objsl
WHERE objectname = p_tlogo
AND objecttype = 'L'.
* object methods
SELECT * FROM objm INTO TABLE p_ts_objm
WHERE objectname = p_tlogo
AND objecttype = 'L'.
ENDMETHOD. "
METHOD save .
FIELD-SYMBOLS: <l_s_tlogo_tables> TYPE pt_s_tlogo_tables.
FIELD-SYMBOLS: <l_t_data> TYPE STANDARD TABLE.
DATA: l_dummy TYPE c.
CHECK NOT p_ts_tlogo_tables IS INITIAL.
e_subrc = 0.
* insert into TLOGO tables
LOOP AT p_ts_tlogo_tables ASSIGNING <l_s_tlogo_tables>.
* delete old records first
IF <l_s_tlogo_tables>-where_clause IS INITIAL.
MESSAGE e220(rsoxml) WITH p_objnm p_tlogo INTO l_dummy.
CALL METHOD cl_rso_application_log=>if_rso_application_log~add_message_level
EXPORTING
i_probclass = if_rso_application_log=>probclass_high
i_detlevel = i_detlevel.
e_subrc = 8.
ELSE.
* #CP-SUPPRESS: FP secure coding, no user input
DELETE FROM (<l_s_tlogo_tables>-tabname) WHERE (<l_s_tlogo_tables>-where_clause).
ENDIF.
* actual insert
ASSIGN <l_s_tlogo_tables>-data->* TO <l_t_data>.
INSERT (<l_s_tlogo_tables>-tabname) FROM TABLE <l_t_data>.
IF sy-subrc <> 0.
MESSAGE e221(rsoxml) WITH p_objnm p_tlogo <l_s_tlogo_tables>-tabname INTO l_dummy.
CALL METHOD cl_rso_application_log=>if_rso_application_log~add_message_level
EXPORTING
i_probclass = if_rso_application_log=>probclass_high
i_detlevel = i_detlevel.
e_subrc = sy-subrc.
ENDIF.
ENDLOOP.
ENDMETHOD. "
ENDCLASS.
CLASS lcl_tlogo_xml_bridge IMPLEMENTATION.
METHOD exists.
* check whether an object with this name exists in the primary table
DATA(ls_objsl) = get_prim_table_objsl( ).
DATA(lv_where_clause) = me->get_where_clause(
iv_tobj_name = ls_objsl-tobj_name
iv_objname = iv_objname
).
SELECT COUNT(*) FROM (ls_objsl-tobj_name) WHERE (lv_where_clause).
rv_object_exists = boolc( sy-dbcnt > 0 ).
validate_count_prim_table( iv_dbcount = sy-dbcnt iv_objname = iv_objname ).
ENDMETHOD.
METHOD validate_count_prim_table.
* The method shall validate that by accident (bad programming of this class) unwanted
* entries from the object's tables are being modified or deleted. The general assumption
* is that from th key-table, only one entry is affected.
* however, this is not true for some exceptions, where the primary table features a
* compound key (e. g. checkpoint group activation variants, AVAR)
DATA(ls_objsl) = get_prim_table_objsl( ).
DATA(lv_where_clause) = me->get_where_clause(
iv_tobj_name = ls_objsl-tobj_name
iv_objname = iv_objname
).
* count the key components
DATA lv_count_key_components TYPE i.
DATA lt_dfies TYPE dfies_table.
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = CONV ddobjname( ls_objsl-tobj_name )
TABLES
dfies_tab = lt_dfies
EXCEPTIONS
not_found = 1.
ASSERT sy-subrc = 0.
CLEAR lv_count_key_components.
LOOP AT lt_dfies TRANSPORTING NO FIELDS WHERE keyflag = abap_true.
ADD 1 TO lv_count_key_components.
ENDLOOP.
* if all key-components are covered by the where clause, obviously only one record must be matched by the where-clause
SPLIT lv_where_clause AT | AND | INTO TABLE DATA(lt_where_components).
IF lines( lt_where_components ) = lv_count_key_components.
ASSERT iv_dbcount <= 1. "Sanity-check: there must not be more than one matching entry in the primary table
ENDIF.
ENDMETHOD.
METHOD delete_object.
* first, check existence of the object
IF me->exists( iv_objname = iv_objname ) = abap_true.
LOOP AT p_ts_objsl ASSIGNING FIELD-SYMBOL(<ls_objsl>).
DATA(lv_where_clause) = me->get_where_clause(
iv_tobj_name = <ls_objsl>-tobj_name
iv_objname = iv_objname
).
* Some sanity checks
ASSERT lv_where_clause IS NOT INITIAL.
DELETE FROM (<ls_objsl>-tobj_name) WHERE (lv_where_clause).
IF <ls_objsl>-prim_table = abap_true.
DATA(lv_dbcnt) = sy-dbcnt.
validate_count_prim_table( iv_dbcount = lv_dbcnt iv_objname = iv_objname ).
IF lv_dbcnt > 0.
rv_deleted = abap_true.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
ENDMETHOD.
METHOD get_where_clause.
* Sadly, the superclass does not provide a reuse-method which generates where-clauses,
* thus the code is copied and refactored (a bit)
TYPES: BEGIN OF lt_s_objkey ,
num TYPE numc3,
value TYPE char128,
END OF lt_s_objkey,
lt_ts_objkey TYPE SORTED TABLE OF lt_s_objkey WITH UNIQUE KEY num.
READ TABLE p_ts_objsl ASSIGNING FIELD-SYMBOL(<l_s_objsl>) WITH KEY tobj_name = iv_tobj_name.
ASSERT sy-subrc = 0.
DATA: l_t_dfies TYPE dfies_table,
l_n TYPE i,
l_m TYPE i,
l_k TYPE i,
l_len TYPE i,
l_s_objkey TYPE lt_s_objkey,
l_ts_objkey TYPE lt_ts_objkey,
l_num TYPE numc3.
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = CONV ddobjname( <l_s_objsl>-tobj_name )
TABLES
dfies_tab = l_t_dfies
EXCEPTIONS
not_found = 1.
ASSERT sy-subrc = 0.
* compose the key (table)
CLEAR l_ts_objkey.
CLEAR l_s_objkey.
l_n = 0.
l_num = 1.
l_k = 0.
l_len = strlen( <l_s_objsl>-tobjkey ).
WHILE l_n <= l_len.
l_s_objkey-num = l_num.
* command
IF <l_s_objsl>-tobjkey+l_n(1) = '/'.
IF NOT l_s_objkey-value IS INITIAL.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
ADD 1 TO l_num.
CLEAR l_s_objkey.
l_s_objkey-num = l_num.
ENDIF.
l_m = l_n + 1.
* '*' means all futher key values
IF <l_s_objsl>-tobjkey+l_m(1) = '*'.
l_s_objkey-value = '*'.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
* object name
ELSEIF <l_s_objsl>-tobjkey+l_m(1) = '&'.
l_s_objkey-value = iv_objname.
* #CP-SUPPRESS: FP no risc
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
* language
ELSEIF <l_s_objsl>-tobjkey+l_m(1) = 'L'.
l_s_objkey-value = sy-langu.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
CLEAR l_s_objkey.
ADD 1 TO l_num.
ADD 1 TO l_n.
ENDIF.
l_k = 0.
* value
ELSE.
l_s_objkey-value+l_k(1) = <l_s_objsl>-tobjkey+l_n(1).
ADD 1 TO l_k.
ENDIF.
ADD 1 TO l_n.
ENDWHILE.
IF NOT l_s_objkey-value IS INITIAL.
INSERT l_s_objkey INTO TABLE l_ts_objkey.
ENDIF.
* compose the where clause
DATA(l_flag_asterics) = rs_c_false.
l_num = 1.
DATA(l_where_stmt) = ||.
LOOP AT l_t_dfies ASSIGNING FIELD-SYMBOL(<l_s_dfies>)
WHERE NOT keyflag IS INITIAL.
* #CP-SUPPRESS: FP no risc
READ TABLE l_ts_objkey INTO l_s_objkey
WITH TABLE KEY num = l_num.
IF sy-subrc <> 0
OR <l_s_dfies>-fieldname = 'LANGU'.
CLEAR l_s_objkey.
ADD 1 TO l_num.
CONTINUE.
ENDIF.
IF l_s_objkey-value = '*'.
l_flag_asterics = rs_c_true.
ENDIF.
IF l_flag_asterics = rs_c_true.
CONTINUE.
ENDIF.
IF NOT l_where_stmt IS INITIAL.
* #CP-SUPPRESS: FP no risc
CONCATENATE l_where_stmt 'AND' INTO l_where_stmt
SEPARATED BY space.
ENDIF.
* #CP-SUPPRESS: FP no risc
CONCATENATE '''' l_s_objkey-value '''' INTO DATA(l_value128).
* #CP-SUPPRESS: FP no risc
CONCATENATE l_where_stmt <l_s_dfies>-fieldname '='
l_value128 INTO l_where_stmt SEPARATED BY space.
ADD 1 TO l_num.
ENDLOOP.
rv_where_on_keys = l_where_stmt.
ENDMETHOD.
METHOD timestamp_to_xml.
"copy of cl_rso_tlogo=>timestamp_to_xml
* this would be more readable, but must be converted before stored on DB
* additional problem: different time formats (language dependent)
* CONVERT TIME STAMP l_conttimestmp TIME ZONE sy-zonlo
* INTO DATE l_date TIME l_time.
* WRITE: l_date TO l_date_c.
* WRITE: l_time TO l_time_c.
* CONCATENATE l_date_c l_time_c INTO l_value SEPARATED BY ', '.
* simple, but works
rv_string = iv_timestamp.
ENDMETHOD.
METHOD get_prim_table_objsl.
READ TABLE p_ts_objsl INTO rs_objsl WITH KEY prim_table = abap_true.
IF sy-subrc <> 0.
* Fallback. For some objects, no primary table is explicitly flagged
* The, the one with only one key field shall be chosen
READ TABLE p_ts_objsl INTO rs_objsl WITH KEY tobjkey = '/&'.
ENDIF.
ASSERT rs_objsl IS NOT INITIAL.
ENDMETHOD.
METHOD get_table_metadata.
* parse all tables of this TLOGO object
LOOP AT p_ts_objsl ASSIGNING FIELD-SYMBOL(<ls_objsl>).
DATA ls_metadata LIKE LINE OF rt_metadata.
ls_metadata-db_table = <ls_objsl>-tobj_name.
INSERT ls_metadata INTO TABLE rt_metadata ASSIGNING FIELD-SYMBOL(<ls_table_metdata>).
DATA(lv_where_clause) = me->get_where_clause(
iv_tobj_name = <ls_objsl>-tobj_name
iv_objname = iv_objname
).
SELECT COUNT(*) INTO <ls_table_metdata>-count FROM (<ls_objsl>-tobj_name) WHERE (lv_where_clause).
* get the DDIC info of the table structure
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = CONV ddobjname( <ls_objsl>-tobj_name )
TABLES
dfies_tab = <ls_table_metdata>-fields_definition
EXCEPTIONS
not_found = 1.
ASSERT sy-subrc = 0.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v0.2-alpha">
<VSEOCLASS>
<CLSNAME>ZSAPLINK_GENERIC_OBJ</CLSNAME>
<VERSION>1</VERSION>
<LANGU>E</LANGU>
<DESCRIPT>Generic adapter for SAPLINK based on sobj</DESCRIPT>
<UUID>00000000000000000000000000000000</UUID>
<CATEGORY>00</CATEGORY>
<EXPOSURE>2</EXPOSURE>
<STATE>1</STATE>
<RELEASE>0</RELEASE>
<AUTHOR></AUTHOR>
<CREATEDON>00000000</CREATEDON>
<CHANGEDBY></CHANGEDBY>
<CHANGEDON>00000000</CHANGEDON>
<CHGDANYBY></CHGDANYBY>
<CHGDANYON>00000000</CHGDANYON>
<CLSEMBED></CLSEMBED>
<CLSABSTRCT>X</CLSABSTRCT>
<CLSFINAL></CLSFINAL>
<CLSCCINCL>X</CLSCCINCL>
<REMOTE></REMOTE>
<FIXPT>X</FIXPT>
<VARCL></VARCL>
<UNICODE>X</UNICODE>
<RSTAT></RSTAT>
<CLSDEFATT></CLSDEFATT>
<CLSDEFMTD></CLSDEFMTD>
<CLSDEFINT></CLSDEFINT>
<CLSBCIMPL></CLSBCIMPL>
<R3RELEASE></R3RELEASE>
<CLSBCTRANS></CLSBCTRANS>
<CLSBCCAT>00</CLSBCCAT>
<CLSADDON></CLSADDON>
<MSG_ID></MSG_ID>
<CLSBCNODEL></CLSBCNODEL>
<CLSPROXY></CLSPROXY>
<CLSSHAREDMEMORY></CLSSHAREDMEMORY>
<WITH_UNIT_TESTS></WITH_UNIT_TESTS>
<DURATION_TYPE>0 </DURATION_TYPE>
<RISK_LEVEL>0 </RISK_LEVEL>
<WITHIN_PACKAGE></WITHIN_PACKAGE>
</VSEOCLASS>
<TEXTPOOL_TABLE/>
</abapGit>