Универсальный загрузчик в MIME репозитарий

Данный загрузчик позволяет загружать в MIME репозитарий как архивы с автораспаковкой содержимого на сервере приложений так и файлы из указанной директории. В завершении загрузки выводится лог.

*&---------------------------------------------------------------------*
*& Report  ZBC_MIME_UPLOAD
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT zbc_mime_upload.
CONSTANTS gc_separator_mime TYPE char1 VALUE '/'.

DATA gv_fromtend_file_separator TYPE char1.

TYPES BEGIN OF gtyp_log.
TYPES icon      TYPE icon_d.
TYPES full_path TYPE string.
TYPES message   TYPE string.
TYPES END OF gtyp_log.

TYPES BEGIN OF gtyp_empty_file_ftext.
TYPES value TYPE char50.
TYPES END OF gtyp_empty_file_ftext.

DATA gt_log TYPE TABLE OF gtyp_log.
DATA go_zip TYPE REF TO cl_abap_zip.
DATA gt_zip_file_list TYPE cl_abap_zip=>t_splice_entries.
DATA gv_begin_time TYPE i.
DATA gv_end_time TYPE i.
DATA gv_import_time TYPE i.

DATA gt_empty_file_ftext TYPE TABLE OF gtyp_empty_file_ftext.

PARAMETERS p_to_url TYPE string DEFAULT 'COMPANY/UI5/LIBRARIES'.
SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS p_zip_up TYPE flag RADIOBUTTON GROUP rad1 DEFAULT 'X'.
PARAMETERS p_zip_ph TYPE string DEFAULT 'C:\'.
PARAMETERS p_fld_up TYPE flag RADIOBUTTON GROUP rad1.
PARAMETERS p_folder TYPE string DEFAULT 'C:\'.
SELECTION-SCREEN END OF BLOCK bl1.
SELECTION-SCREEN BEGIN OF BLOCK bl2 WITH FRAME TITLE text-002.
PARAMETERS p_devcls TYPE devclass DEFAULT 'ZBC_UI5' OBLIGATORY.
PARAMETERS p_trkorr TYPE trkorr OBLIGATORY.
SELECTION-SCREEN END OF BLOCK bl2.

*PARAMETERS p_replac TYPE flag AS CHECKBOX.
*PARAMETERS p_short TYPE flag AS CHECKBOX.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_zip_ph.
  PERFORM select_zip_file.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_folder.
  PERFORM select_folder.

START-OF-SELECTION.
  cl_gui_frontend_services=>get_file_separator(
    CHANGING
      file_separator       = gv_fromtend_file_separator
    EXCEPTIONS
      not_supported_by_gui = 1
      error_no_gui         = 2
      cntl_error           = 3
      OTHERS               = 4
  ).

  REFRESH gt_empty_file_ftext.
  APPEND INITIAL LINE TO gt_empty_file_ftext.

  GET RUN TIME FIELD gv_begin_time.
  IF p_zip_up EQ abap_true.
    PERFORM upload_zip.
  ENDIF.

  PERFORM import_to_mime.
  GET RUN TIME FIELD gv_end_time.
  gv_import_time = ( gv_end_time - gv_begin_time ) / 1000000.
  MESSAGE `Импорт занял ` &&  gv_import_time && ` секунд` TYPE 'I'.

  PERFORM show_log.

*&---------------------------------------------------------------------*
*&      Form  SELECT_ZIP_FILE
*&---------------------------------------------------------------------*
*       Диалог выбора zip файла
*----------------------------------------------------------------------*
FORM select_zip_file .
  DATA lt_file_table   TYPE filetable.
  DATA lv_rc           TYPE i.
  DATA lv_user_action  TYPE i.

  FIELD-SYMBOLS <fs_file> LIKE LINE OF lt_file_table.

  cl_gui_frontend_services=>file_open_dialog(
    EXPORTING
      window_title            = 'Выбрать ZIP файл для загрузки'
      default_extension       = 'ZIP'
*      default_filename        =
      file_filter             = 'ZIP-файлы (*.ZIP)|*.ZIP||'
*      with_encoding           =
*      initial_directory       =
*      multiselection          =
    CHANGING
      file_table              = lt_file_table
      rc                      = lv_rc
      user_action             = lv_user_action
    EXCEPTIONS
      file_open_dialog_failed = 1
      cntl_error              = 2
      error_no_gui            = 3
      not_supported_by_gui    = 4
      OTHERS                  = 5
  ).

  IF lv_user_action NE 0.
    CLEAR p_zip_ph.
    RETURN.
  ENDIF.

  IF lv_rc NE 1.
    CLEAR p_zip_ph.
    RETURN.
  ENDIF.

  READ TABLE lt_file_table ASSIGNING <fs_file> INDEX 1.

  CHECK sy-subrc EQ 0.
  p_zip_ph = <fs_file>-filename.

