CTS integration (#2061)

* Implement facade for Change Transport System

* Render lock item in VIEW_REPO

* Add jump to SE01

* Display transport on stage page

* Optimize transport read on stage page

* Error handling CTS

* Fix indentation

* Disable transport column for local packages

* Code review changes
This commit is contained in:
Fabian Lupa 2018-11-09 05:36:44 +01:00 committed by Lars Hvam
parent 7cdbbc92b6
commit b08ee6a498
11 changed files with 413 additions and 68 deletions

View File

@ -34,6 +34,12 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
END OF ty_changed_by . END OF ty_changed_by .
TYPES: TYPES:
ty_changed_by_tt TYPE SORTED TABLE OF ty_changed_by WITH UNIQUE KEY item. ty_changed_by_tt TYPE SORTED TABLE OF ty_changed_by WITH UNIQUE KEY item.
TYPES:
BEGIN OF ty_transport,
item TYPE zif_abapgit_definitions=>ty_item,
transport TYPE trkorr,
END OF ty_transport,
ty_transport_tt TYPE SORTED TABLE OF ty_transport WITH UNIQUE KEY item.
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online . DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA ms_files TYPE zif_abapgit_definitions=>ty_stage_files . DATA ms_files TYPE zif_abapgit_definitions=>ty_stage_files .
@ -45,6 +51,11 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
!it_local TYPE zif_abapgit_definitions=>ty_files_item_tt !it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING RETURNING
VALUE(rt_changed_by) TYPE ty_changed_by_tt . VALUE(rt_changed_by) TYPE ty_changed_by_tt .
METHODS find_transports
IMPORTING
it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING
VALUE(rt_transports) TYPE ty_transport_tt.
METHODS render_list METHODS render_list
RETURNING RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html . VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
@ -54,6 +65,7 @@ CLASS zcl_abapgit_gui_page_stage DEFINITION
!is_file TYPE zif_abapgit_definitions=>ty_file !is_file TYPE zif_abapgit_definitions=>ty_file
!is_item TYPE zif_abapgit_definitions=>ty_item OPTIONAL !is_item TYPE zif_abapgit_definitions=>ty_item OPTIONAL
!iv_changed_by TYPE xubname OPTIONAL !iv_changed_by TYPE xubname OPTIONAL
!iv_transport TYPE trkorr OPTIONAL
RETURNING RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html . VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_actions METHODS render_actions
@ -77,7 +89,7 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION. CLASS zcl_abapgit_gui_page_stage IMPLEMENTATION.
METHOD build_menu. METHOD build_menu.
@ -135,6 +147,43 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD find_transports.
DATA: li_cts_api TYPE REF TO zif_abapgit_cts_api,
ls_new LIKE LINE OF rt_transports.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF it_local,
<ls_new> LIKE LINE OF rt_transports.
li_cts_api = zcl_abapgit_factory=>get_cts_api( ).
TRY.
LOOP AT it_local ASSIGNING <ls_local> WHERE item IS NOT INITIAL.
IF <ls_local>-item-obj_type IS NOT INITIAL AND
<ls_local>-item-obj_name IS NOT INITIAL AND
<ls_local>-item-devclass IS NOT INITIAL.
IF li_cts_api->is_chrec_possible_for_package( <ls_local>-item-devclass ) = abap_false.
EXIT. " Assume all other objects are also in packages without change recording
ELSEIF li_cts_api->is_object_type_lockable( <ls_local>-item-obj_type ) = abap_true AND
li_cts_api->is_object_locked_in_transport( iv_object_type = <ls_local>-item-obj_type
iv_object_name = <ls_local>-item-obj_name ) = abap_true.
ls_new-item = <ls_local>-item.
ls_new-transport = li_cts_api->get_current_transport_for_obj(
iv_object_type = <ls_local>-item-obj_type
iv_object_name = <ls_local>-item-obj_name
iv_resolve_task_to_request = abap_false ).
INSERT ls_new INTO TABLE rt_transports.
ENDIF.
ENDIF.
ENDLOOP.
CATCH zcx_abapgit_exception.
ASSERT 1 = 2.
ENDTRY.
ENDMETHOD.
METHOD get_page_patch. METHOD get_page_patch.
@ -288,11 +337,15 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
METHOD render_file. METHOD render_file.
DATA: lv_param TYPE string, DATA: lv_param TYPE string,
lv_filename TYPE string. lv_filename TYPE string,
lv_transport_string TYPE string,
lv_transport_html TYPE string.
CREATE OBJECT ro_html. CREATE OBJECT ro_html.
lv_transport_string = iv_transport.
lv_filename = is_file-path && is_file-filename. lv_filename = is_file-path && is_file-filename.
* make sure whitespace is preserved in the DOM * make sure whitespace is preserved in the DOM
REPLACE ALL OCCURRENCES OF ` ` IN lv_filename WITH '&nbsp;'. REPLACE ALL OCCURRENCES OF ` ` IN lv_filename WITH '&nbsp;'.
@ -308,13 +361,21 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
lv_filename = zcl_abapgit_html=>a( lv_filename = zcl_abapgit_html=>a(
iv_txt = lv_filename iv_txt = lv_filename
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_param }| ). iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_param }| ).
IF iv_transport IS NOT INITIAL.
lv_transport_html = zcl_abapgit_html=>a(
iv_txt = lv_transport_string
iv_act = |{ zif_abapgit_definitions=>c_action-jump_transport }?{ iv_transport }| ).
ENDIF.
ro_html->add( |<td class="type">{ is_item-obj_type }</td>| ). ro_html->add( |<td class="type">{ is_item-obj_type }</td>| ).
ro_html->add( |<td class="name">{ lv_filename }</td>| ). ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( |<td class="user">{ iv_changed_by }</td>| ). ro_html->add( |<td class="user">{ iv_changed_by }</td>| ).
ro_html->add( |<td class="transport">{ lv_transport_html }</td>| ).
WHEN 'remote'. WHEN 'remote'.
ro_html->add( '<td class="type">-</td>' ). " Dummy for object type ro_html->add( '<td class="type">-</td>' ). " Dummy for object type
ro_html->add( |<td class="name">{ lv_filename }</td>| ). ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( '<td></td>' ). " Dummy for changed-by ro_html->add( '<td></td>' ). " Dummy for changed-by
ro_html->add( '<td></td>' ). " Dummy for transport
ENDCASE. ENDCASE.
ro_html->add( |<td class="status">?</td>| ). ro_html->add( |<td class="status">?</td>| ).
@ -328,7 +389,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
METHOD render_list. METHOD render_list.
DATA: lt_changed_by TYPE ty_changed_by_tt, DATA: lt_changed_by TYPE ty_changed_by_tt,
ls_changed_by LIKE LINE OF lt_changed_by. ls_changed_by LIKE LINE OF lt_changed_by,
lt_transports TYPE ty_transport_tt,
ls_transport LIKE LINE OF lt_transports.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote, FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
<ls_local> LIKE LINE OF ms_files-local. <ls_local> LIKE LINE OF ms_files-local.
@ -338,6 +401,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ro_html->add( '<table id="stageTab" class="stage_tab w100">' ). ro_html->add( '<table id="stageTab" class="stage_tab w100">' ).
lt_changed_by = find_changed_by( ms_files-local ). lt_changed_by = find_changed_by( ms_files-local ).
lt_transports = find_transports( ms_files-local ).
" Local changes " Local changes
LOOP AT ms_files-local ASSIGNING <ls_local>. LOOP AT ms_files-local ASSIGNING <ls_local>.
@ -346,6 +410,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ro_html->add( '<th>Type</th>' ). ro_html->add( '<th>Type</th>' ).
ro_html->add( '<th>Files to add (click to see diff)</th>' ). ro_html->add( '<th>Files to add (click to see diff)</th>' ).
ro_html->add( '<th>Changed by</th>' ). ro_html->add( '<th>Changed by</th>' ).
ro_html->add( '<th>Transport</th>' ).
ro_html->add( '<th></th>' ). " Status ro_html->add( '<th></th>' ). " Status
ro_html->add( '<th class="cmd">' ). ro_html->add( '<th class="cmd">' ).
ro_html->add( '<a>add</a>&#x2193; <a>reset</a>&#x2193;' ). ro_html->add( '<a>add</a>&#x2193; <a>reset</a>&#x2193;' ).
@ -355,12 +420,16 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ENDAT. ENDAT.
READ TABLE lt_changed_by INTO ls_changed_by WITH KEY item = <ls_local>-item. "#EC CI_SUBRC READ TABLE lt_changed_by INTO ls_changed_by WITH KEY item = <ls_local>-item. "#EC CI_SUBRC
READ TABLE lt_transports INTO ls_transport WITH KEY item = <ls_local>-item. "#EC CI_SUBRC
ro_html->add( render_file( ro_html->add( render_file(
iv_context = 'local' iv_context = 'local'
is_file = <ls_local>-file is_file = <ls_local>-file
is_item = <ls_local>-item is_item = <ls_local>-item
iv_changed_by = ls_changed_by-name ) ). iv_changed_by = ls_changed_by-name
iv_transport = ls_transport-transport ) ).
CLEAR ls_transport.
AT LAST. AT LAST.
ro_html->add( '</tbody>' ). ro_html->add( '</tbody>' ).

