mirror of
https://github.com/abapGit/abapGit.git
synced 2025-04-30 20:03:20 +08:00
SAPLink-artifacts added
This commit is contained in:
parent
6405ac7ab4
commit
35d80083cd
358
zsaplink_generic_obj.clas.abap
Normal file
358
zsaplink_generic_obj.clas.abap
Normal 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.
|
147
zsaplink_generic_obj.clas.locals_def.abap
Normal file
147
zsaplink_generic_obj.clas.locals_def.abap
Normal 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.
|
887
zsaplink_generic_obj.clas.locals_imp.abap
Normal file
887
zsaplink_generic_obj.clas.locals_imp.abap
Normal 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.
|
46
zsaplink_generic_obj.clas.xml
Normal file
46
zsaplink_generic_obj.clas.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user