ENDFORM.                    " SELECT_ZIP_FILE
*&---------------------------------------------------------------------*
*&      Form  UPLOAD_ZIP
*&---------------------------------------------------------------------*
*       Загрузить zip в память
*----------------------------------------------------------------------*
FORM upload_zip .
  TYPES ltyp_binary TYPE x LENGTH 1024.

  DATA lv_x_content TYPE xstring.
  DATA lt_x_binary  TYPE TABLE OF ltyp_binary.
  DATA lv_lenght    TYPE i.

  DATA lv_filelength TYPE i.
  CLEAR gt_zip_file_list.

  FREE go_zip.
  CREATE OBJECT go_zip.

  CALL FUNCTION 'PROGRESS_INDICATOR'
    EXPORTING
      i_text               = 'Загружаем файл'
      i_processed          = 10
      i_total              = 100
      i_output_immediately = abap_true.

  cl_gui_frontend_services=>gui_upload(
    EXPORTING
      filename                = p_zip_ph
      filetype                = 'BIN'
    IMPORTING
      filelength              = lv_filelength
    CHANGING
      data_tab                = lt_x_binary
    EXCEPTIONS
      file_open_error         = 1
      file_read_error         = 2
      no_batch                = 3
      gui_refuse_filetransfer = 4
      invalid_type            = 5
      no_authority            = 6
      unknown_error           = 7
      bad_data_format         = 8
      header_not_allowed      = 9
      separator_not_allowed   = 10
      header_too_long         = 11
      unknown_dp_error        = 12
      access_denied           = 13
      dp_out_of_memory        = 14
      disk_full               = 15
      dp_timeout              = 16
      not_supported_by_gui    = 17
      error_no_gui            = 18
      OTHERS                  = 19
  ).

  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
    EXPORTING
      input_length = lv_filelength
    IMPORTING
      buffer       = lv_x_content
    TABLES
      binary_tab   = lt_x_binary
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.

  CALL FUNCTION 'PROGRESS_INDICATOR'
    EXPORTING
      i_text               = 'Формируем ZIP в оперативке'
      i_processed          = 20
      i_total              = 100
      i_output_immediately = abap_true.

  go_zip->load(
    EXPORTING
      zip             = lv_x_content
    EXCEPTIONS
      zip_parse_error = 1
      OTHERS          = 2
      ).

  CALL FUNCTION 'PROGRESS_INDICATOR'
    EXPORTING
      i_text               = 'Формируем список файлов ZIP'
      i_processed          = 30
      i_total              = 100
      i_output_immediately = abap_true.


  go_zip->splice(
    EXPORTING
      zip             = lv_x_content
*      support_unicode = ABAP_FALSE
    RECEIVING
      entries         = gt_zip_file_list
  ).