View File

@ -40,11 +40,14 @@ CLASS zcl_abapgit_gui_router DEFINITION
METHODS get_page_playground METHODS get_page_playground
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception zcx_abapgit_cancel. RAISING zcx_abapgit_exception zcx_abapgit_cancel.
CLASS-METHODS jump_display_transport
IMPORTING iv_getdata TYPE clike.
ENDCLASS. ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION. CLASS zcl_abapgit_gui_router IMPLEMENTATION.
METHOD get_page_background. METHOD get_page_background.
@ -241,6 +244,9 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
WHEN zif_abapgit_definitions=>c_action-jump_pkg. " Open SE80 WHEN zif_abapgit_definitions=>c_action-jump_pkg. " Open SE80
zcl_abapgit_services_repo=>open_se80( |{ iv_getdata }| ). zcl_abapgit_services_repo=>open_se80( |{ iv_getdata }| ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act. ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-jump_transport.
jump_display_transport( iv_getdata ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
" DB actions " DB actions
WHEN zif_abapgit_definitions=>c_action-db_edit. WHEN zif_abapgit_definitions=>c_action-db_edit.
@ -376,4 +382,14 @@ CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
ENDCASE. ENDCASE.
ENDMETHOD. ENDMETHOD.
METHOD jump_display_transport.
DATA: lv_transport TYPE trkorr.
lv_transport = iv_getdata.
CALL FUNCTION 'TR_DISPLAY_REQUEST'
EXPORTING
i_trkorr = lv_transport.
ENDMETHOD.
ENDCLASS. ENDCLASS.

View File

@ -50,8 +50,9 @@ CLASS zcl_abapgit_gui_view_repo DEFINITION
RETURNING VALUE(ro_toolbar) TYPE REF TO zcl_abapgit_html_toolbar RETURNING VALUE(ro_toolbar) TYPE REF TO zcl_abapgit_html_toolbar
RAISING zcx_abapgit_exception, RAISING zcx_abapgit_exception,
render_item render_item
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html iv_render_transports TYPE abap_bool
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception, RAISING zcx_abapgit_exception,
render_item_files render_item_files
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
@ -65,6 +66,9 @@ CLASS zcl_abapgit_gui_view_repo DEFINITION
get_item_icon get_item_icon
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string, RETURNING VALUE(rv_html) TYPE string,
render_item_lock_column
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
render_empty_package render_empty_package
RETURNING VALUE(rv_html) TYPE string, RETURNING VALUE(rv_html) TYPE string,
render_parent_dir render_parent_dir
@ -85,7 +89,7 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION. CLASS zcl_abapgit_gui_view_repo IMPLEMENTATION.
METHOD build_dir_jump_link. METHOD build_dir_jump_link.
@ -398,20 +402,29 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
METHOD render_item. METHOD render_item.
DATA: lv_link TYPE string. DATA: lv_link TYPE string,
lv_colspan TYPE i.
CREATE OBJECT ro_html. CREATE OBJECT ro_html.
IF iv_render_transports = abap_false.
lv_colspan = 2.
ELSE.
lv_colspan = 3.
ENDIF.
ro_html->add( |<tr{ get_item_class( is_item ) }>| ). ro_html->add( |<tr{ get_item_class( is_item ) }>| ).
IF is_item-obj_name IS INITIAL AND is_item-is_dir = abap_false. IF is_item-obj_name IS INITIAL AND is_item-is_dir = abap_false.
ro_html->add( '<td colspan="2"></td>' ro_html->add( |<td colspan="{ lv_colspan }"></td>|
&& '<td class="object">' && '<td class="object">'
&& '<i class="grey">non-code and meta files</i>' && '<i class="grey">non-code and meta files</i>'
&& '</td>' ). && '</td>' ).
ELSE. ELSE.
ro_html->add( |<td class="icon">{ get_item_icon( is_item ) }</td>| ). ro_html->add( |<td class="icon">{ get_item_icon( is_item ) }</td>| ).
IF iv_render_transports = abap_true.
ro_html->add( render_item_lock_column( is_item ) ).
ENDIF.
IF is_item-is_dir = abap_true. " Subdir IF is_item-is_dir = abap_true. " Subdir
lv_link = build_dir_jump_link( is_item-path ). lv_link = build_dir_jump_link( is_item-path ).
@ -528,6 +541,38 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD render_item_lock_column.
DATA: li_cts_api TYPE REF TO zif_abapgit_cts_api,
lv_transport TYPE trkorr,
lv_transport_string TYPE string,
lv_icon_html TYPE string.
li_cts_api = zcl_abapgit_factory=>get_cts_api( ).
TRY.
IF is_item-obj_type IS INITIAL OR is_item-obj_name IS INITIAL OR
li_cts_api->is_object_type_lockable( is_item-obj_type ) = abap_false OR
li_cts_api->is_object_locked_in_transport( iv_object_type = is_item-obj_type
iv_object_name = is_item-obj_name ) = abap_false.
rv_html = |<td class="icon"></td>|.
ELSE.
lv_transport = li_cts_api->get_current_transport_for_obj( iv_object_type = is_item-obj_type
iv_object_name = is_item-obj_name
iv_resolve_task_to_request = abap_false ).
lv_transport_string = lv_transport.
lv_icon_html = zcl_abapgit_html=>a( iv_txt = zcl_abapgit_html=>icon( iv_name = 'lock/darkgrey'
iv_hint = lv_transport_string )
iv_act = |{ zif_abapgit_definitions=>c_action-jump_transport }?| &&
lv_transport ).
rv_html = |<td class="icon">| &&
|{ lv_icon_html }| &&
|</td>|.
ENDIF.
CATCH zcx_abapgit_exception.
ASSERT 1 = 2.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions. METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
@ -563,15 +608,16 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
METHOD zif_abapgit_gui_page~render. METHOD zif_abapgit_gui_page~render.
DATA: lt_repo_items TYPE zif_abapgit_definitions=>tt_repo_items, DATA: lt_repo_items TYPE zif_abapgit_definitions=>tt_repo_items,
lo_browser TYPE REF TO zcl_abapgit_repo_content_list, lo_browser TYPE REF TO zcl_abapgit_repo_content_list,
lx_error TYPE REF TO zcx_abapgit_exception, lx_error TYPE REF TO zcx_abapgit_exception,
lv_lstate TYPE char1, lv_lstate TYPE char1,
lv_rstate TYPE char1, lv_rstate TYPE char1,
lv_max TYPE abap_bool, lv_max TYPE abap_bool,
lv_max_str TYPE string, lv_max_str TYPE string,
lv_add_str TYPE string, lv_add_str TYPE string,
lo_log TYPE REF TO zcl_abapgit_log. lo_log TYPE REF TO zcl_abapgit_log,
lv_render_transports TYPE abap_bool.
FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_repo_items. FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_repo_items.
@ -582,6 +628,9 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
TRY. TRY.
lv_render_transports = zcl_abapgit_factory=>get_cts_api(
)->is_chrec_possible_for_package( mo_repo->get_package( ) ).
CREATE OBJECT lo_browser CREATE OBJECT lo_browser
EXPORTING EXPORTING
io_repo = mo_repo. io_repo = mo_repo.
@ -624,7 +673,7 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
lv_max = abap_true. lv_max = abap_true.
EXIT. " current loop EXIT. " current loop
ENDIF. ENDIF.
ro_html->add( render_item( <ls_item> ) ). ro_html->add( render_item( is_item = <ls_item> iv_render_transports = lv_render_transports ) ).
ENDLOOP. ENDLOOP.
ENDIF. ENDIF.

View File

@ -24,7 +24,7 @@ if (!Function.prototype.bind) {
}; };
if (this.prototype) { if (this.prototype) {
fNOP.prototype = this.prototype; fNOP.prototype = this.prototype;
} }
fBound.prototype = new fNOP(); fBound.prototype = new fNOP();
@ -39,7 +39,7 @@ if (!String.prototype.includes) {
if (typeof start !== 'number') { if (typeof start !== 'number') {
start = 0; start = 0;
} }
if (start + search.length > this.length) { if (start + search.length > this.length) {
return false; return false;
} else { } else {
@ -64,7 +64,7 @@ function submitSapeventForm(params, action, method) {
var form = document.createElement("form"); var form = document.createElement("form");
form.setAttribute("method", method || "post"); form.setAttribute("method", method || "post");
form.setAttribute("action", "sapevent:" + action); form.setAttribute("action", "sapevent:" + action);
for(var key in params) { for(var key in params) {
var hiddenField = document.createElement("input"); var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("type", "hidden");
@ -133,8 +133,8 @@ function perfOut(prefix) {
var keys = Object.keys(totals); var keys = Object.keys(totals);
for (var i = keys.length - 1; i >= 0; i--) { for (var i = keys.length - 1; i >= 0; i--) {
console.log(prefix console.log(prefix
+ " " + keys[i] + ": " + " " + keys[i] + ": "
+ totals[keys[i]].time.toFixed(3) + "ms" + totals[keys[i]].time.toFixed(3) + "ms"
+ " (" + totals[keys[i]].count.toFixed() +")"); + " (" + totals[keys[i]].count.toFixed() +")");
} }
@ -190,10 +190,10 @@ function StageHelper(params) {
objectSearch: document.getElementById(params.ids.objectSearch), objectSearch: document.getElementById(params.ids.objectSearch),
fileCounter: document.getElementById(params.ids.fileCounter) fileCounter: document.getElementById(params.ids.fileCounter)
}; };
// Table columns (autodetection) // Table columns (autodetection)
this.colIndex = this.detectColumns(); this.colIndex = this.detectColumns();
this.filterTargets = ["name", "user"]; this.filterTargets = ["name", "user", "transport"];
// Constants // Constants
this.HIGHLIGHT_STYLE = "highlight"; this.HIGHLIGHT_STYLE = "highlight";
@ -204,7 +204,7 @@ function StageHelper(params) {
reset: "?", reset: "?",
isValid: function (status) { return "ARI?".indexOf(status) == -1; } isValid: function (status) { return "ARI?".indexOf(status) == -1; }
}; };
this.TEMPLATES = { this.TEMPLATES = {
cmdReset: "<a>reset</a>", cmdReset: "<a>reset</a>",
cmdLocal: "<a>add</a>", cmdLocal: "<a>add</a>",
@ -275,10 +275,10 @@ StageHelper.prototype.onTableClick = function (event) {
} else return; } else return;
if (["TD","TH"].indexOf(td.tagName) == -1 || td.className != "cmd") return; if (["TD","TH"].indexOf(td.tagName) == -1 || td.className != "cmd") return;
var status = this.STATUS[target.innerText]; // Convert anchor text to status var status = this.STATUS[target.innerText]; // Convert anchor text to status
var targetRow = td.parentNode; var targetRow = td.parentNode;
if (td.tagName === "TD") { if (td.tagName === "TD") {
this.updateRow(targetRow, status); this.updateRow(targetRow, status);
} else { // TH } else { // TH
@ -298,7 +298,7 @@ StageHelper.prototype.onTableClick = function (event) {
StageHelper.prototype.onFilter = function (e) { StageHelper.prototype.onFilter = function (e) {
if ( // Enter hit or clear, IE SUCKS ! if ( // Enter hit or clear, IE SUCKS !
e.type === "input" && !e.target.value && this.lastFilterValue e.type === "input" && !e.target.value && this.lastFilterValue
|| e.type === "keypress" && e.which === 13 ) { || e.type === "keypress" && e.which === 13 ) {
this.applyFilterValue(e.target.value); this.applyFilterValue(e.target.value);
submitSapeventForm({ 'filterValue': e.target.value }, "stage_filter", "post"); submitSapeventForm({ 'filterValue': e.target.value }, "stage_filter", "post");
@ -325,7 +325,7 @@ StageHelper.prototype.applyFilterToRow = function (row, filter) {
}; };
}, this); }, this);
var isVisible = false; var isVisible = false;
// Apply filter to cells, mark filtered text // Apply filter to cells, mark filtered text
for (var i = targets.length - 1; i >= 0; i--) { for (var i = targets.length - 1; i >= 0; i--) {
@ -346,8 +346,8 @@ StageHelper.prototype.applyFilterToRow = function (row, filter) {
// Get how status should affect object counter // Get how status should affect object counter
StageHelper.prototype.getStatusImpact = function (status) { StageHelper.prototype.getStatusImpact = function (status) {
if (typeof status !== "string" if (typeof status !== "string"
|| status.length !== 1 || status.length !== 1
|| this.STATUS.isValid(status) ) { || this.STATUS.isValid(status) ) {
alert("Unknown status"); alert("Unknown status");
} else { } else {
@ -383,8 +383,8 @@ StageHelper.prototype.updateRowStatus = function (row, status) {
StageHelper.prototype.updateRowCommand = function (row, status) { StageHelper.prototype.updateRowCommand = function (row, status) {
var cell = row.cells[this.colIndex["cmd"]]; var cell = row.cells[this.colIndex["cmd"]];
if (status === this.STATUS.reset) { if (status === this.STATUS.reset) {
cell.innerHTML = (row.className == "local") cell.innerHTML = (row.className == "local")
? this.TEMPLATES.cmdLocal ? this.TEMPLATES.cmdLocal
: this.TEMPLATES.cmdRemote; : this.TEMPLATES.cmdRemote;
} else { } else {
cell.innerHTML = this.TEMPLATES.cmdReset; cell.innerHTML = this.TEMPLATES.cmdReset;
@ -413,7 +413,7 @@ StageHelper.prototype.collectData = function () {
} }
// Table iteration helper // Table iteration helper
StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) { StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) {
var restArgs = Array.prototype.slice.call(arguments, 2); var restArgs = Array.prototype.slice.call(arguments, 2);
var table = this.dom.stageTab; var table = this.dom.stageTab;
@ -502,7 +502,7 @@ function DiffHelper(params) {
if (document.getElementById(params.ids.filterMenu)) { if (document.getElementById(params.ids.filterMenu)) {
this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this)); this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this));
this.dom.filterButton = document.getElementById(params.ids.filterMenu).parentNode; this.dom.filterButton = document.getElementById(params.ids.filterMenu).parentNode;
} }
// Hijack stage command // Hijack stage command
if (this.dom.stageButton) { if (this.dom.stageButton) {
@ -581,14 +581,14 @@ function displayNews() {
div.style.display = (div.style.display) ? '' : 'none'; div.style.display = (div.style.display) ? '' : 'none';
} }
// Hotkey Overview // Hotkey Overview
function closeHotkeyOverview() { function closeHotkeyOverview() {
var div = document.getElementById("hotkeys"); var div = document.getElementById("hotkeys");
div.style.display = (div.style.display) ? '' : 'none'; div.style.display = (div.style.display) ? '' : 'none';
} }
function KeyNavigation() { function KeyNavigation() {
} }
KeyNavigation.prototype.onkeydown = function(oEvent) { KeyNavigation.prototype.onkeydown = function(oEvent) {
@ -621,7 +621,7 @@ KeyNavigation.prototype.getActiveElementParent = function () {
}; };
KeyNavigation.prototype.onEnterOrSpace = function (oEvent) { KeyNavigation.prototype.onEnterOrSpace = function (oEvent) {
// Enter or space clicks the selected link // Enter or space clicks the selected link
var liSelected = this.getLiSelected(); var liSelected = this.getLiSelected();
@ -695,7 +695,7 @@ function enableArrowListNavigation() {
} }
function LinkHints(sLinkHintKey, sColor){ function LinkHints(sLinkHintKey, sColor){
this.sLinkHintKey = sLinkHintKey; this.sLinkHintKey = sLinkHintKey;
this.sColor = sColor; this.sColor = sColor;
this.oTooltipMap = {}; this.oTooltipMap = {};
this.bTooltipsOn = false; this.bTooltipsOn = false;
@ -715,7 +715,7 @@ LinkHints.prototype.fnRenderTooltip = function (oTooltip, iTooltipCounter) {
}; };
LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){ LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){
// if whe have 333 tooltips we start from 100 // if whe have 333 tooltips we start from 100
return Math.pow(10,iToolTipCount.toString().length - 1); return Math.pow(10,iToolTipCount.toString().length - 1);
@ -724,10 +724,10 @@ LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){
LinkHints.prototype.fnRenderTooltips = function () { LinkHints.prototype.fnRenderTooltips = function () {
// all possible links which should be accessed via tooltip have // all possible links which should be accessed via tooltip have
// sub span which is hidden by default. If we like to show the // sub span which is hidden by default. If we like to show the
// tooltip we have to toggle the css class 'hidden'. // tooltip we have to toggle the css class 'hidden'.
// //
// We use numeric values for the tooltip label. Maybe we can // We use numeric values for the tooltip label. Maybe we can
// support also alphanumeric chars in the future. Then we have to // support also alphanumeric chars in the future. Then we have to
// calculate permutations and that's work. So for the sake of simplicity // calculate permutations and that's work. So for the sake of simplicity
// we stick to numeric values and just increment them. // we stick to numeric values and just increment them.
@ -784,7 +784,7 @@ LinkHints.prototype.fnFilterTooltips = function (sPending) {
}; };
LinkHints.prototype.fnActivateDropDownMenu = function (oTooltip) { LinkHints.prototype.fnActivateDropDownMenu = function (oTooltip) {
// to enable link hint navigation for drop down menu, we must expand // to enable link hint navigation for drop down menu, we must expand
// like if they were hovered // like if they were hovered
oTooltip.parentElement.parentElement.classList.toggle("block"); oTooltip.parentElement.parentElement.classList.toggle("block");
}; };
@ -810,7 +810,7 @@ LinkHints.prototype.onkeypress = function(oEvent){
} }
var activeElementType = ((document.activeElement && document.activeElement.nodeName) || ""); var activeElementType = ((document.activeElement && document.activeElement.nodeName) || "");
// link hints are disabled for input and textareas for obvious reasons. // link hints are disabled for input and textareas for obvious reasons.
// Maybe we must add other types here in the future // Maybe we must add other types here in the future
if (oEvent.key === this.sLinkHintKey && activeElementType !== "INPUT" && activeElementType !== "TEXTAREA") { if (oEvent.key === this.sLinkHintKey && activeElementType !== "INPUT" && activeElementType !== "TEXTAREA") {
@ -818,7 +818,7 @@ LinkHints.prototype.onkeypress = function(oEvent){
this.fnToggleAllTooltips(); this.fnToggleAllTooltips();
} else if (this.bTooltipsOn === true) { } else if (this.bTooltipsOn === true) {
// the user tries to reach a tooltip // the user tries to reach a tooltip
this.sPending += oEvent.key; this.sPending += oEvent.key;
var oTooltip = this.oTooltipMap[this.sPending]; var oTooltip = this.oTooltipMap[this.sPending];
@ -856,8 +856,8 @@ function Hotkeys(oKeyMap){
// these are the hotkeys provided by the backend // these are the hotkeys provided by the backend
Object.keys(this.oKeyMap).forEach(function(sKey){ Object.keys(this.oKeyMap).forEach(function(sKey){
var action = this.oKeyMap[sKey]; var action = this.oKeyMap[sKey];
// We replace the actions with callback functions to unify // We replace the actions with callback functions to unify
// the hotkey execution // the hotkey execution
this.oKeyMap[sKey] = function(oEvent) { this.oKeyMap[sKey] = function(oEvent) {
@ -872,7 +872,7 @@ function Hotkeys(oKeyMap){
if (window[action]) { if (window[action]) {
window[action].call(this); window[action].call(this);
} }
// Or a SAP event // Or a SAP event
var sUiSapEvent = this.getSapEvent(action); var sUiSapEvent = this.getSapEvent(action);
if (sUiSapEvent) { if (sUiSapEvent) {
@ -889,7 +889,7 @@ function Hotkeys(oKeyMap){
Hotkeys.prototype.showHotkeys = function() { Hotkeys.prototype.showHotkeys = function() {
var elHotkeys = document.querySelector('#hotkeys'); var elHotkeys = document.querySelector('#hotkeys');
if (elHotkeys) { if (elHotkeys) {
elHotkeys.style.display = (elHotkeys.style.display) ? '' : 'none'; elHotkeys.style.display = (elHotkeys.style.display) ? '' : 'none';
} }
@ -906,7 +906,7 @@ Hotkeys.prototype.getSapEvent = function(sSapEvent) {
var aSapEvents = document.querySelectorAll('a[href^="sapevent:' + sSapEvent + '"]'); var aSapEvents = document.querySelectorAll('a[href^="sapevent:' + sSapEvent + '"]');
var aFilteredAndNormalizedSapEvents = var aFilteredAndNormalizedSapEvents =
[].map.call(aSapEvents, function(oSapEvent){ [].map.call(aSapEvents, function(oSapEvent){
return fnNormalizeSapEventHref(sSapEvent, oSapEvent); return fnNormalizeSapEventHref(sSapEvent, oSapEvent);
}) })
@ -931,7 +931,7 @@ Hotkeys.prototype.onkeydown = function(oEvent){
return; return;
} }
var var
sKey = oEvent.key || String.fromCharCode(oEvent.keyCode), sKey = oEvent.key || String.fromCharCode(oEvent.keyCode),
fnHotkey = this.oKeyMap[sKey]; fnHotkey = this.oKeyMap[sKey];
@ -948,7 +948,7 @@ function setKeyBindings(oKeyMap){
} }
/* /*
Patch / git add -p Patch / git add -p
*/ */
@ -971,7 +971,7 @@ function Patch() {
PATCH_ADD_ALL: 'patch_add_all', PATCH_ADD_ALL: 'patch_add_all',
PATCH_REMOVE_ALL: 'patch_remove_all' PATCH_REMOVE_ALL: 'patch_remove_all'
}; };
this.ACTION = { this.ACTION = {
PATCH_STAGE: 'patch_stage' PATCH_STAGE: 'patch_stage'
}; };
@ -999,7 +999,7 @@ Patch.prototype.registerClickHandlerSingleLine = function(){
Patch.prototype.registerClickHandlerAllFile = function(){ Patch.prototype.registerClickHandlerAllFile = function(){
// registers the link handlers for add and remove all changes for a file // registers the link handlers for add and remove all changes for a file
this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_ADD_ALL, this.ADD_REMOVE); this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_ADD_ALL, this.ADD_REMOVE);
this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_REMOVE_ALL, this.REMOVE_ADD); this.registerClickHandlerForPatchLinkAll('#' + this.ID.PATCH_REMOVE_ALL, this.REMOVE_ADD);
@ -1007,14 +1007,14 @@ Patch.prototype.registerClickHandlerAllFile = function(){
}; };
Patch.prototype.registerClickHandlerForPatchLink = function(oClassCombination) { Patch.prototype.registerClickHandlerForPatchLink = function(oClassCombination) {
// register onclick handler. When a link is clicked it is // register onclick handler. When a link is clicked it is
// deactivated and its corresponding link gets active // deactivated and its corresponding link gets active
// //
// e.g. if you click on 'add' add is deactivated and 'remove' // e.g. if you click on 'add' add is deactivated and 'remove'
// is activated. // is activated.
var elLinkAll = document.querySelectorAll('.' + this.CSS_CLASS.PATCH + ' a.' + oClassCombination.sClassLinkClicked); var elLinkAll = document.querySelectorAll('.' + this.CSS_CLASS.PATCH + ' a.' + oClassCombination.sClassLinkClicked);
[].forEach.call(elLinkAll,function(elLink){ [].forEach.call(elLinkAll,function(elLink){
elLink.addEventListener('click',function(oEvent){ elLink.addEventListener('click',function(oEvent){
@ -1025,7 +1025,7 @@ Patch.prototype.registerClickHandlerForPatchLink = function(oClassCombination) {
}; };
Patch.prototype.togglePatchActive = function(oEvent, elClicked, elCorrespondingLink){ Patch.prototype.togglePatchActive = function(oEvent, elClicked, elCorrespondingLink){
if (!elClicked.classList.contains(this.CSS_CLASS.PATCH_ACTIVE)){ if (!elClicked.classList.contains(this.CSS_CLASS.PATCH_ACTIVE)){
elClicked.classList.toggle(this.CSS_CLASS.PATCH_ACTIVE); elClicked.classList.toggle(this.CSS_CLASS.PATCH_ACTIVE);
@ -1046,7 +1046,7 @@ Patch.prototype.togglePatchActiveForClassLink = function(oEvent, elClicked, oCla
Patch.prototype.getCorrespodingLinkId = function(sClickedLinkId, oClassCombination){ Patch.prototype.getCorrespodingLinkId = function(sClickedLinkId, oClassCombination){
// e.g. // e.g.
// //
// add_patch_z_test_git_add_p.prog.abap_28 => remove_patch_z_test_git_add_p.prog.abap_28 // add_patch_z_test_git_add_p.prog.abap_28 => remove_patch_z_test_git_add_p.prog.abap_28
// //
@ -1066,7 +1066,7 @@ Patch.prototype.patchLinkClickAll = function(oClassCombination) {
var sTableId = oEvent.srcElement.parentElement.parentElement.parentElement.parentElement.id; var sTableId = oEvent.srcElement.parentElement.parentElement.parentElement.parentElement.id;
var elAddAll = document.querySelectorAll('#' + this.escapeDots(sTableId) + ' a.' + oClassCombination.sClassLinkClicked); var elAddAll = document.querySelectorAll('#' + this.escapeDots(sTableId) + ' a.' + oClassCombination.sClassLinkClicked);
[].forEach.call(elAddAll,function(elem){ [].forEach.call(elAddAll,function(elem){
this.togglePatchActiveForClassLink(oEvent, elem, oClassCombination); this.togglePatchActiveForClassLink(oEvent, elem, oClassCombination);
}.bind(this)); }.bind(this));

View File

@ -0,0 +1,118 @@
"! Change transport system API
CLASS zcl_abapgit_cts_api DEFINITION
PUBLIC
FINAL
CREATE PRIVATE
GLOBAL FRIENDS zcl_abapgit_factory.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_cts_api.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_cts_api IMPLEMENTATION.
METHOD zif_abapgit_cts_api~get_current_transport_for_obj.
DATA: lv_object_lockable TYPE abap_bool,
lv_locked TYPE abap_bool,
lv_transport_request TYPE trkorr,
lv_task TYPE trkorr,
lv_tr_object_name TYPE trobj_name.
lv_tr_object_name = iv_object_name.
CALL FUNCTION 'TR_CHECK_OBJECT_LOCK'
EXPORTING
wi_pgmid = iv_program_id
wi_object = iv_object_type
wi_objname = lv_tr_object_name
IMPORTING
we_lockable_object = lv_object_lockable
we_locked = lv_locked
we_lock_order = lv_transport_request
we_lock_task = lv_task
EXCEPTIONS
empty_key = 1
no_systemname = 2
no_systemtype = 3
unallowed_lock_order = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
IF lv_locked = abap_false.
zcx_abapgit_exception=>raise( |Object { iv_program_id }-{ iv_object_type }-{ iv_object_name } is not locked| ).
ENDIF.
IF lv_object_lockable = abap_false.
zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ).
ENDIF.
IF lv_task IS NOT INITIAL AND lv_task <> lv_transport_request AND iv_resolve_task_to_request = abap_false.
rv_transport = lv_task.
ELSE.
rv_transport = lv_transport_request.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_object_locked_in_transport.
DATA: ls_object_key TYPE e071,
lv_type_check_result TYPE c LENGTH 1,
ls_lock_key TYPE tlock_int,
lv_lock_flag TYPE c LENGTH 1.
ls_object_key-pgmid = iv_program_id.
ls_object_key-object = iv_object_type.
ls_object_key-obj_name = iv_object_name.
CALL FUNCTION 'TR_CHECK_TYPE'
EXPORTING
wi_e071 = ls_object_key
IMPORTING
pe_result = lv_type_check_result
we_lock_key = ls_lock_key.
IF lv_type_check_result <> 'L'.
zcx_abapgit_exception=>raise( |Object type { iv_program_id }-{ iv_object_type } not lockable| ).
ENDIF.
CALL FUNCTION 'TRINT_CHECK_LOCKS'
EXPORTING
wi_lock_key = ls_lock_key
IMPORTING
we_lockflag = lv_lock_flag
EXCEPTIONS
empty_key = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |TRINT_CHECK_LOCKS: { sy-subrc }| ).
ENDIF.
rv_locked = boolc( lv_lock_flag <> space ).
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_object_type_lockable.
DATA: ls_object_key TYPE e071,
lv_type_check_result TYPE c LENGTH 1.
ls_object_key-pgmid = iv_program_id.
ls_object_key-object = iv_object_type.
ls_object_key-obj_name = '*'.
CALL FUNCTION 'TR_CHECK_TYPE'
EXPORTING
wi_e071 = ls_object_key
IMPORTING
pe_result = lv_type_check_result.
rv_lockable = boolc( lv_type_check_result = 'L' ).
ENDMETHOD.
METHOD zif_abapgit_cts_api~is_chrec_possible_for_package.
rv_possible = zcl_abapgit_factory=>get_sap_package( iv_package )->are_changes_recorded_in_tr_req( ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ABAPGIT_CTS_API</CLSNAME>
<VERSION>1</VERSION>
<LANGU>E</LANGU>
<DESCRIPT>Change transport system API</DESCRIPT>
<STATE>1</STATE>
<CLSFINAL>X</CLSFINAL>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -54,6 +54,9 @@ CLASS zcl_abapgit_factory DEFINITION
CLASS-METHODS get_stage_logic CLASS-METHODS get_stage_logic
RETURNING RETURNING
VALUE(ri_logic) TYPE REF TO zif_abapgit_stage_logic . VALUE(ri_logic) TYPE REF TO zif_abapgit_stage_logic .
CLASS-METHODS get_cts_api
RETURNING
VALUE(ri_cts_api) TYPE REF TO zif_abapgit_cts_api.
PRIVATE SECTION. PRIVATE SECTION.
TYPES: TYPES:
@ -96,6 +99,7 @@ CLASS zcl_abapgit_factory DEFINITION
CLASS-DATA gt_syntax_check TYPE tty_syntax_check . CLASS-DATA gt_syntax_check TYPE tty_syntax_check .
CLASS-DATA gi_branch_overview TYPE REF TO zif_abapgit_branch_overview . CLASS-DATA gi_branch_overview TYPE REF TO zif_abapgit_branch_overview .
CLASS-DATA gi_stage_logic TYPE REF TO zif_abapgit_stage_logic . CLASS-DATA gi_stage_logic TYPE REF TO zif_abapgit_stage_logic .
CLASS-DATA gi_cts_api TYPE REF TO zif_abapgit_cts_api.
CLASS-DATA gi_adhoc_code_inspector TYPE REF TO zif_abapgit_code_inspector. CLASS-DATA gi_adhoc_code_inspector TYPE REF TO zif_abapgit_code_inspector.
ENDCLASS. ENDCLASS.
@ -218,6 +222,13 @@ CLASS zcl_abapgit_factory IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD get_cts_api.
IF gi_cts_api IS NOT BOUND.
CREATE OBJECT gi_cts_api TYPE zcl_abapgit_cts_api.
ENDIF.
ri_cts_api = gi_cts_api.
ENDMETHOD.
METHOD get_adhoc_code_inspector. METHOD get_adhoc_code_inspector.
@ -246,6 +257,4 @@ CLASS zcl_abapgit_factory IMPLEMENTATION.
ENDIF. ENDIF.
ENDMETHOD. ENDMETHOD.
ENDCLASS. ENDCLASS.

View File

@ -24,12 +24,15 @@ CLASS zcl_abapgit_injector DEFINITION
CLASS-METHODS set_stage_logic CLASS-METHODS set_stage_logic
IMPORTING IMPORTING
!ii_logic TYPE REF TO zif_abapgit_stage_logic . !ii_logic TYPE REF TO zif_abapgit_stage_logic .
CLASS-METHODS set_cts_api
IMPORTING
ii_cts_api TYPE REF TO zif_abapgit_cts_api.
PRIVATE SECTION. PRIVATE SECTION.
ENDCLASS. ENDCLASS.
CLASS ZCL_ABAPGIT_INJECTOR IMPLEMENTATION. CLASS zcl_abapgit_injector IMPLEMENTATION.
METHOD set_code_inspector. METHOD set_code_inspector.
@ -115,4 +118,8 @@ CLASS ZCL_ABAPGIT_INJECTOR IMPLEMENTATION.
zcl_abapgit_factory=>gi_tadir = ii_tadir. zcl_abapgit_factory=>gi_tadir = ii_tadir.
ENDMETHOD. ENDMETHOD.
METHOD set_cts_api.
zcl_abapgit_factory=>gi_cts_api = ii_cts_api.
ENDMETHOD.
ENDCLASS. ENDCLASS.

View File

@ -0,0 +1,42 @@
"! Change transport system API
INTERFACE zif_abapgit_cts_api PUBLIC.
METHODS:
"! Returns the transport request / task the object is currently locked in
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter iv_object_name | Object name
"! @parameter iv_resolve_task_to_request | Return the transport request number if the object is locked in a task
"! @parameter rv_transport | Transport request / task
"! @raising zcx_abapgit_exception | Object is not locked in a transport
get_current_transport_for_obj IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
iv_object_name TYPE sobj_name
iv_resolve_task_to_request TYPE abap_bool DEFAULT abap_true
RETURNING VALUE(rv_transport) TYPE trkorr
RAISING zcx_abapgit_exception,
"! Check if the object is currently locked in a transport
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter iv_object_name | Object name
"! @parameter rv_locked | Object is locked
"! @raising zcx_abapgit_exception | Object type is not lockable
is_object_locked_in_transport IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
iv_object_name TYPE sobj_name
RETURNING VALUE(rv_locked) TYPE abap_bool
RAISING zcx_abapgit_exception,
"! Check if the object type is lockable
"! @parameter iv_program_id | Program ID
"! @parameter iv_object_type | Object type
"! @parameter rv_lockable | Lockable
is_object_type_lockable IMPORTING iv_program_id TYPE pgmid DEFAULT 'R3TR'
iv_object_type TYPE trobjtype
RETURNING VALUE(rv_lockable) TYPE abap_bool,
"! Check if change recording is possible for the given package
"! @parameter iv_package | Package
"! @parameter rv_possible | Change recording is possible
"! @raising zcx_abapgit_exception | Package could not be loaded
is_chrec_possible_for_package IMPORTING iv_package TYPE devclass
RETURNING VALUE(rv_possible) TYPE abap_bool
RAISING zcx_abapgit_exception.
ENDINTERFACE.

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOINTERF>
<CLSNAME>ZIF_ABAPGIT_CTS_API</CLSNAME>
<VERSION>1</VERSION>
<LANGU>E</LANGU>
<DESCRIPT>Change transport system API</DESCRIPT>
<EXPOSURE>2</EXPOSURE>
<STATE>1</STATE>
<UNICODE>X</UNICODE>
</VSEOINTERF>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -481,6 +481,7 @@ INTERFACE zif_abapgit_definitions PUBLIC.
jump TYPE string VALUE 'jump', jump TYPE string VALUE 'jump',
jump_pkg TYPE string VALUE 'jump_pkg', jump_pkg TYPE string VALUE 'jump_pkg',
jump_transport TYPE string VALUE 'jump_transport',
url TYPE string VALUE 'url', url TYPE string VALUE 'url',
END OF c_action . END OF c_action .