├── src
├── zif_i_a2cc_aggregator.intf.abap
├── zcx_i_a2cc_metrics_impl_error.clas.abap
├── package.devc.xml
├── zif_i_a2cc_metrics_2_json.intf.abap
├── zif_i_a2cc_dependency_analyzer.intf.abap
├── zif_i_a2cc_where_used_provider.intf.abap
├── zif_i_a2cc_package_analyzer.intf.abap
├── zif_i_a2cc_where_used.intf.xml
├── zif_i_a2cc_aggregator.intf.xml
├── zif_i_a2cc_metrics_2_json.intf.xml
├── zif_i_a2cc_package_analyzer.intf.xml
├── zcl_i_a2cc_factory.clas.xml
├── zif_i_a2cc_dependency_analyzer.intf.xml
├── zif_i_a2cc_where_used_provider.intf.xml
├── zcl_i_a2cc_metrics_2_json.clas.xml
├── zcl_i_a2cc_metrics_runner.clas.xml
├── zcl_i_a2cc_aggregator_class.clas.xml
├── zcl_i_a2cc_metrics_file_writer.clas.xml
├── zcl_i_a2cc_package_analyzer.clas.xml
├── zcl_i_a2cc_where_used_clas.clas.xml
├── zcl_i_a2cc_where_used_func.clas.xml
├── zcl_i_a2cc_aggregator_package.clas.xml
├── zcl_i_a2cc_dpndncy_anlyzr_clas.clas.xml
├── zcl_i_a2cc_dpndncy_anlyzr_devc.clas.xml
├── zcl_i_a2cc_where_used_abstract.clas.xml
├── zcx_i_a2cc_metrics_impl_error.clas.xml
├── zcl_i_a2cc_where_used_provider.clas.xml
├── ztti_a2cc_packages.ttyp.xml
├── ztti_a2cc_code_metrics.ttyp.xml
├── zcl_i_a2cc_where_used_clas.clas.abap
├── zcl_i_a2cc_where_used_func.clas.abap
├── zei_a2cc_object_id.dtel.xml
├── zsi_a2cc_packages.tabl.xml
├── zif_i_a2cc_where_used.intf.abap
├── zcl_i_a2cc_metrics_runner.clas.abap
├── zcl_i_a2cc_metrics_file_writer.clas.abap
├── zcl_i_a2cc_factory.clas.abap
├── zi_abap_to_codecharta.prog.xml
├── zcl_i_a2cc_where_used_provider.clas.testclasses.abap
├── zcl_i_a2cc_package_analyzer.clas.abap
├── zcl_i_a2cc_where_used_provider.clas.abap
├── zcl_i_a2cc_dpndncy_anlyzr_devc.clas.abap
├── zcl_i_a2cc_dpndncy_anlyzr_clas.clas.abap
├── zcl_i_a2cc_aggregator_package.clas.abap
├── zcl_i_a2cc_aggregator_class.clas.abap
├── zcl_i_a2cc_where_used_abstract.clas.abap
├── zi_abap_to_codecharta.prog.abap
├── zsi_a2cc_code_metrics.tabl.xml
└── zcl_i_a2cc_metrics_2_json.clas.abap
├── README.md
├── .abapgit.xml
└── LICENSE
/src/zif_i_a2cc_aggregator.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_i_a2cc_aggregator
2 | PUBLIC .
3 | METHODS aggregate_metrics
4 | IMPORTING
5 | metrics TYPE ztti_a2cc_code_metrics
6 | RETURNING
7 | VALUE(result) TYPE ztti_a2cc_code_metrics.
8 | ENDINTERFACE.
9 |
--------------------------------------------------------------------------------
/src/zcx_i_a2cc_metrics_impl_error.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcx_i_a2cc_metrics_impl_error DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC INHERITING FROM cx_static_check.
5 |
6 | PUBLIC SECTION.
7 | PROTECTED SECTION.
8 | PRIVATE SECTION.
9 | ENDCLASS.
10 |
11 |
12 |
13 | CLASS zcx_i_a2cc_metrics_impl_error IMPLEMENTATION.
14 | ENDCLASS.
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ABAP-2-CODE-CHARTA
2 | Covert ABAP Metrics to Code Charta
3 |
4 | Visualize your ABAP Code with Code Charta (https://github.com/MaibornWolff/codecharta).
5 |
6 | This code creates a json file that can be imported into Code Charta
7 |
8 | More information:
9 | https://blogs.sap.com/2021/06/25/code-cities-visualizing-abap-code-metrics-with-abap2codecharta/
10 |
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Visualize ABAP in Code Charta
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_metrics_2_json.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_i_a2cc_metrics_2_json
2 | PUBLIC .
3 | METHODS
4 | to_json
5 | IMPORTING
6 | VALUE(metrics) TYPE ztti_a2cc_code_metrics
7 | analyze_dependecies TYPE abap_bool
8 | analyze_direct_cycles TYPE abap_bool
9 | RETURNING
10 | VALUE(result) TYPE string.
11 |
12 | endinterface.
13 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_dependency_analyzer.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_i_a2cc_dependency_analyzer
2 | PUBLIC .
3 | METHODS find_object_usages
4 | IMPORTING
5 | metrics TYPE ztti_a2cc_code_metrics
6 | analyze_dependecies TYPE abap_bool
7 | analyze_direct_cycles TYPE abap_bool
8 | RETURNING
9 | VALUE(result) TYPE zif_i_a2cc_where_used=>where_used_list.
10 | ENDINTERFACE.
11 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_where_used_provider.intf.abap:
--------------------------------------------------------------------------------
1 | interface ZIF_I_A2CC_WHERE_USED_PROVIDER
2 | public .
3 | TYPES objecttype TYPE c LENGTH 4.
4 | TYPES subtype TYPE c LENGTH 4.
5 | METHODS get IMPORTING objecttype TYPE zif_i_a2cc_where_used_provider=>objecttype subtype TYPE zif_i_a2cc_where_used_provider=>subtype RETURNING VALUE(result) TYPE REF TO zif_i_A2CC_where_used
6 | RAISING zcx_i_A2CC_metrics_impl_error.
7 |
8 | endinterface.
9 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_package_analyzer.intf.abap:
--------------------------------------------------------------------------------
1 | interface ZIF_I_A2CC_PACKAGE_ANALYZER
2 | public .
3 |
4 | METHODS aggregate_packages
5 | IMPORTING
6 | aggregated_metrics type ztti_a2cc_code_metrics
7 | RETURNING
8 | VALUE(result) type ztti_a2cc_packages.
9 |
10 | METHODS get_parent_packages
11 | IMPORTING
12 | package TYPE zsi_a2cc_code_metrics-package
13 | RETURNING
14 | VALUE(result) TYPE string.
15 | endinterface.
16 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_where_used.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_WHERE_USED
7 | E
8 | Get Where Used
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_aggregator.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_AGGREGATOR
7 | E
8 | Metrics agggregator
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_metrics_2_json.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_METRICS_2_JSON
7 | E
8 | Metrics to json
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_package_analyzer.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_PACKAGE_ANALYZER
7 | E
8 | Package_analyzer
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_factory.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_FACTORY
7 | E
8 | Component factory
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_dependency_analyzer.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_DEPENDENCY_ANALYZER
7 | E
8 | Dependency analyzer
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_where_used_provider.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_I_A2CC_WHERE_USED_PROVIDER
7 | E
8 | Where used provider
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_2_json.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_METRICS_2_JSON
7 | D
8 | Metrics to JSON
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_runner.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_METRICS_RUNNER
7 | E
8 | Metrics runner
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_aggregator_class.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_AGGREGATOR_CLASS
7 | E
8 | Metrics aggregator
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_file_writer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_METRICS_FILE_WRITER
7 | E
8 | File Writer
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_package_analyzer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_PACKAGE_ANALYZER
7 | E
8 | Package analyzer
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_clas.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_WHERE_USED_CLAS
7 | E
8 | Where used of Methods
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_func.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_WHERE_USED_FUNC
7 | E
8 | Where used of Methods
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_aggregator_package.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_AGGREGATOR_PACKAGE
7 | E
8 | Metrics aggregator
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_dpndncy_anlyzr_clas.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_DPNDNCY_ANLYZR_CLAS
7 | E
8 | Dependency analyzer
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_dpndncy_anlyzr_devc.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_DPNDNCY_ANLYZR_DEVC
7 | E
8 | Dependency analyzer
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_abstract.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_WHERE_USED_ABSTRACT
7 | D
8 | Where used of Methods
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zcx_i_a2cc_metrics_impl_error.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_I_A2CC_METRICS_IMPL_ERROR
7 | E
8 | Implementation error
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_provider.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_I_A2CC_WHERE_USED_PROVIDER
7 | E
8 | Usage Provider
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/ztti_a2cc_packages.ttyp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZTTI_A2CC_PACKAGES
7 | D
8 | ZSI_A2CC_PACKAGES
9 | S
10 | STRU
11 | T
12 | D
13 | N
14 | Devclass Packages
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/ztti_a2cc_code_metrics.ttyp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZTTI_A2CC_CODE_METRICS
7 | D
8 | ZSI_A2CC_CODE_METRICS
9 | S
10 | STRU
11 | T
12 | D
13 | N
14 | Code Metrics
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | D
6 | /src/
7 | FULL
8 |
9 | - /.gitignore
10 | - /LICENSE
11 | - /README.md
12 | - /package.json
13 | - /.travis.yml
14 | - /.gitlab-ci.yml
15 | - /abaplint.json
16 | - /azure-pipelines.yml
17 | - /.devcontainer.json
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_clas.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_where_used_clas DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC INHERITING FROM zcl_i_a2cc_where_used_abstract.
5 |
6 | PUBLIC SECTION.
7 | METHODS constructor
8 | IMPORTING objecttype TYPE zif_i_a2cc_where_used_provider=>objecttype.
9 | METHODS zif_i_a2cc_where_used~get_cross_references REDEFINITION.
10 | ENDCLASS.
11 |
12 | CLASS zcl_i_a2cc_where_used_clas IMPLEMENTATION.
13 | METHOD zif_i_a2cc_where_used~get_cross_references.
14 | result = get_where_used_list_from_cross( CONV #( object-object ) ) .
15 | ENDMETHOD.
16 |
17 | METHOD constructor.
18 | super->constructor( objecttype ).
19 | ENDMETHOD.
20 | ENDCLASS.
21 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_func.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_where_used_func DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC INHERITING FROM zcl_i_a2cc_where_used_abstract.
5 |
6 | PUBLIC SECTION.
7 | METHODS constructor
8 | IMPORTING objecttype TYPE zif_i_a2cc_where_used_provider=>objecttype.
9 | METHODS zif_i_a2cc_where_used~get_cross_references REDEFINITION.
10 | ENDCLASS.
11 |
12 | CLASS zcl_i_a2cc_where_used_func IMPLEMENTATION.
13 | METHOD zif_i_a2cc_where_used~get_cross_references.
14 | result = get_where_used_list_from_cross( CONV #( object-subobject ) ) .
15 | ENDMETHOD.
16 |
17 | METHOD constructor.
18 | super->constructor( objecttype ).
19 | ENDMETHOD.
20 | ENDCLASS.
21 |
--------------------------------------------------------------------------------
/src/zei_a2cc_object_id.dtel.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZEI_A2CC_OBJECT_ID
7 | D
8 | CHAR61
9 | 16
10 | 08
11 | 08
12 | 16
13 | Zeichenfeld Länge 61
14 | Zeichenfeld
15 | Zeich61
16 | Zeich61
17 | Zeichenfeld
18 | E
19 | D
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/zsi_a2cc_packages.tabl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZSI_A2CC_PACKAGES
7 | INTTAB
8 | E
9 | 1
10 |
11 |
12 |
13 | ZSI_A2CC_PACKAGES
14 | PACKAGE
15 | 0001
16 | DEVCLASS
17 | 0
18 | D
19 | E
20 |
21 |
22 | ZSI_A2CC_PACKAGES
23 | PARENT
24 | 0002
25 | DEVCLASS
26 | 0
27 | D
28 | E
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 BenjaminWeisheit
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 |
--------------------------------------------------------------------------------
/src/zif_i_a2cc_where_used.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_i_a2cc_where_used
2 | PUBLIC .
3 | TYPES object_identifier TYPE string.
4 |
5 | TYPES: BEGIN OF depending_object,
6 | depending_object TYPE object_identifier,
7 | depending_type TYPE trobjtype,
8 | number_of_usages TYPE i,
9 | cycle TYPE i,
10 | END OF depending_object.
11 |
12 | TYPES object_list TYPE HASHED TABLE OF depending_object WITH UNIQUE KEY depending_object depending_type.
13 | TYPES: BEGIN OF object_usages,
14 | object_identifier TYPE object_identifier,
15 | object_type TYPE trobjtype,
16 | references TYPE object_list,
17 | END OF object_usages.
18 |
19 | TYPES: BEGIN OF object_id,
20 | object TYPE zei_a2cc_object_id,
21 | subobject TYPE zei_a2cc_object_id,
22 | END OF object_id.
23 |
24 | TYPES where_used_list TYPE HASHED TABLE OF object_usages WITH UNIQUE KEY object_identifier object_type.
25 |
26 | METHODS get_cross_references
27 | IMPORTING
28 | object TYPE object_id
29 | RETURNING
30 | VALUE(result) TYPE REF TO object_list.
31 | ENDINTERFACE.
32 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_runner.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_metrics_runner DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 | PUBLIC SECTION.
6 | METHODS run_quality_metrics_report
7 | IMPORTING
8 | selection_variant TYPE variant
9 | RETURNING
10 | VALUE(result) TYPE ztti_a2cc_code_metrics
11 | RAISING
12 | cx_salv_bs_sc_runtime_info.
13 | PRIVATE SECTION.
14 | METHODS set_alv_runtime_info.
15 | METHODS submit_code_metrics_report
16 | IMPORTING
17 | selection_variant TYPE variant.
18 | METHODS get_alv_list_from_report
19 | RETURNING
20 | VALUE(result) TYPE ztti_a2cc_code_metrics
21 | RAISING
22 | cx_salv_bs_sc_runtime_info.
23 | ENDCLASS.
24 |
25 | CLASS zcl_i_a2cc_metrics_runner IMPLEMENTATION.
26 | METHOD run_quality_metrics_report.
27 | set_alv_runtime_info( ).
28 | submit_code_metrics_report( selection_variant ).
29 | result = get_alv_list_from_report( ).
30 | ENDMETHOD.
31 |
32 | METHOD get_alv_list_from_report.
33 | FIELD-SYMBOLS TYPE STANDARD TABLE.
34 | DATA alv_list TYPE REF TO data.
35 | cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = alv_list ).
36 | ASSIGN alv_list->* TO .
37 | MOVE-CORRESPONDING TO result.
38 | ENDMETHOD.
39 |
40 | METHOD submit_code_metrics_report.
41 | SUBMIT /sdf/cd_custom_code_metric
42 | USING SELECTION-SET selection_variant
43 | EXPORTING LIST TO MEMORY
44 | AND RETURN.
45 | ENDMETHOD.
46 |
47 | METHOD set_alv_runtime_info.
48 | cl_salv_bs_runtime_info=>set(
49 | EXPORTING display = abap_false
50 | metadata = abap_false
51 | data = abap_true ).
52 | ENDMETHOD.
53 | ENDCLASS.
54 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_file_writer.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_metrics_file_writer DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | METHODS write_json_2_file
8 | IMPORTING
9 | file_name TYPE localfile
10 | json TYPE string.
11 | PRIVATE SECTION.
12 | CONSTANTS utf_8 TYPE string VALUE `UTF-8`.
13 | METHODS convert_string_to_xstring
14 | IMPORTING
15 | string TYPE string
16 | RETURNING
17 | VALUE(result) TYPE xstring.
18 | METHODS write_xstring_to_file
19 | IMPORTING
20 | file_name TYPE localfile
21 | xstring TYPE xstring.
22 | METHODS rplce_placeholders_in_filename
23 | IMPORTING
24 | file_name TYPE localfile
25 | RETURNING
26 | VALUE(result) TYPE localfile.
27 | ENDCLASS.
28 |
29 | CLASS zcl_i_a2cc_metrics_file_writer IMPLEMENTATION.
30 | METHOD write_json_2_file.
31 | write_xstring_to_file(
32 | file_name = rplce_placeholders_in_filename( file_name )
33 | xstring = convert_string_to_xstring( json ) ).
34 | ENDMETHOD.
35 |
36 | METHOD write_xstring_to_file.
37 | OPEN DATASET file_name FOR OUTPUT IN BINARY MODE.
38 | IF sy-subrc NE 0.
39 | WRITE : |Error opening the server filepath: { file_name }|.
40 | ELSE.
41 | TRANSFER xstring TO file_name.
42 | CLOSE DATASET file_name.
43 | WRITE : |File downloaded to the server at: { file_name }|.
44 | ENDIF.
45 | ENDMETHOD.
46 |
47 | METHOD convert_string_to_xstring.
48 | result = cl_abap_codepage=>convert_to( source = string codepage = utf_8 ).
49 | ENDMETHOD.
50 |
51 | METHOD rplce_placeholders_in_filename.
52 | result = file_name.
53 | REPLACE ALL OCCURRENCES OF '' IN result WITH sy-datum.
54 | ENDMETHOD.
55 | ENDCLASS.
56 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_factory.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_factory DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | CONSTANTS: BEGIN OF aggregation_levels,
8 | package TYPE char1 VALUE 'P',
9 | class TYPE char1 VALUE 'C',
10 | END OF aggregation_levels.
11 | CLASS-METHODS create
12 | IMPORTING
13 | aggregation_level TYPE char1
14 | RETURNING
15 | VALUE(result) TYPE REF TO Zif_I_A2CC_METRICS_2_JSON.
16 | PRIVATE SECTION.
17 | class-METHODS create_json_writer
18 | RETURNING
19 | VALUE(result) TYPE REF TO if_sxml_writer.
20 |
21 | ENDCLASS.
22 |
23 | CLASS zcl_i_a2cc_factory IMPLEMENTATION.
24 | METHOD create.
25 | DATA: dependency_analyzer TYPE REF TO zif_i_a2cc_dependency_analyzer,
26 | metric_aggregator TYPE REF TO zif_i_a2cc_aggregator.
27 |
28 | dependency_analyzer = COND #( WHEN aggregation_level = aggregation_levels-package
29 | THEN NEW zcl_i_a2cc_dpndncy_anlyzr_devc( )
30 | ELSE NEW zcl_i_a2cc_dpndncy_anlyzr_Clas( ) ).
31 |
32 | metric_aggregator = COND #( WHEN aggregation_level = aggregation_levels-package
33 | THEN NEW zcl_i_a2cc_aggregator_package( )
34 | ELSE NEW zcl_i_a2cc_aggregator_class( ) ).
35 |
36 | result = NEW zcl_i_a2cc_metrics_2_json(
37 | json_writer = create_json_writer( )
38 | dependency_analyzer = dependency_analyzer
39 | package_analyzer = NEW zcl_i_a2cc_package_analyzer( )
40 | metric_aggregator = metric_aggregator ).
41 | ENDMETHOD.
42 |
43 | METHOD create_json_writer.
44 | result = CAST #( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).
45 | ENDMETHOD.
46 | ENDCLASS.
47 |
--------------------------------------------------------------------------------
/src/zi_abap_to_codecharta.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZI_ABAP_TO_CODECHARTA
7 | S
8 | 1
9 | E
10 | X
11 | D$S
12 | X
13 |
14 |
15 | -
16 | I
17 | BLA
18 | Abhängigkeiten
19 | 22
20 |
21 | -
22 | I
23 | BLD
24 | Aggregationsebene
25 | 27
26 |
27 | -
28 | S
29 | AGG_DEVC
30 | Paket
31 | 38
32 |
33 | -
34 | S
35 | AGG_MODL
36 | Modul
37 | 38
38 |
39 | -
40 | S
41 | CYCLS
42 | Nur direkte Zyklen
43 | 38
44 |
45 | -
46 | S
47 | DPNDNCY
48 | Alle
49 | 38
50 |
51 | -
52 | S
53 | WO_DPND
54 | Ohne
55 | 38
56 |
57 | -
58 | S
59 | FILE
60 | .
61 | 22
62 | D
63 |
64 | -
65 | S
66 | VARNT
67 | .
68 | 16
69 | D
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_provider.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 | *"* use this source file for your ABAP unit test classes
2 | CLASS ltcl_test_provider DEFINITION DEFERRED.
3 | CLASS zcl_i_a2cc_where_used_provider DEFINITION LOCAL FRIENDS ltcl_test_provider.
4 |
5 | CLASS ltcl_test_provider DEFINITION FINAL FOR TESTING
6 | DURATION SHORT
7 | RISK LEVEL HARMLESS.
8 |
9 | PRIVATE SECTION.
10 | DATA cut TYPE REF TO zif_i_A2CC_where_used_provider.
11 | METHODS:
12 | setup,
13 | fail_with_xxxx FOR TESTING RAISING cx_static_check,
14 | succeed_with_meth FOR TESTING RAISING cx_static_check.
15 | ENDCLASS.
16 |
17 | CLASS lth_dummy_where_used DEFINITION FOR TESTING.
18 | PUBLIC SECTION.
19 | INTERFACES zif_i_A2CC_where_used.
20 | ENDCLASS.
21 |
22 | CLASS lth_dummy_where_used IMPLEMENTATION.
23 |
24 | METHOD zif_i_A2CC_where_used~get_cross_references.
25 |
26 | ENDMETHOD.
27 |
28 | ENDCLASS.
29 |
30 |
31 | CLASS ltcl_test_provider IMPLEMENTATION.
32 | METHOD setup.
33 | cut = NEW zcl_i_a2cc_where_used_provider( ).
34 | cast zcl_i_a2cc_where_used_provider( cut )->set_configuration( VALUE #( ( objecttype = 'CLAS' subtype = 'METH' instance = NEW lth_dummy_where_used( ) ) )
35 | ).
36 |
37 | ENDMETHOD.
38 |
39 | METHOD succeed_with_meth.
40 | TRY.
41 | "given configuration with METH
42 | "when called with subtype Meth
43 | cut->get( objecttype = 'CLAS' subtype = 'METH' ).
44 | "then expext implementation
45 | CATCH zcx_i_A2CC_metrics_impl_error.
46 | cl_abap_unit_assert=>fail( 'Expect implementation' ).
47 |
48 | ENDTRY.
49 |
50 | ENDMETHOD.
51 |
52 | METHOD fail_with_xxxx.
53 | CONSTANTS any_non_existant_value TYPE zif_i_A2CC_where_used_provider=>subtype VALUE 'XXXX' ##NO_TEXT.
54 | TRY.
55 | "given instance and
56 | "when called with nonsense subtype
57 | cut->get( objecttype = 'CLAS' subtype = any_non_existant_value ).
58 | "then expext exception
59 | cl_abap_unit_assert=>fail( 'Expect exception zcx_i_metric_implement_error' ).
60 | CATCH zcx_i_A2CC_metrics_impl_error.
61 | ENDTRY.
62 | ENDMETHOD.
63 |
64 | ENDCLASS.
65 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_package_analyzer.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_package_analyzer DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 | PUBLIC SECTION.
6 | INTERFACES zif_i_a2cc_package_analyzer.
7 | PRIVATE SECTION.
8 | METHODS get_parent_packages
9 | IMPORTING
10 | package TYPE zsi_a2cc_code_metrics-package
11 | path TYPE string
12 | RETURNING
13 | VALUE(result) TYPE string.
14 | DATA packages TYPE ztti_a2cc_packages.
15 |
16 | ENDCLASS.
17 | CLASS zcl_i_a2cc_package_analyzer IMPLEMENTATION.
18 | METHOD zif_i_a2cc_package_analyzer~aggregate_packages.
19 | DATA devclasses TYPE RANGE OF devclass.
20 |
21 | devclasses = VALUE #( FOR package IN aggregated_metrics ( sign = 'I' option = 'EQ' low = package-package ) ).
22 | SORT devclasses.
23 | DELETE ADJACENT DUPLICATES FROM devclasses.
24 |
25 | SELECT devclass, parentcl FROM tdevc INTO TABLE @DATA(package_hierarchy) WHERE devclass IN @devclasses AND parentcl IN @devclasses.
26 |
27 | LOOP AT aggregated_metrics REFERENCE INTO DATA(metric).
28 | AT NEW package.
29 | TRY.
30 | APPEND VALUE #( package = metric->package
31 | parent = package_hierarchy[ devclass = metric->package ]-parentcl ) TO packages.
32 | CATCH cx_sy_itab_line_not_found.
33 | APPEND VALUE #( package = metric->package ) TO packages.
34 | ENDTRY.
35 | ENDAT.
36 | ENDLOOP.
37 | result = packages.
38 | ENDMETHOD.
39 |
40 | METHOD zif_i_a2cc_package_analyzer~get_parent_packages.
41 | result = get_parent_packages( package = package
42 | path = CONV #( package ) ).
43 | ENDMETHOD.
44 |
45 | METHOD get_parent_packages.
46 | TRY.
47 | DATA(parent_package) = packages[ package = package ]-parent.
48 | IF parent_package IS INITIAL.
49 | result = path.
50 | ELSE.
51 | result = get_parent_packages( package = parent_package
52 | path = |{ parent_package }/{ path }| ).
53 | ENDIF.
54 | CATCH cx_sy_itab_line_not_found.
55 | result = path.
56 | ENDTRY.
57 | ENDMETHOD.
58 | ENDCLASS.
59 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_provider.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_where_used_provider DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | INTERFACES zif_i_A2CC_where_used_provider.
8 | METHODS constructor.
9 | PRIVATE SECTION.
10 |
11 |
12 |
13 | TYPES: BEGIN OF object_where_used_provider,
14 | objecttype TYPE zif_i_A2CC_where_used_provider=>objecttype,
15 | subtype TYPE zif_i_A2CC_where_used_provider=>subtype,
16 | instance TYPE REF TO zif_i_A2CC_where_used,
17 | END OF object_where_used_provider.
18 | TYPES object_whereused_prov_config TYPE HASHED TABLE OF object_where_used_provider WITH UNIQUE KEY objecttype subtype.
19 | DATA object_provider_config TYPE object_whereused_prov_config.
20 |
21 | METHODS get_instance_by_type IMPORTING
22 | objecttype TYPE zif_i_A2CC_where_used_provider=>objecttype
23 | subtype TYPE zif_i_A2CC_where_used_provider=>subtype
24 | RETURNING
25 | VALUE(result) TYPE REF TO zif_i_A2CC_where_used
26 | RAISING
27 | zcx_i_a2cc_metrics_impl_error.
28 |
29 | METHODS set_configuration IMPORTING object_provider_config TYPE object_whereused_prov_config.
30 | ENDCLASS.
31 |
32 | CLASS zcl_i_a2cc_where_used_provider IMPLEMENTATION.
33 | METHOD constructor.
34 | set_configuration( VALUE #( ( objecttype = 'CLAS' subtype = 'METH' instance = NEW zcl_i_a2cc_where_used_clas( 'CLAS' ) )
35 | ( objecttype = 'FUGR' subtype = 'FUNC' instance = NEW zcl_i_a2cc_where_used_func( 'FUNC' ) ) ) ).
36 | ENDMETHOD.
37 |
38 | METHOD zif_i_A2CC_where_used_provider~get.
39 | result = get_instance_by_type( objecttype = objecttype subtype = subtype ).
40 | ENDMETHOD.
41 |
42 | METHOD get_instance_by_type.
43 | TRY.
44 | result = object_provider_config[ objecttype = objecttype subtype = subtype ]-instance.
45 | CATCH cx_sy_itab_line_not_found.
46 | RAISE EXCEPTION TYPE zcx_i_A2CC_metrics_impl_error.
47 | ENDTRY.
48 | ENDMETHOD.
49 |
50 | METHOD set_configuration.
51 | me->object_provider_config = object_provider_config.
52 | ENDMETHOD.
53 | ENDCLASS.
54 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_dpndncy_anlyzr_devc.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_dpndncy_anlyzr_devc DEFINITION
2 | PUBLIC INHERITING FROM zcl_i_a2cc_dpndncy_anlyzr_clas
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | METHODS constructor.
8 | PROTECTED SECTION.
9 | METHODS collect_object_where_used_list REDEFINITION.
10 | METHODS where_used_analysis REDEFINITION.
11 |
12 | PRIVATE SECTION.
13 |
14 | TYPES:
15 | BEGIN OF object_data,
16 | object_id TYPE zei_a2cc_object_id,
17 | object_type TYPE trobjtype,
18 | package TYPE char30,
19 | END OF object_data .
20 | CONSTANTS package_obj TYPE trobjtype VALUE 'DEVC'.
21 |
22 | DATA:
23 | packages TYPE HASHED TABLE OF object_data WITH UNIQUE KEY object_id object_type.
24 |
25 | METHODS aggregate_to_package_level
26 | IMPORTING
27 | !depending_objects TYPE zif_i_a2cc_where_used=>object_list
28 | RETURNING
29 | VALUE(result) TYPE zif_i_a2cc_where_used=>object_list .
30 | ENDCLASS.
31 |
32 |
33 |
34 | CLASS zcl_i_a2cc_dpndncy_anlyzr_devc IMPLEMENTATION.
35 |
36 | METHOD aggregate_to_package_level.
37 | LOOP AT depending_objects REFERENCE INTO DATA(depending_object).
38 | DATA(package) = COND string( WHEN line_exists( packages[ object_id = depending_object->depending_object object_type = depending_object->depending_type ] )
39 | THEN packages[ object_id = depending_object->depending_object object_type = depending_object->depending_type ]-package
40 | ELSE |{ depending_object->depending_object }.{ depending_object->depending_type }| ).
41 |
42 | INSERT VALUE #( depending_object = package depending_type = package_obj ) INTO TABLE result.
43 | ENDLOOP.
44 | SORT result.
45 | DELETE ADJACENT DUPLICATES FROM result COMPARING depending_object depending_type.
46 | ENDMETHOD.
47 |
48 |
49 | METHOD collect_object_where_used_list.
50 | TRY.
51 | DATA(references) = REF #( me->object_where_used_list_by[ object_identifier = metric->package object_type = package_obj ]-references ).
52 | LOOP AT depending_objects REFERENCE INTO DATA(depending_object).
53 | IF line_exists( references->*[ depending_object = depending_object->depending_object depending_type = depending_object->depending_type ] ).
54 | ASSIGN references->*[ depending_object = depending_object->depending_object depending_type = depending_object->depending_type ] TO FIELD-SYMBOL().
55 | -number_of_usages = -number_of_usages + 1.
56 | ELSE.
57 | INSERT depending_object->* INTO TABLE references->*.
58 | ENDIF.
59 | ENDLOOP.
60 | CATCH cx_sy_itab_line_not_found.
61 | INSERT VALUE #( object_identifier = metric->package object_type = package_obj references = depending_objects ) INTO TABLE object_where_used_list_by.
62 | ENDTRY.
63 | ENDMETHOD.
64 |
65 | METHOD constructor.
66 | super->constructor( ).
67 | ENDMETHOD.
68 |
69 | METHOD where_used_analysis.
70 | LOOP AT metrics REFERENCE INTO DATA(metric).
71 | INSERT VALUE #( object_id = metric->modu_unit_1 object_type = metric->category package = metric->package ) INTO TABLE packages.
72 | ENDLOOP.
73 |
74 | LOOP AT metrics REFERENCE INTO metric.
75 | TRY.
76 | DATA(depending_objects) = where_used_provider->get( objecttype = metric->category subtype = metric->sub_type )->get_cross_references( VALUE #( object = metric->modu_unit_1
77 | subobject = metric->modu_unit_2 ) ).
78 | IF has_where_used_entries( depending_objects ).
79 | collect_object_where_used_list( metric = metric depending_objects = aggregate_to_package_level( depending_objects->* ) ).
80 | ENDIF.
81 | CATCH zcx_i_a2cc_metrics_impl_error.
82 | CONTINUE.
83 | ENDTRY.
84 | ENDLOOP.
85 | ENDMETHOD.
86 | ENDCLASS.
87 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_dpndncy_anlyzr_clas.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_dpndncy_anlyzr_clas DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 | INTERFACES zif_i_a2cc_dependency_analyzer.
7 | METHODS constructor.
8 | PROTECTED SECTION.
9 | METHODS collect_object_where_used_list
10 | IMPORTING
11 | metric TYPE REF TO zsi_a2cc_code_metrics
12 | depending_objects TYPE zif_i_a2cc_where_used=>object_list.
13 | METHODS where_used_analysis
14 | IMPORTING
15 | metrics TYPE ztti_a2cc_code_metrics.
16 |
17 | DATA where_used_provider TYPE REF TO zif_i_a2cc_where_used_provider.
18 | DATA object_where_used_list_by TYPE zif_i_a2cc_where_used=>where_used_list.
19 |
20 | METHODS has_where_used_entries
21 | IMPORTING
22 | object_list TYPE REF TO zif_i_a2cc_where_used=>object_list
23 | RETURNING
24 | VALUE(result) TYPE abap_bool.
25 | PRIVATE SECTION.
26 | DATA: analyze_dependecies TYPE abap_bool,
27 | analyze_direct_cycles TYPE abap_bool.
28 | METHODS analyze_cycles.
29 | ENDCLASS.
30 |
31 | CLASS zcl_i_a2cc_dpndncy_anlyzr_clas IMPLEMENTATION.
32 | METHOD constructor.
33 | where_used_provider = NEW zcl_i_a2cc_where_used_provider( ).
34 | ENDMETHOD.
35 |
36 | METHOD zif_i_a2cc_dependency_analyzer~find_object_usages.
37 | me->analyze_dependecies = analyze_dependecies.
38 | me->analyze_direct_cycles = analyze_direct_cycles.
39 |
40 | IF analyze_dependecies = abap_true OR analyze_direct_cycles = abap_true.
41 | where_used_analysis( metrics ).
42 | ENDIF.
43 | IF analyze_direct_cycles = abap_true.
44 | analyze_cycles( ).
45 | ENDIF.
46 | result = object_where_used_list_by.
47 | ENDMETHOD.
48 |
49 | METHOD where_used_analysis.
50 | LOOP AT metrics REFERENCE INTO DATA(metric).
51 | TRY.
52 | DATA(depending_objects) = where_used_provider->get( objecttype = metric->category subtype = metric->sub_type )->get_cross_references( VALUE #( object = metric->modu_unit_1
53 | subobject = metric->modu_unit_2 ) ).
54 | IF has_where_used_entries( depending_objects ).
55 | collect_object_where_used_list( metric = metric depending_objects = depending_objects->* ).
56 | ENDIF.
57 | CATCH zcx_i_a2cc_metrics_impl_error.
58 | "Fallback for unknown references
59 | INSERT VALUE #( object_identifier = metric->modu_unit_1 references = VALUE #( ( depending_object = |{ zcl_i_a2cc_metrics_2_json=>system }| number_of_usages = 1 ) ) )
60 | INTO TABLE object_where_used_list_by.
61 | ENDTRY.
62 | ENDLOOP.
63 | ENDMETHOD.
64 |
65 | METHOD analyze_cycles.
66 | LOOP AT object_where_used_list_by REFERENCE INTO DATA(object_where_used).
67 | LOOP AT object_where_used->references REFERENCE INTO DATA(reference).
68 | DATA(line_index) = sy-tabix.
69 | TRY.
70 | data(references) = object_where_used_list_by[ object_identifier = reference->depending_object object_type = reference->depending_type ]-references.
71 | DATA(back_refenrence) = references[ depending_object = object_where_used->object_identifier depending_type = object_where_used->object_type ].
72 | reference->cycle = 1.
73 | CATCH cx_sy_itab_line_not_found.
74 | DELETE TABLE object_where_used->references FROM reference->*.
75 | ENDTRY.
76 | ENDLOOP.
77 | ENDLOOP.
78 | ENDMETHOD.
79 |
80 | METHOD has_where_used_entries.
81 | result = boolc( object_list IS NOT INITIAL AND lines( object_list->* ) > 0 ).
82 | ENDMETHOD.
83 |
84 | METHOD collect_object_where_used_list.
85 | TRY.
86 | DATA(references) = REF #( me->object_where_used_list_by[ object_identifier = metric->modu_unit_1 object_type = metric->category ]-references ).
87 | LOOP AT depending_objects REFERENCE INTO DATA(depending_object).
88 | IF line_exists( references->*[ depending_object = depending_object->depending_object depending_type = depending_object->depending_type ] ).
89 | ASSIGN references->*[ depending_object = depending_object->depending_object depending_type = depending_object->depending_type ] TO FIELD-SYMBOL().
90 | -number_of_usages = -number_of_usages + 1.
91 | ELSE.
92 | INSERT depending_object->* INTO TABLE references->*.
93 | ENDIF.
94 | ENDLOOP.
95 | CATCH cx_sy_itab_line_not_found.
96 | INSERT VALUE #( object_identifier = metric->modu_unit_1 object_type = metric->category references = depending_objects ) INTO TABLE object_where_used_list_by.
97 | ENDTRY.
98 | ENDMETHOD.
99 | ENDCLASS.
100 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_aggregator_package.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_aggregator_package DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | INTERFACES zif_i_a2cc_aggregator .
8 | PRIVATE SECTION.
9 | ENDCLASS.
10 |
11 | CLASS zcl_i_a2cc_aggregator_package IMPLEMENTATION.
12 | METHOD zif_i_a2cc_aggregator~aggregate_metrics.
13 | DATA aggregated_metric TYPE zsi_a2cc_code_metrics.
14 |
15 | LOOP AT metrics REFERENCE INTO DATA(metric).
16 | aggregated_metric-component_to_be_changed = metric->component_to_be_changed.
17 | aggregated_metric-package = metric->package.
18 | aggregated_metric-category = 'DEVC'.
19 | aggregated_metric-modu_unit_1 = metric->package.
20 | aggregated_metric-loc = aggregated_metric-loc + metric->loc .
21 | IF metric->nos >= 2.
22 | aggregated_metric-nos = aggregated_metric-nos + metric->nos - 2 . "DO not Consider METHOD/ENDMETHOD
23 | ELSE.
24 | aggregated_metric-nos = aggregated_metric-nos + metric->nos.
25 | ENDIF.
26 | aggregated_metric-noc = aggregated_metric-noc + metric->noc .
27 | aggregated_metric-nop = aggregated_metric-nop + metric->nop .
28 | aggregated_metric-mcc_com = aggregated_metric-mcc_com + metric->mcc_com .
29 | aggregated_metric-vrsd_chan = aggregated_metric-vrsd_chan + metric->vrsd_chan .
30 | aggregated_metric-dd_total = aggregated_metric-dd_total + metric->dd_total .
31 | aggregated_metric-stmts_c = aggregated_metric-stmts_c + metric->stmts_c .
32 | aggregated_metric-stmts_p = aggregated_metric-stmts_p + metric->stmts_p .
33 | aggregated_metric-stmts_i = aggregated_metric-stmts_i + metric->stmts_i .
34 | aggregated_metric-stmts_e = aggregated_metric-stmts_e + metric->stmts_e .
35 | aggregated_metric-stmts_ei = aggregated_metric-stmts_ei + metric->stmts_ei .
36 | aggregated_metric-stmts_d = aggregated_metric-stmts_d + metric->stmts_d .
37 | aggregated_metric-stmts_w = aggregated_metric-stmts_w + metric->stmts_w .
38 | aggregated_metric-stmts_l = aggregated_metric-stmts_l + metric->stmts_l .
39 | aggregated_metric-stmts_ca = aggregated_metric-stmts_ca + metric->stmts_ca .
40 | aggregated_metric-stmts_wh = aggregated_metric-stmts_wh + metric->stmts_wh .
41 | aggregated_metric-stmts_sl = aggregated_metric-stmts_sl + metric->stmts_sl .
42 | aggregated_metric-stmts_ins = aggregated_metric-stmts_ins + metric->stmts_ins .
43 | aggregated_metric-stmts_upd = aggregated_metric-stmts_upd + metric->stmts_upd .
44 | aggregated_metric-stmts_del = aggregated_metric-stmts_del + metric->stmts_del .
45 | aggregated_metric-stmts_mod = aggregated_metric-stmts_mod + metric->stmts_mod .
46 | aggregated_metric-diff_vers = aggregated_metric-diff_vers + metric->diff_vers .
47 | aggregated_metric-diff_mod_l = aggregated_metric-diff_mod_l + metric->diff_mod_l.
48 | aggregated_metric-diff_new_l = aggregated_metric-diff_new_l + metric->diff_new_l.
49 | aggregated_metric-diff_sap = aggregated_metric-diff_sap + metric->diff_sap .
50 | aggregated_metric-mod_db = aggregated_metric-mod_db + metric->mod_db .
51 | aggregated_metric-mod_call = aggregated_metric-mod_call + metric->mod_call .
52 | aggregated_metric-mod_bra = aggregated_metric-mod_bra + metric->mod_bra .
53 | aggregated_metric-number_of_methods = aggregated_metric-number_of_methods + 1.
54 | AT END OF package.
55 | aggregated_metric-average_nos_per_method = aggregated_metric-nos / aggregated_metric-number_of_methods.
56 | aggregated_metric-decission_depth_complexity = aggregated_metric-dd_total.
57 | aggregated_metric-db_access_statements = aggregated_metric-stmts_sl +
58 | aggregated_metric-stmts_ins +
59 | aggregated_metric-stmts_mod +
60 | aggregated_metric-stmts_del.
61 |
62 | aggregated_metric-cyclomatic_complexity = aggregated_metric-stmts_i +
63 | aggregated_metric-stmts_e +
64 | aggregated_metric-stmts_ei +
65 | aggregated_metric-stmts_d +
66 | aggregated_metric-stmts_w +
67 | aggregated_metric-stmts_l +
68 | aggregated_metric-stmts_ca +
69 | aggregated_metric-stmts_wh.
70 | aggregated_metric-cyclomatic_complexity_avg = aggregated_metric-cyclomatic_complexity / aggregated_metric-number_of_methods.
71 |
72 | APPEND aggregated_metric TO result.
73 | CLEAR aggregated_metric.
74 | ENDAT.
75 | ENDLOOP.
76 | ENDMETHOD.
77 | ENDCLASS.
78 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_aggregator_class.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_aggregator_class DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | INTERFACES zif_i_a2cc_aggregator .
8 | PRIVATE SECTION.
9 | ENDCLASS.
10 |
11 | CLASS zcl_i_a2cc_aggregator_class IMPLEMENTATION.
12 | METHOD zif_i_a2cc_aggregator~aggregate_metrics.
13 | DATA aggregated_metric TYPE zsi_a2cc_code_metrics.
14 |
15 | LOOP AT metrics REFERENCE INTO DATA(metric).
16 | aggregated_metric-component_to_be_changed = metric->component_to_be_changed.
17 | aggregated_metric-package = metric->package.
18 | aggregated_metric-category = metric->category.
19 | aggregated_metric-modu_unit_1 = metric->modu_unit_1.
20 | aggregated_metric-loc = aggregated_metric-loc + metric->loc .
21 | IF metric->nos >= 2.
22 | aggregated_metric-nos = aggregated_metric-nos + metric->nos - 2 . "DO not Consider METHOD/ENDMETHOD
23 | ELSE.
24 | aggregated_metric-nos = aggregated_metric-nos + metric->nos.
25 | ENDIF.
26 | aggregated_metric-noc = aggregated_metric-noc + metric->noc .
27 | aggregated_metric-nop = aggregated_metric-nop + metric->nop .
28 | aggregated_metric-mcc_com = aggregated_metric-mcc_com + metric->mcc_com .
29 | aggregated_metric-vrsd_chan = aggregated_metric-vrsd_chan + metric->vrsd_chan .
30 | aggregated_metric-dd_total = aggregated_metric-dd_total + metric->dd_total .
31 | aggregated_metric-stmts_c = aggregated_metric-stmts_c + metric->stmts_c .
32 | aggregated_metric-stmts_p = aggregated_metric-stmts_p + metric->stmts_p .
33 | aggregated_metric-stmts_i = aggregated_metric-stmts_i + metric->stmts_i .
34 | aggregated_metric-stmts_e = aggregated_metric-stmts_e + metric->stmts_e .
35 | aggregated_metric-stmts_ei = aggregated_metric-stmts_ei + metric->stmts_ei .
36 | aggregated_metric-stmts_d = aggregated_metric-stmts_d + metric->stmts_d .
37 | aggregated_metric-stmts_w = aggregated_metric-stmts_w + metric->stmts_w .
38 | aggregated_metric-stmts_l = aggregated_metric-stmts_l + metric->stmts_l .
39 | aggregated_metric-stmts_ca = aggregated_metric-stmts_ca + metric->stmts_ca .
40 | aggregated_metric-stmts_wh = aggregated_metric-stmts_wh + metric->stmts_wh .
41 | aggregated_metric-stmts_sl = aggregated_metric-stmts_sl + metric->stmts_sl .
42 | aggregated_metric-stmts_ins = aggregated_metric-stmts_ins + metric->stmts_ins .
43 | aggregated_metric-stmts_upd = aggregated_metric-stmts_upd + metric->stmts_upd .
44 | aggregated_metric-stmts_del = aggregated_metric-stmts_del + metric->stmts_del .
45 | aggregated_metric-stmts_mod = aggregated_metric-stmts_mod + metric->stmts_mod .
46 | aggregated_metric-diff_vers = aggregated_metric-diff_vers + metric->diff_vers .
47 | aggregated_metric-diff_mod_l = aggregated_metric-diff_mod_l + metric->diff_mod_l.
48 | aggregated_metric-diff_new_l = aggregated_metric-diff_new_l + metric->diff_new_l.
49 | aggregated_metric-diff_sap = aggregated_metric-diff_sap + metric->diff_sap .
50 | aggregated_metric-mod_db = aggregated_metric-mod_db + metric->mod_db .
51 | aggregated_metric-mod_call = aggregated_metric-mod_call + metric->mod_call .
52 | aggregated_metric-mod_bra = aggregated_metric-mod_bra + metric->mod_bra .
53 | aggregated_metric-number_of_methods = aggregated_metric-number_of_methods + 1.
54 | AT END OF modu_unit_1.
55 | aggregated_metric-average_nos_per_method = aggregated_metric-nos / aggregated_metric-number_of_methods.
56 | aggregated_metric-decission_depth_complexity = aggregated_metric-dd_total.
57 | aggregated_metric-db_access_statements = aggregated_metric-stmts_sl +
58 | aggregated_metric-stmts_ins +
59 | aggregated_metric-stmts_mod +
60 | aggregated_metric-stmts_del.
61 |
62 | aggregated_metric-cyclomatic_complexity = aggregated_metric-stmts_i +
63 | aggregated_metric-stmts_e +
64 | aggregated_metric-stmts_ei +
65 | aggregated_metric-stmts_d +
66 | aggregated_metric-stmts_w +
67 | aggregated_metric-stmts_l +
68 | aggregated_metric-stmts_ca +
69 | aggregated_metric-stmts_wh.
70 | aggregated_metric-cyclomatic_complexity_avg = aggregated_metric-cyclomatic_complexity / aggregated_metric-number_of_methods.
71 |
72 |
73 | APPEND aggregated_metric TO result.
74 | CLEAR aggregated_metric.
75 | ENDAT.
76 | ENDLOOP.
77 | ENDMETHOD.
78 | ENDCLASS.
79 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_where_used_abstract.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_i_a2cc_where_used_abstract DEFINITION
2 | PUBLIC
3 | ABSTRACT
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 | CLASS-METHODS class_constructor.
8 | INTERFACES zif_i_a2cc_where_used.
9 | METHODS constructor
10 | IMPORTING objecttype TYPE zif_i_a2cc_where_used_provider=>objecttype.
11 | PROTECTED SECTION.
12 | DATA objecttype TYPE zif_i_a2cc_where_used_provider=>objecttype.
13 | METHODS get_where_used_list_from_cross
14 | IMPORTING
15 | object TYPE string
16 | RETURNING
17 | VALUE(result) TYPE REF TO zif_i_a2cc_where_used~object_list.
18 | PRIVATE SECTION.
19 | TYPES: BEGIN OF internal_object,
20 | type TYPE euobj-type,
21 | id TYPE euobj-id,
22 | END OF internal_object.
23 |
24 | CLASS-DATA internal_objects TYPE SORTED TABLE OF internal_object WITH NON-UNIQUE KEY type.
25 |
26 | METHODS get_enclosing_object
27 | IMPORTING
28 | found_object TYPE REF TO rsfindlst
29 | EXPORTING
30 | enclosing_object TYPE rsobject
31 | enclosing_type TYPE trobjtype .
32 | METHODS get_parent_object_type
33 | IMPORTING
34 | found_object TYPE REF TO rsfindlst
35 | RETURNING
36 | VALUE(result) TYPE seu_obj.
37 | ENDCLASS.
38 |
39 |
40 |
41 | CLASS zcl_i_a2cc_where_used_abstract IMPLEMENTATION.
42 | METHOD class_constructor.
43 | SELECT * FROM euobj INTO CORRESPONDING FIELDS OF TABLE internal_objects WHERE internal = abap_false.
44 | ENDMETHOD.
45 |
46 | METHOD constructor.
47 | me->objecttype = objecttype.
48 | ENDMETHOD.
49 |
50 |
51 | METHOD get_enclosing_object.
52 | DATA group TYPE rs38l_area.
53 | DATA include TYPE progname.
54 |
55 | include = found_object->object.
56 | CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT'
57 | IMPORTING
58 | group = group
59 | CHANGING
60 | include = include
61 | EXCEPTIONS
62 | OTHERS = 6.
63 | IF sy-subrc = 0 AND group IS NOT INITIAL.
64 | enclosing_object = |SAPL{ group }|.
65 | enclosing_type = 'FUGR'.
66 | ELSE.
67 | enclosing_type = 'PROG'.
68 | SELECT SINGLE master FROM d010inc INTO enclosing_object WHERE include = include.
69 | IF sy-subrc <> 0.
70 | enclosing_object = include.
71 | ENDIF.
72 | ENDIF.
73 | ENDMETHOD.
74 |
75 |
76 | METHOD get_where_used_list_from_cross.
77 | DATA: findstrings TYPE TABLE OF rsfind,
78 | found_objects TYPE STANDARD TABLE OF rsfindlst,
79 | scope TYPE STANDARD TABLE OF seu_obj,
80 | find_obj_class TYPE euobj-id.
81 | DATA enclosing_type TYPE trobjtype.
82 | DATA enclosing_object TYPE rsobject.
83 |
84 | findstrings = VALUE #( ( CONV #( object ) ) ).
85 | find_obj_class = me->objecttype.
86 |
87 | CALL FUNCTION 'RS_EU_CROSSREF'
88 | EXPORTING
89 | i_find_obj_cls = find_obj_class
90 | no_dialog = abap_true
91 | TABLES
92 | i_findstrings = findstrings
93 | o_founds = found_objects
94 | i_scope_object_cls = scope
95 | EXCEPTIONS
96 | not_executed = 1
97 | not_found = 2
98 | illegal_object = 3
99 | no_cross_for_this_object = 4
100 | batch = 5
101 | batchjob_error = 6
102 | wrong_type = 7
103 | object_not_exist = 8
104 | OTHERS = 9.
105 | IF sy-subrc IS INITIAL.
106 | result = NEW #( ).
107 | LOOP AT found_objects REFERENCE INTO DATA(found_object).
108 |
109 | IF found_object->encl_objec IS NOT INITIAL.
110 | enclosing_object = found_object->encl_objec.
111 | enclosing_type = get_parent_object_type( found_object ).
112 | ELSE.
113 | get_enclosing_object( EXPORTING found_object = found_object
114 | IMPORTING enclosing_object = enclosing_object
115 | enclosing_type = enclosing_type ).
116 | ENDIF.
117 |
118 | IF line_exists( result->*[ depending_object = enclosing_object depending_type = enclosing_type(4) ] ).
119 | ASSIGN result->*[ depending_object = enclosing_object ] TO FIELD-SYMBOL().
120 | -number_of_usages = -number_of_usages + 1.
121 | ELSE.
122 | INSERT VALUE #( depending_object = enclosing_object depending_type = enclosing_type(4) number_of_usages = 1 ) INTO TABLE result->*.
123 | ENDIF. .
124 | ENDLOOP.
125 | ENDIF.
126 | ENDMETHOD.
127 |
128 | METHOD get_parent_object_type.
129 | result = VALUE seu_obj( internal_objects[ type = found_object->object_cls ]-id OPTIONAL ).
130 |
131 | result = COND #( WHEN result(4) = 'PROG' AND found_object->*(4) = 'SAPL' THEN 'FUGR'
132 | WHEN result = 'METH' THEN 'CLAS'
133 | ELSE result(4) ).
134 | ENDMETHOD.
135 |
136 | METHOD zif_i_a2cc_where_used~get_cross_references.
137 |
138 | ENDMETHOD.
139 | ENDCLASS.
140 |
--------------------------------------------------------------------------------
/src/zi_abap_to_codecharta.prog.abap:
--------------------------------------------------------------------------------
1 | *
2 | * This is version 0.5.3
3 | *
4 | *The MIT License (MIT)
5 | *
6 | *Copyright (c) 2021 Benjamin Weisheit
7 | *
8 | *Permission is hereby granted, free of charge, to any person obtaining a copy
9 | *of this software and associated documentation files (the "Software"), to deal
10 | *in the Software without restriction, including without limitation the rights
11 | *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | *copies of the Software, and to permit persons to whom the Software is
13 | *furnished to do so, subject to the following conditions:
14 | *
15 | *The above copyright notice and this permission notice shall be included in all
16 | *copies or substantial portions of the Software.
17 | *
18 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | *SOFTWARE.
25 |
26 | REPORT zi_abap_to_codecharta.
27 |
28 | CLASS lcl_code_metrics DEFINITION.
29 | PUBLIC SECTION.
30 | METHODS run
31 | IMPORTING
32 | selection_variant TYPE variant
33 | RETURNING
34 | VALUE(result) TYPE ztti_a2cc_code_metrics
35 | RAISING
36 | cx_salv_bs_sc_runtime_info.
37 | PRIVATE SECTION.
38 | METHODS set_alv_runtime_info.
39 | METHODS submit_code_metrics_report
40 | IMPORTING
41 | selection_variant TYPE variant.
42 | METHODS get_alv_list_from_report
43 | RETURNING
44 | VALUE(result) TYPE ztti_a2cc_code_metrics
45 | RAISING
46 | cx_salv_bs_sc_runtime_info.
47 | ENDCLASS.
48 |
49 | CLASS lcl_code_metrics IMPLEMENTATION.
50 | METHOD run.
51 | set_alv_runtime_info( ).
52 | submit_code_metrics_report( selection_variant ).
53 | result = get_alv_list_from_report( ).
54 | ENDMETHOD.
55 |
56 | METHOD get_alv_list_from_report.
57 | FIELD-SYMBOLS TYPE STANDARD TABLE.
58 | DATA alv_list TYPE REF TO data.
59 | cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = alv_list ).
60 | ASSIGN alv_list->* TO .
61 | MOVE-CORRESPONDING TO result.
62 | ENDMETHOD.
63 |
64 | METHOD submit_code_metrics_report.
65 | SUBMIT /sdf/cd_custom_code_metric
66 | USING SELECTION-SET selection_variant
67 | EXPORTING LIST TO MEMORY
68 | AND RETURN.
69 | ENDMETHOD.
70 |
71 | METHOD set_alv_runtime_info.
72 | cl_salv_bs_runtime_info=>set(
73 | EXPORTING display = abap_false
74 | metadata = abap_false
75 | data = abap_true ).
76 | ENDMETHOD.
77 | ENDCLASS.
78 |
79 | CLASS lcl_input_screen DEFINITION.
80 | PUBLIC SECTION.
81 | METHODS check_file_directory
82 | IMPORTING
83 | file TYPE localfile.
84 | METHODS check_variant
85 | IMPORTING
86 | variant TYPE variant.
87 | ENDCLASS.
88 |
89 | CLASS lcl_input_screen IMPLEMENTATION.
90 | METHOD check_file_directory.
91 | DATA directory TYPE localfile.
92 | CALL FUNCTION 'LIST_SPLIT_PATH'
93 | EXPORTING
94 | filename = file
95 | IMPORTING
96 | pathname = directory.
97 | CALL FUNCTION 'PFL_CHECK_DIRECTORY'
98 | EXPORTING
99 | directory_long = directory
100 | EXCEPTIONS
101 | pfl_dir_not_exist = 1
102 | pfl_permission_denied = 2
103 | pfl_cant_build_dataset_name = 3
104 | pfl_file_not_exist = 4
105 | pfl_authorization_missing = 5
106 | OTHERS = 6.
107 | IF sy-subrc <> 0.
108 | CASE sy-subrc.
109 | WHEN 1.
110 | MESSAGE 'Directory does not exist on the appserver'(002) TYPE 'E'.
111 | WHEN 2 OR 5.
112 | MESSAGE 'No permission to the directory on the appserver'(003) TYPE 'E'.
113 | WHEN OTHERS.
114 | MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
115 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
116 | ENDCASE.
117 | ENDIF.
118 | ENDMETHOD.
119 |
120 | METHOD check_variant.
121 | SELECT SINGLE variant INTO @DATA(exists) FROM varid
122 | WHERE report EQ '/SDF/CD_CUSTOM_CODE_METRIC'
123 | AND variant EQ @variant.
124 | IF sy-subrc IS NOT INITIAL.
125 | MESSAGE 'Variant not defined for Code Metrics in tx /SDF/CD_CCA'(001) TYPE 'E'.
126 | ENDIF.
127 | ENDMETHOD.
128 | ENDCLASS.
129 |
130 | CLASS lcl_file_output DEFINITION.
131 | PUBLIC SECTION.
132 | METHODS write_file
133 | IMPORTING
134 | VALUE(file_name) TYPE localfile
135 | json TYPE string.
136 | PRIVATE SECTION.
137 | METHODS convert_string_to_xstring
138 | IMPORTING
139 | string TYPE string
140 | RETURNING
141 | VALUE(result) TYPE xstring.
142 | METHODS write_xstring_to_file
143 | IMPORTING
144 | file_name TYPE localfile
145 | xstring TYPE xstring.
146 | METHODS adjust_filename
147 | IMPORTING
148 | file_name TYPE localfile
149 | RETURNING
150 | VALUE(result) TYPE localfile.
151 | ENDCLASS.
152 |
153 | CLASS lcl_file_output IMPLEMENTATION.
154 | METHOD write_file.
155 | write_xstring_to_file(
156 | file_name = adjust_filename( file_name )
157 | xstring = convert_string_to_xstring( json ) ).
158 | ENDMETHOD.
159 | METHOD write_xstring_to_file.
160 | OPEN DATASET file_name FOR OUTPUT IN BINARY MODE.
161 | IF sy-subrc NE 0.
162 | WRITE : / 'Error Opening the Server Filepath :', file_name.
163 | ELSE.
164 | TRANSFER xstring TO file_name.
165 | CLOSE DATASET file_name.
166 | WRITE : / 'File Downloaded to the Server at :', file_name.
167 | ENDIF.
168 | ENDMETHOD.
169 |
170 | METHOD convert_string_to_xstring.
171 | CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
172 | EXPORTING
173 | text = string
174 | IMPORTING
175 | buffer = result.
176 | ENDMETHOD.
177 |
178 | METHOD adjust_filename.
179 | result = file_name.
180 | REPLACE ALL OCCURRENCES OF '' IN result WITH sy-datum.
181 | ENDMETHOD.
182 | ENDCLASS.
183 |
184 | PARAMETERS varnt TYPE variant.
185 | PARAMETERS file TYPE localfile.
186 |
187 | SELECTION-SCREEN BEGIN OF BLOCK d WITH FRAME TITLE TEXT-bld.
188 | PARAMETERS agg_modl TYPE abap_bool RADIOBUTTON GROUP agg DEFAULT 'X'.
189 | PARAMETERS agg_devc TYPE abap_bool RADIOBUTTON GROUP agg.
190 | SELECTION-SCREEN END OF BLOCK d.
191 |
192 | SELECTION-SCREEN BEGIN OF BLOCK a WITH FRAME TITLE TEXT-bla.
193 | PARAMETERS dpndncy TYPE abap_bool RADIOBUTTON GROUP dpn DEFAULT 'X'.
194 | PARAMETERS wo_dpnd TYPE abap_bool RADIOBUTTON GROUP dpn.
195 | PARAMETERS cycls TYPE abap_bool RADIOBUTTON GROUP dpn.
196 | SELECTION-SCREEN END OF BLOCK a.
197 |
198 | AT SELECTION-SCREEN.
199 | DATA(input_screen) = NEW lcl_input_screen( ).
200 | input_screen->check_file_directory( file ).
201 | input_screen->check_variant( varnt ).
202 |
203 | START-OF-SELECTION.
204 | DATA(code_metrics) = NEW lcl_code_metrics( )->run( varnt ).
205 |
206 | DATA(abap2codecharta) = zcl_i_a2cc_factory=>create( COND #( WHEN agg_devc = abap_true
207 | THEN zcl_i_a2cc_factory=>aggregation_levels-package
208 | ELSE zcl_i_a2cc_factory=>aggregation_levels-class ) ).
209 |
210 | DATA(json) = abap2codecharta->to_json( metrics = code_metrics
211 | analyze_dependecies = dpndncy
212 | analyze_direct_cycles = cycls ).
213 |
214 | NEW lcl_file_output( )->write_file( file_name = file
215 | json = json ).
216 |
--------------------------------------------------------------------------------
/src/zsi_a2cc_code_metrics.tabl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZSI_A2CC_CODE_METRICS
7 | D
8 | INTTAB
9 | D
10 | 1
11 |
12 |
13 |
14 | ZSI_A2CC_CODE_METRICS
15 | PACKAGE
16 | 0001
17 | CHAR30
18 | 0
19 | E
20 |
21 |
22 | ZSI_A2CC_CODE_METRICS
23 | CATEGORY
24 | 0002
25 | CHAR4
26 | 0
27 | E
28 |
29 |
30 | ZSI_A2CC_CODE_METRICS
31 | MODU_UNIT_1
32 | 0003
33 | ZEI_A2CC_OBJECT_ID
34 | 0
35 | E
36 |
37 |
38 | ZSI_A2CC_CODE_METRICS
39 | SUB_TYPE
40 | 0004
41 | CHAR4
42 | 0
43 | E
44 |
45 |
46 | ZSI_A2CC_CODE_METRICS
47 | MODU_UNIT_2
48 | 0005
49 | ZEI_A2CC_OBJECT_ID
50 | 0
51 | E
52 |
53 |
54 | ZSI_A2CC_CODE_METRICS
55 | AUTHOR
56 | 0006
57 | CHAR30
58 | 0
59 | E
60 |
61 |
62 | ZSI_A2CC_CODE_METRICS
63 | CHANGER
64 | 0007
65 | CHAR30
66 | 0
67 | E
68 |
69 |
70 | ZSI_A2CC_CODE_METRICS
71 | SOBJ_NAME
72 | 0008
73 | CHAR128
74 | 0
75 | E
76 |
77 |
78 | ZSI_A2CC_CODE_METRICS
79 | LOC
80 | 0009
81 | INT4
82 | 0
83 | E
84 |
85 |
86 | ZSI_A2CC_CODE_METRICS
87 | NOS
88 | 0010
89 | INT4
90 | 0
91 | E
92 |
93 |
94 | ZSI_A2CC_CODE_METRICS
95 | NOC
96 | 0011
97 | INT4
98 | 0
99 | E
100 |
101 |
102 | ZSI_A2CC_CODE_METRICS
103 | NOP
104 | 0012
105 | INT4
106 | 0
107 | E
108 |
109 |
110 | ZSI_A2CC_CODE_METRICS
111 | MCC_COM
112 | 0013
113 | INT4
114 | 0
115 | E
116 |
117 |
118 | ZSI_A2CC_CODE_METRICS
119 | VRSD_CHAN
120 | 0014
121 | INT4
122 | 0
123 | E
124 |
125 |
126 | ZSI_A2CC_CODE_METRICS
127 | DD_TOTAL
128 | 0015
129 | INT4
130 | 0
131 | E
132 |
133 |
134 | ZSI_A2CC_CODE_METRICS
135 | STMTS_C
136 | 0016
137 | INT4
138 | 0
139 | E
140 |
141 |
142 | ZSI_A2CC_CODE_METRICS
143 | STMTS_P
144 | 0017
145 | INT4
146 | 0
147 | E
148 |
149 |
150 | ZSI_A2CC_CODE_METRICS
151 | STMTS_I
152 | 0018
153 | INT4
154 | 0
155 | E
156 |
157 |
158 | ZSI_A2CC_CODE_METRICS
159 | STMTS_E
160 | 0019
161 | INT4
162 | 0
163 | E
164 |
165 |
166 | ZSI_A2CC_CODE_METRICS
167 | STMTS_EI
168 | 0020
169 | INT4
170 | 0
171 | E
172 |
173 |
174 | ZSI_A2CC_CODE_METRICS
175 | STMTS_D
176 | 0021
177 | INT4
178 | 0
179 | E
180 |
181 |
182 | ZSI_A2CC_CODE_METRICS
183 | STMTS_W
184 | 0022
185 | INT4
186 | 0
187 | E
188 |
189 |
190 | ZSI_A2CC_CODE_METRICS
191 | STMTS_L
192 | 0023
193 | INT4
194 | 0
195 | E
196 |
197 |
198 | ZSI_A2CC_CODE_METRICS
199 | STMTS_CA
200 | 0024
201 | INT4
202 | 0
203 | E
204 |
205 |
206 | ZSI_A2CC_CODE_METRICS
207 | STMTS_WH
208 | 0025
209 | INT4
210 | 0
211 | E
212 |
213 |
214 | ZSI_A2CC_CODE_METRICS
215 | STMTS_SL
216 | 0026
217 | INT4
218 | 0
219 | E
220 |
221 |
222 | ZSI_A2CC_CODE_METRICS
223 | STMTS_INS
224 | 0027
225 | INT4
226 | 0
227 | E
228 |
229 |
230 | ZSI_A2CC_CODE_METRICS
231 | STMTS_UPD
232 | 0028
233 | INT4
234 | 0
235 | E
236 |
237 |
238 | ZSI_A2CC_CODE_METRICS
239 | STMTS_DEL
240 | 0029
241 | INT4
242 | 0
243 | E
244 |
245 |
246 | ZSI_A2CC_CODE_METRICS
247 | STMTS_MOD
248 | 0030
249 | INT4
250 | 0
251 | E
252 |
253 |
254 | ZSI_A2CC_CODE_METRICS
255 | DIFF_VERS
256 | 0031
257 | INT4
258 | 0
259 | E
260 |
261 |
262 | ZSI_A2CC_CODE_METRICS
263 | DIFF_MOD_L
264 | 0032
265 | INT4
266 | 0
267 | E
268 |
269 |
270 | ZSI_A2CC_CODE_METRICS
271 | DIFF_NEW_L
272 | 0033
273 | INT4
274 | 0
275 | E
276 |
277 |
278 | ZSI_A2CC_CODE_METRICS
279 | DIFF_SAP
280 | 0034
281 | INT4
282 | 0
283 | E
284 |
285 |
286 | ZSI_A2CC_CODE_METRICS
287 | MOD_DB
288 | 0035
289 | INT4
290 | 0
291 | E
292 |
293 |
294 | ZSI_A2CC_CODE_METRICS
295 | MOD_CALL
296 | 0036
297 | INT4
298 | 0
299 | E
300 |
301 |
302 | ZSI_A2CC_CODE_METRICS
303 | MOD_BRA
304 | 0037
305 | INT4
306 | 0
307 | E
308 |
309 |
310 | ZSI_A2CC_CODE_METRICS
311 | NUMBER_OF_METHODS
312 | 0038
313 | INT4
314 | 0
315 | E
316 |
317 |
318 | ZSI_A2CC_CODE_METRICS
319 | AVERAGE_NOS_PER_METHOD
320 | 0039
321 | GTB_QUAN_TOTAL
322 | 0
323 | GTB_S_ALV_REFERENCE
324 | GTB_MEINH
325 | E
326 |
327 |
328 | ZSI_A2CC_CODE_METRICS
329 | DECISSION_DEPTH_COMPLEXITY
330 | 0040
331 | GTB_QUAN_TOTAL
332 | 0
333 | GTB_S_ALV_REFERENCE
334 | GTB_MEINH
335 | E
336 |
337 |
338 | ZSI_A2CC_CODE_METRICS
339 | DB_ACCESS_STATEMENTS
340 | 0041
341 | GTB_QUAN_TOTAL
342 | 0
343 | GTB_S_ALV_REFERENCE
344 | GTB_MEINH
345 | E
346 |
347 |
348 | ZSI_A2CC_CODE_METRICS
349 | CYCLOMATIC_COMPLEXITY
350 | 0042
351 | GTB_QUAN_TOTAL
352 | 0
353 | GTB_S_ALV_REFERENCE
354 | GTB_MEINH
355 | E
356 |
357 |
358 | ZSI_A2CC_CODE_METRICS
359 | CYCLOMATIC_COMPLEXITY_AVG
360 | 0043
361 | GTB_QUAN_TOTAL
362 | 0
363 | GTB_S_ALV_REFERENCE
364 | GTB_MEINH
365 | E
366 |
367 |
368 | ZSI_A2CC_CODE_METRICS
369 | COMPONENT_TO_BE_CHANGED
370 | D
371 | 0044
372 | 0
373 | g
374 | 000008
375 | STRG
376 | STRG
377 |
378 |
379 |
380 |
381 |
382 |
--------------------------------------------------------------------------------
/src/zcl_i_a2cc_metrics_2_json.clas.abap:
--------------------------------------------------------------------------------
1 | *
2 | * This is version 0.1.0
3 | *
4 | *The MIT License (MIT)
5 | *
6 | *Copyright (c) 2021 Benjamin Weisheit
7 | *
8 | *Permission is hereby granted, free of charge, to any person obtaining a copy
9 | *of this software and associated documentation files (the "Software"), to deal
10 | *in the Software without restriction, including without limitation the rights
11 | *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | *copies of the Software, and to permit persons to whom the Software is
13 | *furnished to do so, subject to the following conditions:
14 | *
15 | *The above copyright notice and this permission notice shall be included in all
16 | *copies or substantial portions of the Software.
17 | *
18 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | *SOFTWARE.
25 | CLASS zcl_i_a2cc_metrics_2_json DEFINITION
26 | PUBLIC
27 | FINAL
28 | CREATE PUBLIC .
29 |
30 | PUBLIC SECTION.
31 | INTERFACES zif_i_a2cc_metrics_2_json.
32 | METHODS constructor
33 | IMPORTING
34 | json_writer TYPE REF TO if_sxml_writer
35 | package_analyzer TYPE REF TO zif_i_a2cc_package_analyzer
36 | dependency_analyzer TYPE REF TO zif_i_a2cc_dependency_analyzer
37 | metric_aggregator TYPE REF TO zif_i_a2cc_aggregator .
38 |
39 |
40 | CONSTANTS system TYPE string VALUE `/root/SYSTEM/OUTSIDE`.
41 |
42 | PRIVATE SECTION.
43 | CONSTANTS numeric TYPE string VALUE 'num' ##NO_TEXT.
44 | CONSTANTS strng TYPE string VALUE 'str' ##NO_TEXT.
45 | CONSTANTS array TYPE string VALUE 'array' ##NO_TEXT.
46 | CONSTANTS objct TYPE string VALUE 'object' ##NO_TEXT.
47 | DATA object_where_used_list_by TYPE zif_i_a2cc_where_used=>where_used_list.
48 | DATA analyze_dependecies TYPE abap_bool.
49 | DATA analyze_direct_cycles TYPE abap_bool.
50 |
51 |
52 | CLASS-DATA json_writer TYPE REF TO if_sxml_writer.
53 |
54 | METHODS write_package
55 | IMPORTING
56 | package TYPE zsi_a2cc_packages
57 | RAISING
58 | cx_sxml_state_error.
59 | METHODS convert2json
60 | RETURNING
61 | VALUE(result) TYPE string.
62 | METHODS write_edges.
63 | METHODS get_full_classpath
64 | IMPORTING
65 | object TYPE classname
66 | type TYPE trobjtype
67 | RETURNING
68 | VALUE(result) TYPE string.
69 | METHODS open_document
70 | RAISING
71 | cx_sxml_state_error.
72 | METHODS write_node_system_outside
73 | RAISING
74 | cx_sxml_state_error.
75 | METHODS open_nodes
76 | RAISING
77 | cx_sxml_state_error.
78 | METHODS close_nodes
79 | RAISING
80 | cx_sxml_state_error.
81 | METHODS open_edges
82 | RAISING
83 | cx_sxml_state_error.
84 | METHODS close_edges
85 | RAISING
86 | cx_sxml_state_error.
87 | METHODS close_document
88 | RAISING
89 | cx_sxml_state_error.
90 |
91 | METHODS write_nodes
92 | RAISING
93 | cx_sxml_state_error.
94 |
95 | METHODS find_object_usages
96 | IMPORTING
97 | metrics TYPE ztti_a2cc_code_metrics.
98 |
99 | CLASS-METHODS write_element IMPORTING name TYPE string
100 | attr TYPE string OPTIONAL
101 | value TYPE string OPTIONAL
102 | RAISING cx_sxml_state_error.
103 | DATA: aggregated_metrics TYPE ztti_a2cc_code_metrics,
104 | package_analyzer TYPE REF TO zif_i_a2cc_package_analyzer,
105 | dependency_analyzer TYPE REF TO zif_i_a2cc_dependency_analyzer,
106 | metric_aggregator TYPE REF TO zif_i_a2cc_aggregator,
107 | packages TYPE ztti_a2cc_packages.
108 | ENDCLASS.
109 |
110 |
111 |
112 | CLASS zcl_i_a2cc_metrics_2_json IMPLEMENTATION.
113 |
114 |
115 | METHOD close_document.
116 | json_writer->close_element( ).
117 | ENDMETHOD.
118 |
119 |
120 | METHOD close_edges.
121 | json_writer->close_element( ).
122 | ENDMETHOD.
123 |
124 |
125 | METHOD close_nodes.
126 | json_writer->close_element( ).
127 | json_writer->close_element( ).
128 | json_writer->close_element( ).
129 | ENDMETHOD.
130 |
131 |
132 | METHOD constructor.
133 | me->json_writer = json_writer.
134 | me->package_analyzer = package_analyzer.
135 | me->dependency_analyzer = dependency_analyzer.
136 | me->metric_aggregator = metric_aggregator.
137 | ENDMETHOD.
138 |
139 |
140 | METHOD convert2json.
141 | open_document( ).
142 | open_nodes( ).
143 | write_node_system_outside( ).
144 | write_nodes( ).
145 | close_nodes( ).
146 | open_edges( ).
147 | write_edges( ).
148 | close_edges( ).
149 | close_document( ).
150 |
151 | DATA(xjson) = CAST cl_sxml_string_writer( json_writer )->get_output( ).
152 | DATA(reader) = cl_sxml_string_reader=>create( xjson ).
153 | DATA(writer) = CAST if_sxml_writer(
154 | cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).
155 | writer->set_option( option = if_sxml_writer=>co_opt_linebreaks ).
156 | writer->set_option( option = if_sxml_writer=>co_opt_indent ).
157 | reader->next_node( ).
158 | reader->skip_node( writer ).
159 | result = cl_abap_codepage=>convert_from( CAST cl_sxml_string_writer( writer )->get_output( ) ).
160 | ENDMETHOD.
161 |
162 |
163 | METHOD find_object_usages.
164 | object_where_used_list_by = dependency_analyzer->find_object_usages( metrics = metrics
165 | analyze_dependecies = analyze_dependecies
166 | analyze_direct_cycles = analyze_direct_cycles ).
167 | ENDMETHOD.
168 |
169 |
170 | METHOD get_full_classpath.
171 | DATA path TYPE string.
172 |
173 | TRY.
174 | DATA(package) = aggregated_metrics[ modu_unit_1 = object ]-package.
175 | path = package.
176 | path = package_analyzer->get_parent_packages( package ).
177 | result = |/root/{ path }/{ object }.{ type }|.
178 | CATCH cx_sy_itab_line_not_found.
179 | result = system.
180 | ENDTRY.
181 | ENDMETHOD.
182 |
183 |
184 | METHOD open_document.
185 | write_element( name = objct ).
186 | write_element( name = strng attr = 'projectName' value = 'ABAP' ).
187 | json_writer->close_element( ).
188 | write_element( name = strng attr = 'apiVersion' value = '1.1' ).
189 | json_writer->close_element( ).
190 | ENDMETHOD.
191 |
192 |
193 | METHOD open_edges.
194 | write_element( name = array attr = 'edges' ).
195 | ENDMETHOD.
196 |
197 |
198 | METHOD open_nodes.
199 | write_element( name = array attr = 'nodes' ).
200 | write_element( name = objct ).
201 | write_element( name = strng attr = 'name' value = 'root' ).
202 | json_writer->close_element( ).
203 | write_element( name = strng attr = 'type' value = 'Folder' ).
204 | json_writer->close_element( ).
205 | write_element( name = objct attr = 'attributes' ).
206 | json_writer->close_element( ).
207 | write_element( name = strng attr = 'link' ).
208 | json_writer->close_element( ).
209 | write_element( name = array attr = 'children' ).
210 | ENDMETHOD.
211 |
212 |
213 | METHOD zif_i_a2cc_metrics_2_json~to_json.
214 | me->analyze_dependecies = analyze_dependecies.
215 | me->analyze_direct_cycles = analyze_direct_cycles.
216 |
217 | SORT metrics.
218 |
219 | find_object_usages( metrics ).
220 | aggregated_metrics = metric_aggregator->aggregate_metrics( metrics ).
221 | packages = package_analyzer->aggregate_packages( aggregated_metrics ).
222 | result = convert2json( ).
223 | ENDMETHOD.
224 |
225 |
226 | METHOD write_edges.
227 | IF analyze_dependecies = abap_true OR analyze_direct_cycles = abap_true.
228 | LOOP AT object_where_used_list_by REFERENCE INTO DATA(usage).
229 | LOOP AT usage->references REFERENCE INTO DATA(used_by)
230 | WHERE depending_object <> usage->object_identifier.
231 | write_element( name = objct ).
232 | write_element( name = strng attr = 'fromNodeName' value = get_full_classpath( object = CONV #( used_by->depending_object ) type = used_by->depending_type ) ).
233 | json_writer->close_element( ).
234 | write_element( name = strng attr = 'toNodeName' value = get_full_classpath( object = CONV #( usage->object_identifier ) type = usage->object_type ) ).
235 | json_writer->close_element( ).
236 | write_element( name = objct attr = 'attributes' ).
237 | IF analyze_dependecies = abap_true.
238 | write_element( name = numeric attr = 'usage' value = CONV #( used_by->number_of_usages ) ).
239 | json_writer->close_element( ).
240 | ENDIF.
241 | IF used_by->cycle > 0 AND analyze_direct_cycles = abap_true.
242 | write_element( name = numeric attr = 'cycle' value = CONV #( used_by->cycle ) ).
243 | json_writer->close_element( ).
244 | ENDIF.
245 | json_writer->close_element( ).
246 | json_writer->close_element( ).
247 | ENDLOOP.
248 | ENDLOOP.
249 | ENDIF.
250 | ENDMETHOD.
251 |
252 |
253 | METHOD write_element.
254 | json_writer->open_element( name ).
255 | IF attr IS NOT INITIAL.
256 | json_writer->write_attribute( name = 'name' value = attr ).
257 | ENDIF.
258 | IF value IS NOT INITIAL.
259 | json_writer->write_value( value ).
260 | ENDIF.
261 | ENDMETHOD.
262 |
263 |
264 | METHOD write_nodes.
265 | LOOP AT packages REFERENCE INTO DATA(package)
266 | WHERE parent IS INITIAL.
267 | write_package( package->* ).
268 | ENDLOOP.
269 | ENDMETHOD.
270 |
271 |
272 | METHOD write_node_system_outside.
273 | write_element( name = objct ).
274 | write_element( name = strng attr = 'name' value = 'SYSTEM' ).
275 | json_writer->close_element( ).
276 | write_element( name = strng attr = 'type' value = 'Folder' ).
277 | json_writer->close_element( ).
278 | write_element( name = objct attr = 'attributes' ).
279 | json_writer->close_element( ).
280 | write_element( name = strng attr = 'link' ).
281 | json_writer->close_element( ).
282 | write_element( name = array attr = 'children' ).
283 |
284 | write_element( name = objct ).
285 | write_element( name = strng attr = 'name' value = CONV #( 'OUTSIDE' ) ).
286 | json_writer->close_element( ).
287 | write_element( name = strng attr = 'type' value = 'File' ).
288 | json_writer->close_element( ).
289 | write_element( name = objct attr = 'attributes' ).
290 |
291 |
292 | write_element( name = numeric attr = 'LinesOfCode' value = '200' ).
293 | json_writer->close_element( ).
294 | write_element( name = numeric attr = 'Statements' value = '200' ).
295 | json_writer->close_element( ).
296 | write_element( name = numeric attr = 'AvgStatementsPerMethod' value = '30' ).
297 | json_writer->close_element( ).
298 | write_element( name = numeric attr = 'NumberOfChanges' value = '10' ).
299 | json_writer->close_element( ).
300 | write_element( name = numeric attr = 'ComplexityOfConditions' value = '10' ).
301 | json_writer->close_element( ).
302 | write_element( name = numeric attr = 'DecissionDepth' value = '10' ).
303 | json_writer->close_element( ).
304 |
305 | json_writer->close_element( ).
306 | write_element( name = strng attr = 'link' value = VALUE #( ) ).
307 | json_writer->close_element( ).
308 | write_element( name = array attr = 'children' ).
309 | json_writer->close_element( ).
310 | json_writer->close_element( ).
311 |
312 | json_writer->close_element( ).
313 | json_writer->close_element( ).
314 | ENDMETHOD.
315 |
316 |
317 | METHOD write_package.
318 | write_element( name = objct ).
319 | write_element( name = strng attr = 'name' value = CONV #( package-package ) ).
320 | json_writer->close_element( ).
321 | write_element( name = strng attr = 'type' value = 'Folder' ).
322 | json_writer->close_element( ).
323 | write_element( name = objct attr = 'attributes' ).
324 | json_writer->close_element( ).
325 | write_element( name = strng attr = 'link' ).
326 | json_writer->close_element( ).
327 | write_element( name = array attr = 'children' ).
328 | LOOP AT aggregated_metrics REFERENCE INTO DATA(class)
329 | WHERE package = package-package.
330 | write_element( name = objct ).
331 | write_element( name = strng attr = 'name' value = |{ class->modu_unit_1 }.{ class->category }| ).
332 | json_writer->close_element( ).
333 | write_element( name = strng attr = 'type' value = 'File' ).
334 | json_writer->close_element( ).
335 | write_element( name = objct attr = 'attributes' ).
336 |
337 |
338 | write_element( name = numeric attr = 'LinesOfCode' value = CONV #( class->loc ) ).
339 | json_writer->close_element( ).
340 | write_element( name = numeric attr = 'Statements' value = CONV #( class->nos ) ).
341 | json_writer->close_element( ).
342 | write_element( name = numeric attr = 'AvgStatementsPerMethod' value = CONV #( class->average_nos_per_method ) ).
343 | json_writer->close_element( ).
344 | write_element( name = numeric attr = 'NumberOfChanges' value = CONV #( class->diff_vers ) )..
345 | json_writer->close_element( ).
346 | write_element( name = numeric attr = 'DecissionDepth' value = CONV #( class->decission_depth_complexity ) ).
347 | json_writer->close_element( ).
348 | write_element( name = numeric attr = 'DbAccesses' value = CONV #( class->db_access_statements ) ).
349 | json_writer->close_element( ).
350 | write_element( name = numeric attr = 'Complexity' value = CONV #( class->cyclomatic_complexity ) ).
351 | json_writer->close_element( ).
352 | write_element( name = numeric attr = 'AvgComplexityPerMethod' value = CONV #( class->cyclomatic_complexity_avg ) ).
353 | json_writer->close_element( ).
354 |
355 | json_writer->close_element( ).
356 | write_element( name = strng attr = 'link' value = VALUE #( ) ).
357 | json_writer->close_element( ).
358 | write_element( name = array attr = 'children' ).
359 | json_writer->close_element( ).
360 | json_writer->close_element( ).
361 | ENDLOOP.
362 | LOOP AT packages REFERENCE INTO DATA(child_package)
363 | WHERE parent = package-package.
364 | write_package( child_package->* ).
365 | ENDLOOP.
366 | json_writer->close_element( ).
367 | json_writer->close_element( ).
368 | ENDMETHOD.
369 | ENDCLASS.
370 |
--------------------------------------------------------------------------------