ENDFORM.                    " UPLOAD_ZIP
*&---------------------------------------------------------------------*
*&      Form  import_to_mime
*&---------------------------------------------------------------------*
*       Загрузить MIME из zip
*----------------------------------------------------------------------*
FORM import_to_mime.

  FIELD-SYMBOLS <fs_zip_file> LIKE LINE OF gt_zip_file_list.

  " Проверить существует ли указанный корень, если нет, создать
  PERFORM create_folder
    USING p_to_url.

  DATA lv_lines TYPE i.
  DATA lv_line TYPE i.

  IF p_zip_up EQ abap_true.
    lv_lines = lines( gt_zip_file_list ).

    LOOP AT gt_zip_file_list ASSIGNING <fs_zip_file>.

      lv_line = sy-tabix.

      CALL FUNCTION 'PROGRESS_INDICATOR'
        EXPORTING
          i_text               = `Обработка файлов`
          i_processed          = lv_line
          i_total              = lv_lines
          i_output_immediately = abap_true.

      PERFORM upload_zip_file
        USING <fs_zip_file>.

    ENDLOOP.

  ENDIF.

  IF p_fld_up EQ abap_true.
    DATA lt_files_list TYPE rstt_t_files.

    CLEAR lt_files_list.

    CALL FUNCTION 'PROGRESS_INDICATOR'
      EXPORTING
        i_text               = `Формирование списка файлов`
        i_output_immediately = abap_true.

    " Рекурсивно составляем список файлов для загрузки
    PERFORM get_files_list
      USING p_folder
      CHANGING lt_files_list.

    PERFORM upload_directory_files
      USING lt_files_list.
  ENDIF.

ENDFORM.                    " import_to_mime
*&---------------------------------------------------------------------*
*&      Form  CONVERT_ZIP_TO_MIME_PATH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_<FS_ZIP_FILE>_NAME  text
*      <--P_LV_MIME_PATH  text
*----------------------------------------------------------------------*
FORM convert_zip_to_mime_path
  USING iv_path TYPE string
  CHANGING cv_mime_path TYPE string
           cv_is_folder TYPE flag.

  DATA lt_parts_of_path TYPE TABLE OF string.
  DATA lv_filename TYPE string.
  DATA lv_full_path TYPE string.
  DATA lv_extension TYPE string.
  DATA lv_extension_size TYPE i.
  DATA lv_filename_size TYPE i.
  DATA lv_parts_count TYPE i.

  DATA lv_length TYPE i.


*  FIELD-SYMBOLS <fs_part_of_path> LIKE LINE OF lt_parts_of_path.
  FIELD-SYMBOLS <fs_log> LIKE LINE OF gt_log.
  lv_length = strlen( iv_path ) - 1.

  cv_mime_path = iv_path.

  DATA lv_separator LIKE gc_separator_mime.
  IF p_fld_up EQ abap_true.
    REPLACE p_folder IN cv_mime_path WITH space IN CHARACTER MODE.
    REPLACE ALL OCCURRENCES OF gv_fromtend_file_separator IN cv_mime_path WITH gc_separator_mime .
    cv_mime_path = p_to_url && cv_mime_path.
  ENDIF.

  " разделитель в zip совпадлает с разделителем mime
  IF iv_path+lv_length(1) EQ gc_separator_mime.
    cv_is_folder = abap_true.
    cv_mime_path = cv_mime_path(lv_length).
    IF <fs_log> IS ASSIGNED.
      <fs_log>-full_path = cv_mime_path.
    ENDIF.

    RETURN.
  ELSE.
    cv_is_folder = abap_false.
    " Задействуем механизм сокращения имен файлов
    lv_full_path = cv_mime_path.
    DATA lv_file_name	TYPE string.

     " Реализацию см. в следующем листинге
    Zcl_ui5_http_handler=>get_hash_for_long_file_name(
      IMPORTING
        ev_file_name = lv_file_name
      CHANGING
        cv_url       = lv_full_path
    ).

    IF lv_full_path NE cv_mime_path.
      APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
      <fs_log>-icon = icon_led_yellow.
      <fs_log>-message = `Имя файла сокращено ` && lv_file_name && ` на ` && lv_filename.
      <fs_log>-full_path = cv_mime_path.
    ENDIF.
    cv_mime_path = lv_full_path.
