├── .abapgit.xml ├── LICENSE ├── README.md ├── package.devc.xml ├── zrstpda_object_visualizer.prog.abap └── zrstpda_object_visualizer.prog.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | / 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Lars Hvam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ABAP-Object-Visualizer 2 | 3 | Visualize complex object hierarchies in ABAP via [graphviz](http://www.graphviz.org/) 4 | 5 | ### Installation 6 | Install via [abapGit](https://github.com/larshp/abapGit) 7 | 8 | ### Use 9 | 1. Set breakpoint in source code 10 | 2. In the new debugger go to "Script" tab 11 | 3. Load script ZRSTPDA_OBJECT_VISUALIZER from database 12 | 4. Choose option "Execute Directly" 13 | 5. Click "Start Script" 14 | 6. Enter object variable name 15 | 7. Paste clipboard to http://www.webgraphviz.com/ and click "Generate Graph!" 16 | 17 | Graphviz can also be installed locally: http://portableapps.com/node/38245 18 | 19 | Example from https://github.com/larshp/FORMfactor 20 | ![go_class](https://cloud.githubusercontent.com/assets/5888506/9976449/051927b2-5ee5-11e5-945d-4665ba704895.png) 21 | 22 | Example from http://zevolving.com/2012/01/iterator-design-pattern-to-access-linked-list/ 23 | ![linked](https://cloud.githubusercontent.com/assets/5888506/9976450/051bf514-5ee5-11e5-9b20-51b6a9d472b6.png) 24 | -------------------------------------------------------------------------------- /package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Visualizer 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /zrstpda_object_visualizer.prog.abap: -------------------------------------------------------------------------------- 1 | * 2 | REPORT zrstpda_object_visualizer. 3 | 4 | * 5 | *ZRSTPDA_OBJECT_VISUALIZER 6 | *LCL_DEBUGGER_SCRIPT 7 | *ABAP Object Visualizer 8 | *X 9 | 10 | * 11 | 12 | * 13 | 14 | * 15 | 16 | * 17 | 18 | * See https://github.com/larshp/ABAP-Object-Visualizer 19 | 20 | ******************************************************************************** 21 | * The MIT License (MIT) 22 | * 23 | * Copyright (c) 2015 Lars Hvam Petersen 24 | * Copyright (c) 2020 Jacques Nomssi Nzali 25 | * 26 | * Permission is hereby granted, free of charge, to any person obtaining a copy 27 | * of this software and associated documentation files (the "Software"), to deal 28 | * in the Software without restriction, including without limitation the rights 29 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 30 | * copies of the Software, and to permit persons to whom the Software is 31 | * furnished to do so, subject to the following conditions: 32 | * 33 | * The above copyright notice and this permission notice shall be included in all 34 | * copies or substantial portions of the Software. 35 | * 36 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 38 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 39 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 40 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 41 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 42 | * SOFTWARE. 43 | ******************************************************************************** 44 | 45 | CONSTANTS: 46 | c_mode_aut TYPE char01 VALUE 'T', " for ABAP Unit Test 47 | c_mode_url TYPE char01 VALUE 'U', 48 | c_mode_txt TYPE char01 VALUE space. 49 | CONSTANTS c_plantuml_server TYPE string 50 | VALUE 'http://www.plantuml.com/plantuml/img/' ##NO_TEXT. 51 | 52 | TYPES tv_scale TYPE perct. 53 | CONSTANTS c_default_scale TYPE tv_scale VALUE '0.7'. 54 | TYPES: BEGIN OF ts_diagram_config, 55 | local_path TYPE string, 56 | java_jar TYPE string, 57 | java_appl TYPE string, 58 | server_url TYPE string, 59 | output_mode TYPE char01, 60 | skip_dialog TYPE flag, 61 | scale TYPE tv_scale, 62 | shadowing TYPE flag, 63 | display_source TYPE flag, 64 | hpages TYPE sytabix, 65 | vpages TYPE sytabix, 66 | END OF ts_diagram_config. 67 | 68 | CLASS lcl_file_name DEFINITION. 69 | PUBLIC SECTION. 70 | CLASS-METHODS new IMPORTING iv_mode TYPE char01 71 | RETURNING VALUE(ro_file) TYPE REF TO lcl_file_name. 72 | METHODS constructor IMPORTING iv_mode TYPE char01. 73 | METHODS dialog RETURNING VALUE(rv_user_action) TYPE i. 74 | METHODS get_prefix RETURNING VALUE(rv_name) TYPE string 75 | RAISING cx_dynamic_check. 76 | METHODS get_fullpath RETURNING VALUE(rv_name) TYPE string. 77 | PROTECTED SECTION. 78 | TYPES: BEGIN OF ts_fullpath, 79 | title TYPE string, 80 | name TYPE string, 81 | ext TYPE string, 82 | path TYPE string, 83 | filter TYPE string, 84 | END OF ts_fullpath. 85 | DATA ms_file TYPE ts_fullpath. 86 | ENDCLASS. 87 | 88 | *----------------------------------------------------------------------* 89 | * CLASS lcl_plant_uml DEFINITION 90 | *----------------------------------------------------------------------* 91 | CLASS lcl_plant_uml DEFINITION. 92 | PUBLIC SECTION. 93 | METHODS constructor IMPORTING iv_diagram TYPE string. 94 | METHODS to_url IMPORTING iv_base_url TYPE string DEFAULT c_plantuml_server 95 | RETURNING VALUE(rv_url) TYPE string 96 | RAISING cx_dynamic_check. 97 | METHODS output IMPORTING is_cfg TYPE ts_diagram_config RAISING cx_dynamic_check. 98 | PROTECTED SECTION. 99 | TYPES tv_base64 TYPE c LENGTH 65. 100 | CONSTANTS: 101 | c_standard TYPE tv_base64 VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' ##NO_TEXT, 102 | c_plantuml TYPE tv_base64 VALUE '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_0' ##NO_TEXT. 103 | DATA mv_diagram TYPE string. 104 | 105 | METHODS to_xstring IMPORTING iv_string TYPE string 106 | RETURNING VALUE(rv_xstring) TYPE xstring 107 | RAISING cx_dynamic_check. 108 | METHODS source IMPORTING iv_display_source TYPE flag 109 | RETURNING VALUE(rv_source) TYPE string. 110 | 111 | METHODS png_file_name IMPORTING io_name TYPE REF TO lcl_file_name 112 | is_cfg TYPE ts_diagram_config 113 | RETURNING VALUE(rv_name) TYPE string. 114 | 115 | METHODS parameter_string IMPORTING io_name TYPE REF TO lcl_file_name 116 | is_cfg TYPE ts_diagram_config 117 | RETURNING VALUE(rv_param) TYPE string. 118 | METHODS show_html IMPORTING iv_html TYPE string 119 | iv_size TYPE string DEFAULT cl_abap_browser=>xlarge 120 | RAISING cx_dynamic_check. 121 | METHODS to_png IMPORTING io_name TYPE REF TO lcl_file_name 122 | is_cfg TYPE ts_diagram_config 123 | RETURNING VALUE(rv_name) TYPE string. 124 | ENDCLASS. 125 | 126 | *----------------------------------------------------------------------* 127 | * CLASS lcl_file DEFINITION 128 | *----------------------------------------------------------------------* 129 | CLASS lcl_file DEFINITION CREATE PRIVATE. 130 | PUBLIC SECTION. 131 | CONSTANTS: 132 | c_mode_txt TYPE char01 VALUE space, 133 | c_mode_png TYPE char01 VALUE 'P'. 134 | 135 | CLASS-METHODS download 136 | IMPORTING iv_data TYPE xstring 137 | io_name TYPE REF TO lcl_file_name 138 | RETURNING VALUE(rv_subrc) TYPE sysubrc. 139 | ENDCLASS. "lcl_file DEFINITION 140 | 141 | CLASS lcl_file_name_dummy DEFINITION INHERITING FROM lcl_file_name. 142 | PUBLIC SECTION. 143 | METHODS dialog REDEFINITION. 144 | ENDCLASS. 145 | 146 | *---------------------------------------------------------------------* 147 | * CLASS lcl_debugger_script DEFINITION 148 | *---------------------------------------------------------------------* 149 | 150 | *---------------------------------------------------------------------* 151 | CLASS lcl_debugger_script DEFINITION 152 | INHERITING FROM cl_tpda_script_class_super FINAL ##NEEDED. 153 | 154 | PUBLIC SECTION. 155 | METHODS: 156 | script REDEFINITION. 157 | 158 | PRIVATE SECTION. 159 | 160 | CONSTANTS: c_newline 161 | LIKE cl_abap_char_utilities=>newline 162 | VALUE cl_abap_char_utilities=>newline. 163 | 164 | DATA: mt_visited TYPE TABLE OF string, 165 | mv_graph TYPE string. 166 | 167 | METHODS: 168 | popup 169 | RETURNING VALUE(rv_name) TYPE string, 170 | to_clipboard, 171 | to_plantuml 172 | IMPORTING iv_diagram TYPE string, 173 | name 174 | IMPORTING iv_name TYPE string 175 | RETURNING VALUE(rv_name) TYPE string, 176 | handle_tab 177 | IMPORTING iv_name TYPE string 178 | io_descr TYPE REF TO cl_tpda_script_data_descr 179 | RAISING cx_tpda, 180 | handle_object 181 | IMPORTING iv_name TYPE string 182 | io_descr TYPE REF TO cl_tpda_script_data_descr 183 | RAISING cx_tpda, 184 | handle_objref 185 | IMPORTING iv_name TYPE string 186 | RAISING cx_tpda, 187 | handle_string 188 | IMPORTING iv_name TYPE string 189 | io_descr TYPE REF TO cl_tpda_script_data_descr 190 | RAISING cx_tpda, 191 | handle_simple 192 | IMPORTING iv_name TYPE string 193 | io_descr TYPE REF TO cl_tpda_script_data_descr 194 | RAISING cx_tpda, 195 | handle_struct 196 | IMPORTING iv_name TYPE string 197 | io_descr TYPE REF TO cl_tpda_script_data_descr 198 | RAISING cx_tpda, 199 | handle_dataref 200 | IMPORTING !iv_name TYPE string 201 | io_descr TYPE REF TO cl_tpda_script_data_descr 202 | RAISING 203 | cx_tpda , 204 | handle 205 | IMPORTING iv_name TYPE string 206 | RAISING cx_tpda. 207 | 208 | ENDCLASS. "lcl_debugger_script DEFINITION 209 | 210 | *---------------------------------------------------------------------* 211 | * CLASS lcl_debugger_script IMPLEMENTATION 212 | *---------------------------------------------------------------------* 213 | * 214 | *---------------------------------------------------------------------* 215 | CLASS lcl_debugger_script IMPLEMENTATION. 216 | 217 | METHOD popup. 218 | 219 | DATA: lv_returncode TYPE c, 220 | lt_fields TYPE TABLE OF sval. 221 | 222 | APPEND VALUE #( tabname = 'ABAPTXT255' 223 | fieldname = 'LINE' 224 | fieldtext = 'Object'(002) 225 | field_obl = abap_true 226 | value = 'GO_CLASS' ) TO lt_fields. 227 | 228 | CALL FUNCTION 'POPUP_GET_VALUES' 229 | EXPORTING 230 | popup_title = 'Choose object'(005) 231 | IMPORTING 232 | returncode = lv_returncode 233 | TABLES 234 | fields = lt_fields 235 | EXCEPTIONS 236 | error_in_fields = 1 237 | OTHERS = 2. 238 | IF sy-subrc <> 0 OR lv_returncode = 'A'. 239 | RETURN. 240 | ENDIF. 241 | 242 | rv_name = to_upper( VALUE #( lt_fields[ 1 ]-value OPTIONAL ) ). 243 | 244 | ENDMETHOD. 245 | 246 | METHOD handle_simple. 247 | 248 | DATA: lo_elem TYPE REF TO cl_tpda_script_elemdescr, 249 | lv_value TYPE string. 250 | 251 | 252 | lo_elem ?= io_descr. 253 | lv_value = lo_elem->value( ). 254 | 255 | REPLACE ALL OCCURRENCES OF c_newline IN lv_value WITH space. 256 | 257 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 258 | }label = "{ lv_value }"{ c_newline 259 | }shape = "record" ];{ c_newline }|. 260 | 261 | ENDMETHOD. 262 | 263 | METHOD handle_struct. 264 | 265 | DATA: lv_label TYPE string, 266 | lv_edges TYPE string, 267 | lv_name TYPE string, 268 | lt_components TYPE tpda_script_struc_componentsit, 269 | lo_struct TYPE REF TO cl_tpda_script_structdescr, 270 | lv_match_offset TYPE i. 271 | 272 | lo_struct ?= io_descr. 273 | 274 | lo_struct->components( IMPORTING p_components_it = lt_components ). 275 | FIND REGEX '\*$' IN iv_name MATCH OFFSET lv_match_offset. 276 | 277 | lv_label = 'Structure'(004). 278 | LOOP AT lt_components ASSIGNING FIELD-SYMBOL(). 279 | lv_label = |{ lv_label } \| { name( -compname ) }\\{ c_newline }|. 280 | IF lv_match_offset = 0. 281 | lv_name = |{ iv_name }-{ -compname }|. 282 | ELSE. 283 | lv_name = |{ iv_name(lv_match_offset) }{ -compname }|. 284 | ENDIF. 285 | lv_edges = |{ lv_edges }"{ name( iv_name ) }": -> "{ name( lv_name ) }";{ c_newline }|. 286 | 287 | handle( lv_name ). 288 | ENDLOOP. 289 | 290 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 291 | }label = "{ lv_label }"{ c_newline 292 | }shape = "record" ];{ c_newline 293 | }{ lv_edges }|. 294 | 295 | ENDMETHOD. 296 | 297 | METHOD name. 298 | 299 | rv_name = iv_name. 300 | REPLACE ALL OCCURRENCES OF: 301 | '{' IN rv_name WITH '\{', 302 | '}' IN rv_name WITH '\}'. 303 | 304 | ENDMETHOD. 305 | 306 | METHOD handle_tab. 307 | 308 | DATA: lv_name TYPE string, 309 | lv_label TYPE string, 310 | lv_edges TYPE string, 311 | lo_table TYPE REF TO cl_tpda_script_tabledescr. 312 | 313 | 314 | lo_table ?= io_descr. 315 | lv_label = 'Table'(001). 316 | DO lo_table->linecnt( ) TIMES. 317 | lv_name = |{ iv_name }[{ sy-index }]|. 318 | 319 | lv_label = |{ lv_label } \| { sy-index }\\{ c_newline }|. 320 | lv_edges = |{ lv_edges }"{ name( iv_name ) }": -> "{ name( lv_name ) }";{ c_newline }|. 322 | 323 | handle( lv_name ). 324 | ENDDO. 325 | 326 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 327 | }label = "{ lv_label }"{ c_newline 328 | }shape = "record" ];{ c_newline 329 | }{ lv_edges }|. 330 | 331 | ENDMETHOD. 332 | 333 | METHOD handle_object. 334 | 335 | DATA: lo_object TYPE REF TO cl_tpda_script_objectdescr, 336 | lv_name TYPE string, 337 | lv_label TYPE string, 338 | lv_color TYPE string, 339 | lv_edges TYPE string, 340 | lv_type TYPE string, 341 | lt_attributes TYPE tpda_script_object_attribut_it. 342 | 343 | lo_object ?= io_descr. 344 | lt_attributes = lo_object->attributes( ). 345 | 346 | lv_label = 'Object'(002). 347 | LOOP AT lt_attributes ASSIGNING FIELD-SYMBOL(). 348 | lv_label = |{ lv_label } \| { name( -name ) }\\{ c_newline }|. 349 | 350 | CONCATENATE iv_name '-' -name INTO lv_name. 351 | 352 | CASE -acckind. 353 | WHEN if_tpda_control=>ak_private. 354 | lv_color = 'red'. 355 | lv_type = 'private'. 356 | WHEN if_tpda_control=>ak_protected. 357 | lv_color = 'yellow'. 358 | lv_type = 'protected'. 359 | WHEN if_tpda_control=>ak_public. 360 | lv_color = 'green'. 361 | lv_type = 'public'. 362 | WHEN OTHERS. 363 | ASSERT 1 = 1 + 1. 364 | ENDCASE. 365 | lv_edges = |{ lv_edges }"{ name( iv_name ) }": -> "{ name( lv_name ) }" [fontcolor={ lv_color 367 | } label="{ lv_type }"];{ c_newline }|. 368 | 369 | handle( lv_name ). 370 | ENDLOOP. 371 | 372 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 373 | }label = "{ lv_label }"{ c_newline 374 | }shape = "record" ];{ c_newline 375 | }{ lv_edges }|. 376 | 377 | ENDMETHOD. 378 | 379 | METHOD handle_objref. 380 | 381 | DATA: ls_info TYPE tpda_scr_quick_info, 382 | lv_label TYPE string. 383 | 384 | FIELD-SYMBOLS: TYPE tpda_sys_symbobjref. 385 | 386 | 387 | ls_info = cl_tpda_script_data_descr=>get_quick_info( iv_name ). 388 | 389 | ASSIGN ls_info-quickdata->* TO . 390 | IF -instancename <> '{O:initial}'. 391 | handle( -instancename ). 392 | ENDIF. 393 | 394 | IF iv_name CA '{'. 395 | lv_label = 'ref'. 396 | ELSE. 397 | lv_label = iv_name. 398 | ENDIF. 399 | 400 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 401 | }label = "{ lv_label }"{ c_newline 402 | }shape = "record" ];{ c_newline 403 | }"{ name( iv_name ) }" -> "{ name( -instancename ) }";{ c_newline 404 | }|. 405 | 406 | ENDMETHOD. 407 | 408 | METHOD handle_string. 409 | 410 | DATA: lo_string TYPE REF TO cl_tpda_script_stringdescr, 411 | lv_value TYPE string. 412 | 413 | 414 | lo_string ?= io_descr. 415 | lv_value = lo_string->value( ). 416 | 417 | REPLACE ALL OCCURRENCES OF c_newline IN lv_value WITH space. 418 | 419 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 420 | }label = "'{ lv_value }'"{ c_newline 421 | }shape = "record" ];{ c_newline }|. 422 | 423 | ENDMETHOD. 424 | 425 | METHOD handle_dataref. 426 | DATA: ls_info TYPE tpda_scr_quick_info. 427 | 428 | FIELD-SYMBOLS: TYPE tpda_sys_symbdatref. 429 | 430 | ls_info = cl_tpda_script_data_descr=>get_quick_info( iv_name ). 431 | ASSIGN ls_info-quickdata->* TO . 432 | 433 | FIND REGEX '^\{[A-Z]:initial\}$' IN -instancename IGNORING CASE. 434 | IF sy-subrc <> 0. 435 | handle( -instancename ). 436 | ENDIF. 437 | 438 | mv_graph = |{ mv_graph }"{ name( iv_name ) }" [{ c_newline 439 | }label = "ref"{ c_newline 440 | }shape = "record" ];{ c_newline 441 | }"{ name( iv_name ) }" -> "{ name( -instancename ) }";{ c_newline }|. 442 | 443 | 444 | ENDMETHOD. 445 | 446 | METHOD script. 447 | 448 | DATA: lv_name TYPE string, 449 | lx_tpda TYPE REF TO cx_tpda. 450 | 451 | 452 | TRY. 453 | lv_name = popup( ). 454 | IF lv_name IS INITIAL. 455 | RETURN. 456 | ENDIF. 457 | CLEAR mt_visited. 458 | handle( lv_name ). 459 | mv_graph = |digraph g \{{ c_newline 460 | }graph [{ c_newline 461 | }rankdir = "LR"{ c_newline 462 | }];{ c_newline 463 | }{ mv_graph }{ c_newline 464 | }\}|. 465 | to_plantuml( |@startdot\n{ mv_graph }\n@enddot| ). 466 | to_clipboard( ). 467 | CATCH cx_tpda_varname. 468 | MESSAGE 'Unknown variable'(006) TYPE 'I'. 469 | CATCH cx_tpda INTO lx_tpda. 470 | MESSAGE lx_tpda TYPE 'I'. 471 | ENDTRY. 472 | 473 | ENDMETHOD. 474 | 475 | METHOD handle. 476 | 477 | DATA: ls_info TYPE tpda_scr_quick_info, 478 | lo_descr TYPE REF TO cl_tpda_script_data_descr. 479 | 480 | TRY. 481 | 482 | READ TABLE mt_visited FROM iv_name TRANSPORTING NO FIELDS. 483 | IF sy-subrc = 0. 484 | RETURN. 485 | ENDIF. 486 | APPEND iv_name TO mt_visited. 487 | 488 | lo_descr = cl_tpda_script_data_descr=>factory( iv_name ). 489 | ls_info = cl_tpda_script_data_descr=>get_quick_info( iv_name ). 490 | 491 | CASE ls_info-metatype. 492 | WHEN cl_tpda_script_data_descr=>mt_simple. 493 | handle_simple( iv_name = iv_name 494 | io_descr = lo_descr ). 495 | WHEN cl_tpda_script_data_descr=>mt_struct. 496 | handle_struct( iv_name = iv_name 497 | io_descr = lo_descr ). 498 | WHEN cl_tpda_script_data_descr=>mt_string. 499 | handle_string( iv_name = iv_name 500 | io_descr = lo_descr ). 501 | WHEN cl_tpda_script_data_descr=>mt_tab. 502 | handle_tab( iv_name = iv_name 503 | io_descr = lo_descr ). 504 | WHEN cl_tpda_script_data_descr=>mt_datref. 505 | handle_dataref( iv_name = iv_name 506 | io_descr = lo_descr ). 507 | WHEN cl_tpda_script_data_descr=>mt_object. 508 | handle_object( iv_name = iv_name 509 | io_descr = lo_descr ). 510 | WHEN cl_tpda_script_data_descr=>mt_objref. 511 | handle_objref( iv_name ). 512 | ENDCASE. 513 | CATCH cx_root. 514 | ASSERT 1 = 1 + 1. 515 | ENDTRY. 516 | 517 | ENDMETHOD. "script 518 | 519 | METHOD to_clipboard. 520 | 521 | DATA: lt_table TYPE STANDARD TABLE OF abaptxt255 ##NEEDED, 522 | lv_rc TYPE i. 523 | 524 | 525 | SPLIT mv_graph AT c_newline INTO TABLE lt_table. 526 | 527 | cl_gui_frontend_services=>clipboard_export( 528 | IMPORTING 529 | data = lt_table 530 | CHANGING 531 | rc = lv_rc 532 | EXCEPTIONS 533 | cntl_error = 1 534 | error_no_gui = 2 535 | not_supported_by_gui = 3 536 | no_authority = 4 537 | OTHERS = 5 ). "#EC CI_SUBRC 538 | ASSERT sy-subrc = 0. 539 | 540 | MESSAGE 'Exported to clipboard'(003) TYPE 'I'. 541 | 542 | ENDMETHOD. 543 | 544 | METHOD to_plantuml. 545 | DATA ls_cfg TYPE ts_diagram_config. 546 | 547 | ls_cfg-scale = c_default_scale. 548 | ls_cfg-server_url = c_plantuml_server. 549 | ls_cfg-hpages = 1. 550 | ls_cfg-vpages = 1. 551 | ls_cfg-output_mode = c_mode_url. 552 | 553 | NEW lcl_plant_uml( iv_diagram )->output( ls_cfg ). 554 | ENDMETHOD. 555 | 556 | ENDCLASS. "lcl_debugger_script IMPLEMENTATION 557 | 558 | *----------------------------------------------------------------------* 559 | * CLASS lcl_plant_uml IMPLEMENTATION 560 | *----------------------------------------------------------------------* 561 | CLASS lcl_plant_uml IMPLEMENTATION. 562 | 563 | METHOD constructor. 564 | mv_diagram = iv_diagram. 565 | ENDMETHOD. "constructor 566 | 567 | METHOD source. 568 | CLEAR rv_source. 569 | CHECK iv_display_source EQ abap_true. 570 | rv_source = |

{ mv_diagram }

|. 571 | ENDMETHOD. 572 | 573 | METHOD show_html. 574 | cl_abap_browser=>show_html( html_string = iv_html 575 | size = iv_size 576 | context_menu = abap_true ). 577 | ENDMETHOD. 578 | 579 | METHOD output. 580 | CASE is_cfg-output_mode. 581 | WHEN c_mode_url. 582 | show_html( |\n{ source( is_cfg-display_source ) }| ). 583 | 584 | WHEN OTHERS. 585 | * export data as PlantUML source 586 | lcl_file=>download( io_name = lcl_file_name=>new( is_cfg-output_mode ) 587 | iv_data = to_xstring( mv_diagram ) ). 588 | ENDCASE. 589 | ENDMETHOD. "output 590 | 591 | METHOD to_url. 592 | DATA lv_bin TYPE xstring. 593 | * for PlantUML Server: Convert to UTF-8, then deflate, then encode (base64 variant) 594 | cl_abap_gzip=>compress_binary( 595 | EXPORTING 596 | raw_in = to_xstring( mv_diagram ) " UTF-8 597 | compress_level = 9 598 | IMPORTING 599 | gzip_out = lv_bin ). 600 | 601 | rv_url = iv_base_url && 602 | translate( val = cl_http_utility=>encode_x_base64( lv_bin ) 603 | from = c_standard 604 | to = c_plantuml ). 605 | ENDMETHOD. "to_url 606 | 607 | METHOD to_xstring. 608 | cl_abap_conv_out_ce=>create( encoding = 'UTF-8' )->convert( EXPORTING data = iv_string 609 | IMPORTING buffer = rv_xstring ). 610 | ENDMETHOD. "to_xstring 611 | 612 | METHOD parameter_string. 613 | rv_param = |-jar { is_cfg-java_jar } -o { is_cfg-local_path } "{ io_name->get_fullpath( ) }"|. 614 | ENDMETHOD. 615 | 616 | METHOD png_file_name. 617 | TRY. 618 | rv_name = |{ is_cfg-local_path }{ io_name->get_prefix( ) }.png|. 619 | CATCH cx_dynamic_check. 620 | CLEAR rv_name. 621 | ENDTRY. 622 | ENDMETHOD. 623 | 624 | METHOD to_png. 625 | CLEAR rv_name. 626 | cl_gui_frontend_services=>execute( 627 | EXPORTING application = is_cfg-java_appl 628 | parameter = parameter_string( io_name = io_name 629 | is_cfg = is_cfg ) 630 | synchronous = 'X' 631 | EXCEPTIONS OTHERS = 1 ). 632 | CHECK sy-subrc EQ 0. 633 | rv_name = png_file_name( io_name = io_name 634 | is_cfg = is_cfg ). 635 | ENDMETHOD. 636 | 637 | ENDCLASS. "lcl_plant_uml IMPLEMENTATION 638 | 639 | CLASS lcl_file_name_dummy IMPLEMENTATION. 640 | 641 | METHOD dialog. 642 | ms_file-path = |test.txt|. 643 | rv_user_action = cl_gui_frontend_services=>action_cancel. 644 | ENDMETHOD. 645 | 646 | ENDCLASS. 647 | 648 | *----------------------------------------------------------------------* 649 | * CLASS lcl_file IMPLEMENTATION 650 | *----------------------------------------------------------------------* 651 | CLASS lcl_file IMPLEMENTATION. 652 | 653 | METHOD download. 654 | rv_subrc = 1. 655 | CHECK io_name->dialog( ) NE cl_gui_frontend_services=>action_cancel. 656 | 657 | rv_subrc = cl_uml_utilities=>save_xml_local( xml = iv_data 658 | filename = io_name->get_fullpath( ) ). 659 | ENDMETHOD. 660 | 661 | ENDCLASS. "lcl_file IMPLEMENTATION 662 | 663 | CLASS lcl_file_name IMPLEMENTATION. 664 | 665 | METHOD new. 666 | CASE iv_mode. 667 | WHEN c_mode_aut. 668 | ro_file = NEW lcl_file_name_dummy( iv_mode ). 669 | WHEN OTHERS. 670 | ro_file = NEW lcl_file_name( iv_mode ). 671 | ENDCASE. 672 | ENDMETHOD. 673 | 674 | METHOD constructor. 675 | CASE iv_mode. 676 | WHEN c_mode_txt. 677 | ms_file = VALUE #( title = |Save UML text source| 678 | ext = |.txt| ). 679 | WHEN OTHERS. 680 | ms_file = VALUE #( title = |Save As...| 681 | ext = |.txt| ). 682 | ENDCASE. 683 | ENDMETHOD. 684 | 685 | METHOD get_prefix. 686 | rv_name = shift_right( val = ms_file-name 687 | places = strlen( ms_file-ext ) ). 688 | ENDMETHOD. 689 | 690 | METHOD get_fullpath. 691 | rv_name = ms_file-path. 692 | ENDMETHOD. 693 | 694 | METHOD dialog. 695 | DATA lv_path TYPE string ##needed. 696 | 697 | CLEAR rv_user_action. 698 | 699 | cl_gui_frontend_services=>file_save_dialog( 700 | EXPORTING 701 | window_title = ms_file-title " Window Title 702 | default_extension = ms_file-ext " Default Extension 703 | file_filter = ms_file-filter 704 | CHANGING 705 | filename = ms_file-name " File Name to Save 706 | path = lv_path " Path to File 707 | fullpath = ms_file-path " Path + File Name 708 | user_action = rv_user_action 709 | " User Action (C Class Const ACTION_OK, ACTION_OVERWRITE etc) 710 | * file_encoding = 711 | EXCEPTIONS 712 | OTHERS = 0 ). 713 | ENDMETHOD. 714 | 715 | ENDCLASS. 716 | -------------------------------------------------------------------------------- /zrstpda_object_visualizer.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZRSTPDA_OBJECT_VISUALIZER 7 | S 8 | S 9 | X 10 | X 11 | D$S 12 | X 13 | 14 | 15 | 16 | I 17 | 001 18 | Table 19 | 15 20 | 21 | 22 | I 23 | 002 24 | Object 25 | 16 26 | 27 | 28 | I 29 | 003 30 | Exported to clipboard 31 | 42 32 | 33 | 34 | I 35 | 004 36 | Structure 37 | 19 38 | 39 | 40 | I 41 | 005 42 | Choose object 43 | 23 44 | 45 | 46 | I 47 | 006 48 | Unknown variable 49 | 26 50 | 51 | 52 | R 53 | ABAP Object Visualizer 54 | 22 55 | 56 | 57 | 58 | 59 | 60 | --------------------------------------------------------------------------------