├── .abapgit.xml ├── LICENSE ├── README.md └── src ├── demo ├── package.devc.xml ├── zabapgraph_demo.prog.abap └── zabapgraph_demo.prog.xml ├── package.devc.xml ├── zabapgraph_string_template.prog.abap ├── zabapgraph_string_template.prog.xml ├── zcl_abap_graph.clas.abap ├── zcl_abap_graph.clas.locals_imp.abap ├── zcl_abap_graph.clas.xml ├── zcl_abap_graph_attr.clas.abap ├── zcl_abap_graph_attr.clas.locals_imp.abap ├── zcl_abap_graph_attr.clas.xml ├── zcl_abap_graph_node_record.clas.abap ├── zcl_abap_graph_node_record.clas.locals_imp.abap ├── zcl_abap_graph_node_record.clas.xml ├── zcl_abap_graph_node_simple.clas.abap ├── zcl_abap_graph_node_simple.clas.xml ├── zcl_abap_graph_node_table.clas.abap ├── zcl_abap_graph_node_table.clas.locals_imp.abap ├── zcl_abap_graph_node_table.clas.xml ├── zcl_abap_graph_string_template.clas.abap ├── zcl_abap_graph_string_template.clas.testclasses.abap ├── zcl_abap_graph_string_template.clas.xml ├── zcl_abap_graph_utilities.clas.abap ├── zcl_abap_graph_utilities.clas.xml ├── zcx_abap_graph.clas.abap ├── zcx_abap_graph.clas.xml ├── zif_abap_graph_node.intf.abap └── zif_abap_graph_node.intf.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Marcello Urbani 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ABAP Graph 2 | 3 | A library to create graphviz graphs in ABAP, see the example code in the demo folder. 4 | 5 | Developed for [Abap debugger object graph extension](https://github.com/marcellourbani/abap_debugger_object_graph_extension) to give a more compact layout 6 | 7 | ## Example graphs 8 | 9 | From http://zevolving.com/2012/01/iterator-design-pattern-to-access-linked-list/ ) 10 | 11 | ![image](https://user-images.githubusercontent.com/2453277/45267892-94c1da00-b46c-11e8-8759-411cb635c4d2.png) 12 | 13 | Another example from the excellent [Writing Testable Code for ABAP](https://open.sap.com/courses/wtc1) opensap course 14 | ![image](https://user-images.githubusercontent.com/2453277/45267904-ed917280-b46c-11e8-8c6c-d57bd72083fa.png) 15 | -------------------------------------------------------------------------------- /src/demo/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Abap Graph demos 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/demo/zabapgraph_demo.prog.abap: -------------------------------------------------------------------------------- 1 | * 2 | report zabapgraph_demo. 3 | 4 | data: graph type ref to zcl_abap_graph, 5 | ex type ref to cx_root. 6 | 7 | selection-screen begin of screen 1001. 8 | * dummy for triggering screen on Java SAP GUI 9 | selection-screen end of screen 1001. 10 | selection-screen comment /1(50) text-001. 11 | parameters: p_screen radiobutton group dest, 12 | p_file radiobutton group dest. 13 | 14 | 15 | start-of-selection. 16 | try. 17 | perform main. 18 | 19 | catch cx_root into ex. 20 | message ex type 'I'. 21 | endtry. 22 | 23 | class dummy definition. 24 | public section. 25 | class-data: _instance type ref to dummy. 26 | data: tr type e070. 27 | endclass. 28 | 29 | * 30 | form main. 31 | data: gv_html_viewer type ref to cl_gui_html_viewer, 32 | simplenode1 type ref to zcl_abap_graph_node_simple, 33 | simplenode2 type ref to zcl_abap_graph_node_simple, 34 | recordnode type ref to zcl_abap_graph_node_record, 35 | tablenode type ref to zcl_abap_graph_node_table, 36 | partid1 type string, 37 | partid2 type string, 38 | cellattrs type ref to zcl_abap_graph_attr, 39 | partid3 type string. 40 | 41 | try. 42 | graph = zcl_abap_graph=>create( ). 43 | simplenode1 = zcl_abap_graph_node_simple=>create( id = '1' label = 'node 1' graph = graph ). 44 | simplenode2 = zcl_abap_graph_node_simple=>create( id = '2' label = 'node 2' graph = graph ). 45 | 46 | recordnode = zcl_abap_graph_node_record=>create( id = '3' label = 'record' graph = graph escape = abap_false ). 47 | recordnode->addcomponent( name = 'First' value = 'foo' ). 48 | recordnode->addcomponent( name = 'Second' value = 'bar' ). 49 | recordnode->headerattr->set( name = 'bgcolor' value = 'lavender' ). 50 | 51 | partid1 = recordnode->addcomponent( name = 'protected' value = 'protectedv' partid = 'p3' bgcolor = 'yellow' ). 52 | partid2 = recordnode->addcomponent( name = 'private' value = 'privatev' partid = 'p4' bgcolor = 'red' ). 53 | 54 | 55 | tablenode = zcl_abap_graph_node_table=>create( graph = graph id = '"{table1}"' label = 'Table 1' ). 56 | tablenode->setcolumn( id = 'COL1' name = 'First column' ). 57 | tablenode->setcolumn( id = 'COL2' name = 'Second column' ). 58 | tablenode->setcolumn( id = 'COL3' ). 59 | tablenode->setcell( columnid = 'COL1' row = 3 value = '3,1' ). 60 | tablenode->setcell( columnid = 'COL3' row = 1 value = '1,3' ). 61 | 62 | cellattrs = zcl_abap_graph_attr=>create( abap_true ). 63 | cellattrs->set( name = 'bgcolor' value = 'red' ). 64 | 65 | partid3 = tablenode->setcell( columnid = 'COL2' row = 2 value = '2,2' attributes = cellattrs partid = 'central' ). 66 | 67 | simplenode1->linkto( destination = simplenode2->id label = 'link' ). 68 | simplenode1->linkto( recordnode->id ). 69 | recordnode->linkto( source = partid1 destination = partid2 color = 'red' label = 'link between cells' ). 70 | simplenode2->linkto( partid2 ). 71 | simplenode1->linkto( tablenode->id ). 72 | recordnode->linkto( destination = partid3 73 | color = 'green' 74 | label = 'to table center' 75 | source = partid2 ). 76 | 77 | 78 | if p_screen is initial. 79 | zcl_abap_graph_utilities=>show_in_browser( graph ). 80 | else. 81 | 82 | create object gv_html_viewer 83 | exporting 84 | query_table_disabled = abap_true 85 | parent = cl_gui_container=>screen0. 86 | 87 | zcl_abap_graph_utilities=>show_in_viewer( viewer = gv_html_viewer graph = graph ). 88 | 89 | call selection-screen 1001. " trigger screen 90 | endif. 91 | catch cx_root into ex. 92 | message ex type 'I'. 93 | endtry. 94 | 95 | endform. 96 | -------------------------------------------------------------------------------- /src/demo/zabapgraph_demo.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZABAPGRAPH_DEMO 7 | S 8 | 1 9 | X 10 | D$S 11 | X 12 | 13 | 14 | 15 | I 16 | 001 17 | Display on screen might not work in windows 18 | 82 19 | 20 | 21 | R 22 | demo abap graph 23 | 15 24 | 25 | 26 | S 27 | P_FILE 28 | Open graph in browser 29 | 29 30 | 31 | 32 | S 33 | P_SCREEN 34 | Display on screen(java gui) 35 | 35 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Grapg generation classes 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/zabapgraph_string_template.prog.abap: -------------------------------------------------------------------------------- 1 | define agdefinitions. 2 | data: __abapgraph_templ type ref to zcl_abap_graph_string_template. 3 | 4 | field-symbols: <__abapgraph_varname> type string, 5 | <__abapgraph_varvalue> type any. 6 | end-of-definition. 7 | 8 | define agexpand. 9 | __abapgraph_templ = zcl_abap_graph_string_template=>create( &1 ). 10 | loop at __abapgraph_templ->varnames assigning <__abapgraph_varname>. 11 | assign (<__abapgraph_varname>) to <__abapgraph_varvalue>. 12 | if sy-subrc = 0. 13 | __abapgraph_templ->set_variable( name = <__abapgraph_varname> value = <__abapgraph_varvalue> ). 14 | endif. 15 | endloop. 16 | &2 = __abapgraph_templ->render( ). 17 | 18 | end-of-definition. 19 | -------------------------------------------------------------------------------- /src/zabapgraph_string_template.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZABAPGRAPH_STRING_TEMPLATE 7 | I 8 | E 9 | X 10 | 11 | 12 | 13 | R 14 | Include ZABAPGRAPH_STRING_TEMPLATE 15 | 34 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/zcl_abap_graph.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph definition public final create private . 2 | 3 | public section. 4 | constants: c_browser_url type string value 'https://marcellourbani.github.io/Graphviz-browser/index.html#/graph'. 5 | data: default_node_attr type ref to zcl_abap_graph_attr read-only, 6 | default_graph_attr type ref to zcl_abap_graph_attr read-only. 7 | 8 | class-methods create 9 | returning 10 | value(r_result) type ref to zcl_abap_graph. 11 | methods: 12 | generate_html_wrapper 13 | importing baseurl type string default c_browser_url 14 | value(comments) type string optional 15 | returning value(wrapper) type string, 16 | 17 | generate returning value(r_result) type string, 18 | addnode importing node type ref to zif_abap_graph_node, 19 | has_id importing i_id type string 20 | returning value(r_result) type abap_bool, 21 | register_id 22 | importing 23 | id type string, 24 | get_node importing value(nodeid) type string 25 | returning value(node) type ref to zif_abap_graph_node. 26 | 27 | protected section. 28 | private section. 29 | data temp type string. 30 | data uploadpath type string. 31 | data downloadpath type string. 32 | data nodes type zif_abap_graph_node=>tt_node. 33 | data valid_ids type hashed table of string with unique key table_line. 34 | 35 | methods get_defaults 36 | returning 37 | value(r_result) type string. 38 | endclass. 39 | 40 | 41 | 42 | class zcl_abap_graph implementation. 43 | 44 | method create. 45 | 46 | create object r_result. 47 | r_result->default_node_attr = zcl_abap_graph_attr=>create( ). 48 | r_result->default_graph_attr = zcl_abap_graph_attr=>create( ). 49 | r_result->default_node_attr->set( name = 'shape' value = 'record' ). 50 | r_result->default_graph_attr->set( name = 'rankdir' value = 'LR' ). 51 | 52 | endmethod. 53 | 54 | method generate_html_wrapper. 55 | data: lines type table of string, 56 | graphlines type table of string, 57 | graph type string, 58 | iframe type string. 59 | field-symbols: like line of graphlines. 60 | graph = generate( ). 61 | replace all occurrences of '\' in graph with '\\'. 62 | replace all occurrences of '''' in graph with '\'''. 63 | 64 | split graph at cl_abap_char_utilities=>newline into table graphlines. 65 | 66 | concatenate '' to lines, 117 | '' to lines, 118 | '' to lines, 119 | '' to lines. 120 | 121 | concatenate lines of lines into wrapper separated by cl_abap_char_utilities=>cr_lf. 122 | endmethod. 123 | 124 | 125 | method generate. 126 | data: itemcode type string, 127 | nodelinks type zif_abap_graph_node=>tt_link, 128 | nodescode type string, 129 | links type zif_abap_graph_node=>tt_link. 130 | field-symbols: like line of nodes, 131 | like line of links. 132 | agdefinitions. 133 | 134 | loop at nodes assigning . 135 | itemcode = ->render( ). 136 | nodelinks = ->getlinks( ). 137 | append lines of nodelinks to links. 138 | agexpand '{nodescode}\n{itemcode}' nodescode. 139 | endloop. 140 | 141 | loop at links assigning . 142 | clear itemcode. 143 | if -attributes is bound. 144 | itemcode = -attributes->render( ). 145 | endif. 146 | 147 | agexpand '{nodescode}\n{-parentid} -> {-childid}{itemcode};' nodescode. 148 | endloop. 149 | 150 | itemcode = get_defaults( ). 151 | 152 | agexpand 'digraph \{\n{itemcode}\n{nodescode}\n\}' r_result. 153 | 154 | endmethod. 155 | 156 | method addnode. 157 | register_id( node->id ). 158 | append node to nodes. 159 | endmethod. 160 | 161 | 162 | method get_defaults. 163 | data: graphdefaults type string. 164 | 165 | r_result = default_node_attr->render( ). 166 | if not r_result is initial. 167 | concatenate 'node' r_result into r_result. 168 | endif. 169 | 170 | graphdefaults = default_graph_attr->render( ). 171 | if graphdefaults <> ''. 172 | concatenate 'graph' graphdefaults space r_result into r_result respecting blanks. 173 | endif. 174 | endmethod. 175 | 176 | 177 | method has_id. 178 | read table valid_ids with table key table_line = i_id transporting no fields. 179 | if sy-subrc = 0. 180 | r_result = abap_true. 181 | endif. 182 | endmethod. 183 | 184 | 185 | method register_id. 186 | if id is initial. 187 | zcx_abap_graph=>raise( 'A node or node part must have a valid ID' ). 188 | endif. 189 | 190 | if has_id( id ) = abap_true. 191 | zcx_abap_graph=>raise( 'A node or node part must have an unique ID' ). 192 | endif. 193 | 194 | insert id into table valid_ids. 195 | endmethod. 196 | 197 | 198 | method get_node. 199 | field-symbols: like line of nodes. 200 | nodeid = zcl_abap_graph_utilities=>quoteifneeded( nodeid ). 201 | read table valid_ids with table key table_line = nodeid transporting no fields. 202 | 203 | if sy-subrc = 0. 204 | loop at nodes assigning . 205 | if ->id = nodeid. 206 | node = . 207 | exit. 208 | endif. 209 | endloop. 210 | 211 | endif. 212 | 213 | endmethod. 214 | 215 | endclass. 216 | -------------------------------------------------------------------------------- /src/zcl_abap_graph.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for the definition and implementation of 2 | *"* local helper classes, interface definitions and type 3 | *"* declarations 4 | include zabapgraph_string_template. 5 | -------------------------------------------------------------------------------- /src/zcl_abap_graph.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH 7 | E 8 | Graph representation in ABAP 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_attr.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_attr definition public final create private . 2 | public section. 3 | types: begin of ty_attribute, 4 | name type string, 5 | value type string, 6 | end of ty_attribute, 7 | tt_attribute type hashed table of ty_attribute with unique key name. 8 | "a full list of available attributes is at https://graphviz.gitlab.io/_pages/doc/info/attrs.html 9 | constants: atype_label type string value 'label', 10 | atype_shape type string value 'shape', 11 | atype_rankdir type string value 'rankdir', 12 | atype_color type string value 'color', 13 | rankdir_horizontal type string value 'LR', 14 | rankdir_vertical type string value 'TB'. 15 | 16 | class-methods create importing forhtml type abap_bool optional 17 | returning value(r_result) type ref to zcl_abap_graph_attr. 18 | 19 | methods: set importing value(name) type string value(value) type string, 20 | setraw importing name type string value type string, 21 | render returning value(attrstring) type string. 22 | private section. 23 | data: attributes type tt_attribute, 24 | forhtml type abap_bool. 25 | endclass. 26 | 27 | 28 | 29 | class zcl_abap_graph_attr implementation. 30 | 31 | method create. 32 | 33 | create object r_result. 34 | r_result->forhtml = forhtml. 35 | 36 | endmethod. 37 | 38 | method set. 39 | value = zcl_abap_graph_utilities=>quoteifneeded( value ). 40 | setraw( name = name value = value ). 41 | endmethod. 42 | 43 | method render. 44 | field-symbols: like line of attributes. 45 | 46 | agdefinitions. 47 | 48 | loop at attributes assigning . 49 | agexpand '{attrstring} {-name} = {-value}' attrstring. 50 | endloop. 51 | 52 | if attrstring <> '' and forhtml = abap_false. 53 | agexpand '[{attrstring}]' attrstring. 54 | endif. 55 | 56 | endmethod. 57 | 58 | method setraw. 59 | 60 | data: attr type ty_attribute. 61 | delete table attributes with table key name = name. 62 | 63 | if value <> ''. 64 | attr-name = name. 65 | attr-value = value . 66 | insert attr into table attributes. 67 | endif. 68 | 69 | endmethod. 70 | 71 | endclass. 72 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_attr.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for the definition and implementation of 2 | *"* local helper classes, interface definitions and type 3 | *"* declarations 4 | include zabapgraph_string_template. 5 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_attr.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_ATTR 7 | E 8 | attributes for graph nodes and links 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_record.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_node_record definition public final create private . 2 | 3 | public section. 4 | interfaces: zif_abap_graph_node. 5 | aliases: attributes for zif_abap_graph_node~attributes, 6 | id for zif_abap_graph_node~id, 7 | graph for zif_abap_graph_node~graph, 8 | ty_link for zif_abap_graph_node~ty_link, 9 | tt_link for zif_abap_graph_node~tt_link, 10 | getlinks for zif_abap_graph_node~getlinks , 11 | linkto for zif_abap_graph_node~linkto , 12 | render for zif_abap_graph_node~render , 13 | tt_node for zif_abap_graph_node~tt_node , 14 | ty_nod for zif_abap_graph_node~ty_node . 15 | types: begin of ty_component, 16 | name type string, 17 | value type string, 18 | partid type string, 19 | nameattributes like attributes, 20 | valueattributes like attributes, 21 | end of ty_component, 22 | tt_component type table of ty_component. 23 | 24 | data: headerattr like attributes read-only. 25 | 26 | class-methods create importing id type string 27 | label type string optional 28 | graph type ref to zcl_abap_graph 29 | escape type abap_bool default abap_true 30 | returning value(r_result) type ref to zcl_abap_graph_node_record. 31 | methods: addcomponent importing name type string 32 | value type string 33 | escape type abap_bool default abap_true 34 | bgcolor type string optional 35 | value(partid) type string optional 36 | nameattributes like attributes optional 37 | valueattributes like attributes optional 38 | returning value(componentid) type string. 39 | 40 | 41 | protected section. 42 | data: mainlabel type string. 43 | private section. 44 | data: links type tt_link, 45 | components type tt_component. 46 | 47 | methods validatesource 48 | importing 49 | i_source type string. 50 | methods getcomp 51 | importing 52 | partid type string 53 | returning 54 | value(r_result) type string. 55 | 56 | endclass. 57 | 58 | 59 | 60 | class zcl_abap_graph_node_record implementation. 61 | method create. 62 | if not graph is bound. 63 | zcx_abap_graph=>raise( 'A node requires valid parent graph' ). 64 | endif. 65 | create object r_result. 66 | r_result->id = zcl_abap_graph_utilities=>quoteifneeded( id ). 67 | r_result->graph = graph. 68 | r_result->attributes = zcl_abap_graph_attr=>create( ). 69 | if escape = abap_true. 70 | r_result->mainlabel = cl_http_utility=>escape_html( label ). 71 | else. 72 | r_result->mainlabel = label . 73 | endif. 74 | r_result->attributes->set( name = 'shape' value = 'plaintext' ). 75 | r_result->headerattr = zcl_abap_graph_attr=>create( abap_true ). 76 | graph->addnode( r_result ). 77 | endmethod. 78 | 79 | method zif_abap_graph_node~getlinks. 80 | links = me->links. 81 | endmethod. 82 | 83 | method zif_abap_graph_node~linkto. 84 | data: esclabel type string. 85 | field-symbols: like line of links. 86 | 87 | append initial line to links assigning . 88 | if source = ''. 89 | -parentid = id. 90 | else. 91 | validatesource( source ). 92 | -parentid = source. 93 | endif. 94 | if graph->has_id( destination ) = abap_false. 95 | zcx_abap_graph=>raise( 'Destination must be a valid part of the node' ). 96 | endif. 97 | -childid = destination. 98 | -attributes = zcl_abap_graph_attr=>create( ). 99 | esclabel = cl_http_utility=>escape_html( label ). 100 | -attributes->set( name = 'label' value = esclabel ). 101 | -attributes->set( name = 'color' value = color ). 102 | -attributes->set( name = 'fontcolor' value = color ). 103 | endmethod. 104 | 105 | method zif_abap_graph_node~render. 106 | data: temp type string, 107 | nameattr type string, 108 | valueattr type string, 109 | comp type string. 110 | 111 | field-symbols: like line of components. 112 | agdefinitions. 113 | 114 | temp = headerattr->render( ). 115 | 116 | agexpand '<\n' 117 | temp. 118 | 119 | 120 | loop at components assigning . 121 | comp = getcomp( -partid ). 122 | nameattr = -nameattributes->render( ). 123 | valueattr = -valueattributes->render( ). 124 | agexpand '{temp}\n{-name}{-value}' temp. 125 | endloop. 126 | agexpand '{temp}\n
{mainlabel}
>' temp. 127 | 128 | attributes->setraw( name = 'label' value = temp ). 129 | temp = attributes->render( ). 130 | 131 | agexpand '{id}{temp};' dotsource. 132 | 133 | endmethod. 134 | 135 | method addcomponent. 136 | 137 | field-symbols: like line of components. 138 | 139 | if partid <> ''. 140 | partid = zcl_abap_graph_utilities=>quoteifneeded( partid ). 141 | concatenate id ':' partid into componentid. 142 | "will raise an exception for invalid/already used IDs 143 | graph->register_id( componentid ). 144 | endif. 145 | 146 | append initial line to components assigning . 147 | 148 | -name = name. 149 | -partid = partid. 150 | if escape = abap_true. 151 | -value = cl_http_utility=>escape_html( value ). 152 | else. 153 | -value = value . 154 | endif. 155 | if nameattributes is bound. 156 | -nameattributes = nameattributes. 157 | else. 158 | -nameattributes = zcl_abap_graph_attr=>create( abap_true ). 159 | endif. 160 | if valueattributes is bound. 161 | -valueattributes = valueattributes. 162 | else. 163 | -valueattributes = zcl_abap_graph_attr=>create( abap_true ). 164 | endif. 165 | if bgcolor <> ''. 166 | -nameattributes->set( name = 'bgcolor' value = bgcolor ). 167 | -valueattributes->set( name = 'bgcolor' value = bgcolor ). 168 | endif. 169 | 170 | endmethod. 171 | 172 | 173 | method validatesource. 174 | data: parent type string, 175 | child type string. 176 | if graph->has_id( i_source ) = abap_true. 177 | find regex '(".+"):(".+")$' in i_source submatches parent child. 178 | endif. 179 | if sy-subrc <> 0 or parent <> id. 180 | zcx_abap_graph=>raise( 'Source must be a valid part of the node' ). 181 | endif. 182 | endmethod. 183 | 184 | 185 | method getcomp. 186 | if partid <> ''. 187 | concatenate ' port=' partid ' ' into r_result respecting blanks. 188 | endif. 189 | endmethod. 190 | 191 | endclass. 192 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_record.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for the definition and implementation of 2 | *"* local helper classes, interface definitions and type 3 | *"* declarations 4 | include zabapgraph_string_template. 5 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_record.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_NODE_RECORD 7 | E 8 | Name-value pairs in a table 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_simple.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_node_simple definition public final create private . 2 | 3 | public section. 4 | interfaces: zif_abap_graph_node. 5 | aliases: attributes for zif_abap_graph_node~attributes, 6 | id for zif_abap_graph_node~id, 7 | graph for zif_abap_graph_node~graph, 8 | ty_link for zif_abap_graph_node~ty_link, 9 | tt_link for zif_abap_graph_node~tt_link, 10 | getlinks for zif_abap_graph_node~getlinks , 11 | linkto for zif_abap_graph_node~linkto , 12 | render for zif_abap_graph_node~render , 13 | tt_node for zif_abap_graph_node~tt_node , 14 | ty_nod for zif_abap_graph_node~ty_node . 15 | class-methods create importing id type string 16 | graph type ref to zcl_abap_graph 17 | value(label) type string optional 18 | value(shape) type string optional 19 | returning value(r_result) type ref to zcl_abap_graph_node_simple. 20 | protected section. 21 | private section. 22 | data links type tt_link. 23 | 24 | endclass. 25 | 26 | 27 | 28 | class zcl_abap_graph_node_simple implementation. 29 | 30 | 31 | method create. 32 | if not graph is bound. 33 | zcx_abap_graph=>raise( 'A node requires valid parent graph' ). 34 | endif. 35 | 36 | create object r_result. 37 | r_result->id = zcl_abap_graph_utilities=>quoteifneeded( id ). 38 | r_result->attributes = zcl_abap_graph_attr=>create( ). 39 | label = cl_http_utility=>escape_html( label ). 40 | label = zcl_abap_graph_utilities=>quoteifneeded( label ). 41 | shape = zcl_abap_graph_utilities=>quoteifneeded( shape ). 42 | r_result->attributes->set( name = 'label' value = label ). 43 | r_result->attributes->set( name = 'shape' value = shape ). 44 | graph->addnode( r_result ). 45 | 46 | endmethod. 47 | 48 | method zif_abap_graph_node~getlinks. 49 | links = me->links. 50 | endmethod. 51 | 52 | method zif_abap_graph_node~linkto. 53 | field-symbols: like line of links. 54 | 55 | append initial line to links assigning . 56 | -parentid = id."ignore source for simple nodes 57 | -childid = destination. 58 | -attributes = zcl_abap_graph_attr=>create( ). 59 | -attributes->set( name = 'label' value = label ). 60 | -attributes->set( name = 'color' value = color ). 61 | -attributes->set( name = 'fontcolor' value = color ). 62 | endmethod. 63 | 64 | 65 | method zif_abap_graph_node~render. 66 | data: attstr type string. 67 | 68 | attstr = attributes->render( ). 69 | concatenate id attstr ';' into dotsource. 70 | 71 | endmethod. 72 | endclass. 73 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_simple.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_NODE_SIMPLE 7 | E 8 | simple graph node 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_table.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_node_table definition public final create private . 2 | 3 | public section. 4 | 5 | interfaces zif_abap_graph_node . 6 | 7 | aliases attributes for zif_abap_graph_node~attributes . 8 | aliases graph for zif_abap_graph_node~graph . 9 | aliases id for zif_abap_graph_node~id . 10 | aliases getlinks for zif_abap_graph_node~getlinks . 11 | aliases linkto for zif_abap_graph_node~linkto . 12 | aliases render for zif_abap_graph_node~render . 13 | aliases tt_link for zif_abap_graph_node~tt_link . 14 | aliases tt_node for zif_abap_graph_node~tt_node . 15 | aliases ty_link for zif_abap_graph_node~ty_link . 16 | aliases ty_nod for zif_abap_graph_node~ty_node . 17 | 18 | types: 19 | begin of ty_column, 20 | id type string, 21 | name type string, 22 | end of ty_column, 23 | begin of ty_cell, 24 | columnid type string, 25 | value type string, 26 | partid type string, 27 | attributes type ref to zcl_abap_graph_attr, 28 | end of ty_cell, 29 | ty_line type hashed table of ty_cell with unique key columnid. 30 | 31 | data: headerattr like attributes, 32 | titleattr like attributes. 33 | 34 | class-methods create 35 | importing 36 | id type string 37 | label type string optional 38 | graph type ref to zcl_abap_graph 39 | escape type abap_bool default abap_true 40 | returning 41 | value(r_result) type ref to zcl_abap_graph_node_table . 42 | methods: 43 | setcolumn importing id type string name type string optional, 44 | setcell importing 45 | columnid type string 46 | row type i 47 | value type string 48 | escape type abap_bool default abap_true 49 | value(partid) type string optional 50 | attributes type ref to zcl_abap_graph_attr optional 51 | returning 52 | value(componentid) type string . 53 | protected section. 54 | data: mainlabel type string. 55 | private section. 56 | data: links type tt_link, 57 | columns type standard table of ty_column with key id, 58 | cells type standard table of ty_line. 59 | 60 | methods validatesource 61 | importing 62 | i_source type string. 63 | methods getcomp 64 | importing 65 | partid type string 66 | returning 67 | value(r_result) type string. 68 | methods check_column 69 | importing 70 | i_columnid type string. 71 | methods hasheaders 72 | returning 73 | value(r_result) type abap_bool. 74 | methods get_cell 75 | importing 76 | line type zcl_abap_graph_node_table=>ty_line 77 | columnid type string 78 | returning 79 | value(r_result) type string. 80 | 81 | endclass. 82 | 83 | 84 | 85 | class zcl_abap_graph_node_table implementation. 86 | 87 | 88 | method check_column. 89 | 90 | read table columns with key id = i_columnid transporting no fields. 91 | if sy-subrc <> 0. 92 | zcx_abap_graph=>raise( 'A node or node part must have a valid ID' ). 93 | endif. 94 | 95 | endmethod. 96 | 97 | 98 | method create. 99 | 100 | if not graph is bound. 101 | zcx_abap_graph=>raise( 'A node requires valid parent graph' ). 102 | endif. 103 | create object r_result. 104 | r_result->id = zcl_abap_graph_utilities=>quoteifneeded( id ). 105 | r_result->graph = graph. 106 | r_result->attributes = zcl_abap_graph_attr=>create( ). 107 | if escape = abap_true. 108 | r_result->mainlabel = cl_http_utility=>escape_html( label ). 109 | else. 110 | r_result->mainlabel = label . 111 | endif. 112 | r_result->attributes->set( name = 'shape' value = 'plaintext' ). 113 | r_result->headerattr = zcl_abap_graph_attr=>create( abap_true ). 114 | r_result->titleattr = zcl_abap_graph_attr=>create( abap_true ). 115 | graph->addnode( r_result ). 116 | 117 | endmethod. 118 | 119 | 120 | method getcomp. 121 | if partid <> ''. 122 | concatenate ' port=' partid ' ' into r_result respecting blanks. 123 | endif. 124 | endmethod. 125 | 126 | 127 | method get_cell. 128 | data: attrtext type string, 129 | porttext type string. 130 | field-symbols: like line of line. 131 | agdefinitions. 132 | 133 | read table line with table key columnid = columnid assigning . 134 | if sy-subrc = 0. 135 | porttext = getcomp( -partid ). 136 | if -attributes is bound. 137 | attrtext = -attributes->render( ). 138 | agexpand '{-value}' r_result. 139 | else. 140 | agexpand '{-value}' r_result. 141 | endif. 142 | else. 143 | r_result = ''. 144 | endif. 145 | endmethod. 146 | 147 | 148 | method hasheaders. 149 | loop at columns transporting no fields where name <> ''. 150 | r_result = abap_true. 151 | exit. 152 | endloop. 153 | endmethod. 154 | 155 | 156 | method setcell. 157 | data: numlines type i, 158 | missing type i, 159 | cell type ty_cell. 160 | 161 | field-symbols: like line of cells. 162 | 163 | check_column( columnid ). 164 | if partid <> ''. 165 | partid = zcl_abap_graph_utilities=>quoteifneeded( partid ). 166 | concatenate id ':' partid into componentid. 167 | "will raise an exception for invalid/already used IDs 168 | graph->register_id( componentid ). 169 | endif. 170 | read table cells index row assigning . 171 | if sy-subrc <> 0. 172 | numlines = lines( cells ). 173 | missing = row - numlines. 174 | do missing times. 175 | append initial line to cells assigning . 176 | enddo. 177 | endif. 178 | 179 | delete table with table key columnid = columnid. 180 | cell-columnid = columnid. 181 | cell-partid = partid. 182 | if escape = abap_true. 183 | cell-value = cl_http_utility=>escape_html( value ). 184 | else. 185 | cell-value = value . 186 | endif. 187 | cell-attributes = attributes. 188 | insert cell into table . 189 | 190 | endmethod. 191 | 192 | 193 | method setcolumn. 194 | field-symbols: like line of columns. 195 | 196 | delete columns where id = id. 197 | append initial line to columns assigning . 198 | 199 | -id = id. 200 | -name = name. 201 | endmethod. 202 | 203 | 204 | method validatesource. 205 | data: parent type string, 206 | child type string. 207 | if graph->has_id( i_source ) = abap_true. 208 | find regex '(".+"):(".+")$' in i_source submatches parent child. 209 | endif. 210 | if sy-subrc <> 0 or parent <> id. 211 | zcx_abap_graph=>raise( 'Source must be a valid part of the node' ). 212 | endif. 213 | endmethod. 214 | 215 | 216 | method zif_abap_graph_node~getlinks. 217 | links = me->links. 218 | endmethod. 219 | 220 | 221 | method zif_abap_graph_node~linkto. 222 | data: partid type string, 223 | mainid type string. 224 | field-symbols: like line of links. 225 | 226 | append initial line to links assigning . 227 | if source = ''. 228 | -parentid = id. 229 | else. 230 | validatesource( source ). 231 | -parentid = source. 232 | endif. 233 | if graph->has_id( destination ) = abap_false. 234 | zcx_abap_graph=>raise( 'Destination must be a valid part of the node' ). 235 | endif. 236 | -childid = destination. 237 | -attributes = zcl_abap_graph_attr=>create( ). 238 | -attributes->set( name = 'label' value = label ). 239 | -attributes->set( name = 'color' value = color ). 240 | -attributes->set( name = 'fontcolor' value = color ). 241 | endmethod. 242 | 243 | 244 | method zif_abap_graph_node~render. 245 | data: temp type string, 246 | comp type string, 247 | numcols type string, 248 | item type string, 249 | cellcode type string, 250 | attrs type string. 251 | field-symbols: like line of columns, 252 | like line of cells. 253 | 254 | * field-symbols: like line of components. 255 | agdefinitions. 256 | 257 | numcols = lines( columns ). 258 | agexpand '<' dotsource. 259 | "table title/name 260 | if mainlabel <> ''. 261 | headerattr->set( name = 'colspan' value = numcols ). 262 | attrs = headerattr->render( ). 263 | agexpand '{dotsource}{mainlabel}' dotsource. 264 | endif. 265 | 266 | "column headers 267 | if hasheaders( ) = abap_true. 268 | temp = ''. 269 | attrs = titleattr->render( ). 270 | loop at columns assigning . 271 | item = -name. 272 | if -name is initial. 273 | item = -id. 274 | endif. 275 | agexpand '{temp}{item}' temp. 276 | endloop. 277 | agexpand '{dotsource}\n{temp}' dotsource. 278 | endif. 279 | 280 | "table contents 281 | loop at cells assigning . 282 | temp = ''. 283 | loop at columns assigning . 284 | item = get_cell( line = columnid = -id ). 285 | concatenate temp item into temp respecting blanks. 286 | endloop. 287 | agexpand '{dotsource}\n{temp}' dotsource. 288 | endloop. 289 | 290 | agexpand '{dotsource}\n
>' dotsource. 291 | 292 | attributes->setraw( name = 'label' value = dotsource ). 293 | temp = attributes->render( ). 294 | 295 | agexpand '{id}{temp};' dotsource. 296 | 297 | endmethod. 298 | endclass. 299 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_table.clas.locals_imp.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for the definition and implementation of 2 | *"* local helper classes, interface definitions and type 3 | *"* declarations 4 | include zabapgraph_string_template. 5 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_node_table.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_NODE_TABLE 7 | E 8 | Name-value pairs in a table 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_string_template.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_string_template definition public create public . 2 | 3 | public section. 4 | 5 | data template type string read-only . 6 | data: 7 | varnames type table of string read-only . 8 | data varvalues type tihttpnvp read-only . 9 | data var_not_found type flag read-only . 10 | 11 | class-methods create 12 | importing 13 | !i_template type csequence 14 | returning 15 | value(r_result) type ref to zcl_abap_graph_string_template . 16 | methods set_variable 17 | importing 18 | !name type string 19 | !value type any . 20 | methods render 21 | returning 22 | value(output) type string . 23 | protected section. 24 | private section. 25 | 26 | types: 27 | begin of ty_chunk, 28 | offset type i, 29 | length type i, 30 | replace type flag, 31 | variablename type string, 32 | value type string, 33 | end of ty_chunk . 34 | 35 | data: 36 | chunks type table of ty_chunk . 37 | 38 | methods parse . 39 | methods decode 40 | importing 41 | !encoded type string 42 | returning 43 | value(decoded) type string . 44 | methods varname 45 | importing 46 | !match type string 47 | returning 48 | value(varname) type string . 49 | methods get_var_value 50 | importing 51 | !i_variablename type string 52 | returning 53 | value(r_result) type string . 54 | ENDCLASS. 55 | 56 | 57 | 58 | CLASS ZCL_ABAP_GRAPH_STRING_TEMPLATE IMPLEMENTATION. 59 | 60 | 61 | method create. 62 | 63 | 64 | create object r_result. 65 | 66 | r_result->template = i_template. 67 | r_result->parse( ). 68 | 69 | 70 | endmethod. 71 | 72 | 73 | method decode. 74 | 75 | case encoded. 76 | when '\T'. 77 | decoded = cl_abap_char_utilities=>horizontal_tab. 78 | when '\N'. 79 | decoded = cl_abap_char_utilities=>newline. 80 | when '\R'. 81 | decoded = cl_abap_char_utilities=>cr_lf(1). 82 | when '\F'. 83 | decoded = cl_abap_char_utilities=>form_feed. 84 | when others. 85 | decoded = encoded+1. 86 | endcase. 87 | 88 | 89 | endmethod. 90 | 91 | 92 | method get_var_value. 93 | 94 | field-symbols: like line of varvalues. 95 | read table varvalues assigning with key name = i_variablename. 96 | if sy-subrc = 0. 97 | r_result = -value. 98 | else. 99 | var_not_found = 'X'. 100 | endif. 101 | 102 | endmethod. 103 | 104 | 105 | method parse. 106 | 107 | data: regex type ref to cl_abap_regex, 108 | matcher type ref to cl_abap_matcher, 109 | matches type match_result_tab, 110 | lastchunk like line of chunks, 111 | tmp type string. 112 | field-symbols: like line of matches, 113 | like line of chunks. 114 | 115 | create object regex 116 | exporting 117 | pattern = 118 | '(\\.)|(\{\s*(?:(?:[a-zA-Z_][a-z_0-9]*)|(?:<[a-zA-Z_][a-z_0-9]*>))(?:(?:->?|=>)[a-zA-Z_][a-z_0-9]*)*\s*\})' 119 | ignore_case = abap_false. 120 | 121 | matcher = regex->create_matcher( text = template ). 122 | matches = matcher->find_all( ). 123 | sort matches by offset. 124 | 125 | loop at matches assigning . 126 | append initial line to chunks assigning . 127 | "if there's something between matches, add it 128 | lastchunk-offset = lastchunk-offset + lastchunk-length. 129 | if lastchunk-offset < -offset. 130 | -length = -offset - lastchunk-offset. 131 | -offset = lastchunk-offset. 132 | append initial line to chunks assigning . 133 | endif. 134 | "now the actual variable to be replaced 135 | -length = -length. 136 | -offset = -offset. 137 | -replace = 'X'. 138 | tmp = template+-offset(-length). 139 | translate tmp to upper case. 140 | if tmp(1) = '\'. 141 | -value = decode( tmp ). 142 | else. 143 | -variablename = varname( tmp ). 144 | endif. 145 | lastchunk = . 146 | 147 | endloop. 148 | lastchunk-offset = lastchunk-offset + lastchunk-length. 149 | if strlen( template ) > lastchunk-offset. 150 | append initial line to chunks assigning . 151 | -length = strlen( template ) - lastchunk-offset. 152 | -offset = lastchunk-offset. 153 | endif. 154 | 155 | endmethod. 156 | 157 | 158 | method render. 159 | 160 | data: varvalue type string. 161 | 162 | field-symbols: like line of chunks, 163 | type data. 164 | 165 | loop at chunks assigning . 166 | if -replace = ''. 167 | concatenate output template+-offset(-length) into output respecting blanks. 168 | elseif -variablename = ''. 169 | concatenate output -value into output respecting blanks. 170 | else. 171 | varvalue = get_var_value( -variablename ). 172 | concatenate output varvalue into output respecting blanks. 173 | endif. 174 | endloop. 175 | 176 | 177 | endmethod. 178 | 179 | 180 | method set_variable. 181 | 182 | data: var like line of varvalues, 183 | td type ref to cl_abap_typedescr, 184 | temp(50) type c. 185 | 186 | var-name = name. 187 | translate var-name to upper case. 188 | 189 | td = cl_abap_typedescr=>describe_by_data( value ). 190 | if td->kind = cl_abap_typedescr=>kind_elem. 191 | case td->type_kind. 192 | when cl_abap_typedescr=>typekind_float. 193 | if value < 1000000000. 194 | write value to temp style cl_abap_format=>o_simple. 195 | else. 196 | write value to temp style cl_abap_format=>o_engineering. 197 | endif. 198 | var-value = temp. 199 | condense var-value no-gaps. 200 | when cl_abap_typedescr=>typekind_date 201 | or cl_abap_typedescr=>typekind_time 202 | or cl_abap_typedescr=>typekind_decfloat 203 | or cl_abap_typedescr=>typekind_decfloat16 204 | or cl_abap_typedescr=>typekind_decfloat34. 205 | write value to temp. 206 | var-value = temp. 207 | condense var-value. 208 | when cl_abap_typedescr=>typekind_int 209 | or cl_abap_typedescr=>typekind_int1 210 | or '8' " cl_abap_typedescr=>typekind_int8 211 | or cl_abap_typedescr=>typekind_int2 212 | or cl_abap_typedescr=>typekind_hex. 213 | var-value = value. 214 | condense var-value. 215 | when others. 216 | var-value = value. 217 | endcase. 218 | endif. 219 | delete varvalues where name = var-name. 220 | append var to varvalues. 221 | 222 | endmethod. 223 | 224 | 225 | method varname. 226 | 227 | data: l type i. 228 | l = strlen( match ) - 2. 229 | varname = match+1(l). 230 | condense varname no-gaps. 231 | collect varname into varnames. 232 | 233 | endmethod. 234 | ENDCLASS. 235 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_string_template.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for your ABAP unit test classes 2 | include zabapgraph_string_template. 3 | class dummy definition for testing. 4 | public section. 5 | class-data: instance type ref to dummy. 6 | data: strvalue type string value 'Astring', 7 | intvalue type i value 1234, 8 | e070 type e070. 9 | endclass. 10 | class test_template definition for testing inheriting from cl_aunit_assert."#AU Risk_Level Harmless #AU Duration Short 11 | private section. 12 | methods: simple_values for testing, 13 | class_members for testing, 14 | indirect for testing, 15 | escapes for testing, 16 | fieldsymbols for testing. 17 | 18 | 19 | endclass. 20 | 21 | class test_template implementation. 22 | 23 | method class_members. 24 | data: result type string, 25 | obj type ref to dummy. 26 | 27 | agdefinitions. 28 | SET COUNTRY 'DE'. "for date formats 29 | create object obj. 30 | obj->e070-trkorr = 'NPLK900001'. 31 | obj->e070-as4date = '20100112'. 32 | 33 | agexpand 'A{obj->e070-trkorr}B{obj->intvalue}C{ obj->e070-as4date }D{obj->e070-as4time}.' result. 34 | assert_equals( act = result exp = 'ANPLK900001B1234C12.01.2010D00:00:00.' ). 35 | 36 | endmethod. 37 | 38 | method indirect. 39 | data: result type string. 40 | 41 | agdefinitions. 42 | SET COUNTRY 'US'. "for date formats 43 | create object dummy=>instance. 44 | dummy=>instance->e070-trkorr = 'NPLK900001'. 45 | dummy=>instance->e070-as4date = '20100112'. 46 | 47 | agexpand 'A{dummy=>instance->e070-trkorr}B{dummy=>instance->intvalue}C{ dummy=>instance->instance->e070-as4date }.' result. 48 | assert_equals( act = result exp = 'ANPLK900001B1234C01/12/2010.' ). 49 | 50 | endmethod. 51 | 52 | method simple_values. 53 | data: str1 type string value 'foo', 54 | float1 type f value '1.25', 55 | result type string. 56 | 57 | agdefinitions. 58 | SET COUNTRY 'US'. "for decimal separators 59 | 60 | agexpand 'string={str1} float = { float1 }.' result. 61 | assert_equals( act = result exp = 'string=foo float = 1.25.' ). 62 | 63 | float1 = float1 * 1000000000. 64 | 65 | agexpand 'string={str1} float = { float1 }.' result. 66 | assert_equals( act = result exp = 'string=foo float = 1.25E+09.' ). 67 | 68 | endmethod. 69 | 70 | method escapes. 71 | data: str1 type string value 'foo', 72 | result type string, 73 | expected type string. 74 | 75 | agdefinitions. 76 | 77 | agexpand '{str1} tab\tnewline\nff\fcrlf\r\n.' result. 78 | concatenate 'foo tab' cl_abap_char_utilities=>horizontal_tab 79 | 'newline' cl_abap_char_utilities=>newline 80 | 'ff' cl_abap_char_utilities=>form_feed 81 | 'crlf' cl_abap_char_utilities=>cr_lf 82 | '.' into expected. 83 | assert_equals( act = result exp = expected ). 84 | 85 | endmethod. 86 | 87 | method fieldsymbols. 88 | data: str1 type string value 'foo', 89 | result type string. 90 | 91 | field-symbols: type any. 92 | 93 | agdefinitions. 94 | assign str1 to . 95 | 96 | agexpand '{}' result. 97 | 98 | assert_equals( act = result exp = 'foo' ). 99 | 100 | 101 | endmethod. 102 | 103 | endclass. 104 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_string_template.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 7 | E 8 | 1 9 | X 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 17 | CHUNKS 18 | E 19 | CHUNKS 20 | 21 | 22 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 23 | CREATE 24 | E 25 | CREATE 26 | 27 | 28 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 29 | DECODE 30 | E 31 | DECODE 32 | 33 | 34 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 35 | GET_VAR_VALUE 36 | E 37 | GET_VAR_VALUE 38 | 39 | 40 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 41 | PARSE 42 | E 43 | PARSE 44 | 45 | 46 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 47 | RENDER 48 | E 49 | RENDER 50 | 51 | 52 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 53 | SET_VARIABLE 54 | E 55 | SET_VARIABLE 56 | 57 | 58 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 59 | TEMPLATE 60 | E 61 | TEMPLATE 62 | 63 | 64 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 65 | TY_CHUNK 66 | E 67 | TY_CHUNK 68 | 69 | 70 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 71 | VARNAME 72 | E 73 | VARNAME 74 | 75 | 76 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 77 | VARNAMES 78 | E 79 | VARNAMES 80 | 81 | 82 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 83 | VARVALUES 84 | E 85 | VARVALUES 86 | 87 | 88 | ZCL_ABAP_GRAPH_STRING_TEMPLATE 89 | VAR_NOT_FOUND 90 | E 91 | VAR_NOT_FOUND 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_utilities.clas.abap: -------------------------------------------------------------------------------- 1 | class zcl_abap_graph_utilities definition public final create public . 2 | public section. 3 | class-methods: quoteifneeded importing raw type string 4 | returning value(escaped) type string, 5 | show_in_browser importing graph type ref to zcl_abap_graph 6 | comments type string optional, 7 | show_in_viewer importing graph type ref to zcl_abap_graph 8 | viewer type ref to cl_gui_html_viewer, 9 | get_temp_file_url returning value(r_result) type string. 10 | private section. 11 | class-data uploadpath type string. 12 | class-data downloadpath type string. 13 | endclass. 14 | 15 | 16 | 17 | class zcl_abap_graph_utilities implementation. 18 | method quoteifneeded. 19 | data: first type c. 20 | if raw <> ''. 21 | first = raw. 22 | if first <> '"'. 23 | concatenate '"' raw '"' into escaped respecting blanks. 24 | else. 25 | escaped = raw. 26 | endif. 27 | endif. 28 | 29 | endmethod. 30 | 31 | method show_in_browser. 32 | data: url type string, 33 | contents type string, 34 | itab type table of string. 35 | 36 | url = get_temp_file_url( ). 37 | contents = graph->generate_html_wrapper( comments = comments ). 38 | append contents to itab. 39 | if url <> ''. 40 | call function 'GUI_DOWNLOAD' 41 | exporting 42 | filename = url 43 | tables 44 | data_tab = itab 45 | exceptions 46 | others = 22. 47 | endif. 48 | if sy-subrc <> 0 or url = ''. 49 | zcx_abap_graph=>raise( 'Error writing graph file' ). 50 | endif. 51 | 52 | cl_gui_frontend_services=>execute( 53 | exporting 54 | document = url 55 | operation = ' ' 56 | exceptions 57 | file_extension_unknown = 1 58 | file_not_found = 2 59 | path_not_found = 3 60 | error_execute_failed = 4 61 | error_no_gui = 6 62 | others = 7 ). 63 | if sy-subrc <> 0. 64 | zcx_abap_graph=>raise( 'Failed to open URL' ). 65 | endif. 66 | 67 | endmethod. 68 | 69 | method show_in_viewer. 70 | data: contents type string, 71 | xstrcont type xstring, 72 | url type w3url, 73 | xdatatab type table of w3_mime, " RAW255 74 | size type int4. 75 | 76 | contents = graph->generate_html_wrapper( ). 77 | 78 | call function 'SCMS_STRING_TO_XSTRING' 79 | exporting 80 | text = contents 81 | importing 82 | buffer = xstrcont 83 | exceptions 84 | others = 1. 85 | 86 | 87 | call function 'SCMS_XSTRING_TO_BINARY' 88 | exporting 89 | buffer = xstrcont 90 | importing 91 | output_length = size 92 | tables 93 | binary_tab = xdatatab. 94 | 95 | viewer->load_data( 96 | exporting 97 | size = size 98 | importing 99 | assigned_url = url 100 | changing 101 | data_table = xdatatab 102 | exceptions 103 | others = 1 ) ##NO_TEXT. 104 | 105 | viewer->show_url( url ). 106 | endmethod. 107 | 108 | method get_temp_file_url. 109 | data: separator type c, 110 | guid type guid_32. 111 | 112 | cl_gui_frontend_services=>get_file_separator( 113 | changing 114 | file_separator = separator 115 | exceptions 116 | others = 4 ). 117 | if sy-subrc = 0. 118 | cl_gui_frontend_services=>get_upload_download_path( 119 | changing 120 | upload_path = uploadpath 121 | download_path = downloadpath 122 | exceptions 123 | others = 6 ). 124 | endif. 125 | if sy-subrc = 0. 126 | call function 'GUID_CREATE' 127 | importing 128 | ev_guid_32 = guid. 129 | 130 | if downloadpath is initial. 131 | 132 | concatenate guid '.html' into r_result. 133 | 134 | else. 135 | 136 | concatenate downloadpath separator guid '.html' into r_result. 137 | 138 | endif. 139 | endif. 140 | endmethod. 141 | 142 | endclass. 143 | -------------------------------------------------------------------------------- /src/zcl_abap_graph_utilities.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_ABAP_GRAPH_UTILITIES 7 | E 8 | utility methods 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcx_abap_graph.clas.abap: -------------------------------------------------------------------------------- 1 | class zcx_abap_graph definition public inheriting from cx_no_check create public . 2 | 3 | public section. 4 | 5 | constants zcx_abap_graph type sotr_conc value '0242AC1100021EE8AB9BDF0D95850806' ##NO_TEXT. 6 | class-methods raise 7 | importing 8 | previous like previous optional 9 | errormessage type csequence. 10 | data errormessage type string . 11 | 12 | methods constructor 13 | importing 14 | !textid like textid optional 15 | !previous like previous optional 16 | !errormessage type string optional . 17 | protected section. 18 | private section. 19 | endclass. 20 | 21 | 22 | 23 | class zcx_abap_graph implementation. 24 | 25 | method raise. 26 | 27 | data: exc type ref to zcx_abap_graph, 28 | messagetext type string. 29 | 30 | messagetext = errormessage. 31 | 32 | create object exc 33 | exporting 34 | textid = zcx_abap_graph 35 | previous = previous 36 | errormessage = messagetext. 37 | 38 | raise exception exc. 39 | 40 | endmethod. 41 | 42 | 43 | method constructor ##ADT_SUPPRESS_GENERATION. 44 | super->constructor( textid = textid previous = previous ). 45 | if textid is initial. 46 | me->textid = zcx_abap_graph . 47 | endif. 48 | me->errormessage = errormessage . 49 | endmethod. 50 | endclass. 51 | -------------------------------------------------------------------------------- /src/zcx_abap_graph.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCX_ABAP_GRAPH 7 | E 8 | Abap graph exception 9 | 40 10 | 1 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 |
18 | 0242AC1100021EE8AB9BDF0D95850806 19 | E 20 | 1 21 | CA== 22 |
23 | 24 | 25 | 0242AC1100021EE8AB9BDF0D95850806 26 | E 27 | 0001 28 | X 29 | R 30 | 255 31 | &errormessage& 32 | 33 | 34 |
35 |
36 | 37 | 38 | ZCX_ABAP_GRAPH 39 | CONSTRUCTOR 40 | E 41 | CONSTRUCTOR 42 | 43 | 44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /src/zif_abap_graph_node.intf.abap: -------------------------------------------------------------------------------- 1 | interface zif_abap_graph_node public. 2 | types: begin of ty_link, 3 | parentid type string, 4 | childid type string, 5 | attributes type ref to zcl_abap_graph_attr, 6 | end of ty_link, 7 | tt_link type table of ty_link with key parentid childid, 8 | ty_node type ref to zif_abap_graph_node, 9 | tt_node type table of ty_node with default key. 10 | data: id type string read-only, 11 | graph type ref to zcl_abap_graph read-only, 12 | attributes type ref to zcl_abap_graph_attr read-only. 13 | 14 | methods: render returning value(dotsource) type string, 15 | linkto importing destination type string 16 | color type string optional 17 | label type string optional 18 | source type string optional 19 | returning value(link) type ty_link, 20 | getlinks returning value(links) type tt_link. 21 | 22 | endinterface. 23 | -------------------------------------------------------------------------------- /src/zif_abap_graph_node.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_ABAP_GRAPH_NODE 7 | E 8 | Graph node 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | --------------------------------------------------------------------------------