Skip to content

Latest commit

 

History

History
executable file
·
974 lines (762 loc) · 29 KB

File metadata and controls

executable file
·
974 lines (762 loc) · 29 KB

Improved Graph Architecture Design for ZRAY

Date: 2025-12-02 Subject: Redesign ZCL_XRAY_GRAPH with cleaner architecture and complete functionality Status: Design Proposal


Current Architecture Issues

Problems with ZCL_XRAY_GRAPH

From analyzing the ZRAY source code, we identified these issues:

  1. Mixed Responsibilities

    • Querying CROSS/WBCROSSGT
    • Caching logic
    • Graph traversal
    • Filter management
    • Node detection
    • All in one class (God Object anti-pattern)
  2. Incomplete Functionality

    • DOWN traversal well-developed
    • UP traversal less comprehensive
    • Not all CROSS types handled (only F, R, T, S, U)
    • Not all WBCROSSGT types handled (only ME, TY, DA, EV, TK)
    • Missing types: Messages (N), Authorities (A), Transformations (2), etc.
  3. Tight Coupling

    • Caching logic embedded in traversal
    • Filter ranges hardcoded in methods
    • Difficult to test individual components
    • Hard to extend with new traversal strategies
  4. Limited Extensibility

    • Adding new analysis requires modifying core class
    • No visitor pattern for graph operations
    • Filter composition is cumbersome
    • No fluent API for configuration

Proposed Architecture

Design Principles

  1. Single Responsibility - Each class has one clear purpose
  2. Open/Closed - Open for extension, closed for modification
  3. Interface Segregation - Small, focused interfaces
  4. Dependency Inversion - Depend on abstractions, not concretions
  5. Testability - Each component easily unit-testable

Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                      Client Code (Reports)                      │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                   ZCL_RAY_GRAPH_BUILDER                         │
│   (Fluent API for constructing graph traversals)               │
│   →new( )->with_package('Z*')->traverse_down()->build()        │
└─────────────────────────────────────────────────────────────────┘
              ↓                    ↓                    ↓
    ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
    │  Repository      │  │  Traverser       │  │  Filter          │
    │  (Data Access)   │  │  (Algorithm)     │  │  (Scope)         │
    └──────────────────┘  └──────────────────┘  └──────────────────┘
              ↓                    ↓                    ↓
┌─────────────────────────────────────────────────────────────────┐
│                      ZCL_RAY_GRAPH                              │
│             (Core graph data structure)                         │
│             Nodes + Edges + Indexes                             │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                   Graph Analyzers (Visitors)                    │
│   Metrics | Clustering | Paths | Impact | Visualization        │
└─────────────────────────────────────────────────────────────────┘

Component Design

1. Repository Layer (Data Access)

Interface: ZIF_RAY_GRAPH_REPOSITORY

INTERFACE zif_ray_graph_repository.
  " Query for dependencies (DOWN)
  METHODS query_dependencies_by_include
    IMPORTING it_includes TYPE tt_include
    RETURNING VALUE(rt_edges) TYPE tt_raw_edge.

  " Query for usage (UP)
  METHODS query_usage_by_object
    IMPORTING iv_type TYPE string
              iv_name TYPE string
    RETURNING VALUE(rt_edges) TYPE tt_raw_edge.

  " Get object metadata
  METHODS get_object_info
    IMPORTING iv_type TYPE string
              iv_name TYPE string
    RETURNING VALUE(rs_info) TYPE ts_object_info.
ENDINTERFACE.

Implementation: ZCL_RAY_GRAPH_REPO_CROSS

CLASS zcl_ray_graph_repo_cross DEFINITION
  IMPLEMENTING zif_ray_graph_repository.

  PUBLIC SECTION.
    TYPES: BEGIN OF ts_cross_entry,
             type    TYPE cross-type,
             name    TYPE cross-name,
             include TYPE cross-include,
             prog    TYPE cross-prog,
           END OF ts_cross_entry.

    METHODS query_dependencies_by_include REDEFINITION.
    METHODS query_usage_by_object REDEFINITION.
    METHODS get_object_info REDEFINITION.

  PRIVATE SECTION.
    DATA: mt_type_handlers TYPE tt_type_handler.

    METHODS query_cross
      IMPORTING it_includes TYPE tt_include
                it_filters  TYPE tt_filter
      RETURNING VALUE(rt_cross) TYPE tt_cross_entry.

    METHODS cross_to_edge
      IMPORTING is_cross TYPE ts_cross_entry
      RETURNING VALUE(rs_edge) TYPE ts_raw_edge.