*    SPLIT iv_zip_path AT gc_separator_mime INTO TABLE lt_parts_of_path.
*    lv_parts_count = lines( lt_parts_of_path ).
*    READ TABLE lt_parts_of_path ASSIGNING <fs_part_of_path>
*      INDEX lv_parts_count.
*    IF sy-subrc EQ 0.
*      lv_filename = <fs_part_of_path>.
*      IF strlen( <fs_part_of_path> ) GT 40.
*        IF p_short EQ abap_true.
*          SPLIT lv_filename AT '.' INTO lv_filename lv_extension.
*          lv_extension_size = strlen( lv_extension ).
*          lv_filename_size = 40 - lv_extension_size - 1.
*          CONCATENATE lv_filename(lv_filename_size) '.' lv_extension INTO lv_filename.
**        cv_mime_path = lv_filename.
*          APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
*          <fs_log>-icon = icon_led_yellow.
*          <fs_log>-message = `Имя файла сокращено ` && <fs_part_of_path> && ` на ` && lv_filename.
*        ELSE.
**        cv_mime_path = lv_filename.
*          APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
*          <fs_log>-icon = icon_led_yellow.
*          <fs_log>-message = `Имя файла сокращено ` && <fs_part_of_path> && ` на ` && lv_filename(40).
*        ENDIF.
*      ENDIF.
*    ENDIF.
*
*    CLEAR lv_full_path.
*
*    CONCATENATE p_to_url gc_separator_mime INTO lv_full_path.
*
*    lv_parts_count = lv_parts_count - 1.
*
*    LOOP AT lt_parts_of_path ASSIGNING <fs_part_of_path>
*      TO lv_parts_count.
*      CONCATENATE lv_full_path <fs_part_of_path> gc_separator_mime INTO lv_full_path.
*    ENDLOOP.
*
*    CONCATENATE lv_full_path lv_filename INTO lv_full_path.
*
*    cv_mime_path = lv_full_path.
*
*    IF <fs_log> IS ASSIGNED.
*      <fs_log>-full_path = cv_mime_path.
*    ENDIF.


  ENDIF.


*resources/sap/ui/commons/form/
*resources/sap/ui/commons/form/Form-dbg.js

ENDFORM.                    " CONVERT_ZIP_TO_MIME_PATH
*&---------------------------------------------------------------------*
*&      Form  SHOW_LOG
*&---------------------------------------------------------------------*
*       Показать лог
*----------------------------------------------------------------------*
FORM show_log .
  cl_salv_table=>factory(
    IMPORTING
      r_salv_table   = DATA(lo_grid)
    CHANGING
      t_table        = gt_log
  ).

  lo_grid->get_functions( )->set_default( ).

  lo_grid->get_columns( )->get_column( 'ICON     ' )->set_output_length( 8 ).
  lo_grid->get_columns( )->get_column( 'ICON     ' )->set_long_text( 'Статус' ).
  lo_grid->get_columns( )->get_column( 'ICON     ' )->set_medium_text( 'Статус' ).
  lo_grid->get_columns( )->get_column( 'ICON     ' )->set_short_text( 'Статус' ).
  lo_grid->get_columns( )->get_column( 'FULL_PATH' )->set_output_length( 100 ).
  lo_grid->get_columns( )->get_column( 'FULL_PATH' )->set_long_text( 'Путь' ).
  lo_grid->get_columns( )->get_column( 'FULL_PATH' )->set_medium_text( 'Путь' ).
  lo_grid->get_columns( )->get_column( 'FULL_PATH' )->set_short_text( 'Путь' ).
  lo_grid->get_columns( )->get_column( 'MESSAGE  ' )->set_output_length( 150 ).
  lo_grid->get_columns( )->get_column( 'MESSAGE  ' )->set_long_text( 'Сообщение' ).
  lo_grid->get_columns( )->get_column( 'MESSAGE  ' )->set_medium_text( 'Сообщение' ).
  lo_grid->get_columns( )->get_column( 'MESSAGE  ' )->set_short_text( 'Сообщение' ).

  lo_grid->display( ).
