abapGit/src/zcl_abapgit_folder_logic.clas.abap
2018-12-02 12:13:50 +01:00

207 lines
6.4 KiB
ABAP

CLASS zcl_abapgit_folder_logic DEFINITION
PUBLIC
CREATE PUBLIC .
PUBLIC SECTION.
METHODS package_to_path
IMPORTING
!iv_top TYPE devclass
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit
!iv_package TYPE devclass
RETURNING
VALUE(rv_path) TYPE string
RAISING
zcx_abapgit_exception .
METHODS path_to_package
IMPORTING
!iv_top TYPE devclass
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit
!iv_path TYPE string
!iv_create_if_not_exists TYPE abap_bool DEFAULT abap_true
RETURNING
VALUE(rv_package) TYPE devclass
RAISING
zcx_abapgit_exception .
CLASS-METHODS get_instance
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_folder_logic .
PROTECTED SECTION.
METHODS get_parent
IMPORTING
!iv_package TYPE devclass
RETURNING
VALUE(rv_parent) TYPE devclass.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_devclass_info,
devclass TYPE devclass,
namespace TYPE namespace,
parentcl TYPE parentcl,
END OF ty_devclass_info .
TYPES:
ty_devclass_info_tt TYPE SORTED TABLE OF ty_devclass_info
WITH UNIQUE KEY devclass .
DATA mt_parent TYPE ty_devclass_info_tt .
ENDCLASS.
CLASS ZCL_ABAPGIT_FOLDER_LOGIC IMPLEMENTATION.
METHOD get_instance.
CREATE OBJECT ro_instance.
ENDMETHOD.
METHOD get_parent.
DATA: ls_parent LIKE LINE OF mt_parent.
"Determine Parent Package
READ TABLE mt_parent INTO ls_parent
WITH TABLE KEY devclass = iv_package.
IF sy-subrc <> 0.
rv_parent = zcl_abapgit_factory=>get_sap_package( iv_package )->read_parent( ).
ls_parent-devclass = iv_package.
ls_parent-parentcl = rv_parent.
INSERT ls_parent INTO TABLE mt_parent.
ELSE.
rv_parent = ls_parent-parentcl.
ENDIF.
ENDMETHOD.
METHOD package_to_path.
DATA: lv_len TYPE i,
lv_path TYPE string,
lv_message TYPE string,
lv_parentcl TYPE tdevc-parentcl,
lv_folder_logic TYPE string.
IF iv_top = iv_package.
rv_path = io_dot->get_starting_folder( ).
ELSE.
lv_parentcl = get_parent( iv_package ).
IF lv_parentcl IS INITIAL.
zcx_abapgit_exception=>raise( |error, expected parent package, { iv_package }| ).
ELSE.
lv_folder_logic = io_dot->get_folder_logic( ).
CASE lv_folder_logic.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full.
lv_len = 0.
IF iv_package(1) = '$'.
lv_len = 1.
ENDIF.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
lv_len = strlen( lv_parentcl ).
IF iv_package(lv_len) <> lv_parentcl.
* if abapGit project is installed in package ZZZ, all subpackages should be named
* ZZZ_something. This will define the folder name in the zip file to be "something",
* similarily with online projects. Alternatively change to FULL folder logic
lv_message = 'PREFIX: Unexpected package naming (' && iv_package && ')'
&& 'you might switch to FULL folder logic' ##no_text.
zcx_abapgit_exception=>raise( lv_message ).
ENDIF.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Invalid folder logic: { lv_folder_logic }| ).
ENDCASE.
lv_path = iv_package+lv_len.
IF strlen( lv_path ) = 0.
zcx_abapgit_exception=>raise( |Folder logic: length = 0, parent: {
lv_parentcl }, child: { iv_package }| ).
ENDIF.
IF lv_path(1) = '_'.
lv_path = lv_path+1.
ENDIF.
IF strlen( lv_path ) = 0.
zcx_abapgit_exception=>raise( |Folder logic: length = 0, parent: {
lv_parentcl }, child: { iv_package }| ).
ENDIF.
TRANSLATE lv_path USING '/#'.
TRANSLATE lv_path TO LOWER CASE.
CONCATENATE lv_path '/' INTO lv_path.
rv_path = package_to_path( iv_top = iv_top
io_dot = io_dot
iv_package = lv_parentcl ).
CONCATENATE rv_path lv_path INTO rv_path.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD path_to_package.
DATA: lv_length TYPE i,
lv_parent TYPE devclass,
lv_new TYPE string,
lv_path TYPE string,
lv_absolute_name TYPE string,
lv_top TYPE devclass,
lt_unique_package_names TYPE HASHED TABLE OF devclass WITH UNIQUE KEY table_line.
lv_top = iv_top.
lv_length = strlen( io_dot->get_starting_folder( ) ).
IF lv_length > strlen( iv_path ).
* treat as not existing locally
RETURN.
ENDIF.
lv_path = iv_path+lv_length.
lv_parent = lv_top.
rv_package = lv_top.
INSERT iv_top INTO TABLE lt_unique_package_names.
WHILE lv_path CA '/'.
SPLIT lv_path AT '/' INTO lv_new lv_path.
CASE io_dot->get_folder_logic( ).
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full.
lv_absolute_name = lv_new.
TRANSLATE lv_absolute_name USING '#/'.
IF iv_top(1) = '$'.
CONCATENATE '$' lv_absolute_name INTO lv_absolute_name.
ENDIF.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
CONCATENATE rv_package '_' lv_new INTO lv_absolute_name.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
TRANSLATE lv_absolute_name TO UPPER CASE.
IF strlen( lv_absolute_name ) > 30.
zcx_abapgit_exception=>raise( |Package { lv_absolute_name } exceeds ABAP 30-characters-name limit| ).
ENDIF.
rv_package = lv_absolute_name.
READ TABLE lt_unique_package_names TRANSPORTING NO FIELDS
WITH TABLE KEY table_line = rv_package.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( |Package { rv_package } has a subpackage with the same name| ).
ELSE.
INSERT rv_package INTO TABLE lt_unique_package_names.
ENDIF.
IF zcl_abapgit_factory=>get_sap_package( rv_package )->exists( ) = abap_false AND
iv_create_if_not_exists = abap_true.
zcl_abapgit_factory=>get_sap_package( lv_parent )->create_child( rv_package ).
ENDIF.
lv_parent = rv_package.
ENDWHILE.
ENDMETHOD.
ENDCLASS.