ENDCLASS.

Implementation: ZCL_RAY_GRAPH_REPO_WBCROSSGT

CLASS zcl_ray_graph_repo_wbcrossgt DEFINITION
  IMPLEMENTING zif_ray_graph_repository.

  PUBLIC SECTION.
    TYPES: BEGIN OF ts_wbcrossgt_entry,
             otype   TYPE wbcrossgt-otype,
             name    TYPE wbcrossgt-name,
             include TYPE wbcrossgt-include,
           END OF ts_wbcrossgt_entry.

    METHODS query_dependencies_by_include REDEFINITION.
    METHODS query_usage_by_object REDEFINITION.
    METHODS get_object_info REDEFINITION.

  PRIVATE SECTION.
    METHODS query_wbcrossgt
      IMPORTING it_includes TYPE tt_include
                it_filters  TYPE tt_filter
      RETURNING VALUE(rt_wbcrossgt) TYPE tt_wbcrossgt_entry.

    METHODS wbcrossgt_to_edge
      IMPORTING is_wbcrossgt TYPE ts_wbcrossgt_entry
      RETURNING VALUE(rs_edge) TYPE ts_raw_edge.
ENDCLASS.

Decorator: ZCL_RAY_GRAPH_REPO_CACHED

CLASS zcl_ray_graph_repo_cached DEFINITION
  IMPLEMENTING zif_ray_graph_repository.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING io_repository TYPE REF TO zif_ray_graph_repository
                iv_seed       TYPE string OPTIONAL.

    METHODS query_dependencies_by_include REDEFINITION.
    METHODS query_usage_by_object REDEFINITION.
    METHODS get_object_info REDEFINITION.

    METHODS clear_cache.

  PRIVATE SECTION.
    DATA: mo_repository TYPE REF TO zif_ray_graph_repository,
          mv_seed       TYPE string,
          mt_cache_nodes TYPE tt_cached_node,
          mt_cache_edges TYPE tt_cached_edge.

    METHODS load_from_cache
      IMPORTING it_includes TYPE tt_include
      RETURNING VALUE(rt_edges) TYPE tt_raw_edge.

    METHODS save_to_cache
      IMPORTING it_edges TYPE tt_raw_edge.
ENDCLASS.

Composite: ZCL_RAY_GRAPH_REPO_COMPOSITE

CLASS zcl_ray_graph_repo_composite DEFINITION
  IMPLEMENTING zif_ray_graph_repository.

  PUBLIC SECTION.
    " Combines CROSS + WBCROSSGT queries
    METHODS constructor
      IMPORTING io_cross_repo TYPE REF TO zif_ray_graph_repository
                io_wbcrossgt_repo TYPE REF TO zif_ray_graph_repository.

    METHODS query_dependencies_by_include REDEFINITION.
    METHODS query_usage_by_object REDEFINITION.

  PRIVATE SECTION.
    DATA: mo_cross_repo TYPE REF TO zif_ray_graph_repository,
          mo_wbcrossgt_repo TYPE REF TO zif_ray_graph_repository.
ENDCLASS.

2. Filter Layer (Scope Management)

Interface: ZIF_RAY_GRAPH_FILTER

INTERFACE zif_ray_graph_filter.
  " Check if edge should be included
  METHODS matches
    IMPORTING is_edge TYPE ts_raw_edge
    RETURNING VALUE(rv_matches) TYPE abap_bool.

  " Check if node should be included
  METHODS matches_node
    IMPORTING is_node TYPE ts_node
    RETURNING VALUE(rv_matches) TYPE abap_bool.