ENDFORM.                    " SHOW_LOG
*&---------------------------------------------------------------------*
*&      Form  UPLOAD_ZIP_FILE
*&---------------------------------------------------------------------*
*       Загрузить файл из ZIP
*----------------------------------------------------------------------*
FORM upload_zip_file
  USING is_zip_file TYPE cl_abap_zip=>t_splice_entry.
  DATA lv_mime_path TYPE string.
  DATA lv_is_folder TYPE flag.
  DATA lt_mime_files TYPE string_table.
  DATA lv_content TYPE xstring.

  FIELD-SYMBOLS <fs_log> LIKE LINE OF gt_log.

  CLEAR lv_is_folder.
  CLEAR lv_mime_path.
  PERFORM convert_zip_to_mime_path
    USING is_zip_file-name
    CHANGING lv_mime_path
             lv_is_folder.

  CASE lv_is_folder.
    WHEN abap_true.
      PERFORM create_folder
        USING lv_mime_path.
    WHEN abap_false.
      go_zip->get(
        EXPORTING
          name                    = is_zip_file-name
        IMPORTING
          content                 = lv_content
        EXCEPTIONS
          zip_index_error         = 1
          zip_decompression_error = 2
          OTHERS                  = 3
      ).

      IF sy-subrc EQ 0. "AND lv_content IS NOT INITIAL.
        cl_mime_repository_api=>get_api( )->properties(
          EXPORTING
            i_url               = lv_mime_path
            i_check_authority   = ' '
          IMPORTING
            e_is_folder         = lv_is_folder
          EXCEPTIONS
            parameter_missing   = 1
            error_occured       = 2
            not_found           = 3
            permission_failure  = 4
            OTHERS              = 5
        ).

        IF sy-subrc EQ 3.
          IF lv_content IS INITIAL.
            CALL FUNCTION 'SCMS_FTEXT_TO_XSTRING'
              EXPORTING
                input_length = 1
*               FIRST_LINE   = 0
*               LAST_LINE    = 0
*               MIMETYPE     = ' '
*               ENCODING     =
              IMPORTING
                buffer       = lv_content
              TABLES
                ftext_tab    = gt_empty_file_ftext
              EXCEPTIONS
                failed       = 1
                OTHERS       = 2.

          ENDIF.

          cl_mime_repository_api=>get_api( )->put(
            EXPORTING
              i_url                     = lv_mime_path
              i_content                 = lv_content
              i_check_authority         = ' '
              i_dev_package             = p_devcls
              i_corr_number             = p_trkorr
            EXCEPTIONS
              parameter_missing         = 1
              error_occured             = 2
              cancelled                 = 3
              permission_failure        = 4
              data_inconsistency        = 5
              new_loio_already_exists   = 6
              is_folder                 = 7
              OTHERS                    = 8
          ).

          IF sy-subrc EQ 0.
            APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
            <fs_log>-full_path = lv_mime_path.
            <fs_log>-icon = icon_led_green.
            <fs_log>-message = `Файл успешно загружен.`.
*              WRITE: / icon_led_green && ` ` && lv_mime_path && `: Файл успешно загружен.`.


          ELSE.
            APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
            <fs_log>-full_path = lv_mime_path.
            <fs_log>-icon = icon_led_red.
            <fs_log>-message = `Не удалось загрузить файл.`.
*              WRITE: / icon_led_red && ` ` && lv_mime_path && `: Не удалось загрузить файл.`.
          ENDIF.
        ELSE.
          APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
          <fs_log>-full_path = lv_mime_path.
          <fs_log>-icon = icon_led_yellow.
          <fs_log>-message = `Файл уже существует.`.
*            WRITE: / icon_led_yellow && ` ` && lv_mime_path && `: Файл уже существует.` .
        ENDIF.
      ENDIF.
  ENDCASE.
ENDFORM.                    " UPLOAD_ZIP_FILE
*&---------------------------------------------------------------------*
*&      Form  CREATE_FOLDER
*&---------------------------------------------------------------------*
*       Создать папаку в mime
*----------------------------------------------------------------------*
FORM create_folder
  USING iv_folder_url TYPE string.

  DATA lt_mime_files TYPE string_table.

  FIELD-SYMBOLS <fs_log> LIKE LINE OF gt_log.

  CLEAR lt_mime_files.

  cl_mime_repository_api=>get_api( )->file_list(
          EXPORTING
            i_url              = iv_folder_url
            i_recursive_call   = ' '
            i_check_authority  = ' '
          IMPORTING
            e_files            = lt_mime_files
          EXCEPTIONS
            parameter_missing  = 1
            error_occured      = 2
            not_found          = 3
            permission_failure = 4
            is_not_folder      = 5
            OTHERS             = 6
        ).

  IF sy-subrc EQ 3.
    cl_mime_repository_api=>get_api( )->create_folder(
      EXPORTING
        i_url                         = iv_folder_url
        i_check_authority             = ' '
        i_dev_package                 = p_devcls
        i_corr_number                 = p_trkorr
        i_folder_role                 = 'PUBLIC'
      EXCEPTIONS
        parameter_missing             = 1
        error_occured                 = 2
        cancelled                     = 3
        permission_failure            = 4
        folder_exists                 = 5
        OTHERS                        = 6
    ).
    IF sy-subrc <> 0.
      APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
      <fs_log>-full_path = iv_folder_url.
      <fs_log>-icon = icon_led_red.
      <fs_log>-message = 'Не удалось создать каталог.'.
