process_docget

in src/zgoog_cl_content_repo_gcs.clas.abap [0:0]


  METHOD process_docget.
    TYPES:
      BEGIN OF lty_comp_data,
        comp_id TYPE sdok_filnm,
        data    TYPE xstring,
      END OF lty_comp_data,

      ltt_comp_data TYPE HASHED TABLE OF lty_comp_data WITH UNIQUE KEY comp_id.

    DATA: lo_contrep       TYPE REF TO data,
          lo_docid         TYPE REF TO data,
          lo_gcs           TYPE REF TO zgoog_cl_storage_cont_repo_v1,
          lo_struc         TYPE REF TO cl_abap_structdescr,
          lo_entity        TYPE REF TO if_http_entity,
          lo_abap_sdk_excp TYPE REF TO /goog/cx_sdk.

    DATA: lv_contrep      TYPE string,
          lv_docid        TYPE string,
          lv_pversion     TYPE string,
          lv_seckey       TYPE string,
          lv_smand        TYPE c LENGTH 1,
          lv_signature    TYPE c LENGTH 1,
          lv_q_prefix     TYPE string,
          lv_data         TYPE xstring,
          lv_msg          TYPE string,
          lv_status       TYPE string,
          lv_inumcomps    TYPE i,
          lv_numcomps     TYPE string,
          lv_size         TYPE string,
          lv_mimetype     TYPE string,
          lv_compid       TYPE string,
          lv_p_bucket     TYPE string,
          lv_ret_code     TYPE i,
          lv_err_text     TYPE string,
          lv_crea_date    TYPE d,
          lv_crea_time    TYPE t,
          lv_chng_date    TYPE d,
          lv_chng_time    TYPE t,
          lv_dummy        TYPE string,
          lv_timec        TYPE string,
          lv_datec        TYPE string,
          lv_timem        TYPE string,
          lv_datem        TYPE string,
          lv_doc_status   TYPE scms_docst,
          lv_time_updated TYPE string,
          lv_time_created TYPE string,
          lv_bucket       TYPE string.

    DATA: ls_object_list   TYPE /goog/cl_storage_v1=>ty_016,
          ls_err_resp      TYPE /goog/err_resp,
          ls_output_object TYPE /goog/cl_storage_v1=>ty_013,
          ls_component     TYPE REF TO abap_compdescr,
          ls_metadata      TYPE scms_acinf,
          ls_info          TYPE scms_acinf,
          ls_comp_data     TYPE lty_comp_data,
          ls_data          TYPE xstring.

    DATA: lt_infos     TYPE STANDARD TABLE OF scms_acinf,
          lt_comp_data TYPE ltt_comp_data,
          lt_txt       TYPE STANDARD TABLE OF sdokcntasc,
          lt_bin       TYPE STANDARD TABLE OF sdokcntbin.

    FIELD-SYMBOLS: <lv_contrep>       TYPE c,
                   <lv_docid>         TYPE c,
                   <ls_metadata_comp> TYPE any,
                   <ls_source>        TYPE any,
                   <ls_target>        TYPE any,
                   <ls_source_val>    TYPE any,
                   <ls_comp_data>     TYPE lty_comp_data.

    get_parameter_c( EXPORTING iv_name      = 'contRep '
                               iv_mandatory = 'S'
                     IMPORTING ev_value_s   = lv_contrep
                               er_value     = lo_contrep ).
    get_parameter_c( EXPORTING iv_name      = 'docId'
                               iv_mandatory = 'S'
                     IMPORTING ev_value_s   = lv_docid
                               er_value     = lo_docid ).

    ASSIGN lo_contrep->* TO <lv_contrep>.
    ASSIGN lo_docid->*   TO <lv_docid>.

    lv_pversion = get_parameter( iv_name      = 'pVersion'
                                 iv_mandatory = 'X' ).
    lv_seckey   = get_parameter( iv_name = 'secKey' ).

    IF lv_seckey IS NOT INITIAL.
      lv_smand = 'S'.
      get_parameter( iv_name      = 'accessMode'
                     iv_mandatory = lv_smand ).
      get_parameter( iv_name      = 'authId'
                     iv_mandatory = lv_smand ).
      get_parameter( iv_name      = 'expiration'
                     iv_mandatory = lv_smand ).
    ENDIF.

    check_parameter_consistence( ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    lv_signature = check_signature( iv_docprot = 'r' ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    load_goog_repo_config( <lv_contrep> ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    TRY.
        CREATE OBJECT lo_gcs EXPORTING iv_key_name = gs_repo_config-keyname.

        lv_q_prefix = <lv_docid>.
        lv_p_bucket = gs_repo_config-bucket.

        lo_gcs->list_objects( EXPORTING iv_q_prefix = lv_q_prefix
                                        iv_p_bucket = lv_p_bucket
                              IMPORTING es_output   = ls_object_list
                                        ev_ret_code = lv_ret_code
                                        ev_err_text = lv_err_text
                                        es_err_resp = ls_err_resp ).
        IF lo_gcs->is_success( lv_ret_code ) <> abap_true.
          set_error( iv_code = lv_ret_code
                     iv_text = lv_err_text ).
          RETURN.
        ELSEIF ls_object_list-items IS INITIAL.
          set_error( iv_code = 404
                     iv_text = 'Document not found in the repository' ) ##NO_TEXT.
          RETURN.
        ELSE.

          FIELD-SYMBOLS: <ls_item> TYPE /goog/cl_storage_v1=>ty_013.
          LOOP AT ls_object_list-items ASSIGNING <ls_item>.
            lv_bucket = gs_repo_config-bucket.

            lo_gcs->add_common_qparam( iv_name  = 'alt'
                                       iv_value = 'media' ).

            lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_bucket
                                           iv_p_object = <ls_item>-name
                                 IMPORTING es_output   = ls_output_object
                                           ev_ret_code = lv_ret_code
                                           ev_err_text = lv_err_text
                                           es_err_resp = ls_err_resp
                                           es_raw      = lv_data ).

            IF <ls_item>-name = <lv_docid> && '/' && <lv_docid>.
              lo_gcs->clear_all_common_qparams( ).

              lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_bucket
                                             iv_p_object = <ls_item>-name
                                   IMPORTING es_output   = ls_output_object
                                             ev_ret_code = lv_ret_code
                                             ev_err_text = lv_err_text
                                             es_err_resp = ls_err_resp
                                             es_raw      = ls_data ).

              TRY.
                  lv_timec = substring( val = ls_output_object-time_created
                                        off = 11
                                        len = 8 ).
                  lv_datec = substring( val = ls_output_object-time_created
                                        off = 0
                                        len = 10 ).
                  lv_timem = substring( val = ls_output_object-updated
                                        off = 11
                                        len = 8 ).
                  lv_datem = substring( val = ls_output_object-updated
                                        off = 0
                                        len = 10 ).
                CATCH cx_sy_range_out_of_bounds.
                  " Do nothing
              ENDTRY.
              lv_doc_status = 0.

            ELSE.
              lo_gcs->clear_all_common_qparams( ).

              lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_bucket
                                             iv_p_object = <ls_item>-name
                                   IMPORTING es_output   = ls_output_object
                                             ev_ret_code = lv_ret_code
                                             ev_err_text = lv_err_text
                                             es_err_resp = ls_err_resp
                                             es_raw      = ls_data ).

              IF ls_output_object-metadata IS BOUND.
                ASSIGN ls_output_object-metadata->* TO <ls_metadata_comp>.

                lo_struc ?= cl_abap_structdescr=>describe_by_data( <ls_metadata_comp> ).

                LOOP AT lo_struc->components REFERENCE INTO ls_component.

                  ASSIGN COMPONENT ls_component->name OF STRUCTURE <ls_metadata_comp> TO <ls_source>.
                  IF sy-subrc IS NOT INITIAL.
                    CONTINUE.
                  ENDIF.

                  ASSIGN COMPONENT ls_component->name OF STRUCTURE ls_metadata TO <ls_target>.
                  IF sy-subrc IS NOT INITIAL.
                    CONTINUE.
                  ENDIF.

                  ASSIGN <ls_source>->* TO <ls_source_val>.
                  <ls_target> = <ls_source_val>.

                ENDLOOP.
              ENDIF.

              MOVE-CORRESPONDING ls_metadata TO ls_info.
              TRY.
                  lv_time_created = ls_output_object-time_created(19).
                  ls_info-crea_time  = convert_str_to_time( lv_time_created ).

                  lv_time_updated = ls_output_object-updated(19).
                  ls_info-chng_time  = convert_str_to_time( lv_time_updated ).

                  APPEND ls_info TO lt_infos.
                CATCH cx_sy_range_out_of_bounds.
                  " Do nothing
              ENDTRY.

              ls_comp_data-comp_id = ls_info-comp_id.
              ls_comp_data-data    = lv_data.
              INSERT ls_comp_data INTO TABLE lt_comp_data.

            ENDIF.

          ENDLOOP.

        ENDIF.

      CATCH /goog/cx_sdk INTO lo_abap_sdk_excp.
        lv_msg = lo_abap_sdk_excp->get_text( ).
        set_error( iv_code = 400
                   iv_text = lv_msg ).
        RETURN.

    ENDTRY.

    lv_status = format_status( iv_status = lv_doc_status ).

    lo_entity = go_server->response.
    DESCRIBE TABLE lt_infos LINES lv_inumcomps.
    lv_numcomps = lv_inumcomps.

    lo_entity->set_header_field( name  = 'Content-Type' ##NO_TEXT
                                 value = 'multipart/form-data' ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-dateC'
                                 value = lv_datec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-timeC'
                                 value = lv_timec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-dateM'
                                 value = lv_datec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-timeM'
                                 value = lv_timec ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-numComps'
                                 value = lv_numcomps ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-contRep'
                                 value = lv_contrep ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-docId'
                                 value = lv_docid ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-docStatus'
                                 value = lv_status ) ##NO_TEXT.
    lo_entity->set_header_field( name  = 'X-pVersion'
                                 value = lv_pversion ) ##NO_TEXT.

    " Add new header field to disable auto sniffing by IE
    lo_entity->set_header_field( name  = 'X-Content-Type-Options'
                                 value = 'nosniff' ) ##NO_TEXT.

    LOOP AT lt_infos INTO ls_info.

      format_timestamp( EXPORTING iv_timestamp = ls_info-crea_time
                        IMPORTING ev_date      = lv_datec
                                  ev_time      = lv_timec ).
      format_timestamp( EXPORTING iv_timestamp = ls_info-chng_time
                        IMPORTING ev_date      = lv_datem
                                  ev_time      = lv_timem ).

      lv_size = ls_info-comp_size.
      lv_mimetype = ls_info-mimetype.
      lv_compid   = ls_info-comp_id.
      lv_status = 'online'.

      READ TABLE lt_comp_data ASSIGNING <ls_comp_data>
           WITH TABLE KEY comp_id = ls_info-comp_id.
      IF sy-subrc IS NOT INITIAL.
        CONTINUE.
      ENDIF.

      lv_data = <ls_comp_data>-data.
      lv_size = xstrlen( lv_data ).

      lo_entity = go_server->response->add_multipart( ).

      lo_entity->suppress_content_type( ).

      lo_entity->set_header_field( name  = 'Content-Type'
                                   value = lv_mimetype ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'Content-Length'
                                   value = lv_size ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compId'
                                   value = lv_compid ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-Content-Length'
                                   value = lv_size ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compDateC'
                                   value = lv_datec ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compTimeC'
                                   value = lv_timec ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compDateM'
                                   value = lv_datem ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compTimeM'
                                   value = lv_timem ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-compStatus'
                                   value = lv_status ) ##NO_TEXT.
      lo_entity->set_header_field( name  = 'X-pVersion'
                                   value = lv_pversion ) ##NO_TEXT.

      " Add new header field to disable auto sniffing by IE
      lo_entity->set_header_field( name  = 'X-Content-Type-Options'
                                   value = 'nosniff' ) ##NO_TEXT.
      TRY.
          lo_entity->set_data( data = lv_data ).
        CATCH cx_vsi.
          MESSAGE e025(cms) WITH 'Virus scan detected '
                                 'an infected file '
                                 'while trying to access the file.'
                                 'Operation aborted'
                                 INTO lv_dummy ##NO_TEXT.
          sys_error_set( ).
          gs_error-status_code = 500.
      ENDTRY.
    ENDLOOP.