ENDINTERFACE.

Implementation: ZCL_RAY_GRAPH_FILTER_PACKAGE

CLASS zcl_ray_graph_filter_package DEFINITION
  IMPLEMENTING zif_ray_graph_filter.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING it_packages TYPE tt_package_pattern.  " 'Z*', '$ZRAY*'

    METHODS matches REDEFINITION.
    METHODS matches_node REDEFINITION.

  PRIVATE SECTION.
    DATA: mtr_packages TYPE RANGE OF devclass.
ENDCLASS.

Implementation: ZCL_RAY_GRAPH_FILTER_TYPE

CLASS zcl_ray_graph_filter_type DEFINITION
  IMPLEMENTING zif_ray_graph_filter.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING it_types TYPE tt_object_type.  " CLAS, PROG, FUNC

    METHODS matches REDEFINITION.
    METHODS matches_node REDEFINITION.

  PRIVATE SECTION.
    DATA: mt_types TYPE tt_object_type.
ENDCLASS.

Composite: ZCL_RAY_GRAPH_FILTER_COMPOSITE

CLASS zcl_ray_graph_filter_composite DEFINITION
  IMPLEMENTING zif_ray_graph_filter.

  PUBLIC SECTION.
    METHODS add_filter
      IMPORTING io_filter TYPE REF TO zif_ray_graph_filter.

    METHODS matches REDEFINITION.
    METHODS matches_node REDEFINITION.

  PRIVATE SECTION.
    DATA: mt_filters TYPE tt_filter_ref.
    DATA: mv_operator TYPE char3.  " AND, OR
ENDCLASS.

Builder: ZCL_RAY_GRAPH_FILTER_BUILDER

CLASS zcl_ray_graph_filter_builder DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS create
      RETURNING VALUE(ro_builder) TYPE REF TO zcl_ray_graph_filter_builder.

    METHODS with_package
      IMPORTING iv_pattern TYPE string
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_filter_builder.

    METHODS with_type
      IMPORTING iv_type TYPE string
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_filter_builder.

    METHODS exclude_sap_standard
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_filter_builder.

    METHODS build
      RETURNING VALUE(ro_filter) TYPE REF TO zif_ray_graph_filter.

  PRIVATE SECTION.
    DATA: mt_package_patterns TYPE tt_string,
          mt_types TYPE tt_object_type,
          mv_exclude_sap TYPE abap_bool.
ENDCLASS.

" Usage:
DATA(lo_filter) = zcl_ray_graph_filter_builder=>create( )
  ->with_package( 'Z*' )
  ->with_package( '$ZRAY*' )
  ->with_type( 'CLAS' )
  ->with_type( 'FUNC' )
  ->exclude_sap_standard( )
  ->build( ).

3. Traversal Layer (Algorithms)

Interface: ZIF_RAY_GRAPH_TRAVERSER

INTERFACE zif_ray_graph_traverser.
  " Execute traversal
  METHODS traverse
    IMPORTING it_starting_nodes TYPE tt_node_id
              io_repository     TYPE REF TO zif_ray_graph_repository
              io_filter         TYPE REF TO zif_ray_graph_filter
              is_config         TYPE ts_traversal_config
    RETURNING VALUE(ro_graph)   TYPE REF TO zcl_ray_graph.

  TYPES: BEGIN OF ts_traversal_config,
           max_depth      TYPE i,
           max_nodes      TYPE i,
           max_edges      TYPE i,
           stop_at_boundary TYPE abap_bool,
         END OF ts_traversal_config.
ENDINTERFACE.

Implementation: ZCL_RAY_GRAPH_TRAV_DOWN

CLASS zcl_ray_graph_trav_down DEFINITION
  IMPLEMENTING zif_ray_graph_traverser.

  PUBLIC SECTION.
    METHODS traverse REDEFINITION.

  PRIVATE SECTION.
    METHODS traverse_level
      IMPORTING it_nodes TYPE tt_node_id
                iv_level TYPE i
                io_repository TYPE REF TO zif_ray_graph_repository
                io_filter TYPE REF TO zif_ray_graph_filter
                is_config TYPE ts_traversal_config
      CHANGING co_graph TYPE REF TO zcl_ray_graph.

    METHODS get_includes_for_node
      IMPORTING is_node TYPE ts_node
      RETURNING VALUE(rt_includes) TYPE tt_include.