*          WRITE: / icon_led_red  && ` ` && &1 && `: Не удалось создать каталог.`.
    ELSE.
      APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
      <fs_log>-full_path = iv_folder_url.
      <fs_log>-icon = icon_led_green.
      <fs_log>-message = 'Каталог успешно создан.'.
*          WRITE: / icon_led_green && ` ` && &1 && `: Каталог успешно создан.`.
    ENDIF.
  ELSEIF sy-subrc EQ 0.
    APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
    <fs_log>-full_path = iv_folder_url.
    <fs_log>-icon = icon_led_yellow.
    <fs_log>-message = 'Каталог уже существует.'.
*          WRITE: / icon_led_yellow  && ` ` && &1 && `: Каталог уже существует.`.
  ELSE.
    APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
    <fs_log>-full_path = iv_folder_url.
    <fs_log>-icon = icon_led_red.
    <fs_log>-message = 'Ошибка чтения каталога'.
*          WRITE: / icon_led_red  && ` ` && &1 && `: Ошибка чтения каталога.`.
  ENDIF.
ENDFORM.                    " CREATE_FOLDER
*&---------------------------------------------------------------------*
*&      Form  UPLOAD_DIRECTORY_FILES
*&---------------------------------------------------------------------*
*       Рекурсивная загрузка файлов директории
*----------------------------------------------------------------------*
FORM upload_directory_files
  USING it_files TYPE rstt_t_files.

  TYPES ltyp_binary TYPE x LENGTH 1024.

  DATA lt_x_binary  TYPE TABLE OF ltyp_binary.
  DATA lv_lenght    TYPE i.

  DATA lv_mime_path TYPE string.
  DATA lv_is_folder TYPE flag.
  DATA lt_mime_files TYPE string_table.
  DATA lv_content TYPE xstring.

  DATA lv_filename TYPE string.

  FIELD-SYMBOLS <fs_log> LIKE LINE OF gt_log.

  DATA(lv_lines) = lines( it_files ).
  DATA lv_line TYPE i.

  LOOP AT it_files ASSIGNING FIELD-SYMBOL(<fs_file>).
    lv_line = sy-tabix.

    CALL FUNCTION 'PROGRESS_INDICATOR'
      EXPORTING
        i_text               = `Обработка файлов`
        i_processed          = lv_line
        i_total              = lv_lines
        i_output_immediately = abap_true.


    CLEAR lv_is_folder.
    CLEAR lv_mime_path.

    lv_filename = <fs_file>-filename.
    PERFORM convert_zip_to_mime_path
      USING lv_filename
      CHANGING lv_mime_path
               lv_is_folder.

    CASE lv_is_folder.
      WHEN abap_true.
        PERFORM create_folder
          USING lv_mime_path.
      WHEN abap_false.

        cl_gui_frontend_services=>gui_upload(
          EXPORTING
            filename                = lv_filename
            filetype                = 'BIN'
          IMPORTING
            filelength              = lv_lenght
          CHANGING
            data_tab                = lt_x_binary
          EXCEPTIONS
            file_open_error         = 1
            file_read_error         = 2
            no_batch                = 3
            gui_refuse_filetransfer = 4
            invalid_type            = 5
            no_authority            = 6
            unknown_error           = 7
            bad_data_format         = 8
            header_not_allowed      = 9
            separator_not_allowed   = 10
            header_too_long         = 11
            unknown_dp_error        = 12
            access_denied           = 13
            dp_out_of_memory        = 14
            disk_full               = 15
            dp_timeout              = 16
            not_supported_by_gui    = 17
            error_no_gui            = 18
            OTHERS                  = 19
        ).

        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
          <fs_log>-full_path = lv_mime_path.
          <fs_log>-icon = icon_led_red.
          <fs_log>-message = `Не удалось загрузить файл.`.
          CONTINUE.
        ENDIF.

        CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
          EXPORTING
            input_length = lv_lenght
          IMPORTING
            buffer       = lv_content
          TABLES
            binary_tab   = lt_x_binary
          EXCEPTIONS
            failed       = 1
            OTHERS       = 2.

        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
          <fs_log>-full_path = lv_mime_path.
          <fs_log>-icon = icon_led_red.
          <fs_log>-message = `Не удалось загрузить файл.`.
          CONTINUE.
        ENDIF.

        IF sy-subrc EQ 0. "AND lv_content IS NOT INITIAL.
          cl_mime_repository_api=>get_api( )->properties(
            EXPORTING
              i_url               = lv_mime_path
              i_check_authority   = ' '
            IMPORTING
              e_is_folder         = lv_is_folder
            EXCEPTIONS
              parameter_missing   = 1
              error_occured       = 2
              not_found           = 3
              permission_failure  = 4
              OTHERS              = 5
          ).

          IF sy-subrc EQ 3.
            IF lv_content IS INITIAL.
              CALL FUNCTION 'SCMS_FTEXT_TO_XSTRING'
                EXPORTING
                  input_length = 1