ENDCLASS.

" Implementation:
METHOD traverse.
  ro_graph = NEW zcl_ray_graph( ).

  " Add starting nodes
  LOOP AT it_starting_nodes INTO DATA(lv_node_id).
    ro_graph->add_node( lv_node_id ).
  ENDLOOP.

  " Traverse level by level
  DATA(lt_current_level) = it_starting_nodes.
  DATA(lv_depth) = 0.

  WHILE lt_current_level IS NOT INITIAL.
    lv_depth = lv_depth + 1.

    " Check limits
    IF is_config-max_depth > 0 AND lv_depth > is_config-max_depth.
      EXIT.
    ENDIF.

    " Process current level
    traverse_level(
      EXPORTING it_nodes = lt_current_level
                iv_level = lv_depth
                io_repository = io_repository
                io_filter = io_filter
                is_config = is_config
      CHANGING co_graph = ro_graph
    ).

    " Get nodes discovered at this level for next iteration
    lt_current_level = ro_graph->get_nodes_at_level( lv_depth ).
  ENDWHILE.
ENDMETHOD.

Implementation: ZCL_RAY_GRAPH_TRAV_UP

CLASS zcl_ray_graph_trav_up DEFINITION
  IMPLEMENTING zif_ray_graph_traverser.

  PUBLIC SECTION.
    METHODS traverse REDEFINITION.

  PRIVATE SECTION.
    METHODS traverse_level
      IMPORTING it_nodes TYPE tt_node_id
                iv_level TYPE i
                io_repository TYPE REF TO zif_ray_graph_repository
                io_filter TYPE REF TO zif_ray_graph_filter
                is_config TYPE ts_traversal_config
      CHANGING co_graph TYPE REF TO zcl_ray_graph.

    METHODS query_usage
      IMPORTING is_node TYPE ts_node
                io_repository TYPE REF TO zif_ray_graph_repository
      RETURNING VALUE(rt_edges) TYPE tt_raw_edge.
ENDCLASS.

Implementation: ZCL_RAY_GRAPH_TRAV_BIDIRECTIONAL

CLASS zcl_ray_graph_trav_bidirectional DEFINITION
  IMPLEMENTING zif_ray_graph_traverser.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING io_down_traverser TYPE REF TO zif_ray_graph_traverser
                io_up_traverser   TYPE REF TO zif_ray_graph_traverser.

    METHODS traverse REDEFINITION.

  PRIVATE SECTION.
    DATA: mo_down_traverser TYPE REF TO zif_ray_graph_traverser,
          mo_up_traverser   TYPE REF TO zif_ray_graph_traverser.
ENDCLASS.

" Implementation:
METHOD traverse.
  " Execute both traversals
  DATA(lo_down_graph) = mo_down_traverser->traverse(
    it_starting_nodes = it_starting_nodes
    io_repository = io_repository
    io_filter = io_filter
    is_config = is_config
  ).

  DATA(lo_up_graph) = mo_up_traverser->traverse(
    it_starting_nodes = it_starting_nodes
    io_repository = io_repository
    io_filter = io_filter
    is_config = is_config
  ).

  " Merge graphs
  ro_graph = zcl_ray_graph=>merge(
    io_graph1 = lo_down_graph
    io_graph2 = lo_up_graph
  ).
ENDMETHOD.

4. Graph Core (Data Structure)

Class: ZCL_RAY_GRAPH

CLASS zcl_ray_graph DEFINITION.
  PUBLIC SECTION.
    " Node operations
    METHODS add_node
      IMPORTING is_node TYPE ts_node.

    METHODS get_node
      IMPORTING iv_node_id TYPE string
      RETURNING VALUE(rs_node) TYPE ts_node.

    METHODS get_all_nodes
      RETURNING VALUE(rt_nodes) TYPE tt_node.

    " Edge operations
    METHODS add_edge
      IMPORTING is_edge TYPE ts_edge.

    METHODS get_edges_from
      IMPORTING iv_node_id TYPE string
      RETURNING VALUE(rt_edges) TYPE tt_edge.

    METHODS get_edges_to
      IMPORTING iv_node_id TYPE string
      RETURNING VALUE(rt_edges) TYPE tt_edge.

    METHODS get_all_edges
      RETURNING VALUE(rt_edges) TYPE tt_edge.

    " Graph operations
    METHODS merge
      IMPORTING io_graph TYPE REF TO zcl_ray_graph
      RETURNING VALUE(ro_merged) TYPE REF TO zcl_ray_graph.

    CLASS-METHODS merge IMPORTING io_graph1 TYPE REF TO zcl_ray_graph
                                  io_graph2 TYPE REF TO zcl_ray_graph
                        RETURNING VALUE(ro_merged) TYPE REF TO zcl_ray_graph.

    " Visitor pattern
    METHODS accept
      IMPORTING io_visitor TYPE REF TO zif_ray_graph_visitor.

    " Metrics
    METHODS get_node_count
      RETURNING VALUE(rv_count) TYPE i.

    METHODS get_edge_count
      RETURNING VALUE(rv_count) TYPE i.

  PRIVATE SECTION.
    DATA: mt_nodes TYPE HASHED TABLE OF ts_node WITH UNIQUE KEY id,
          mt_edges TYPE STANDARD TABLE OF ts_edge,
          mt_index_from TYPE HASHED TABLE OF ts_edge_index WITH UNIQUE KEY from_id edge_id,
          mt_index_to   TYPE HASHED TABLE OF ts_edge_index WITH UNIQUE KEY to_id edge_id.
ENDCLASS.

Types:

TYPES: BEGIN OF ts_node,
         id            TYPE string,
         object_type   TYPE trobjtype,
         object_name   TYPE sobj_name,
         enclosing_type TYPE trobjtype,
         enclosing_name TYPE sobj_name,
         package       TYPE devclass,
         include       TYPE programm,
         level         TYPE i,
         metadata      TYPE REF TO data,
       END OF ts_node.

TYPES: BEGIN OF ts_edge,
         id     TYPE string,
         from   TYPE string,
         to     TYPE string,
         type   TYPE string,  " CALLS, USES, IMPLEMENTS, etc.
         source TYPE string,  " CROSS, WBCROSSGT
       END OF ts_edge.

5. Builder Layer (Fluent API)

Class: ZCL_RAY_GRAPH_BUILDER

CLASS zcl_ray_graph_builder DEFINITION.
  PUBLIC SECTION.
    " Factory
    CLASS-METHODS new
      RETURNING VALUE(ro_builder) TYPE REF TO zcl_ray_graph_builder.

    " Configuration
    METHODS with_starting_nodes
      IMPORTING it_nodes TYPE tt_node_id
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS with_package
      IMPORTING iv_package TYPE string
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS with_object_type
      IMPORTING iv_type TYPE string
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    " Traversal direction
    METHODS traverse_down
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS traverse_up
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS traverse_both
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    " Limits
    METHODS max_depth
      IMPORTING iv_depth TYPE i
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS max_nodes
      IMPORTING iv_nodes TYPE i
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    " Filters
    METHODS exclude_sap_standard
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS with_filter
      IMPORTING io_filter TYPE REF TO zif_ray_graph_filter
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    " Caching
    METHODS use_cache
      IMPORTING iv_seed TYPE string
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    METHODS bypass_cache
      RETURNING VALUE(ro_self) TYPE REF TO zcl_ray_graph_builder.

    " Build
    METHODS build
      RETURNING VALUE(ro_graph) TYPE REF TO zcl_ray_graph.

  PRIVATE SECTION.
    DATA: mt_starting_nodes TYPE tt_node_id,
          mo_repository TYPE REF TO zif_ray_graph_repository,
          mo_traverser TYPE REF TO zif_ray_graph_traverser,
          mo_filter TYPE REF TO zif_ray_graph_filter,
          ms_config TYPE zif_ray_graph_traverser=>ts_traversal_config,
          mv_use_cache TYPE abap_bool,
          mv_cache_seed TYPE string.

    METHODS create_repository
      RETURNING VALUE(ro_repository) TYPE REF TO zif_ray_graph_repository.

    METHODS create_traverser
      RETURNING VALUE(ro_traverser) TYPE REF TO zif_ray_graph_traverser.

    METHODS create_filter
      RETURNING VALUE(ro_filter) TYPE REF TO zif_ray_graph_filter.