*                 FIRST_LINE   = 0
*                 LAST_LINE    = 0
*                 MIMETYPE     = ' '
*                 ENCODING     =
                IMPORTING
                  buffer       = lv_content
                TABLES
                  ftext_tab    = gt_empty_file_ftext
                EXCEPTIONS
                  failed       = 1
                  OTHERS       = 2.

            ENDIF.

            cl_mime_repository_api=>get_api( )->put(
              EXPORTING
                i_url                     = lv_mime_path
                i_content                 = lv_content
                i_check_authority         = ' '
                i_description             = lv_mime_path
                i_dev_package             = p_devcls
                i_corr_number             = p_trkorr
              EXCEPTIONS
                parameter_missing         = 1
                error_occured             = 2
                cancelled                 = 3
                permission_failure        = 4
                data_inconsistency        = 5
                new_loio_already_exists   = 6
                is_folder                 = 7
                OTHERS                    = 8
            ).

            IF sy-subrc EQ 0.
              APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
              <fs_log>-full_path = lv_mime_path.
              <fs_log>-icon = icon_led_green.
              <fs_log>-message = `Файл успешно загружен.`.
*              WRITE: / icon_led_green && ` ` && lv_mime_path && `: Файл успешно загружен.`.


            ELSE.
              APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
              <fs_log>-full_path = lv_mime_path.
              <fs_log>-icon = icon_led_red.
              <fs_log>-message = `Не удалось загрузить файл.`.
*              WRITE: / icon_led_red && ` ` && lv_mime_path && `: Не удалось загрузить файл.`.
            ENDIF.
          ELSE.
            APPEND INITIAL LINE TO gt_log ASSIGNING <fs_log>.
            <fs_log>-full_path = lv_mime_path.
            <fs_log>-icon = icon_led_yellow.
            <fs_log>-message = `Файл уже существует.`.
*            WRITE: / icon_led_yellow && ` ` && lv_mime_path && `: Файл уже существует.` .
          ENDIF.
        ENDIF.
    ENDCASE.


  ENDLOOP.