ENDCLASS.

Usage Example:

" Simple DOWN traversal
DATA(lo_graph) = zcl_ray_graph_builder=>new( )
  ->with_package( '$ZRAY_10' )
  ->traverse_down( )
  ->max_depth( 3 )
  ->exclude_sap_standard( )
  ->build( ).

" UP traversal with caching
DATA(lo_graph) = zcl_ray_graph_builder=>new( )
  ->with_starting_nodes( VALUE #( ( 'CLAS.ZCL_CHANGED_CLASS' ) ) )
  ->traverse_up( )
  ->use_cache( 'SEED_001' )
  ->build( ).

" Bidirectional with custom filter
DATA(lo_filter) = zcl_ray_graph_filter_builder=>create( )
  ->with_package( 'Z*' )
  ->with_type( 'CLAS' )
  ->with_type( 'FUNC' )
  ->build( ).

DATA(lo_graph) = zcl_ray_graph_builder=>new( )
  ->with_package( '$ZXRAY' )
  ->traverse_both( )
  ->with_filter( lo_filter )
  ->max_depth( 5 )
  ->build( ).

6. Analyzer Layer (Visitors)

Interface: ZIF_RAY_GRAPH_VISITOR

INTERFACE zif_ray_graph_visitor.
  METHODS visit_graph
    IMPORTING io_graph TYPE REF TO zcl_ray_graph.

  METHODS visit_node
    IMPORTING is_node TYPE ts_node.

  METHODS visit_edge
    IMPORTING is_edge TYPE ts_edge.

  METHODS get_result
    RETURNING VALUE(rr_result) TYPE REF TO data.
ENDINTERFACE.

Implementation: ZCL_RAY_GRAPH_ANALYZER_METRICS

CLASS zcl_ray_graph_analyzer_metrics DEFINITION
  IMPLEMENTING zif_ray_graph_visitor.

  PUBLIC SECTION.
    TYPES: BEGIN OF ts_metrics,
             node_count    TYPE i,
             edge_count    TYPE i,
             package_count TYPE i,
             max_depth     TYPE i,
             density       TYPE p LENGTH 8 DECIMALS 4,
           END OF ts_metrics.

    METHODS visit_graph REDEFINITION.
    METHODS get_result REDEFINITION.

  PRIVATE SECTION.
    DATA: ms_metrics TYPE ts_metrics.
ENDCLASS.

Implementation: ZCL_RAY_GRAPH_ANALYZER_CLUSTER

CLASS zcl_ray_graph_analyzer_cluster DEFINITION
  IMPLEMENTING zif_ray_graph_visitor.

  PUBLIC SECTION.
    TYPES: BEGIN OF ts_cluster,
             id       TYPE string,
             name     TYPE string,
             nodes    TYPE tt_node,
             cohesion TYPE p LENGTH 8 DECIMALS 4,
           END OF ts_cluster.

    TYPES: tt_clusters TYPE STANDARD TABLE OF ts_cluster.

    METHODS constructor
      IMPORTING iv_method TYPE string DEFAULT 'PACKAGE'.  " PACKAGE, CONNECTIVITY, TYPE

    METHODS visit_graph REDEFINITION.
    METHODS get_result REDEFINITION.

  PRIVATE SECTION.
    DATA: mv_method TYPE string,
          mt_clusters TYPE tt_clusters.

    METHODS cluster_by_package
      IMPORTING io_graph TYPE REF TO zcl_ray_graph.

    METHODS cluster_by_connectivity
      IMPORTING io_graph TYPE REF TO zcl_ray_graph.
ENDCLASS.

Usage:

" Calculate metrics
DATA(lo_metrics_visitor) = NEW zcl_ray_graph_analyzer_metrics( ).
lo_graph->accept( lo_metrics_visitor ).
DATA(ls_metrics) = CAST ts_metrics( lo_metrics_visitor->get_result( ) ).

WRITE: / 'Nodes:', ls_metrics-node_count,
       / 'Edges:', ls_metrics-edge_count.

" Cluster by package
DATA(lo_cluster_visitor) = NEW zcl_ray_graph_analyzer_cluster( 'PACKAGE' ).
lo_graph->accept( lo_cluster_visitor ).
DATA(lt_clusters) = CAST tt_clusters( lo_cluster_visitor->get_result( ) ).

Complete Type Handler Implementation

Extended Type Coverage

Current ZCL_XRAY_GRAPH only handles: F, R, T, S, U (CROSS) and ME, TY, DA, EV, TK (WBCROSSGT)

New comprehensive handler:

CLASS zcl_ray_graph_type_handler DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS get_handler_for_cross_type
      IMPORTING iv_type TYPE cross-type
      RETURNING VALUE(ro_handler) TYPE REF TO zif_ray_node_handler.

    CLASS-METHODS get_handler_for_wbcrossgt_type
      IMPORTING iv_otype TYPE wbcrossgt-otype
      RETURNING VALUE(ro_handler) TYPE REF TO zif_ray_node_handler.

  PRIVATE SECTION.
    " Complete CROSS type coverage
    CLASS-DATA: go_handler_0 TYPE REF TO zcl_ray_node_handler_msag,  " Message class (SE91)
                go_handler_2 TYPE REF TO zcl_ray_node_handler_xslt,  " Transformation
                go_handler_3 TYPE REF TO zcl_ray_node_handler_clas,  " Exception messages
                go_handler_a TYPE REF TO zcl_ray_node_handler_suso,  " Authority object
                go_handler_e TYPE REF TO zcl_ray_node_handler_status, " PF-STATUS
                go_handler_f TYPE REF TO zcl_ray_node_handler_func,  " Function module
                go_handler_m TYPE REF TO zcl_ray_node_handler_shlp,  " Search help (Dynpro)
                go_handler_n TYPE REF TO zcl_ray_node_handler_msag,  " Messages (T100A)
                go_handler_p TYPE REF TO zcl_ray_node_handler_para,  " Parameters
                go_handler_r TYPE REF TO zcl_ray_node_handler_prog,  " Report
                go_handler_s TYPE REF TO zcl_ray_node_handler_tabl,  " Table
                go_handler_t TYPE REF TO zcl_ray_node_handler_tran,  " Transaction
                go_handler_u TYPE REF TO zcl_ray_node_handler_perform, " Perform
                go_handler_v TYPE REF TO zcl_ray_node_handler_mcob,  " Matchcode
                go_handler_y TYPE REF TO zcl_ray_node_handler_tran.  " Transaction variant

    " WBCROSSGT handlers (generic, no special handlers needed)
    CLASS-DATA: go_handler_me TYPE REF TO zcl_ray_node_handler_method,
                go_handler_ty TYPE REF TO zcl_ray_node_handler_type,
                go_handler_da TYPE REF TO zcl_ray_node_handler_data,
                go_handler_ev TYPE REF TO zcl_ray_node_handler_event,
                go_handler_tk TYPE REF TO zcl_ray_node_handler_typekey.
ENDCLASS.

Migration Strategy

Phase 1: Build New Architecture (Week 1-2)

  • Create interfaces (ZIF_RAY_GRAPH_*)
  • Implement repository layer
  • Implement filter layer
  • Unit tests for each component

Phase 2: Implement Traversal (Week 3-4)

  • Implement DOWN traverser
  • Implement UP traverser
  • Implement bidirectional traverser
  • Integration tests

Phase 3: Builder & Analyzers (Week 5)

  • Implement graph builder with fluent API
  • Implement visitor pattern
  • Create analyzer implementations
  • Documentation and examples

Phase 4: Integration (Week 6)

  • Update ZCL_RAY_10_DEEP_GRAPH to use new architecture
  • Migrate existing callers
  • Performance testing
  • Backward compatibility layer (optional)

Phase 5: Deprecate Old (Week 7+)

  • Mark ZCL_XRAY_GRAPH as deprecated
  • Provide migration guide
  • Monitor usage, remove when safe

Benefits of New Architecture

For Developers

  • Clear separation of concerns - Easy to understand
  • Testable - Each component unit-testable
  • Extensible - Add new analyzers without changing core
  • Fluent API - Readable, self-documenting code

For Performance

  • Pluggable caching - Can use different cache strategies
  • Lazy evaluation - Only compute what's needed
  • Parallelization potential - Repositories can query in parallel

For Functionality

  • Complete type coverage - All CROSS/WBCROSSGT types
  • Bidirectional traversal - UP and DOWN equally supported
  • Advanced filters - Composable, reusable
  • Rich analysis - Visitors for any graph operation

Example: Complete Workflow

" 1. Build graph
DATA(lo_graph) = zcl_ray_graph_builder=>new( )
  ->with_package( '$ZRAY_10' )
  ->traverse_down( )
  ->max_depth( 3 )
  ->exclude_sap_standard( )
  ->use_cache( 'ZRAY_10_SEED_001' )
  ->build( ).

" 2. Analyze metrics
DATA(lo_metrics) = NEW zcl_ray_graph_analyzer_metrics( ).
lo_graph->accept( lo_metrics ).
DATA(ls_metrics) = lo_metrics->get_metrics( ).

WRITE: / 'Graph contains:', ls_metrics-node_count, 'nodes',
       / 'Connected by:', ls_metrics-edge_count, 'edges'.

" 3. Cluster by package
DATA(lo_clusterer) = NEW zcl_ray_graph_analyzer_cluster( 'PACKAGE' ).
lo_graph->accept( lo_clusterer ).
DATA(lt_clusters) = lo_clusterer->get_clusters( ).

LOOP AT lt_clusters INTO DATA(ls_cluster).
  WRITE: / 'Cluster:', ls_cluster-name,
         / '  Size:', ls_cluster-size,
         / '  Cohesion:', ls_cluster-cohesion.
ENDLOOP.

" 4. Find impact of changing a class
DATA(lo_impact) = NEW zcl_ray_graph_analyzer_impact( ).
lo_impact->analyze(
  io_graph = lo_graph
  iv_changed_node = 'CLAS.ZCL_RAY_10_SPIDER'
).
DATA(ls_impact) = lo_impact->get_impact_report( ).

WRITE: / 'Changing ZCL_RAY_10_SPIDER would affect:',
       / '  Nodes:', lines( ls_impact-affected_nodes ),
       / '  Packages:', lines( ls_impact-affected_packages ),
       / '  Risk:', ls_impact-risk_level.

" 5. Generate visualization
DATA(lo_viz) = NEW zcl_ray_graph_viz_mermaid( ).
DATA(lv_mermaid) = lo_viz->generate(
  io_graph = lo_graph
  is_config = VALUE #(
    direction = 'TD'
    group_by_package = abap_true
    max_nodes = 50  " Limit for readability
  )
).

" Save to documentation
zcl_ray_00_doc=>save(
  iv_node = '$ZRAY_10'
  iv_doc_type = 'MERMAID'
  iv_content = lv_mermaid
).

Conclusion

This redesigned architecture:

  • ✅ Separates concerns (repository, traversal, filtering, analysis)
  • ✅ Supports all CROSS/WBCROSSGT types
  • ✅ Enables UP, DOWN, and bidirectional traversal
  • ✅ Provides fluent, readable API
  • ✅ Extensible via visitor pattern
  • ✅ Fully testable
  • ✅ Performance-optimized with pluggable caching

Ready for implementation in both ABAP (ZRAY improvement) and Go (vsp)!