ENDFORM.                    " UPLOAD_DIRECTORY_FILES
*&---------------------------------------------------------------------*
*&      Form  GET_FILES_LIST
*&---------------------------------------------------------------------*
*       Составляем список файлов для загрузки
*----------------------------------------------------------------------*
FORM get_files_list  USING    iv_folder
                     CHANGING ct_files_list TYPE rstt_t_files.

  DATA lt_fiels       TYPE rstt_t_files.
  DATA lt_directories TYPE rstt_t_files.
  DATA lv_count       TYPE i.
  DATA lv_full_path   TYPE string.

  " Получить список файлов текущей директории
  cl_gui_frontend_services=>directory_list_files(
    EXPORTING
      directory                   = iv_folder
      files_only                  = abap_true
*       directories_only            =
    CHANGING
      file_table                  = lt_fiels
      count                       = lv_count
    EXCEPTIONS
      cntl_error                  = 1
      directory_list_files_failed = 2
      wrong_parameter             = 3
      error_no_gui                = 4
      not_supported_by_gui        = 5
      OTHERS                      = 6
  ).

  " Добавить в общий список файлов для загрузки
  LOOP AT lt_fiels ASSIGNING FIELD-SYMBOL(<fs_file>).
    lv_full_path = iv_folder && gv_fromtend_file_separator && <fs_file>-filename.
    <fs_file>-filename = lv_full_path.
    APPEND <fs_file> TO ct_files_list.
  ENDLOOP.

  " Получить список нижестоящих директорий
  cl_gui_frontend_services=>directory_list_files(
      EXPORTING
        directory                   = iv_folder
*        files_only                  = abap_true
        directories_only            = abap_true
      CHANGING
        file_table                  = lt_directories
        count                       = lv_count
      EXCEPTIONS
        cntl_error                  = 1
        directory_list_files_failed = 2
        wrong_parameter             = 3
        error_no_gui                = 4
        not_supported_by_gui        = 5
        OTHERS                      = 6
    ).

  " Запустить рекурсивную загрузку по нижестоящим директориям
  LOOP AT lt_directories ASSIGNING FIELD-SYMBOL(<fs_directory>).
    lv_full_path = iv_folder && gv_fromtend_file_separator && <fs_directory>-filename.
    PERFORM get_files_list
      USING lv_full_path
      CHANGING ct_files_list.
  ENDLOOP.
ENDFORM.                    " GET_FILES_LIST
*&---------------------------------------------------------------------*
*&      Form  SELECT_FOLDER
*&---------------------------------------------------------------------*
*       Выбрать папку для загрузки
*----------------------------------------------------------------------*
FORM select_folder .
  cl_gui_frontend_services=>directory_browse(
    EXPORTING
      window_title         = 'Папка с исходными файлами для загрузки'
*      initial_folder       =
    CHANGING
      selected_folder      = p_folder
    EXCEPTIONS
      cntl_error           = 1
      error_no_gui         = 2
      not_supported_by_gui = 3
      OTHERS               = 4
  ).
  IF sy-subrc <> 0.
*   MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
*              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    " SELECT_FOLDER

Реализация статического метода Zcl_ui5_http_handler=>get_hash_for_long_file_name

METHOD GET_HASH_FOR_LONG_FILE_NAME.

  DATA lt_result    TYPE match_result_tab.
  DATA lv_file_name TYPE string.
  DATA lv_hash      TYPE hash160.
  data lv_lines     type i.

  FIELD-SYMBOLS <ls_result> LIKE LINE OF lt_result.

*--- check if file name is longer than 40 char
  FIND ALL OCCURRENCES OF '/'
   IN cv_url
   RESULTS lt_result.

  lv_lines = lines( lt_result ).

  READ TABLE lt_result ASSIGNING <ls_result> INDEX lv_lines.

  IF sy-subrc = 0 AND <ls_result>-offset > 0.
    lv_file_name = cv_url+<ls_result>-offset.
    SHIFT lv_file_name BY 1 PLACES LEFT.

    IF strlen( lv_file_name ) > 40.
      CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR'
        EXPORTING
*         ALG            = 'SHA1'
          data           = lv_file_name
*         LENGTH         = 0
        IMPORTING
          hash           = lv_hash
*         HASHLEN        =
*         HASHX          =
*         HASHXLEN       =
*         HASHSTRING     =
*         HASHXSTRING    =
*         HASHB64STRING  =
        EXCEPTIONS
          unknown_alg    = 1
          param_error    = 2
          internal_error = 3
          OTHERS         = 4.
      ASSERT sy-subrc = 0.

      CONCATENATE cv_url(<ls_result>-offset) '/'  lv_hash INTO cv_url.

    ENDIF.
    ev_file_name = lv_file_name.
  ELSEIF sy-subrc NE 0.
    ev_file_name = cv_url.
  ENDIF.

ENDMETHOD.