├── .abapgit.xml ├── LICENSE ├── README.md ├── abaplint.json ├── plantuml.txt └── src ├── package.devc.xml ├── zblame.tran.xml ├── zcl_timem_asset_css.clas.abap ├── zcl_timem_asset_css.clas.xml ├── zcl_timem_asset_factory.clas.abap ├── zcl_timem_asset_factory.clas.xml ├── zcl_timem_asset_html_blame.clas.abap ├── zcl_timem_asset_html_blame.clas.xml ├── zcl_timem_asset_html_tmachine.clas.abap ├── zcl_timem_asset_html_tmachine.clas.xml ├── zcl_timem_author.clas.abap ├── zcl_timem_author.clas.xml ├── zcl_timem_consts.clas.abap ├── zcl_timem_consts.clas.xml ├── zcl_timem_diff.clas.abap ├── zcl_timem_diff.clas.testclasses.abap ├── zcl_timem_diff.clas.xml ├── zcl_timem_dynpro.clas.abap ├── zcl_timem_dynpro.clas.xml ├── zcl_timem_gui.clas.abap ├── zcl_timem_gui.clas.xml ├── zcl_timem_gui_handler.clas.abap ├── zcl_timem_gui_handler.clas.xml ├── zcl_timem_gui_viewer.clas.abap ├── zcl_timem_gui_viewer.clas.xml ├── zcl_timem_object_clas.clas.abap ├── zcl_timem_object_clas.clas.xml ├── zcl_timem_object_factory.clas.abap ├── zcl_timem_object_factory.clas.xml ├── zcl_timem_object_fugr.clas.abap ├── zcl_timem_object_fugr.clas.xml ├── zcl_timem_object_func.clas.abap ├── zcl_timem_object_func.clas.xml ├── zcl_timem_object_prog.clas.abap ├── zcl_timem_object_prog.clas.xml ├── zcl_timem_object_prog_includes.clas.abap ├── zcl_timem_object_prog_includes.clas.xml ├── zcl_timem_object_tr.clas.abap ├── zcl_timem_object_tr.clas.xml ├── zcl_timem_options.clas.abap ├── zcl_timem_options.clas.xml ├── zcl_timem_part.clas.abap ├── zcl_timem_part.clas.xml ├── zcl_timem_parts.clas.abap ├── zcl_timem_parts.clas.xml ├── zcl_timem_request.clas.abap ├── zcl_timem_request.clas.xml ├── zcl_timem_run.clas.abap ├── zcl_timem_run.clas.xml ├── zcl_timem_stats.clas.abap ├── zcl_timem_stats.clas.xml ├── zcl_timem_summary.clas.abap ├── zcl_timem_summary.clas.xml ├── zcl_timem_syntax_abap.clas.abap ├── zcl_timem_syntax_abap.clas.xml ├── zcl_timem_syntax_highlighter.clas.abap ├── zcl_timem_syntax_highlighter.clas.testclasses.abap ├── zcl_timem_syntax_highlighter.clas.xml ├── zcl_timem_userexit_default.clas.abap ├── zcl_timem_userexit_default.clas.xml ├── zcl_timem_userexits.clas.abap ├── zcl_timem_userexits.clas.xml ├── zcl_timem_version.clas.abap ├── zcl_timem_version.clas.xml ├── zcl_timem_versno.clas.abap ├── zcl_timem_versno.clas.xml ├── zcl_timem_vrsd.clas.abap ├── zcl_timem_vrsd.clas.xml ├── zcx_timem.clas.abap ├── zcx_timem.clas.xml ├── zif_timem_asset.intf.abap ├── zif_timem_asset.intf.xml ├── zif_timem_object.intf.abap ├── zif_timem_object.intf.xml ├── zif_timem_userexit.intf.abap ├── zif_timem_userexit.intf.xml ├── ztimem_css_main.xslt.source.xml ├── ztimem_css_main.xslt.xml ├── ztimem_css_theme_dark.xslt.source.xml ├── ztimem_css_theme_dark.xslt.xml ├── ztimem_css_theme_light.xslt.source.xml ├── ztimem_css_theme_light.xslt.xml ├── ztimem_custom_field.dtel.xml ├── ztimem_data.tabl.xml ├── ztimem_html_blame.xslt.source.xml ├── ztimem_html_blame.xslt.xml ├── ztimem_html_timemachine.xslt.source.xml ├── ztimem_html_timemachine.xslt.xml ├── ztimem_line.tabl.xml ├── ztimem_line_t.ttyp.xml ├── ztimem_mode.doma.xml ├── ztimem_mode.dtel.xml ├── ztimem_object_type.doma.xml ├── ztimem_object_type.dtel.xml ├── ztimem_part.tabl.xml ├── ztimem_part_source.tabl.xml ├── ztimem_part_source_t.ttyp.xml ├── ztimem_part_t.ttyp.xml ├── ztimem_percentage.dtel.xml ├── ztimem_stats.tabl.xml ├── ztimem_summary.tabl.xml ├── ztimem_summary_line.tabl.xml ├── ztimem_summary_line_t.ttyp.xml ├── ztimem_summary_t.ttyp.xml ├── ztimem_summary_titles.tabl.xml ├── ztimem_theme.doma.xml ├── ztimem_theme.dtel.xml ├── ztimem_timestamp_t.ttyp.xml ├── ztimemachine.msag.xml ├── ztimemachine.prog.abap ├── ztimemachine.prog.xml └── ztimemachine.tran.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | /.gitlab-ci.yml 15 | /abaplint.json 16 | /azure-pipelines.yml 17 | /plantuml.txt 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nuno Godinho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abapTimeMachine 2 | 3 | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=abapinho_abapTimeMachine&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=abapinho_abapTimeMachine) 4 | 5 | `abapTimeMachine` provides a simple way to look at past versions of classes, function groups, etc, as a whole (as opposed to the crappy native include-oriented approach). Alternatively, it also partially emulates [git-blame](https://www.git-scm.com/docs/git-blame) by showing "what revision and author last modified each line of a file" for any given version. 6 | 7 | ## Why 8 | 9 | ABAP's versioning system is unbelievably bad. There is no native way to see how a whole class or a whole function group were at a given time in the past. Besides, it makes it very hard to find out which user was responsible for which changes. `abapTimeMachine` is here to solve both these problems. 10 | 11 | ## How 12 | 13 | Please read the [Wiki](https://github.com/abapinho/abapTimeMachine/wiki) to learn how to install and use `ZTIMEMACHINE`. 14 | 15 | ## Requirements 16 | 17 | * ABAP Version: 7.40 or higher 18 | * [abapGit](https://abapgit.org) 19 | 20 | ## FAQ 21 | 22 | For questions/comments/bugs/feature requests/wishes please create an [issue](https://github.com/abapinho/abapTimeMachine/issues). 23 | 24 | ## Credits 25 | 26 | * Most code by [Nuno Godinho](https://github.com/nununo) 27 | * Diff algorithm and syntax highlighter parcially copied from [abapGit](https://abapgit.org) 28 | -------------------------------------------------------------------------------- /abaplint.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/src/**/*.*", 4 | "exclude": [], 5 | "skipGeneratedGatewayClasses": true, 6 | "skipGeneratedPersistentClasses": true, 7 | "skipGeneratedFunctionGroups": true, 8 | "useApackDependencies": false, 9 | "skipIncludesWithoutMain": false 10 | }, 11 | "dependencies": [ 12 | { 13 | "url": "https://github.com/abaplint/deps", 14 | "folder": "/deps", 15 | "files": "/src/**/*.*" 16 | } 17 | ], 18 | "syntax": { 19 | "version": "v750", 20 | "errorNamespace": "^(Z|Y|LCL_|TY_|LIF_)", 21 | "globalConstants": [], 22 | "globalMacros": [] 23 | }, 24 | "rules": { 25 | "7bit_ascii": true, 26 | "abapdoc": false, 27 | "allowed_object_naming": true, 28 | "allowed_object_types": true, 29 | "ambiguous_statement": true, 30 | "avoid_use": { 31 | "define": false, 32 | "statics": true, 33 | "defaultKey": false, 34 | "break": true, 35 | "describeLines": true 36 | }, 37 | "begin_end_names": true, 38 | "begin_single_include": true, 39 | "call_transaction_authority_check": true, 40 | "chain_mainly_declarations": { 41 | "definitions": true, 42 | "write": true, 43 | "move": true, 44 | "refresh": true, 45 | "unassign": true, 46 | "clear": true, 47 | "hide": true, 48 | "free": true, 49 | "include": true, 50 | "check": true, 51 | "sort": true 52 | }, 53 | "check_abstract": true, 54 | "check_comments": false, 55 | "check_ddic": true, 56 | "check_include": true, 57 | "check_no_handler_pragma": true, 58 | "check_subrc": false, 59 | "check_syntax": true, 60 | "check_text_elements": true, 61 | "check_transformation_exists": true, 62 | "class_attribute_names": false, 63 | "cloud_types": true, 64 | "colon_missing_space": true, 65 | "commented_code": false, 66 | "constructor_visibility_public": true, 67 | "contains_tab": { 68 | "exclude": [], 69 | "severity": "Error", 70 | "spaces": 1 71 | }, 72 | "cyclomatic_complexity": { 73 | "exclude": [], 74 | "severity": "Error", 75 | "max": 20 76 | }, 77 | "dangerous_statement": { 78 | "exclude": [], 79 | "severity": "Error", 80 | "execSQL": true, 81 | "kernelCall": true, 82 | "systemCall": true, 83 | "insertReport": true, 84 | "generateDynpro": true, 85 | "generateReport": true, 86 | "generateSubroutine": true, 87 | "deleteReport": true, 88 | "deleteTextpool": true, 89 | "deleteDynpro": true, 90 | "importDynpro": true 91 | }, 92 | "db_operation_in_loop": true, 93 | "definitions_top": false, 94 | "description_empty": true, 95 | "double_space": false, 96 | "downport": true, 97 | "empty_line_in_statement": false, 98 | "empty_statement": true, 99 | "empty_structure": false, 100 | "exit_or_check": true, 101 | "exporting": true, 102 | "forbidden_identifier": false, 103 | "forbidden_pseudo_and_pragma": false, 104 | "forbidden_void_type": false, 105 | "form_tables_obsolete": true, 106 | "fully_type_constants": true, 107 | "function_module_recommendations": false, 108 | "functional_writing": true, 109 | "global_class": true, 110 | "identical_conditions": true, 111 | "identical_contents": true, 112 | "identical_descriptions": false, 113 | "identical_form_names": true, 114 | "if_in_if": true, 115 | "implement_methods": true, 116 | "in_statement_indentation": false, 117 | "indentation": false, 118 | "inline_data_old_versions": true, 119 | "intf_referencing_clas": false, 120 | "keep_single_parameter_on_one_line": true, 121 | "keyword_case": false, 122 | "line_break_multiple_parameters": false, 123 | "line_break_style": true, 124 | "line_length": { 125 | "exclude": [], 126 | "severity": "Error", 127 | "length": 130 128 | }, 129 | "line_only_punc": false, 130 | "local_class_naming": true, 131 | "local_testclass_location": true, 132 | "local_variable_names": false, 133 | "main_file_contents": true, 134 | "many_parenthesis": true, 135 | "max_one_method_parameter_per_line": true, 136 | "max_one_statement": true, 137 | "message_exists": true, 138 | "method_implemented_twice": true, 139 | "method_length": false, 140 | "method_overwrites_builtin": true, 141 | "method_parameter_names": false, 142 | "mix_returning": true, 143 | "modify_only_own_db_tables": true, 144 | "msag_consistency": true, 145 | "names_no_dash": true, 146 | "nesting": { 147 | "exclude": [], 148 | "severity": "Error", 149 | "depth": 5 150 | }, 151 | "newline_between_methods": { 152 | "exclude": [], 153 | "severity": "Error", 154 | "count": 3, 155 | "logic": "less" 156 | }, 157 | "no_public_attributes": false, 158 | "no_yoda_conditions": false, 159 | "object_naming": true, 160 | "obsolete_statement": { 161 | "exclude": [], 162 | "severity": "Error", 163 | "refresh": false, 164 | "compute": true, 165 | "add": true, 166 | "subtract": true, 167 | "multiply": true, 168 | "divide": true, 169 | "move": true, 170 | "requested": true, 171 | "occurs": true, 172 | "setExtended": true, 173 | "withHeaderLine": true, 174 | "fieldSymbolStructure": true, 175 | "typePools": true, 176 | "load": true, 177 | "parameter": true, 178 | "ranges": true, 179 | "communication": true, 180 | "pack": true, 181 | "selectWithoutInto": true, 182 | "freeMemory": true, 183 | "exitFromSQL": true 184 | }, 185 | "omit_parameter_name": true, 186 | "omit_receiving": true, 187 | "parser_702_chaining": true, 188 | "parser_error": true, 189 | "parser_missing_space": true, 190 | "prefer_inline": false, 191 | "prefer_is_not": true, 192 | "prefer_raise_exception_new": true, 193 | "prefer_returning_to_exporting": true, 194 | "prefer_xsdbool": false, 195 | "preferred_compare_operator": true, 196 | "prefix_is_current_class": false, 197 | "reduce_string_templates": true, 198 | "release_idoc": true, 199 | "remove_descriptions": false, 200 | "rfc_error_handling": true, 201 | "select_add_order_by": true, 202 | "select_performance": false, 203 | "selection_screen_naming": { 204 | "exclude": [], 205 | "severity": "Error", 206 | "patternKind": "required", 207 | "ignoreNames": [], 208 | "ignorePatterns": [], 209 | "parameter": "^P_.+$", 210 | "selectOption": "^S_.+$" 211 | }, 212 | "sequential_blank": { 213 | "exclude": [], 214 | "severity": "Error", 215 | "lines": 4 216 | }, 217 | "short_case": { 218 | "exclude": [], 219 | "severity": "Error", 220 | "length": 1, 221 | "allow": [] 222 | }, 223 | "sicf_consistency": true, 224 | "space_before_colon": true, 225 | "space_before_dot": true, 226 | "sql_escape_host_variables": false, 227 | "start_at_tab": true, 228 | "superclass_final": true, 229 | "sy_modification": true, 230 | "tabl_enhancement_category": true, 231 | "try_without_catch": true, 232 | "type_form_parameters": true, 233 | "types_naming": { 234 | "exclude": [], 235 | "severity": "Error", 236 | "pattern": "^TY_.+$" 237 | }, 238 | "uncaught_exception": true, 239 | "unknown_types": true, 240 | "unreachable_code": true, 241 | "unsecure_fae": true, 242 | "unused_methods": true, 243 | "unused_types": { 244 | "exclude": [], 245 | "severity": "Error", 246 | "skipNames": [] 247 | }, 248 | "unused_variables": { 249 | "exclude": [], 250 | "severity": "Error", 251 | "skipNames": [] 252 | }, 253 | "use_bool_expression": true, 254 | "use_class_based_exceptions": true, 255 | "use_line_exists": true, 256 | "use_new": false, 257 | "when_others_last": true, 258 | "whitespace_end": true, 259 | "xml_consistency": true 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /plantuml.txt: -------------------------------------------------------------------------------- 1 | @startuml 2 | package "User-exits" { 3 | interface ZIF_TIMEM_USEREXIT 4 | ZCL_TIMEM_USEREXITS "1" *-- "many" ZIF_TIMEM_USEREXIT 5 | } 6 | 7 | package "Object" { 8 | interface ZIF_TIMEM_OBJECT 9 | 10 | ZCL_TIMEM_OBJECT_PROG --|> ZIF_TIMEM_OBJECT 11 | ZCL_TIMEM_OBJECT_CLAS --|> ZIF_TIMEM_OBJECT 12 | ZCL_TIMEM_OBJECT_FUGR --|> ZIF_TIMEM_OBJECT 13 | 14 | ZCL_TIMEM_OBJECT_FACTORY ..> ZIF_TIMEM_OBJECT 15 | ZCL_TIMEM_OBJECT_FACTORY ..> ZCL_TIMEM_OBJECT_PROG 16 | ZCL_TIMEM_OBJECT_FACTORY ..> ZCL_TIMEM_OBJECT_PROG_INCLUDES 17 | ZCL_TIMEM_OBJECT_FACTORY ..> ZCL_TIMEM_OBJECT_CLAS 18 | ZCL_TIMEM_OBJECT_FACTORY ..> ZCL_TIMEM_OBJECT_FUGR 19 | } 20 | 21 | package "Parts" { 22 | ZCL_TIMEM_VERSION ..> ZCL_TIMEM_AUTHOR 23 | 24 | ZCL_TIMEM_PART "1" *-- "many" ZCL_TIMEM_VERSION 25 | ZCL_TIMEM_PART ..> ZCL_TIMEM_DIFF 26 | ZCL_TIMEM_PART ..> ZCL_TIMEM_VRSD 27 | 28 | ZCL_TIMEM_AGGREGATED_FIELDS ..> ZCL_TIMEM_AGGREATED_FIELD 29 | ZCL_TIMEM_AGGREGATED_FIELD --> ZCL_TIMEM_REQUEST 30 | 31 | ZCL_TIMEM_PARTS "1" *-- "many" ZCL_TIMEM_PART 32 | ZCL_TIMEM_PARTS *-- ZCL_TIMEM_USEREXITS 33 | ZCL_TIMEM_PARTS ..> ZCL_TIMEM_STATS 34 | ZCL_TIMEM_PARTS ..> ZCL_TIMEM_AGGREGATED_FIELDS 35 | ZCL_TIMEM_PARTS ..> ZCL_TIMEM_OBJECT_FACTORY 36 | ZCL_TIMEM_PARTS ..> ZIF_TIMEM_OBJECT 37 | } 38 | 39 | package "GUI" { 40 | abstract ZCL_TIMEM_SYNTAX_HIGHLIGHTER 41 | 42 | ZCL_TIMEM_SYNTAX_ABAP --|> ZCL_TIMEM_SYNTAX_HIGHLIGHTER 43 | 44 | interface ZIF_TIMEM_ASSET 45 | ZCL_TIMEM_ASSET_CSS --|> ZIF_TIMEM_ASSET 46 | ZCL_TIMEM_ASSET_HTML_BLAME --|> ZIF_TIMEM_ASSET 47 | ZCL_TIMEM_ASSET_HTML_TMACHINE --|> ZIF_TIMEM_ASSET 48 | ZCL_TIMEM_ASSET_FACTORY ..> ZIF_TIMEM_ASSET 49 | ZCL_TIMEM_ASSET_FACTORY ..> ZCL_TIMEM_ASSET_CSS 50 | ZCL_TIMEM_ASSET_FACTORY ..> ZCL_TIMEM_ASSET_HTML_BLAME 51 | ZCL_TIMEM_ASSET_FACTORY ..> ZCL_TIMEM_ASSET_HTML_TMACHINE 52 | 53 | ZCL_TIMEM_GUI_VIEWER *-- ZCL_TIMEM_USEREXITS 54 | ZCL_TIMEM_GUI_VIEWER ..> ZCL_TIMEM_ASSET_FACTORY 55 | ZCL_TIMEM_GUI_VIEWER ..> ZIF_TIMEM_ASSET 56 | 57 | ZCL_TIMEM_GUI_HANDLER *-- ZCL_TIMEM_USEREXITS 58 | ZCL_TIMEM_GUI_HANDLER o-- ZCL_TIMEM_GUI 59 | 60 | ZCL_TIMEM_GUI *-- ZCL_TIMEM_GUI_HANDLER 61 | ZCL_TIMEM_GUI *-- ZCL_TIMEM_GUI_VIEWER 62 | ZCL_TIMEM_GUI *-- ZCL_TIMEM_PARTS 63 | ZCL_TIMEM_GUI ..> ZCL_TIMEM_SYNTAX_ABAP 64 | } 65 | 66 | package "Run" { 67 | class ZTIMEMACHINE << (P,grey) >> 68 | ZTIMEMACHINE *.. ZCL_TIMEM_DYNPRO 69 | ZTIMEMACHINE *.. ZCL_TIMEM_RUN 70 | ZCL_TIMEM_RUN ..> ZCL_TIMEM_GUI 71 | 72 | class SE91_ZTIMEMACHINE << (T,grey) >> 73 | SE91_ZTIMEMACHINE ..> ZTIMEMACHINE 74 | 75 | class SE91_ZBLAME << (T,grey) >> 76 | SE91_ZBLAME ..> ZTIMEMACHINE 77 | } 78 | 79 | package "Used everywhere" { 80 | interface ZIF_TIMEM_CONSTS 81 | class ZCL_TIMEM_OPTIONS 82 | class ZCX_TIMEM 83 | } 84 | @enduml 85 | -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | abapTimeMachine 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/zblame.tran.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZBLAME 7 | ZTIMEMACHINE 8 | 1000 9 | gA== 10 | 11 | 12 | ZBLAME 13 | 1 14 | X 15 | X 16 | 17 | 18 | E 19 | ZBLAME 20 | ABAP Blame 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_css.clas.abap: -------------------------------------------------------------------------------- 1 | "! Renders a CSS asset which is generated from a Transformation based on 2 | "! the provided theme name 3 | class ZCL_TIMEM_ASSET_CSS definition 4 | public 5 | final 6 | create private 7 | 8 | global friends ZCL_TIMEM_ASSET_FACTORY . 9 | 10 | public section. 11 | 12 | interfaces ZIF_TIMEM_ASSET . 13 | 14 | "! Constructor for a CSS asset 15 | "! @parameter theme | Theme name which will determine which transformation to use 16 | "! to generate the CSS asset 17 | methods CONSTRUCTOR 18 | importing 19 | !theme type ZTIMEM_THEME . 20 | PROTECTED SECTION. 21 | PRIVATE SECTION. 22 | DATA theme_transformation TYPE char30. 23 | ENDCLASS. 24 | 25 | 26 | 27 | CLASS ZCL_TIMEM_ASSET_CSS IMPLEMENTATION. 28 | 29 | 30 | METHOD constructor. 31 | theme_transformation = |ZTIMEM_CSS_THEME_{ theme }|. 32 | ENDMETHOD. 33 | 34 | 35 | METHOD zif_timem_asset~get_content. 36 | DATA theme_css TYPE string. 37 | DATA(css) = ||. 38 | 39 | CALL TRANSFORMATION ztimem_css_main 40 | SOURCE XML css 41 | RESULT XML result. 42 | 43 | CALL TRANSFORMATION (theme_transformation) 44 | SOURCE XML css 45 | RESULT XML theme_css. 46 | 47 | result = |{ result }{ theme_css }|. 48 | ENDMETHOD. 49 | 50 | 51 | METHOD zif_timem_asset~get_subtype. 52 | result = 'css'. 53 | ENDMETHOD. 54 | 55 | 56 | METHOD zif_timem_asset~get_url. 57 | result = 'abaptimemachine.css'. 58 | ENDMETHOD. 59 | ENDCLASS. 60 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_css.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_ASSET_CSS 7 | E 8 | abapTimeMachine Asset CSS 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_factory.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_asset_factory DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | METHODS create_instance 8 | IMPORTING 9 | !asset_type TYPE string 10 | !data TYPE ztimem_data 11 | mode TYPE ztimem_mode 12 | theme TYPE ztimem_theme 13 | RETURNING 14 | VALUE(result) TYPE REF TO zif_timem_asset . 15 | PROTECTED SECTION. 16 | PRIVATE SECTION. 17 | ENDCLASS. 18 | 19 | 20 | 21 | CLASS zcl_timem_asset_factory IMPLEMENTATION. 22 | 23 | 24 | METHOD create_instance. 25 | result = SWITCH #( 26 | asset_type 27 | WHEN zcl_timem_consts=>asset_type-css THEN NEW zcl_timem_asset_css( theme ) 28 | WHEN zcl_timem_consts=>asset_type-html THEN 29 | SWITCH #( 30 | mode 31 | WHEN zcl_timem_consts=>mode-blame THEN NEW zcl_timem_asset_html_blame( data ) 32 | WHEN zcl_timem_consts=>mode-time_machine THEN NEW zcl_timem_asset_html_tmachine( data ) ) ). 33 | ENDMETHOD. 34 | ENDCLASS. 35 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_factory.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_ASSET_FACTORY 7 | E 8 | abapTimeMachine Asset factory 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CREATE_INSTANCE 17 | DATA 18 | E 19 | abapTimeMachine Parts 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_html_blame.clas.abap: -------------------------------------------------------------------------------- 1 | "! Renders the main HTML page from a Transformation which receives the deep 2 | "! structure with all the required data 3 | class ZCL_TIMEM_ASSET_HTML_BLAME definition 4 | public 5 | final 6 | create private 7 | 8 | global friends ZCL_TIMEM_ASSET_FACTORY . 9 | 10 | public section. 11 | 12 | interfaces ZIF_TIMEM_ASSET . 13 | 14 | "! Constructor for the main HTML asset 15 | "! @parameter is_parts | Deep structure containing all the information that 16 | "! is to be rendered as HTML. 17 | methods CONSTRUCTOR 18 | importing 19 | !DATA type ZTIMEM_DATA . 20 | PROTECTED SECTION. 21 | private section. 22 | 23 | data DATA type ZTIMEM_DATA . 24 | ENDCLASS. 25 | 26 | 27 | 28 | CLASS ZCL_TIMEM_ASSET_HTML_BLAME IMPLEMENTATION. 29 | 30 | 31 | METHOD constructor. 32 | me->data = data. 33 | ENDMETHOD. 34 | 35 | 36 | METHOD zif_timem_asset~get_content. 37 | CALL TRANSFORMATION ztimem_html_blame 38 | SOURCE data = data 39 | RESULT XML result 40 | OPTIONS xml_header = 'NO'. 41 | ENDMETHOD. 42 | 43 | 44 | METHOD zif_timem_asset~get_subtype. 45 | result = 'html'. 46 | ENDMETHOD. 47 | 48 | 49 | METHOD zif_timem_asset~get_url. 50 | result = 'blame.html'. 51 | ENDMETHOD. 52 | ENDCLASS. 53 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_html_blame.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_ASSET_HTML_BLAME 7 | E 8 | abapTimeMachine Asset HTML 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | DATA 18 | E 19 | abapTimeMachine Parts 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_html_tmachine.clas.abap: -------------------------------------------------------------------------------- 1 | "! Renders the main HTML page from a Transformation which receives the deep 2 | "! structure with all the required data 3 | class ZCL_TIMEM_ASSET_HTML_TMACHINE definition 4 | public 5 | final 6 | create private 7 | 8 | global friends ZCL_TIMEM_ASSET_FACTORY . 9 | 10 | public section. 11 | 12 | interfaces ZIF_TIMEM_ASSET . 13 | 14 | "! Constructor for the main HTML asset 15 | "! @parameter is_parts | Deep structure containing all the information that 16 | "! is to be rendered as HTML. 17 | methods CONSTRUCTOR 18 | importing 19 | !DATA type ZTIMEM_DATA . 20 | PROTECTED SECTION. 21 | private section. 22 | 23 | data DATA type ZTIMEM_DATA . 24 | ENDCLASS. 25 | 26 | 27 | 28 | CLASS ZCL_TIMEM_ASSET_HTML_TMACHINE IMPLEMENTATION. 29 | 30 | 31 | METHOD constructor. 32 | me->data = data. 33 | ENDMETHOD. 34 | 35 | 36 | METHOD zif_timem_asset~get_content. 37 | CALL TRANSFORMATION ztimem_html_timemachine 38 | SOURCE data = data 39 | RESULT XML result 40 | OPTIONS xml_header = 'NO'. 41 | ENDMETHOD. 42 | 43 | 44 | METHOD zif_timem_asset~get_subtype. 45 | result = 'html'. 46 | ENDMETHOD. 47 | 48 | 49 | METHOD zif_timem_asset~get_url. 50 | result = 'timemachine.html'. 51 | ENDMETHOD. 52 | ENDCLASS. 53 | -------------------------------------------------------------------------------- /src/zcl_timem_asset_html_tmachine.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_ASSET_HTML_TMACHINE 7 | E 8 | abapTimeMachine Asset HTML 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | DATA 17 | E 18 | abapTimeMachine Parts 19 | 20 | 21 | 22 | 23 | CONSTRUCTOR 24 | DATA 25 | E 26 | abapTimeMachine Parts 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/zcl_timem_author.clas.abap: -------------------------------------------------------------------------------- 1 | "! An SAP user 2 | CLASS zcl_timem_author DEFINITION 3 | PUBLIC 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | 9 | "! Returns the user's name (or the username if the user no longer exists) 10 | METHODS get_name 11 | IMPORTING 12 | !uname TYPE syuname 13 | RETURNING 14 | VALUE(result) TYPE string 15 | RAISING 16 | zcx_timem . 17 | PROTECTED SECTION. 18 | PRIVATE SECTION. 19 | TYPES: 20 | BEGIN OF ty_s_author, 21 | uname TYPE syuname, 22 | name TYPE string, 23 | END OF ty_s_author, 24 | ty_t_author TYPE SORTED TABLE OF ty_s_author WITH UNIQUE KEY uname. 25 | 26 | CLASS-DATA authors TYPE ty_t_author. 27 | ENDCLASS. 28 | 29 | 30 | 31 | CLASS ZCL_TIMEM_AUTHOR IMPLEMENTATION. 32 | 33 | 34 | METHOD get_name. 35 | DATA author LIKE LINE OF authors. 36 | 37 | READ TABLE authors INTO author WITH KEY uname = uname. 38 | IF sy-subrc <> 0. 39 | author-uname = uname. 40 | SELECT name_textc INTO author-name 41 | UP TO 1 ROWS 42 | FROM user_addr 43 | WHERE bname = uname 44 | ORDER BY name_textc. 45 | EXIT. 46 | ENDSELECT. 47 | IF sy-subrc <> 0. 48 | author-name = uname. 49 | ENDIF. 50 | INSERT author INTO TABLE authors. 51 | ENDIF. 52 | result = author-name. 53 | ENDMETHOD. 54 | ENDCLASS. 55 | -------------------------------------------------------------------------------- /src/zcl_timem_author.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_AUTHOR 7 | E 8 | abapTimeMachine author 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_consts.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_consts DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PRIVATE . 5 | 6 | PUBLIC SECTION. 7 | CONSTANTS version TYPE char10 VALUE '0.37b' ##NO_TEXT. 8 | 9 | CONSTANTS: 10 | BEGIN OF mode, 11 | time_machine TYPE ztimem_mode VALUE 'T', 12 | blame TYPE ztimem_mode VALUE 'B', 13 | END OF mode . 14 | 15 | CONSTANTS: 16 | BEGIN OF fieldname, 17 | request TYPE name_feld VALUE 'REQUEST', 18 | author TYPE name_feld VALUE 'AUTHOR', 19 | custom1 TYPE name_feld VALUE 'CUSTOM1', 20 | custom2 TYPE name_feld VALUE 'CUSTOM2', 21 | custom3 TYPE name_feld VALUE 'CUSTOM3', 22 | END OF fieldname. 23 | 24 | CONSTANTS: 25 | BEGIN OF asset_type, 26 | css TYPE string VALUE 'CSS', 27 | html TYPE string VALUE 'HTML', 28 | END OF asset_type . 29 | 30 | PROTECTED SECTION. 31 | PRIVATE SECTION. 32 | ENDCLASS. 33 | 34 | 35 | 36 | CLASS ZCL_TIMEM_CONSTS IMPLEMENTATION. 37 | ENDCLASS. 38 | -------------------------------------------------------------------------------- /src/zcl_timem_consts.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_CONSTS 7 | E 8 | ZCL_TIMEM_CONSTS 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_diff.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_diff DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | METHODS constructor 8 | IMPORTING 9 | ignore_case TYPE boolean 10 | ignore_indentation TYPE boolean. 11 | 12 | "! Takes two source lists - old and new - and returns a new source list 13 | "! which merges both, adding for each line an indicator of how it changed 14 | "! between both versions: (I)nsert/(D)elete/(U)pdate. 15 | "! @parameter lines_old | Old source list 16 | "! @parameter lines_new | New source list 17 | METHODS compute 18 | IMPORTING 19 | !lines_old TYPE ztimem_line_t 20 | !lines_new TYPE ztimem_line_t 21 | RETURNING 22 | VALUE(result) TYPE ztimem_line_t . 23 | PROTECTED SECTION. 24 | PRIVATE SECTION. 25 | CONSTANTS: 26 | BEGIN OF c_diff, 27 | insert TYPE c LENGTH 1 VALUE 'I', 28 | delete TYPE c LENGTH 1 VALUE 'D', 29 | update TYPE c LENGTH 1 VALUE 'U', 30 | END OF c_diff . 31 | 32 | DATA ignore_case TYPE boolean. 33 | DATA ignore_indentation TYPE boolean. 34 | 35 | METHODS compute_delta 36 | IMPORTING 37 | !lines_old TYPE ztimem_line_t 38 | !lines_new TYPE ztimem_line_t 39 | RETURNING 40 | VALUE(result) TYPE vxabapt255_tab . 41 | 42 | METHODS get_source 43 | IMPORTING 44 | !it_line TYPE ztimem_line_t 45 | RETURNING VALUE(result) TYPE abaptxt255_tab. 46 | 47 | METHODS process_line 48 | IMPORTING 49 | !i_line TYPE text1000 50 | RETURNING VALUE(result) TYPE text1000. 51 | ENDCLASS. 52 | 53 | 54 | 55 | CLASS zcl_timem_diff IMPLEMENTATION. 56 | METHOD constructor. 57 | me->ignore_case = ignore_case. 58 | me->ignore_indentation = ignore_indentation. 59 | ENDMETHOD. 60 | 61 | 62 | METHOD compute. 63 | DATA old_index TYPE i VALUE 1. 64 | DATA new_index TYPE i VALUE 1. 65 | DATA s_line LIKE LINE OF result. 66 | 67 | IF lines_old IS INITIAL. 68 | result = lines_new. 69 | RETURN. 70 | ENDIF. 71 | 72 | DATA(t_delta) = compute_delta( lines_old = lines_old lines_new = lines_new ). 73 | 74 | DO. 75 | READ TABLE t_delta INTO DATA(s_delta) WITH KEY number = old_index. 76 | IF sy-subrc = 0. 77 | DELETE t_delta INDEX sy-tabix. 78 | 79 | CASE s_delta-vrsflag. 80 | WHEN c_diff-delete. 81 | old_index = old_index + 1. 82 | 83 | WHEN c_diff-insert. 84 | READ TABLE lines_new INTO s_line INDEX new_index. 85 | ASSERT sy-subrc = 0. 86 | s_line-source = s_delta-line. 87 | INSERT s_line INTO TABLE result. 88 | new_index = new_index + 1. 89 | 90 | WHEN c_diff-update. 91 | READ TABLE lines_new INTO s_line INDEX new_index. 92 | ASSERT sy-subrc = 0. 93 | INSERT s_line INTO TABLE result. 94 | new_index = new_index + 1. 95 | old_index = old_index + 1. 96 | 97 | WHEN OTHERS. 98 | ASSERT 0 = 1. 99 | 100 | ENDCASE. 101 | ELSE. 102 | READ TABLE lines_old INTO s_line INDEX old_index. 103 | ASSERT sy-subrc = 0. 104 | INSERT s_line INTO TABLE result. 105 | new_index = new_index + 1. 106 | old_index = old_index + 1. 107 | 108 | ENDIF. 109 | 110 | IF new_index > lines( lines_new ) AND old_index > lines( lines_old ). 111 | " Current loop 112 | EXIT. 113 | ENDIF. 114 | ENDDO. 115 | ENDMETHOD. 116 | 117 | 118 | METHOD compute_delta. 119 | DATA t_trdirtab_old TYPE TABLE OF trdir. 120 | DATA t_trdirtab_new TYPE TABLE OF trdir. 121 | DATA t_trdir_delta TYPE TABLE OF xtrdir. 122 | 123 | DATA(t_source_old) = get_source( lines_old ). 124 | DATA(t_source_new) = get_source( lines_new ). 125 | 126 | CALL FUNCTION 'SVRS_COMPUTE_DELTA_REPS' 127 | TABLES 128 | texttab_old = t_source_old 129 | texttab_new = t_source_new 130 | trdirtab_old = t_trdirtab_old 131 | trdirtab_new = t_trdirtab_new 132 | trdir_delta = t_trdir_delta 133 | text_delta = result. 134 | ENDMETHOD. 135 | 136 | 137 | METHOD get_source. 138 | result = VALUE abaptxt255_tab( 139 | FOR s_line IN it_line 140 | ( line = process_line( s_line-source ) ) ). 141 | ENDMETHOD. 142 | 143 | 144 | METHOD process_line. 145 | result = i_line. 146 | IF me->ignore_case = abap_true. 147 | result = to_upper( result ). 148 | ENDIF. 149 | IF me->ignore_indentation = abap_true. 150 | SHIFT result LEFT DELETING LEADING space. 151 | ENDIF. 152 | ENDMETHOD. 153 | ENDCLASS. 154 | -------------------------------------------------------------------------------- /src/zcl_timem_diff.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for your ABAP unit test classes 2 | CLASS ltcl_diff DEFINITION FINAL FOR TESTING 3 | DURATION SHORT 4 | RISK LEVEL HARMLESS. 5 | 6 | PRIVATE SECTION. 7 | DATA: o_diff TYPE REF TO zcl_timem_diff. 8 | METHODS: 9 | setup, 10 | changed_line FOR TESTING RAISING cx_static_check, 11 | ignore_case FOR TESTING RAISING cx_static_check, 12 | ignore_indentation FOR TESTING RAISING cx_static_check, 13 | empty_old FOR TESTING RAISING cx_static_check, 14 | empty_both FOR TESTING RAISING cx_static_check, 15 | empty_new FOR TESTING RAISING cx_static_check. 16 | ENDCLASS. 17 | 18 | 19 | CLASS ltcl_diff IMPLEMENTATION. 20 | METHOD setup. 21 | ENDMETHOD. 22 | 23 | 24 | METHOD changed_line. 25 | o_diff = NEW #( ignore_case = abap_false 26 | ignore_indentation = abap_false ). 27 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ( source = 'AaA' author = 'A' ) ) 28 | lines_new = VALUE #( ( source = 'aAa' author = 'B' ) ) ). 29 | cl_abap_unit_assert=>assert_equals( act = t_blame[ 1 ]-author 30 | exp = 'B' ). 31 | ENDMETHOD. 32 | 33 | 34 | METHOD ignore_case. 35 | o_diff = NEW #( ignore_case = abap_true 36 | ignore_indentation = abap_false ). 37 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ( source = 'AaA' author = 'A' ) ) 38 | lines_new = VALUE #( ( source = 'aAa' author = 'B' ) ) ). 39 | cl_abap_unit_assert=>assert_equals( act = t_blame[ 1 ]-author 40 | exp = 'A' ). 41 | ENDMETHOD. 42 | 43 | 44 | METHOD ignore_indentation. 45 | o_diff = NEW #( ignore_case = abap_false 46 | ignore_indentation = abap_true ). 47 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ( source = ' AaA' author = 'A' ) ) 48 | lines_new = VALUE #( ( source = ' AaA' author = 'B' ) ) ). 49 | cl_abap_unit_assert=>assert_equals( act = t_blame[ 1 ]-author 50 | exp = 'A' ). 51 | ENDMETHOD. 52 | 53 | 54 | METHOD empty_old. 55 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ) 56 | lines_new = VALUE #( ( source = 'bbb' author = 'B' ) 57 | ( source = 'bbb' author = 'B' ) ) ). 58 | cl_abap_unit_assert=>assert_equals( act = t_blame[ 1 ]-author 59 | exp = 'B' ). 60 | cl_abap_unit_assert=>assert_equals( act = lines( t_blame ) 61 | exp = 2 ). 62 | ENDMETHOD. 63 | 64 | 65 | METHOD empty_new. 66 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ( source = 'bbb' author = 'B' ) 67 | ( source = 'bbb' author = 'B' ) ) 68 | lines_new = VALUE #( ) ). 69 | cl_abap_unit_assert=>assert_equals( act = lines( t_blame ) 70 | exp = 0 ). 71 | ENDMETHOD. 72 | 73 | 74 | METHOD empty_both. 75 | DATA(t_blame) = o_diff->compute( lines_old = VALUE #( ) 76 | lines_new = VALUE #( ) ). 77 | cl_abap_unit_assert=>assert_equals( act = lines( t_blame ) 78 | exp = 0 ). 79 | ENDMETHOD. 80 | ENDCLASS. 81 | -------------------------------------------------------------------------------- /src/zcl_timem_diff.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_DIFF 7 | E 8 | abapTimeMachine DIFF 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zcl_timem_dynpro.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_dynpro DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | DATA dynnr TYPE sydynnr READ-ONLY . 9 | 10 | METHODS constructor 11 | IMPORTING 12 | !dynnr TYPE sydynnr . 13 | METHODS remove_toolbar . 14 | METHODS hide_buttons. 15 | PROTECTED SECTION. 16 | PRIVATE SECTION. 17 | ENDCLASS. 18 | 19 | 20 | 21 | CLASS ZCL_TIMEM_DYNPRO IMPLEMENTATION. 22 | 23 | 24 | METHOD constructor. 25 | me->dynnr = dynnr. 26 | ENDMETHOD. 27 | 28 | 29 | METHOD hide_buttons. 30 | DATA: ucomms TYPE TABLE OF sy-ucomm. 31 | 32 | " Button Execute 33 | APPEND 'CRET' TO ucomms. 34 | " Button Save 35 | APPEND 'GET' TO ucomms. 36 | 37 | CALL FUNCTION 'RS_SET_SELSCREEN_STATUS' 38 | EXPORTING 39 | p_status = sy-pfkey 40 | TABLES 41 | p_exclude = ucomms. 42 | 43 | ENDMETHOD. 44 | 45 | 46 | METHOD remove_toolbar. 47 | " Borrowed from abapGit 48 | 49 | DATA header TYPE rpy_dyhead. 50 | DATA containers TYPE dycatt_tab. 51 | DATA fields_to_containers TYPE dyfatc_tab. 52 | DATA flow_logic TYPE swydyflow. 53 | 54 | CALL FUNCTION 'RPY_DYNPRO_READ' 55 | EXPORTING 56 | progname = sy-cprog 57 | dynnr = me->dynnr 58 | IMPORTING 59 | header = header 60 | TABLES 61 | containers = containers 62 | fields_to_containers = fields_to_containers 63 | flow_logic = flow_logic 64 | EXCEPTIONS 65 | cancelled = 1 66 | not_found = 2 67 | permission_error = 3 68 | OTHERS = 4. 69 | IF sy-subrc IS NOT INITIAL. 70 | " Ignore errors, just exit 71 | RETURN. 72 | ENDIF. 73 | 74 | IF header-no_toolbar = abap_true. 75 | " No change required 76 | RETURN. 77 | ENDIF. 78 | 79 | header-no_toolbar = abap_true. 80 | 81 | CALL FUNCTION 'RPY_DYNPRO_INSERT' 82 | EXPORTING 83 | header = header 84 | suppress_exist_checks = abap_true 85 | TABLES 86 | containers = containers 87 | fields_to_containers = fields_to_containers 88 | flow_logic = flow_logic 89 | EXCEPTIONS 90 | cancelled = 1 91 | already_exists = 2 92 | program_not_exists = 3 93 | not_executed = 4 94 | missing_required_field = 5 95 | illegal_field_value = 6 96 | field_not_allowed = 7 97 | not_generated = 8 98 | illegal_field_position = 9 99 | OTHERS = 10. 100 | IF sy-subrc <> 2 AND sy-subrc <> 0. 101 | " Ignore errors, just exit 102 | ASSERT 1 = 1. 103 | ENDIF. 104 | ENDMETHOD. 105 | ENDCLASS. 106 | -------------------------------------------------------------------------------- /src/zcl_timem_dynpro.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_DYNPRO 7 | E 8 | abapTimeMachine Dynpro 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | E 18 | CONSTRUCTOR 19 | 20 | 21 | DYNNR 22 | E 23 | Dynpro Number 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/zcl_timem_gui.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_gui DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | METHODS constructor 9 | IMPORTING 10 | !object_type TYPE ztimem_object_type 11 | !object_name TYPE sobj_name 12 | RAISING 13 | zcx_timem . 14 | 15 | METHODS display 16 | RAISING 17 | zcx_timem . 18 | 19 | METHODS revert 20 | IMPORTING 21 | ts TYPE timestamp 22 | RAISING 23 | zcx_timem. 24 | 25 | PROTECTED SECTION. 26 | PRIVATE SECTION. 27 | DATA object_type TYPE ztimem_object_type. 28 | DATA object_name TYPE sobj_name. 29 | DATA parts TYPE REF TO zcl_timem_parts . 30 | DATA viewer TYPE REF TO zcl_timem_gui_viewer . 31 | DATA options TYPE REF TO zcl_timem_options. 32 | 33 | METHODS highlight_source 34 | CHANGING 35 | !data TYPE ztimem_data. 36 | 37 | METHODS deduplicate_header_fields 38 | CHANGING 39 | !data TYPE ztimem_data . 40 | 41 | METHODS load_parts 42 | IMPORTING 43 | ignore_unreleased TYPE boolean 44 | RAISING 45 | zcx_timem. 46 | ENDCLASS. 47 | 48 | 49 | 50 | CLASS zcl_timem_gui IMPLEMENTATION. 51 | 52 | 53 | METHOD constructor. 54 | me->object_type = object_type. 55 | me->object_name = object_name. 56 | me->options = zcl_timem_options=>get_instance( ). 57 | load_parts( options->ignore_unreleased ). 58 | DATA(handler) = NEW zcl_timem_gui_handler( me ). 59 | me->viewer = NEW #( handler ). 60 | ENDMETHOD. 61 | 62 | 63 | METHOD deduplicate_header_fields. 64 | DATA previous TYPE ztimem_line. 65 | 66 | LOOP AT data-parts REFERENCE INTO DATA(part). 67 | LOOP AT part->lines REFERENCE INTO DATA(line). 68 | IF line->line_num <> 1 AND line->version_number = previous-version_number. 69 | CLEAR line->author. 70 | CLEAR line->author_name. 71 | CLEAR line->version_number. 72 | CLEAR line->request. 73 | CLEAR line->task. 74 | CLEAR line->date. 75 | CLEAR line->time. 76 | CLEAR line->custom1. 77 | CLEAR line->custom2. 78 | CLEAR line->custom3. 79 | ELSE. 80 | previous = line->*. 81 | ENDIF. 82 | ENDLOOP. 83 | ENDLOOP. 84 | ENDMETHOD. 85 | 86 | 87 | METHOD display. 88 | DATA(data) = parts->to_struct( 89 | mode = options->mode 90 | timestamp = options->timestamp 91 | ignore_case = options->ignore_case 92 | ignore_indentation = options->ignore_indentation ). 93 | NEW zcl_timem_userexits( )->before_rendering( CHANGING data = data ). 94 | highlight_source( CHANGING data = data ). 95 | deduplicate_header_fields( CHANGING data = data ). 96 | viewer->render( 97 | data = data 98 | mode = options->mode 99 | theme = options->theme ). 100 | ENDMETHOD. 101 | 102 | 103 | METHOD highlight_source. 104 | DATA(highlighter) = NEW zcl_timem_syntax_abap( ). 105 | 106 | LOOP AT data-parts REFERENCE INTO DATA(part). 107 | LOOP AT part->lines REFERENCE INTO DATA(line). 108 | line->source = highlighter->process_line( CONV #( line->source ) ). 109 | ENDLOOP. 110 | ENDLOOP. 111 | ENDMETHOD. 112 | 113 | 114 | METHOD load_parts. 115 | me->parts = NEW zcl_timem_parts( object_type = object_type 116 | object_name = object_name 117 | ignore_unreleased = ignore_unreleased ). 118 | ENDMETHOD. 119 | 120 | 121 | METHOD revert. 122 | parts->revert( ts ). 123 | load_parts( options->ignore_unreleased ). 124 | ENDMETHOD. 125 | ENDCLASS. 126 | -------------------------------------------------------------------------------- /src/zcl_timem_gui.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_GUI 7 | E 8 | abapTimeMachine GUI 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | DEDUPLICATE_HEADER_FIELDS 17 | DATA 18 | E 19 | abapTimeMachine Parts 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_gui_handler.clas.abap: -------------------------------------------------------------------------------- 1 | "! HTML screen event handler to deal with user interaction during the HTML 2 | "! presentation. It will decode the request and process it depending on the 3 | "! requested action. For example, it will navigate to the requested source code. 4 | CLASS zcl_timem_gui_handler DEFINITION 5 | PUBLIC 6 | FINAL 7 | CREATE PUBLIC . 8 | 9 | PUBLIC SECTION. 10 | 11 | METHODS constructor 12 | IMPORTING 13 | !gui TYPE REF TO zcl_timem_gui . 14 | 15 | "! Handler method 16 | "! @parameter action | Action 17 | "! @parameter getdata | Data details 18 | METHODS on_sapevent 19 | FOR EVENT sapevent OF cl_gui_html_viewer 20 | IMPORTING 21 | !action 22 | !getdata . 23 | 24 | PROTECTED SECTION. 25 | PRIVATE SECTION. 26 | DATA gui TYPE REF TO zcl_timem_gui. 27 | DATA userexits TYPE REF TO zcl_timem_userexits. 28 | 29 | METHODS display_request 30 | IMPORTING 31 | request TYPE trkorr. 32 | 33 | METHODS display_user 34 | IMPORTING 35 | user TYPE uname. 36 | 37 | METHODS display_source 38 | IMPORTING 39 | type TYPE versobjtyp 40 | object_name TYPE versobjnam. 41 | 42 | METHODS display_version. 43 | 44 | METHODS decode_source_type_and_name 45 | IMPORTING 46 | i_getdata TYPE c 47 | EXPORTING 48 | e_type TYPE versobjtyp 49 | e_object_name TYPE versobjnam. 50 | 51 | METHODS revert 52 | IMPORTING 53 | ts TYPE timestamp. 54 | ENDCLASS. 55 | 56 | 57 | 58 | CLASS zcl_timem_gui_handler IMPLEMENTATION. 59 | 60 | 61 | METHOD constructor. 62 | me->gui = gui. 63 | userexits = NEW #( ). 64 | ENDMETHOD. 65 | 66 | 67 | METHOD decode_source_type_and_name. 68 | DATA mtdkey TYPE seocpdkey. 69 | SPLIT i_getdata AT '|' INTO e_type e_object_name. 70 | SHIFT e_type LEFT DELETING LEADING space. 71 | SHIFT e_object_name LEFT DELETING LEADING space. 72 | 73 | CASE e_type. 74 | WHEN 'CPUB'. 75 | e_object_name = cl_oo_classname_service=>get_pubsec_name( CONV #( e_object_name ) ). 76 | e_type = 'PROG'. 77 | 78 | WHEN 'CPRO'. 79 | e_object_name = cl_oo_classname_service=>get_prosec_name( CONV #( e_object_name ) ). 80 | e_type = 'PROG'. 81 | 82 | WHEN 'CPRI'. 83 | e_object_name = cl_oo_classname_service=>get_prisec_name( CONV #( e_object_name ) ). 84 | e_type = 'PROG'. 85 | 86 | WHEN 'CDEF' OR 'CINC' OR 'CMAC' OR 'REPS' OR 'CCAU'. 87 | " object_name is already the include so treat it as a program 88 | e_type = 'PROG'. 89 | 90 | WHEN 'METH'. 91 | SPLIT e_object_name AT space INTO mtdkey-clsname mtdkey-cpdname. 92 | cl_oo_classname_service=>get_method_include( 93 | EXPORTING 94 | mtdkey = mtdkey 95 | RECEIVING 96 | result = e_object_name 97 | EXCEPTIONS 98 | class_not_existing = 1 99 | method_not_existing = 2 100 | OTHERS = 3 ). 101 | IF sy-subrc <> 0. 102 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno 103 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. 104 | ENDIF. 105 | e_type = 'PROG'. 106 | WHEN OTHERS. 107 | RETURN. 108 | ENDCASE. 109 | ENDMETHOD. 110 | 111 | 112 | METHOD display_request. 113 | CALL FUNCTION 'TR_DISPLAY_REQUEST' 114 | EXPORTING 115 | i_trkorr = request. 116 | ENDMETHOD. 117 | 118 | 119 | METHOD display_source. 120 | CALL FUNCTION 'RS_TOOL_ACCESS' 121 | EXPORTING 122 | operation = 'SHOW' 123 | object_name = object_name 124 | object_type = type 125 | EXCEPTIONS 126 | not_executed = 1 127 | invalid_object_type = 2 128 | OTHERS = 3. 129 | IF sy-subrc <> 0. 130 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno 131 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. 132 | ENDIF. 133 | ENDMETHOD. 134 | 135 | 136 | METHOD display_user. 137 | DATA return TYPE bapiret2_t. 138 | CALL FUNCTION 'BAPI_USER_GET_DETAIL' 139 | EXPORTING 140 | username = user 141 | TABLES 142 | return = return. 143 | IF line_exists( return[ type = 'E' ] ). 144 | MESSAGE 'User no longer exists' TYPE 'I' DISPLAY LIKE 'E'. 145 | ELSE. 146 | CALL FUNCTION 'SUID_IDENTITY_MAINT' 147 | EXPORTING 148 | i_username = user 149 | i_tcode_mode = 6. 150 | ENDIF. 151 | ENDMETHOD. 152 | 153 | 154 | METHOD display_version. 155 | TRY. 156 | gui->display( ). 157 | CATCH zcx_timem. 158 | " Ignore error 159 | ASSERT 1 = 1. 160 | ENDTRY. 161 | ENDMETHOD. 162 | 163 | 164 | METHOD on_sapevent. 165 | DATA ts TYPE timestamp. 166 | 167 | action = condense( action ). 168 | getdata = condense( getdata ). 169 | CASE action. 170 | WHEN 'author'. 171 | display_user( CONV #( getdata ) ). 172 | 173 | WHEN 'request'. 174 | display_request( CONV #( getdata ) ). 175 | 176 | WHEN 'revert'. 177 | " Revert to the requested timestmap 178 | ts = CONV #( getdata+7 ). 179 | revert( ts ). 180 | " And then display the new present time 181 | GET TIME STAMP FIELD ts. 182 | zcl_timem_options=>get_instance( )->set( timestamp = ts ). 183 | display_version( ). 184 | 185 | WHEN 'source'. 186 | decode_source_type_and_name( 187 | EXPORTING 188 | i_getdata = getdata 189 | IMPORTING 190 | e_type = DATA(type) 191 | e_object_name = DATA(object_name) ). 192 | display_source( type = type 193 | object_name = object_name ). 194 | 195 | WHEN 'timetravel'. 196 | " Depending on the link, getdata may be just the timestamp xxx or be like timestamp=xxx 197 | ts = COND #( WHEN getdata(10) = 'timestamp=' THEN getdata+10 ELSE getdata ). 198 | zcl_timem_options=>get_instance( )->set( timestamp = ts ). 199 | display_version( ). 200 | 201 | WHEN OTHERS. 202 | userexits->on_sapevent( 203 | action = action 204 | getdata = getdata ). 205 | ENDCASE. 206 | ENDMETHOD. 207 | 208 | 209 | METHOD revert. 210 | TRY. 211 | gui->revert( ts ). 212 | CATCH zcx_timem INTO DATA(exc). 213 | DATA(text) = exc->get_text( ). 214 | MESSAGE text TYPE 'E'. 215 | ENDTRY. 216 | ENDMETHOD. 217 | ENDCLASS. 218 | -------------------------------------------------------------------------------- /src/zcl_timem_gui_handler.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_GUI_HANDLER 7 | E 8 | abapTimeMachine Output events 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_gui_viewer.clas.abap: -------------------------------------------------------------------------------- 1 | "! Takes a deep structure with all the information of the requested object, 2 | "! renders the HTML and CSS assets based on the requested theme and displays it. 3 | CLASS zcl_timem_gui_viewer DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | CONSTANTS: 11 | BEGIN OF c_theme, 12 | light TYPE ztimem_theme VALUE 'LIGHT', 13 | dark TYPE ztimem_theme VALUE 'DARK', 14 | END OF c_theme . 15 | 16 | "! Constructor which takes a theme as input 17 | "! @parameter i_theme | Theme name 18 | METHODS constructor 19 | IMPORTING 20 | !io_handler TYPE REF TO zcl_timem_gui_handler . 21 | "! Takes a deep structure with all the information of the object, renders 22 | "! the HTML and CSS assets and displays them. 23 | METHODS render 24 | IMPORTING 25 | !data TYPE ztimem_data 26 | mode TYPE ztimem_mode 27 | theme TYPE ztimem_theme 28 | RAISING 29 | zcx_timem . 30 | PROTECTED SECTION. 31 | PRIVATE SECTION. 32 | DATA html_viewer TYPE REF TO cl_gui_html_viewer. 33 | DATA userexits TYPE REF TO zcl_timem_userexits. 34 | 35 | METHODS add_asset 36 | IMPORTING 37 | !asset TYPE REF TO zif_timem_asset 38 | RETURNING 39 | VALUE(result) TYPE w3url . 40 | 41 | METHODS register_events 42 | IMPORTING 43 | io_handler TYPE REF TO zcl_timem_gui_handler. 44 | 45 | CLASS-METHODS xstring_2_bintab 46 | IMPORTING 47 | !xstr TYPE xstring 48 | RETURNING 49 | VALUE(result) TYPE lvc_t_mime . 50 | ENDCLASS. 51 | 52 | 53 | 54 | CLASS ZCL_TIMEM_GUI_VIEWER IMPLEMENTATION. 55 | 56 | 57 | METHOD add_asset. 58 | DATA(content) = asset->get_content( ). 59 | 60 | userexits->modify_asset_content( 61 | EXPORTING 62 | subtype = asset->get_subtype( ) 63 | CHANGING 64 | content = content ). 65 | 66 | DATA(xstr) = cl_abap_codepage=>convert_to( source = content codepage = 'UTF-8' ). 67 | 68 | DATA(t_bintab) = xstring_2_bintab( xstr ). 69 | 70 | html_viewer->load_data( 71 | EXPORTING 72 | url = asset->get_url( ) 73 | type = 'text' 74 | subtype = asset->get_subtype( ) 75 | CHANGING 76 | data_table = t_bintab 77 | EXCEPTIONS 78 | dp_invalid_parameter = 1 79 | dp_error_general = 2 80 | cntl_error = 3 81 | html_syntax_notcorrect = 4 82 | OTHERS = 5 ). 83 | IF sy-subrc <> 0. 84 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno 85 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. 86 | ENDIF. 87 | result = asset->get_url( ). 88 | ENDMETHOD. 89 | 90 | 91 | METHOD constructor. 92 | userexits = NEW #( ). 93 | html_viewer = NEW cl_gui_html_viewer( parent = cl_gui_container=>screen0 94 | query_table_disabled = abap_true ). 95 | register_events( io_handler ). 96 | ENDMETHOD. 97 | 98 | 99 | METHOD register_events. 100 | DATA t_event TYPE cntl_simple_events. 101 | t_event = VALUE #( ( appl_event = abap_true 102 | eventid = html_viewer->m_id_sapevent ) ). 103 | html_viewer->set_registered_events( t_event ). 104 | SET HANDLER io_handler->on_sapevent FOR html_viewer. 105 | ENDMETHOD. 106 | 107 | 108 | METHOD render. 109 | " Creates the screen0 container 110 | SKIP. 111 | 112 | add_asset( NEW zcl_timem_asset_factory( )->create_instance( 113 | asset_type = zcl_timem_consts=>asset_type-css 114 | data = data 115 | mode = mode 116 | theme = theme ) ). 117 | 118 | DATA(url) = add_asset( NEW zcl_timem_asset_factory( )->create_instance( 119 | asset_type = zcl_timem_consts=>asset_type-html 120 | data = data 121 | mode = mode 122 | theme = theme ) ). 123 | 124 | html_viewer->show_url( 125 | EXPORTING 126 | url = url 127 | EXCEPTIONS 128 | cntl_error = 1 129 | cnht_error_not_allowed = 2 130 | cnht_error_parameter = 3 131 | dp_error_general = 4 132 | OTHERS = 5 ). 133 | IF sy-subrc <> 0. 134 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno 135 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. 136 | ENDIF. 137 | ENDMETHOD. 138 | 139 | 140 | METHOD xstring_2_bintab. 141 | CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' 142 | EXPORTING 143 | buffer = xstr 144 | TABLES 145 | binary_tab = result. 146 | ENDMETHOD. 147 | ENDCLASS. 148 | -------------------------------------------------------------------------------- /src/zcl_timem_gui_viewer.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_GUI_VIEWER 7 | E 8 | abapTimeMachine Display HTML 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | RENDER 17 | DATA 18 | E 19 | abapTimeMachine Parts 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_object_clas.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a class object. It will be able to create and return a list 2 | "! of all the parts the class is made of. 3 | class ZCL_TIMEM_OBJECT_CLAS definition 4 | public 5 | final 6 | create public . 7 | 8 | public section. 9 | 10 | interfaces ZIF_TIMEM_OBJECT . 11 | 12 | "! Constructor for the class object. 13 | "! @parameter i_name | Class name 14 | methods CONSTRUCTOR 15 | importing 16 | !NAME type SEOCLSNAME 17 | raising 18 | ZCX_TIMEM . 19 | protected section. 20 | private section. 21 | 22 | data NAME type SEOCLSNAME . 23 | ENDCLASS. 24 | 25 | 26 | 27 | CLASS ZCL_TIMEM_OBJECT_CLAS IMPLEMENTATION. 28 | 29 | 30 | METHOD constructor. 31 | me->name = name. 32 | ENDMETHOD. 33 | 34 | 35 | METHOD zif_timem_object~check_exists. 36 | cl_abap_classdescr=>describe_by_name( 37 | EXPORTING 38 | p_name = name 39 | EXCEPTIONS 40 | type_not_found = 1 41 | OTHERS = 2 ). 42 | IF sy-subrc = 0. 43 | result = abap_true. 44 | ENDIF. 45 | ENDMETHOD. 46 | 47 | 48 | METHOD zif_timem_object~get_name. 49 | result = name. 50 | ENDMETHOD. 51 | 52 | 53 | METHOD zif_timem_object~get_tadir_list. 54 | " All sort of includes 55 | result = VALUE #( 56 | ( name = 'Class pool' object_name = CONV #( name ) type = 'CLSD' ) 57 | ( name = 'Public section' object_name = CONV #( name ) type = 'CPUB' ) 58 | ( name = 'Protected section' object_name = CONV #( name ) type = 'CPRO' ) 59 | ( name = 'Private section' object_name = CONV #( name ) type = 'CPRI' ) 60 | ( name = 'Local class definition' object_name = cl_oo_classname_service=>get_ccdef_name( name ) type = 'CDEF' ) 61 | ( name = 'Local class implementation' object_name = cl_oo_classname_service=>get_ccimp_name( name ) type = 'CINC' ) 62 | ( name = 'Local macros' object_name = cl_oo_classname_service=>get_ccmac_name( name ) type = 'CINC' ) 63 | ( name = 'Local types' object_name = cl_oo_classname_service=>get_cl_name( name ) type = 'REPS' ) 64 | ( name = 'Local test classes' object_name = cl_oo_classname_service=>get_ccau_name( name ) type = 'CINC' ) ). 65 | 66 | " Class methods 67 | result = VALUE #( BASE result 68 | FOR method_include IN cl_oo_classname_service=>get_all_method_includes( name ) 69 | LET method_name = cl_oo_classname_service=>get_method_by_include( method_include-incname )-cpdname 70 | IN ( name = |{ to_lower( method_name ) }()| 71 | object_name = |{ name WIDTH = 30 }{ method_name }| 72 | type = 'METH' ) ). 73 | ENDMETHOD. 74 | ENDCLASS. 75 | -------------------------------------------------------------------------------- /src/zcl_timem_object_clas.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_CLAS 7 | E 8 | abapTimeMachine Class 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_object_factory.clas.abap: -------------------------------------------------------------------------------- 1 | "! Factory class for the object family: 2 | "! - Class 3 | "! - Function group 4 | "! - Function module 5 | "! - Program 6 | CLASS zcl_timem_object_factory DEFINITION 7 | PUBLIC 8 | FINAL 9 | CREATE PUBLIC . 10 | 11 | PUBLIC SECTION. 12 | 13 | CONSTANTS: 14 | BEGIN OF gc_object_type, 15 | program TYPE ztimem_object_type VALUE 'PROG', 16 | program_includes TYPE ztimem_object_type VALUE 'PRGI', 17 | class TYPE ztimem_object_type VALUE 'CLAS', 18 | function_group TYPE ztimem_object_type VALUE 'FUGR', 19 | function TYPE ztimem_object_type VALUE 'FUNC', 20 | transport_request TYPE ztimem_object_type VALUE 'TR', 21 | END OF gc_object_type . 22 | 23 | "! Creates and returns an instance to the requested object 24 | "! @parameter i_object_type | Object type 25 | "! @parameter i_object_name | Object name 26 | METHODS get_instance 27 | IMPORTING 28 | !object_type TYPE ztimem_object_type 29 | !object_name TYPE sobj_name 30 | RETURNING 31 | VALUE(result) TYPE REF TO zif_timem_object 32 | RAISING 33 | zcx_timem . 34 | PROTECTED SECTION. 35 | PRIVATE SECTION. 36 | ENDCLASS. 37 | 38 | 39 | 40 | CLASS ZCL_TIMEM_OBJECT_FACTORY IMPLEMENTATION. 41 | 42 | 43 | METHOD get_instance. 44 | result = SWITCH #( 45 | object_type 46 | WHEN gc_object_type-program THEN NEW zcl_timem_object_prog( object_name ) 47 | WHEN gc_object_type-program_includes THEN NEW zcl_timem_object_prog_includes( object_name ) 48 | WHEN gc_object_type-class THEN NEW zcl_timem_object_clas( CONV #( object_name ) ) 49 | WHEN gc_object_type-function_group THEN NEW zcl_timem_object_fugr( CONV #( object_name ) ) 50 | WHEN gc_object_type-function THEN NEW zcl_timem_object_func( CONV #( object_name ) ) 51 | WHEN gc_object_type-transport_request THEN NEW zcl_timem_object_tr( CONV #( object_name ) ) ). 52 | IF result IS NOT BOUND OR NOT result->check_exists( ). 53 | RAISE EXCEPTION TYPE zcx_timem 54 | EXPORTING 55 | textid = zcx_timem=>object_not_found. 56 | ENDIF. 57 | ENDMETHOD. 58 | ENDCLASS. 59 | -------------------------------------------------------------------------------- /src/zcl_timem_object_factory.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_FACTORY 7 | E 8 | abapTimeMachine Object factory 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_object_fugr.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a function group object. It will be able to create and 2 | "! return a list of all the parts the function group is made of. 3 | CLASS zcl_timem_object_fugr DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | INTERFACES zif_timem_object . 11 | 12 | "! Constructor for the function group object. 13 | "! @parameter i_name | Function group name 14 | METHODS constructor 15 | IMPORTING 16 | !name TYPE rs38l_area . 17 | PROTECTED SECTION. 18 | PRIVATE SECTION. 19 | TYPES ty_t_rs38l_incl TYPE STANDARD TABLE OF rs38l_incl WITH KEY table_line. 20 | 21 | DATA name TYPE rs38l_area . 22 | 23 | METHODS get_main_name 24 | RETURNING 25 | VALUE(result) TYPE program . 26 | 27 | METHODS get_functions 28 | RETURNING 29 | VALUE(result) TYPE ty_t_rs38l_incl. 30 | ENDCLASS. 31 | 32 | 33 | 34 | CLASS ZCL_TIMEM_OBJECT_FUGR IMPLEMENTATION. 35 | 36 | 37 | METHOD constructor. 38 | me->name = name. 39 | ENDMETHOD. 40 | 41 | 42 | METHOD get_functions. 43 | CALL FUNCTION 'RS_FUNCTION_POOL_CONTENTS' 44 | EXPORTING 45 | function_pool = name 46 | TABLES 47 | functab = result 48 | EXCEPTIONS 49 | function_pool_not_found = 1 50 | OTHERS = 2. 51 | IF sy-subrc = 0. 52 | SORT result BY funcname ASCENDING. 53 | DELETE ADJACENT DUPLICATES FROM result COMPARING funcname. 54 | ENDIF. 55 | ENDMETHOD. 56 | 57 | 58 | METHOD get_main_name. 59 | DATA namespace TYPE rs38l-namespace. 60 | DATA group TYPE rs38l-area. 61 | 62 | CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT' 63 | EXPORTING 64 | complete_area = name 65 | IMPORTING 66 | namespace = namespace 67 | group = group 68 | EXCEPTIONS 69 | OTHERS = 1. 70 | IF sy-subrc = 0. 71 | result = |{ namespace }SAPL{ group }|. 72 | ENDIF. 73 | ENDMETHOD. 74 | 75 | 76 | METHOD zif_timem_object~check_exists. 77 | CALL FUNCTION 'RS_FUNCTION_POOL_EXISTS' 78 | EXPORTING 79 | function_pool = name 80 | EXCEPTIONS 81 | pool_not_exists = 1. 82 | result = boolc( sy-subrc = 0 ). 83 | ENDMETHOD. 84 | 85 | 86 | METHOD zif_timem_object~get_name. 87 | result = name. 88 | ENDMETHOD. 89 | 90 | 91 | METHOD zif_timem_object~get_tadir_list. 92 | DATA t_include TYPE STANDARD TABLE OF progname. 93 | 94 | DATA(main_program) = get_main_name( ). 95 | CALL FUNCTION 'RS_GET_ALL_INCLUDES' 96 | EXPORTING 97 | program = main_program 98 | TABLES 99 | includetab = t_include 100 | EXCEPTIONS 101 | not_existent = 1 102 | no_program = 2 103 | OTHERS = 3. 104 | IF sy-subrc <> 0. 105 | RAISE EXCEPTION TYPE zcx_timem. 106 | ENDIF. 107 | 108 | result = VALUE #( ( 109 | name = |Program { main_program }| 110 | object_name = CONV #( main_program ) 111 | type = 'REPS' ) ). 112 | 113 | DATA(t_function) = get_functions( ). 114 | LOOP AT t_include INTO DATA(include). 115 | IF NOT line_exists( t_function[ include = include ] ). 116 | result = VALUE #( BASE result 117 | ( name = |Include { include }| 118 | object_name = CONV #( include ) 119 | type = 'REPS' ) ). 120 | ENDIF. 121 | ENDLOOP. 122 | 123 | LOOP AT t_function REFERENCE INTO DATA(os_function). 124 | result = VALUE #( BASE result 125 | ( name = |Function module { os_function->funcname }| 126 | object_name = CONV #( os_function->funcname ) 127 | type = 'FUNC' ) ). 128 | ENDLOOP. 129 | ENDMETHOD. 130 | ENDCLASS. 131 | -------------------------------------------------------------------------------- /src/zcl_timem_object_fugr.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_FUGR 7 | E 8 | abapTimeMachine Function group 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_object_func.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a function module object. It will be able to create and 2 | "! return a list of all the parts the function module is made of. 3 | CLASS zcl_timem_object_func DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | INTERFACES zif_timem_object . 11 | 12 | "! Constructor for the function module object. 13 | "! @parameter i_name | Function module name 14 | METHODS constructor 15 | IMPORTING 16 | !name TYPE rs38l_fnam . 17 | PROTECTED SECTION. 18 | PRIVATE SECTION. 19 | 20 | DATA name TYPE rs38l_fnam . 21 | ENDCLASS. 22 | 23 | 24 | 25 | CLASS ZCL_TIMEM_OBJECT_FUNC IMPLEMENTATION. 26 | 27 | 28 | METHOD constructor. 29 | me->name = name. 30 | ENDMETHOD. 31 | 32 | 33 | METHOD zif_timem_object~check_exists. 34 | CALL FUNCTION 'FUNCTION_EXISTS' 35 | EXPORTING 36 | funcname = name 37 | EXCEPTIONS 38 | function_not_exist = 1 39 | OTHERS = 2. 40 | result = boolc( sy-subrc = 0 ). 41 | ENDMETHOD. 42 | 43 | 44 | METHOD zif_timem_object~get_name. 45 | result = name. 46 | ENDMETHOD. 47 | 48 | 49 | METHOD zif_timem_object~get_tadir_list. 50 | result = VALUE #( ( 51 | name = CONV #( name ) 52 | object_name = CONV #( name ) 53 | type = 'FUNC' ) ). 54 | ENDMETHOD. 55 | ENDCLASS. 56 | -------------------------------------------------------------------------------- /src/zcl_timem_object_func.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_FUNC 7 | E 8 | abapTimeMachine Program 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | E 18 | CONSTRUCTOR 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/zcl_timem_object_prog.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a program/include object. This object consists of a single part which 2 | "! this class will be able to create and return. 3 | CLASS zcl_timem_object_prog DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | INTERFACES zif_timem_object . 11 | 12 | "! Constructor for the program/include object. 13 | "! @parameter i_name | Program/include name 14 | METHODS constructor 15 | IMPORTING 16 | !name TYPE sobj_name . 17 | PROTECTED SECTION. 18 | PRIVATE SECTION. 19 | 20 | DATA name TYPE sobj_name . 21 | ENDCLASS. 22 | 23 | 24 | 25 | CLASS ZCL_TIMEM_OBJECT_PROG IMPLEMENTATION. 26 | 27 | 28 | METHOD constructor. 29 | me->name = name. 30 | ENDMETHOD. 31 | 32 | 33 | METHOD zif_timem_object~check_exists. 34 | SELECT SINGLE name INTO name 35 | FROM trdir 36 | WHERE name = name. 37 | result = boolc( sy-subrc = 0 ). 38 | ENDMETHOD. 39 | 40 | 41 | METHOD zif_timem_object~get_name. 42 | result = name. 43 | ENDMETHOD. 44 | 45 | 46 | METHOD zif_timem_object~get_tadir_list. 47 | result = VALUE #( ( 48 | name = CONV #( name ) 49 | object_name = CONV #( name ) 50 | type = 'REPS' ) ). 51 | ENDMETHOD. 52 | ENDCLASS. 53 | -------------------------------------------------------------------------------- /src/zcl_timem_object_prog.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_PROG 7 | E 8 | abapTimeMachine Program 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | E 18 | CONSTRUCTOR 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/zcl_timem_object_prog_includes.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a program/include object. This object consists of a single part which 2 | "! this class will be able to create and return. 3 | CLASS zcl_timem_object_prog_includes DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | INTERFACES zif_timem_object . 11 | 12 | "! Constructor for the program/include object. 13 | "! @parameter i_name | Program/include name 14 | METHODS constructor 15 | IMPORTING 16 | !name TYPE sobj_name . 17 | PROTECTED SECTION. 18 | PRIVATE SECTION. 19 | TYPES ty_t_rpy_repo TYPE STANDARD TABLE OF rpy_repo WITH KEY inclname. 20 | 21 | DATA name TYPE sobj_name . 22 | 23 | METHODS get_includes 24 | RETURNING VALUE(result) TYPE ty_t_rpy_repo. 25 | ENDCLASS. 26 | 27 | 28 | 29 | CLASS ZCL_TIMEM_OBJECT_PROG_INCLUDES IMPLEMENTATION. 30 | 31 | 32 | METHOD constructor. 33 | me->name = name. 34 | ENDMETHOD. 35 | 36 | 37 | METHOD get_includes. 38 | CALL FUNCTION 'RPY_PROGRAM_READ' 39 | EXPORTING 40 | program_name = name 41 | only_texts = abap_true 42 | TABLES 43 | include_tab = result 44 | EXCEPTIONS 45 | cancelled = 1 46 | not_found = 2 47 | permission_error = 3 48 | OTHERS = 4. 49 | IF sy-subrc <> 0. 50 | ASSERT 1 = 0. 51 | ENDIF. 52 | ENDMETHOD. 53 | 54 | 55 | METHOD zif_timem_object~check_exists. 56 | SELECT SINGLE name INTO name 57 | FROM trdir 58 | WHERE name = name. 59 | result = boolc( sy-subrc = 0 ). 60 | ENDMETHOD. 61 | 62 | 63 | METHOD zif_timem_object~get_name. 64 | result = name. 65 | ENDMETHOD. 66 | 67 | 68 | METHOD zif_timem_object~get_tadir_list. 69 | result = VALUE #( ( 70 | name = CONV #( name ) 71 | object_name = CONV #( name ) 72 | type = 'REPS' ) ). 73 | 74 | DATA(includes) = get_includes( ). 75 | 76 | result = VALUE #( 77 | BASE result 78 | FOR include IN includes 79 | ( name = include-title 80 | object_name = include-inclname 81 | type = 'REPS' ) ). 82 | ENDMETHOD. 83 | ENDCLASS. 84 | -------------------------------------------------------------------------------- /src/zcl_timem_object_prog_includes.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_PROG_INCLUDES 7 | E 8 | abapTimeMachine Program 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | E 18 | CONSTRUCTOR 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/zcl_timem_object_tr.clas.abap: -------------------------------------------------------------------------------- 1 | "! Representation of a program/include object. This object consists of a single part which 2 | "! this class will be able to create and return. 3 | CLASS zcl_timem_object_tr DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC. 7 | 8 | PUBLIC SECTION. 9 | 10 | INTERFACES zif_timem_object. 11 | 12 | METHODS constructor 13 | IMPORTING 14 | !id TYPE trkorr. 15 | PROTECTED SECTION. 16 | PRIVATE SECTION. 17 | TYPES ty_t_object TYPE TABLE OF REF TO zif_timem_object WITH KEY table_line. 18 | DATA id TYPE trkorr. 19 | 20 | METHODS get_object_keys 21 | RETURNING 22 | VALUE(result) TYPE trwbo_t_e071 23 | RAISING 24 | zcx_timem. 25 | 26 | METHODS get_objects_for_keys 27 | IMPORTING 28 | object_keys TYPE trwbo_t_e071 29 | RETURNING 30 | VALUE(result) TYPE ty_t_object 31 | RAISING 32 | zcx_timem. 33 | 34 | METHODS get_object 35 | IMPORTING 36 | object_key TYPE trwbo_s_e071 37 | RETURNING 38 | VALUE(result) TYPE REF TO zif_timem_object 39 | RAISING 40 | zcx_timem. 41 | ENDCLASS. 42 | 43 | 44 | 45 | CLASS zcl_timem_object_tr IMPLEMENTATION. 46 | 47 | 48 | METHOD constructor. 49 | me->id = id. 50 | ENDMETHOD. 51 | 52 | 53 | METHOD get_object. 54 | result = COND #( 55 | WHEN object_key-pgmid = 'R3TR' AND ( object_key-object = 'CLAS' OR object_key-object = 'FUGR' ) 56 | OR object_key-pgmid = 'LIMU' AND object_key-object = 'FUNC' 57 | THEN NEW zcl_timem_object_factory( )->get_instance( 58 | object_type = object_key-object 59 | object_name = CONV #( object_key-obj_name ) ) 60 | WHEN object_key-pgmid = 'LIMU' AND object_key-object = 'REPS' 61 | THEN NEW zcl_timem_object_factory( )->get_instance( 62 | object_type = 'PROG' 63 | object_name = CONV #( object_key-obj_name ) ) ). 64 | ENDMETHOD. 65 | 66 | 67 | METHOD get_object_keys. 68 | DATA request_data TYPE trwbo_request. 69 | 70 | request_data-h-trkorr = id. 71 | CALL FUNCTION 'TRINT_READ_REQUEST' 72 | EXPORTING 73 | iv_read_objs = abap_true 74 | CHANGING 75 | cs_request = request_data 76 | EXCEPTIONS 77 | error_occured = 1 78 | OTHERS = 2. 79 | IF sy-subrc <> 0. 80 | RAISE EXCEPTION TYPE zcx_timem. 81 | ENDIF. 82 | result = request_data-objects. 83 | SORT result BY pgmid ASCENDING object ASCENDING obj_name ASCENDING. 84 | DELETE ADJACENT DUPLICATES FROM result COMPARING pgmid object obj_name. 85 | ENDMETHOD. 86 | 87 | 88 | METHOD get_objects_for_keys. 89 | result = VALUE #( 90 | FOR object_key IN object_keys 91 | ( get_object( object_key ) ) ). 92 | DELETE result WHERE table_line IS NOT BOUND. 93 | ENDMETHOD. 94 | 95 | 96 | METHOD zif_timem_object~check_exists. 97 | TRY. 98 | NEW zcl_timem_request( me->id ). 99 | result = abap_true. 100 | CATCH zcx_timem. 101 | result = abap_false. 102 | ENDTRY. 103 | ENDMETHOD. 104 | 105 | 106 | METHOD zif_timem_object~get_name. 107 | result = id. 108 | ENDMETHOD. 109 | 110 | 111 | METHOD zif_timem_object~get_tadir_list. 112 | DATA(object_keys) = get_object_keys( ). 113 | DATA(objects) = get_objects_for_keys( object_keys ). 114 | result = REDUCE #( 115 | INIT t = VALUE #( ) 116 | FOR object IN objects 117 | FOR tadir_item IN object->get_tadir_list( ) 118 | NEXT t = VALUE #( BASE t ( tadir_item ) ) ). 119 | ENDMETHOD. 120 | ENDCLASS. 121 | -------------------------------------------------------------------------------- /src/zcl_timem_object_tr.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OBJECT_TR 7 | E 8 | abapTimeMachine Program 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CONSTRUCTOR 17 | E 18 | CONSTRUCTOR 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/zcl_timem_options.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_options DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PRIVATE . 5 | 6 | PUBLIC SECTION. 7 | "! Mode (Blame or Time Machine) 8 | DATA mode TYPE ztimem_mode READ-ONLY . 9 | 10 | "! Diff operation should ignore case 11 | DATA ignore_case TYPE boolean READ-ONLY . 12 | 13 | "! Diff operation should ignore indentation 14 | DATA ignore_indentation TYPE boolean READ-ONLY . 15 | 16 | "! CSS theme name 17 | DATA theme TYPE ztimem_theme READ-ONLY . 18 | 19 | "! Timestamp 20 | DATA timestamp TYPE timestamp READ-ONLY . 21 | 22 | "! Date 23 | DATA date TYPE datum READ-ONLY . 24 | 25 | "! Time 26 | DATA time TYPE uzeit READ-ONLY . 27 | 28 | " Ignore unreleased requests 29 | DATA ignore_unreleased TYPE boolean READ-ONLY. 30 | 31 | CLASS-METHODS class_constructor . 32 | 33 | CLASS-METHODS get_instance 34 | RETURNING 35 | VALUE(result) TYPE REF TO zcl_timem_options . 36 | 37 | METHODS set "#EC OPTL_PARAM 38 | IMPORTING 39 | !mode TYPE ztimem_mode OPTIONAL 40 | !ignore_case TYPE boolean OPTIONAL 41 | !ignore_indentation TYPE boolean OPTIONAL 42 | !timestamp TYPE timestamp OPTIONAL 43 | !theme TYPE ztimem_theme OPTIONAL 44 | !ignore_unreleased TYPE boolean OPTIONAL. 45 | 46 | PROTECTED SECTION. 47 | PRIVATE SECTION. 48 | CLASS-DATA: instance TYPE REF TO zcl_timem_options. 49 | ENDCLASS. 50 | 51 | 52 | 53 | CLASS ZCL_TIMEM_OPTIONS IMPLEMENTATION. 54 | 55 | 56 | METHOD class_constructor. 57 | instance = NEW #( ). 58 | instance->set( 59 | mode = zcl_timem_consts=>mode-blame 60 | ignore_case = abap_false 61 | ignore_indentation = abap_false 62 | timestamp = CONV #( |{ sy-datum }235959| ) 63 | theme = zcl_timem_gui_viewer=>c_theme-light ). 64 | ENDMETHOD. 65 | 66 | 67 | METHOD get_instance. 68 | result = instance. 69 | ENDMETHOD. 70 | 71 | 72 | METHOD set. 73 | IF mode IS SUPPLIED. 74 | me->mode = mode. 75 | ENDIF. 76 | 77 | IF ignore_case IS SUPPLIED. 78 | me->ignore_case = ignore_case. 79 | ENDIF. 80 | 81 | IF ignore_indentation IS SUPPLIED. 82 | me->ignore_indentation = ignore_indentation. 83 | ENDIF. 84 | 85 | IF ignore_unreleased IS SUPPLIED. 86 | me->ignore_unreleased = ignore_unreleased. 87 | ENDIF. 88 | 89 | IF theme IS SUPPLIED. 90 | me->theme = theme. 91 | ENDIF. 92 | 93 | IF timestamp IS SUPPLIED. 94 | me->timestamp = timestamp. 95 | CONVERT TIME STAMP timestamp TIME ZONE space INTO DATE me->date TIME me->time. 96 | ENDIF. 97 | ENDMETHOD. 98 | ENDCLASS. 99 | -------------------------------------------------------------------------------- /src/zcl_timem_options.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_OPTIONS 7 | E 8 | abapTimeMachine Options 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | IGNORE_CASE 17 | E 18 | Boolean Variable (X=true, -=false, space=unknown) 19 | 20 | 21 | IGNORE_INDENTATION 22 | E 23 | Boolean Variable (X=true, -=false, space=unknown) 24 | 25 | 26 | MODE 27 | E 28 | Single-Character Flag 29 | 30 | 31 | THEME 32 | E 33 | abapTimeMachine theme 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/zcl_timem_part.clas.abap: -------------------------------------------------------------------------------- 1 | "! Represents a part of an object, including all the versions of that part that 2 | "! exist in the system. 3 | CLASS zcl_timem_part DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | "! Object name 11 | DATA name TYPE string READ-ONLY . 12 | "! Part type 13 | DATA vrsd_type TYPE versobjtyp READ-ONLY . 14 | "! Part name 15 | DATA vrsd_name TYPE versobjnam READ-ONLY . 16 | 17 | "! Constructs a new part 18 | "! @parameter name | Object name 19 | "! @parameter vrsd_type | Part type 20 | "! @parameter vrsd_name | Part object 21 | METHODS constructor 22 | IMPORTING 23 | !name TYPE string 24 | !vrsd_type TYPE versobjtyp 25 | !vrsd_name TYPE versobjnam 26 | ignore_unreleased TYPE boolean 27 | RAISING 28 | zcx_timem . 29 | 30 | METHODS get_timestamps 31 | RETURNING 32 | VALUE(result) TYPE ztimem_timestamp_t . 33 | 34 | METHODS revert 35 | IMPORTING 36 | ts TYPE timestamp 37 | RAISING zcx_timem. 38 | 39 | METHODS to_struct 40 | IMPORTING 41 | mode TYPE ztimem_mode 42 | ts TYPE timestamp 43 | ignore_case TYPE boolean 44 | ignore_indentation TYPE boolean 45 | RETURNING 46 | VALUE(result) TYPE ztimem_part_source 47 | RAISING 48 | zcx_timem. 49 | 50 | PROTECTED SECTION. 51 | PRIVATE SECTION. 52 | 53 | TYPES: 54 | ty_t_version TYPE STANDARD TABLE OF REF TO zcl_timem_version WITH KEY table_line . 55 | 56 | DATA versions TYPE ty_t_version . 57 | 58 | METHODS get_source 59 | IMPORTING 60 | mode TYPE ztimem_mode 61 | ts TYPE timestamp 62 | ignore_case TYPE boolean 63 | ignore_indentation TYPE boolean 64 | RETURNING 65 | VALUE(result) TYPE ztimem_line_t 66 | RAISING 67 | zcx_timem . 68 | 69 | METHODS load_versions 70 | IMPORTING 71 | !vrsd_type TYPE versobjtyp 72 | !vrsd_name TYPE versobjnam 73 | ignore_unreleased TYPE boolean 74 | RAISING 75 | zcx_timem . 76 | 77 | METHODS get_version_at_timestamp 78 | IMPORTING 79 | ts TYPE timestamp 80 | RETURNING 81 | VALUE(result) TYPE REF TO zcl_timem_version . 82 | 83 | METHODS get_versions_until_timestamp 84 | IMPORTING 85 | ts TYPE timestamp 86 | RETURNING 87 | VALUE(result) TYPE ty_t_version . 88 | 89 | "! Calculates and returns a list of the diffed source already filled with blame 90 | "! details. 91 | METHODS get_diffed_source_with_blame 92 | IMPORTING 93 | ts TYPE timestamp 94 | ignore_case TYPE boolean 95 | ignore_indentation TYPE boolean 96 | RETURNING 97 | VALUE(result) TYPE ztimem_line_t 98 | RAISING 99 | zcx_timem . 100 | 101 | METHODS get_source_at_timestamp 102 | IMPORTING 103 | ts TYPE timestamp 104 | RETURNING 105 | VALUE(result) TYPE ztimem_line_t 106 | RAISING 107 | zcx_timem . 108 | ENDCLASS. 109 | 110 | 111 | 112 | CLASS zcl_timem_part IMPLEMENTATION. 113 | 114 | 115 | METHOD constructor. 116 | me->name = name. 117 | me->vrsd_type = vrsd_type. 118 | me->vrsd_name = vrsd_name. 119 | load_versions( vrsd_type = vrsd_type 120 | vrsd_name = vrsd_name 121 | ignore_unreleased = ignore_unreleased ). 122 | ENDMETHOD. 123 | 124 | 125 | METHOD get_diffed_source_with_blame. 126 | DATA(diff) = NEW zcl_timem_diff( 127 | ignore_case = ignore_case 128 | ignore_indentation = ignore_indentation ). 129 | LOOP AT get_versions_until_timestamp( ts ) INTO DATA(version). 130 | result = diff->compute( lines_old = result 131 | lines_new = version->get_source( ) ). 132 | ENDLOOP. 133 | ENDMETHOD. 134 | 135 | 136 | METHOD get_source. 137 | result = SWITCH #( 138 | mode 139 | WHEN zcl_timem_consts=>mode-blame THEN get_diffed_source_with_blame( 140 | ts = ts 141 | ignore_case = ignore_case 142 | ignore_indentation = ignore_indentation ) 143 | WHEN zcl_timem_consts=>mode-time_machine THEN get_source_at_timestamp( ts ) ). 144 | ENDMETHOD. 145 | 146 | 147 | METHOD get_source_at_timestamp. 148 | DATA(version) = get_version_at_timestamp( ts ). 149 | IF version IS BOUND. 150 | result = version->get_source( ). 151 | ENDIF. 152 | ENDMETHOD. 153 | 154 | 155 | METHOD get_timestamps. 156 | DATA ts LIKE LINE OF result. 157 | LOOP AT versions INTO DATA(version). 158 | ts = |{ version->date }{ version->time }|. 159 | COLLECT ts INTO result. 160 | ENDLOOP. 161 | ENDMETHOD. 162 | 163 | 164 | METHOD get_versions_until_timestamp. 165 | CONVERT TIME STAMP ts TIME ZONE space INTO DATE DATA(date) TIME DATA(time). 166 | result = VALUE #( 167 | FOR version IN versions 168 | WHERE ( 169 | table_line->date < date OR 170 | ( table_line->date = date AND 171 | table_line->time <= time ) ) 172 | ( version ) ). 173 | ENDMETHOD. 174 | 175 | 176 | METHOD get_version_at_timestamp. 177 | CONVERT TIME STAMP ts TIME ZONE space INTO DATE DATA(date) TIME DATA(time). 178 | " The last one should be the one we want 179 | LOOP AT versions INTO result WHERE 180 | table_line->date < date OR 181 | ( table_line->date = date AND 182 | table_line->time <= time ). 183 | ENDLOOP. 184 | ENDMETHOD. 185 | 186 | 187 | METHOD load_versions. 188 | DATA(vrsd) = NEW zcl_timem_vrsd( type = vrsd_type 189 | name = vrsd_name 190 | ignore_unreleased = ignore_unreleased ). 191 | 192 | versions = VALUE #( FOR s_vrsd IN vrsd->vrsd_list 193 | ( NEW zcl_timem_version( s_vrsd ) ) ). 194 | ENDMETHOD. 195 | 196 | 197 | METHOD revert. 198 | DATA(version) = get_version_at_timestamp( ts ). 199 | IF version IS BOUND. 200 | version->retrieve( ). 201 | ENDIF. 202 | ENDMETHOD. 203 | 204 | 205 | METHOD to_struct. 206 | result = VALUE ztimem_part_source( 207 | name = me->name 208 | type = me->vrsd_type 209 | object_name = me->vrsd_name 210 | lines = me->get_source( 211 | mode = mode 212 | ts = ts 213 | ignore_case = ignore_case 214 | ignore_indentation = ignore_indentation ) ). 215 | ENDMETHOD. 216 | ENDCLASS. 217 | -------------------------------------------------------------------------------- /src/zcl_timem_part.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_PART 7 | E 8 | abapTimeMachine Part 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_parts.clas.abap: -------------------------------------------------------------------------------- 1 | "! List of parts of an object. 2 | CLASS zcl_timem_parts DEFINITION 3 | PUBLIC 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | 9 | "! Constructor for an object parts 10 | "! @parameter i_object_type | Object type 11 | "! @parameter i_object_name | Object name 12 | METHODS constructor 13 | IMPORTING 14 | !object_type TYPE ztimem_object_type 15 | !object_name TYPE sobj_name 16 | ignore_unreleased TYPE boolean 17 | RAISING 18 | zcx_timem . 19 | 20 | "! Returns a deep structure containing all the details for all the parts. 21 | METHODS to_struct 22 | IMPORTING 23 | mode TYPE ztimem_mode 24 | timestamp TYPE timestamp 25 | ignore_case TYPE boolean 26 | ignore_indentation TYPE boolean 27 | RETURNING 28 | VALUE(result) TYPE ztimem_data 29 | RAISING 30 | zcx_timem . 31 | 32 | METHODS revert 33 | IMPORTING 34 | ts TYPE timestamp 35 | RAISING 36 | zcx_timem. 37 | PROTECTED SECTION. 38 | PRIVATE SECTION. 39 | 40 | DATA object_type TYPE ztimem_object_type . 41 | DATA object_name TYPE sobj_name . 42 | DATA parts TYPE zif_timem_object=>ty_t_part_ref . 43 | DATA userexits TYPE REF TO zcl_timem_userexits. 44 | 45 | "! Load all the data, creating the actual parts 46 | "! which will load all the versions 47 | "! @parameter io_counter | To keep track of progress 48 | METHODS load 49 | IMPORTING 50 | ignore_unreleased TYPE boolean 51 | RAISING 52 | zcx_timem . 53 | 54 | METHODS get_stats 55 | IMPORTING 56 | !parts TYPE ztimem_part_source_t 57 | RETURNING 58 | VALUE(result) TYPE ztimem_stats 59 | RAISING zcx_timem. 60 | 61 | METHODS get_timestamps 62 | RETURNING 63 | VALUE(result) TYPE ztimem_timestamp_t . 64 | 65 | METHODS get_lines 66 | IMPORTING 67 | !parts TYPE ztimem_part_source_t 68 | RETURNING 69 | VALUE(result) TYPE ztimem_line_t. 70 | 71 | METHODS get_summaries 72 | IMPORTING 73 | lines TYPE ztimem_line_t 74 | RETURNING 75 | VALUE(result) TYPE ztimem_summary_t 76 | RAISING 77 | zcx_timem. 78 | ENDCLASS. 79 | 80 | 81 | 82 | CLASS zcl_timem_parts IMPLEMENTATION. 83 | 84 | 85 | METHOD constructor. 86 | me->object_type = object_type. 87 | me->object_name = object_name. 88 | me->userexits = NEW #( ). 89 | load( ignore_unreleased ). 90 | ENDMETHOD. 91 | 92 | 93 | METHOD to_struct. 94 | DATA(t_part) = 95 | VALUE ztimem_part_source_t( 96 | FOR part IN parts 97 | ( part->to_struct( 98 | mode = mode 99 | ts = timestamp 100 | ignore_case = ignore_case 101 | ignore_indentation = ignore_indentation ) ) ). 102 | DELETE t_part WHERE lines IS INITIAL. 103 | 104 | " The custom fields and anything else related to the parts must be edited at this point 105 | " because it can affect the aggregated results (timestamps, stats and summaries) 106 | userexits->modify_parts( CHANGING parts = t_part ). 107 | 108 | result = VALUE #( name = object_name 109 | type = object_type 110 | version = zcl_timem_consts=>version 111 | parts = t_part 112 | timestamps = get_timestamps( ) 113 | stats = get_stats( t_part ) 114 | timestamp = timestamp 115 | summaries = get_summaries( get_lines( t_part ) ) 116 | ignore_case = ignore_case 117 | ignore_indentation = ignore_indentation ). 118 | ENDMETHOD. 119 | 120 | 121 | METHOD get_lines. 122 | result = VALUE ztimem_line_t( 123 | FOR part IN parts 124 | FOR line IN part-lines 125 | ( line ) ). 126 | ENDMETHOD. 127 | 128 | 129 | METHOD get_stats. 130 | result = NEW zcl_timem_stats( get_lines( parts ) )->stats. 131 | ENDMETHOD. 132 | 133 | 134 | METHOD get_summaries. 135 | result = VALUE #( 136 | ( NEW zcl_timem_summary( 'AUTHOR' )->build( lines ) ) 137 | ( NEW zcl_timem_summary( 'REQUEST' )->build( lines ) ) 138 | ( NEW zcl_timem_summary( 'CUSTOM1' )->build( lines ) ) 139 | ( NEW zcl_timem_summary( 'CUSTOM2' )->build( lines ) ) 140 | ( NEW zcl_timem_summary( 'CUSTOM3' )->build( lines ) ) ). 141 | ENDMETHOD. 142 | 143 | 144 | METHOD get_timestamps. 145 | " Gather timestamps from all parts 146 | LOOP AT parts INTO DATA(part). 147 | DATA(t_timestamp_part) = part->get_timestamps( ). 148 | LOOP AT t_timestamp_part INTO DATA(ts). 149 | COLLECT ts INTO result. 150 | ENDLOOP. 151 | ENDLOOP. 152 | SORT result BY table_line DESCENDING. 153 | ENDMETHOD. 154 | 155 | 156 | METHOD load. 157 | DATA(object) = NEW zcl_timem_object_factory( )->get_instance( object_type = object_type 158 | object_name = object_name ). 159 | 160 | DATA(tadir_list) = object->get_tadir_list( ). 161 | 162 | userexits->modify_tadir_list( CHANGING tadir_list = tadir_list ). 163 | 164 | LOOP AT tadir_list REFERENCE INTO DATA(tadir_item). 165 | TRY. 166 | DATA(part) = NEW zcl_timem_part( name = tadir_item->name 167 | vrsd_name = tadir_item->object_name 168 | vrsd_type = tadir_item->type 169 | ignore_unreleased = ignore_unreleased ). 170 | INSERT part INTO TABLE parts. 171 | CATCH zcx_timem. 172 | " Doesn't exist? Carry on 173 | ASSERT 1 = 1. 174 | ENDTRY. 175 | ENDLOOP. 176 | ENDMETHOD. 177 | 178 | 179 | METHOD revert. 180 | LOOP AT parts INTO DATA(part). 181 | part->revert( ts ). 182 | ENDLOOP. 183 | ENDMETHOD. 184 | ENDCLASS. 185 | -------------------------------------------------------------------------------- /src/zcl_timem_parts.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_PARTS 7 | E 8 | abapTimeMachine Parts 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_request.clas.abap: -------------------------------------------------------------------------------- 1 | "! Represents an SAP transport request 2 | CLASS zcl_timem_request DEFINITION 3 | PUBLIC 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | TYPES: 9 | BEGIN OF ty_s_system, 10 | sysid TYPE sysid, 11 | subrc TYPE sysubrc, 12 | date TYPE as4date, 13 | time TYPE as4time, 14 | END OF ty_s_system, 15 | ty_t_system TYPE STANDARD TABLE OF ty_s_system WITH KEY sysid. 16 | 17 | "! Transport request ID 18 | DATA id TYPE trkorr READ-ONLY . 19 | "! Transport request description 20 | DATA description TYPE as4text READ-ONLY . 21 | "! Transport request status 22 | DATA status TYPE trstatus READ-ONLY. 23 | 24 | "! Constructs an instance for the given request ID 25 | METHODS constructor 26 | IMPORTING 27 | !id TYPE trkorr 28 | RAISING zcx_timem. 29 | 30 | METHODS get_imported_systems 31 | RETURNING 32 | VALUE(result) TYPE ty_t_system. 33 | 34 | METHODS get_task_for_object 35 | IMPORTING 36 | object_type TYPE versobjtyp 37 | object_name TYPE versobjnam 38 | RETURNING VALUE(result) TYPE e070. 39 | PROTECTED SECTION. 40 | PRIVATE SECTION. 41 | TYPES: 42 | BEGIN OF ty_date_time, 43 | date TYPE datum, 44 | time TYPE uzeit, 45 | END OF ty_date_time. 46 | 47 | METHODS populate_details 48 | IMPORTING 49 | !id TYPE trkorr 50 | RAISING 51 | zcx_timem. 52 | 53 | METHODS get_system_latest_datetime 54 | IMPORTING 55 | system TYPE ctslg_system 56 | RETURNING VALUE(result) TYPE ty_date_time. 57 | 58 | METHODS get_latest_task_for_object 59 | IMPORTING 60 | object_type TYPE versobjtyp 61 | object_name TYPE versobjnam 62 | RETURNING VALUE(result) TYPE e070. 63 | 64 | METHODS get_task_if_only_one 65 | RETURNING VALUE(result) TYPE e070. 66 | ENDCLASS. 67 | 68 | 69 | 70 | CLASS zcl_timem_request IMPLEMENTATION. 71 | 72 | 73 | METHOD constructor. 74 | me->id = id. 75 | populate_details( id ). 76 | ENDMETHOD. 77 | 78 | 79 | METHOD get_imported_systems. 80 | DATA cofile TYPE ctslg_cofile. 81 | CALL FUNCTION 'TR_READ_GLOBAL_INFO_OF_REQUEST' 82 | EXPORTING 83 | iv_trkorr = id 84 | IMPORTING 85 | es_cofile = cofile. 86 | 87 | LOOP AT cofile-systems INTO DATA(system). 88 | DATA(dt) = get_system_latest_datetime( system ). 89 | result = VALUE #( 90 | BASE result 91 | ( sysid = system-systemid 92 | subrc = system-rc 93 | date = dt-date 94 | time = dt-time ) ). 95 | ENDLOOP. 96 | ENDMETHOD. 97 | 98 | 99 | METHOD populate_details. 100 | SELECT as4text, trstatus INTO (@description, @status) 101 | UP TO 1 ROWS 102 | FROM e070 103 | LEFT JOIN e07t ON e07t~trkorr = e070~trkorr WHERE e070~trkorr = @id 104 | ORDER BY as4text, trstatus. 105 | EXIT. 106 | ENDSELECT. 107 | IF sy-subrc <> 0. 108 | RAISE EXCEPTION TYPE zcx_timem. 109 | ENDIF. 110 | ENDMETHOD. 111 | 112 | 113 | METHOD get_system_latest_datetime. 114 | result = REDUCE #( 115 | INIT dt TYPE ty_date_time 116 | FOR step IN system-steps 117 | FOR action IN step-actions 118 | NEXT dt = COND #( 119 | WHEN action-date > dt-date AND action-time > dt-time 120 | THEN VALUE #( date = |{ action-date DATE = RAW }| time = |{ action-time TIME = RAW }| ) 121 | ELSE dt ) ). 122 | ENDMETHOD. 123 | 124 | METHOD get_task_for_object. 125 | " TODO 126 | " This approach was taken because the relationship between VRSD and E071 127 | " is not direct so sometimes method get_latest_task_for_object fails to 128 | " find anything in E071. Assuming that the most common scenario is for a 129 | " TR to have only one task, we first try to get a single task and only if 130 | " there is more than one do we use E071. This doesn't solve 100% of the 131 | " cases but should take care of many. I still hope to find a definitive 132 | " solution someday though. 133 | result = get_task_if_only_one( ). 134 | 135 | IF result IS INITIAL. 136 | " If here then there is more than one task for this request 137 | result = get_latest_task_for_object( 138 | object_type = object_type 139 | object_name = object_name ). 140 | ENDIF. 141 | 142 | IF result IS INITIAL AND object_type = 'REPS'. 143 | " This is a unfortunate hack. I hope to find a way to avoid this. 144 | " For some reason in VRSD the object type for programs is REPS 145 | " (which stands for report source) for a given TR, but in E071 the 146 | " object type registered is PROG. This is a workaround to 147 | " be sure the request details are found in those cases. 148 | result = get_task_for_object( 149 | object_type = 'PROG' 150 | object_name = object_name ). 151 | ENDIF. 152 | 153 | " For TRs with more than one task for which the relationship between VRSD 154 | " and E071 is not direct this can still fail. Example: 155 | " - VRSD: REPS + LZFUNCTIONGROUPNAMETOP 156 | " - E071: FUGR + ZFUNCTIONGROUP 157 | ENDMETHOD. 158 | 159 | 160 | METHOD get_task_if_only_one. 161 | DATA e070_list TYPE STANDARD TABLE OF e070. 162 | SELECT trkorr as4user as4date as4time 163 | INTO CORRESPONDING FIELDS OF TABLE e070_list 164 | FROM e070 165 | WHERE strkorr = me->id 166 | ORDER BY PRIMARY KEY. 167 | IF lines( e070_list ) = 1. 168 | result = e070_list[ 1 ]. 169 | ENDIF. 170 | ENDMETHOD. 171 | 172 | 173 | METHOD get_latest_task_for_object. 174 | SELECT e070~trkorr as4user as4date as4time 175 | INTO (result-trkorr, result-as4user, result-as4date, result-as4time) 176 | FROM e070 177 | INNER JOIN e071 ON e071~trkorr = e070~trkorr 178 | UP TO 1 ROWS 179 | WHERE strkorr = me->id 180 | AND object = object_type 181 | AND obj_name = object_name 182 | ORDER BY as4date DESCENDING as4time DESCENDING. 183 | EXIT. 184 | ENDSELECT. 185 | ENDMETHOD. 186 | ENDCLASS. 187 | -------------------------------------------------------------------------------- /src/zcl_timem_request.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_REQUEST 7 | E 8 | abapTimeMachine Request 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_run.clas.abap: -------------------------------------------------------------------------------- 1 | "! Main entry point. Instantiated by the program to run the whole show: 2 | "! 1. Load all the information 3 | "! 2. Display results in HTML page 4 | CLASS zcl_timem_run DEFINITION 5 | PUBLIC 6 | FINAL 7 | CREATE PUBLIC . 8 | 9 | PUBLIC SECTION. 10 | 11 | "! Execute everything 12 | METHODS go 13 | IMPORTING 14 | !object_type TYPE ztimem_object_type 15 | !object_name TYPE sobj_name 16 | RAISING 17 | zcx_timem . 18 | PROTECTED SECTION. 19 | PRIVATE SECTION. 20 | METHODS on_loading_version_source 21 | FOR EVENT loading_source OF zcl_timem_version 22 | IMPORTING 23 | !type 24 | !name 25 | !version_number. 26 | ENDCLASS. 27 | 28 | 29 | 30 | CLASS ZCL_TIMEM_RUN IMPLEMENTATION. 31 | 32 | 33 | METHOD go. 34 | SET HANDLER me->on_loading_version_source FOR ALL INSTANCES. 35 | NEW zcl_timem_gui( object_type = object_type 36 | object_name = object_name )->display( ). 37 | ENDMETHOD. 38 | 39 | 40 | METHOD on_loading_version_source. 41 | CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR' 42 | EXPORTING 43 | text = |Loading { type } { name } { version_number }|. 44 | ENDMETHOD. 45 | ENDCLASS. 46 | -------------------------------------------------------------------------------- /src/zcl_timem_run.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_RUN 7 | E 8 | abapTimeMachine Run 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_stats.clas.abap: -------------------------------------------------------------------------------- 1 | "! Takes a list of code with blame information and fills a structure 2 | "! with several calculated statistic indicators: 3 | "! - total lines of code 4 | "! - number of empty lines 5 | "! - number of comment lines 6 | "! - number of versions 7 | "! - date of oldest version 8 | "! - date of newest version 9 | CLASS zcl_timem_stats DEFINITION 10 | PUBLIC 11 | FINAL 12 | CREATE PUBLIC . 13 | 14 | PUBLIC SECTION. 15 | 16 | "! Statistics structure 17 | DATA stats TYPE ztimem_stats READ-ONLY . 18 | 19 | "! Constructor which receives a source code and immediately fills the stats 20 | "! structure attribute with all the calculated values. 21 | METHODS constructor 22 | IMPORTING 23 | !lines TYPE ztimem_line_t . 24 | PROTECTED SECTION. 25 | PRIVATE SECTION. 26 | 27 | METHODS get_comment_lines 28 | IMPORTING 29 | !lines TYPE ztimem_line_t 30 | RETURNING 31 | VALUE(result) TYPE i . 32 | 33 | METHODS get_empty_lines 34 | IMPORTING 35 | !lines TYPE ztimem_line_t 36 | RETURNING 37 | VALUE(result) TYPE i . 38 | 39 | METHODS get_date_oldest 40 | IMPORTING 41 | !lines TYPE ztimem_line_t 42 | RETURNING 43 | VALUE(result) TYPE datum . 44 | 45 | METHODS get_date_latest 46 | IMPORTING 47 | !lines TYPE ztimem_line_t 48 | RETURNING 49 | VALUE(result) TYPE datum . 50 | ENDCLASS. 51 | 52 | 53 | 54 | CLASS ZCL_TIMEM_STATS IMPLEMENTATION. 55 | 56 | 57 | METHOD constructor. 58 | stats = VALUE #( 59 | total_lines = lines( lines ) 60 | comment_lines = get_comment_lines( lines ) 61 | empty_lines = get_empty_lines( lines ) 62 | date_oldest = get_date_oldest( lines ) 63 | date_latest = get_date_latest( lines ) ). 64 | ENDMETHOD. 65 | 66 | 67 | METHOD get_comment_lines. 68 | DATA first_char TYPE char1. 69 | LOOP AT lines REFERENCE INTO DATA(line). 70 | first_char = shift_left( line->source ). 71 | IF first_char CO '*"'. 72 | result = result + 1. 73 | ENDIF. 74 | ENDLOOP. 75 | ENDMETHOD. 76 | 77 | 78 | METHOD get_date_latest. 79 | result = '00000000'. 80 | LOOP AT lines REFERENCE INTO DATA(line). 81 | IF line->date > result. 82 | result = line->date. 83 | ENDIF. 84 | ENDLOOP. 85 | ENDMETHOD. 86 | 87 | 88 | METHOD get_date_oldest. 89 | result = '999999999'. 90 | LOOP AT lines REFERENCE INTO DATA(line). 91 | IF line->date < result. 92 | result = line->date. 93 | ENDIF. 94 | ENDLOOP. 95 | ENDMETHOD. 96 | 97 | 98 | METHOD get_empty_lines. 99 | DATA(lines_aux) = lines. 100 | DELETE lines_aux WHERE source IS NOT INITIAL. 101 | result = lines( lines_aux ). 102 | ENDMETHOD. 103 | ENDCLASS. 104 | -------------------------------------------------------------------------------- /src/zcl_timem_stats.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_STATS 7 | E 8 | abapTimeMachine Statistics 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_summary.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_summary DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | METHODS constructor 9 | IMPORTING 10 | !fieldname TYPE name_feld . 11 | 12 | METHODS build 13 | IMPORTING 14 | lines TYPE ztimem_line_t 15 | RETURNING 16 | VALUE(result) TYPE ztimem_summary 17 | RAISING 18 | zcx_timem . 19 | 20 | PROTECTED SECTION. 21 | PRIVATE SECTION. 22 | TYPES: 23 | BEGIN OF ty_s_value_request, 24 | value TYPE string, 25 | request TYPE verskorrno, 26 | END OF ty_s_value_request, 27 | ty_t_value_request TYPE SORTED TABLE OF ty_s_value_request WITH UNIQUE KEY value request. 28 | 29 | DATA fieldname TYPE name_feld. 30 | 31 | METHODS build_lines 32 | IMPORTING 33 | !lines TYPE ztimem_line_t 34 | RETURNING 35 | VALUE(result) TYPE ztimem_summary_line_t 36 | RAISING 37 | zcx_timem . 38 | 39 | METHODS total_lines_count 40 | IMPORTING 41 | summary_lines TYPE ztimem_summary_line_t 42 | RETURNING 43 | VALUE(result) TYPE int2. 44 | 45 | METHODS build_value_request_list 46 | IMPORTING 47 | !lines TYPE ztimem_line_t 48 | RETURNING 49 | VALUE(result) TYPE ty_t_value_request. 50 | 51 | METHODS add_line_to_summary_lines 52 | IMPORTING 53 | !line TYPE ztimem_line 54 | CHANGING 55 | summary_lines TYPE ztimem_summary_line_t. 56 | 57 | METHODS calc_missing_data 58 | IMPORTING 59 | lines TYPE ztimem_line_t 60 | CHANGING 61 | summary_lines TYPE ztimem_summary_line_t 62 | RAISING 63 | zcx_timem. 64 | 65 | METHODS request_count_for_value 66 | IMPORTING 67 | value TYPE string 68 | value_requests TYPE ty_t_value_request 69 | RETURNING VALUE(result) TYPE i. 70 | ENDCLASS. 71 | 72 | 73 | 74 | CLASS ZCL_TIMEM_SUMMARY IMPLEMENTATION. 75 | 76 | 77 | METHOD add_line_to_summary_lines. 78 | ASSIGN COMPONENT fieldname OF STRUCTURE line TO FIELD-SYMBOL(). 79 | IF sy-subrc <> 0. 80 | RETURN. 81 | ENDIF. 82 | 83 | " Insert if it doesn't yet exist 84 | IF NOT line_exists( summary_lines[ value = ] ). 85 | INSERT VALUE #( value = ) INTO TABLE summary_lines. "#EC CI_SUBRC 86 | ENDIF. 87 | 88 | READ TABLE summary_lines ASSIGNING FIELD-SYMBOL() WITH KEY value = . 89 | IF sy-subrc = 0. 90 | -line_count = -line_count + 1. 91 | ENDIF. 92 | ENDMETHOD. 93 | 94 | 95 | METHOD build. 96 | result = VALUE #( 97 | fieldname = fieldname 98 | lines = build_lines( lines ) 99 | title = |{ fieldname } list| 100 | value_title = fieldname ). 101 | NEW zcl_timem_userexits( )->modify_summary( CHANGING summary = result ). 102 | ENDMETHOD. 103 | 104 | 105 | METHOD build_lines. 106 | LOOP AT lines INTO DATA(line). 107 | add_line_to_summary_lines( 108 | EXPORTING 109 | line = line 110 | CHANGING 111 | summary_lines = result ). 112 | ENDLOOP. 113 | 114 | " If we only have one line and no value was found... this summary is pointless 115 | IF lines( result ) = 1 AND result[ 1 ]-value IS INITIAL. 116 | CLEAR result. 117 | ENDIF. 118 | 119 | calc_missing_data( 120 | EXPORTING 121 | lines = lines 122 | CHANGING 123 | summary_lines = result ). 124 | ENDMETHOD. 125 | 126 | 127 | METHOD build_value_request_list. 128 | LOOP AT lines INTO DATA(line). 129 | ASSIGN COMPONENT fieldname OF STRUCTURE line TO FIELD-SYMBOL(). 130 | IF sy-subrc = 0. 131 | " Store fieldname+request (it will not have duplicates because the table has a UNIQUE KEY 132 | INSERT VALUE #( value = request = line-request ) INTO TABLE result. 133 | ENDIF. 134 | ENDLOOP. 135 | ENDMETHOD. 136 | 137 | 138 | METHOD calc_missing_data. 139 | DATA(total_lines) = total_lines_count( summary_lines ). 140 | DATA(value_requests) = build_value_request_list( lines ). 141 | LOOP AT summary_lines ASSIGNING FIELD-SYMBOL(). 142 | -percentage = -line_count / total_lines. 143 | -request_count = request_count_for_value( 144 | value = CONV #( -value ) 145 | value_requests = value_requests ). 146 | ENDLOOP. 147 | ENDMETHOD. 148 | 149 | 150 | METHOD constructor. 151 | me->fieldname = fieldname. 152 | ENDMETHOD. 153 | 154 | 155 | METHOD request_count_for_value. 156 | result = REDUCE int2( 157 | INIT x = 0 158 | FOR value_request IN value_requests 159 | WHERE ( value = value ) 160 | NEXT x = x + 1 ). 161 | ENDMETHOD. 162 | 163 | 164 | METHOD total_lines_count. 165 | result = REDUCE int2( 166 | INIT x = 0 167 | FOR summary_line IN summary_lines 168 | NEXT x = x + summary_line-line_count ). 169 | ENDMETHOD. 170 | ENDCLASS. 171 | -------------------------------------------------------------------------------- /src/zcl_timem_summary.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_SUMMARY 7 | E 8 | ZCL_TIMEM_LINES 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_syntax_abap.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_SYNTAX_ABAP 7 | E 8 | abapTimeMachine Syntax Highlighting 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_syntax_highlighter.clas.abap: -------------------------------------------------------------------------------- 1 | "! Abstract class representing a generic syntax highlighter. It was copied from 2 | "! the abapGit project as-is and used as a black box that just works :) 3 | class ZCL_TIMEM_SYNTAX_HIGHLIGHTER definition 4 | public 5 | abstract 6 | create public . 7 | 8 | public section. 9 | 10 | class-methods CREATE 11 | importing 12 | !IV_FILENAME type STRING 13 | returning 14 | value(RO_INSTANCE) type ref to ZCL_TIMEM_SYNTAX_HIGHLIGHTER . 15 | methods PROCESS_LINE 16 | importing 17 | !IV_LINE type STRING 18 | returning 19 | value(RESULT) type STRING . 20 | protected section. 21 | 22 | types: 23 | BEGIN OF ty_match, 24 | token TYPE c LENGTH 1, " Type of matches 25 | offset TYPE i, " Beginning position of the string that should be formatted 26 | length TYPE i, " Length of the string that should be formatted 27 | text_tag TYPE string, " Type of text tag 28 | END OF ty_match . 29 | types: 30 | ty_match_tt TYPE STANDARD TABLE OF ty_match WITH DEFAULT KEY . 31 | types: 32 | BEGIN OF ty_rule, 33 | regex TYPE REF TO cl_abap_regex, 34 | token TYPE c LENGTH 1, 35 | style TYPE string, 36 | relevant_submatch TYPE i, 37 | END OF ty_rule . 38 | 39 | constants C_TOKEN_NONE type C value '.' ##NO_TEXT. 40 | data: 41 | mt_rules TYPE STANDARD TABLE OF ty_rule . 42 | 43 | methods ADD_RULE 44 | importing 45 | !IV_REGEX type STRING 46 | !IV_TOKEN type C 47 | !IV_STYLE type STRING 48 | !IV_SUBMATCH type I optional . 49 | methods PARSE_LINE 50 | importing 51 | !IV_LINE type STRING 52 | returning 53 | value(RESULT) type TY_MATCH_TT . 54 | methods ORDER_MATCHES 55 | abstract 56 | importing 57 | !IV_LINE type STRING 58 | changing 59 | !CT_MATCHES type TY_MATCH_TT . 60 | methods EXTEND_MATCHES 61 | importing 62 | !IV_LINE type STRING 63 | changing 64 | !CT_MATCHES type TY_MATCH_TT . 65 | methods FORMAT_LINE 66 | importing 67 | !IV_LINE type STRING 68 | !IT_MATCHES type TY_MATCH_TT 69 | returning 70 | value(RESULT) type STRING . 71 | methods APPLY_STYLE 72 | importing 73 | !IV_LINE type STRING 74 | !IV_CLASS type STRING 75 | returning 76 | value(RESULT) type STRING . 77 | private section. 78 | ENDCLASS. 79 | 80 | 81 | 82 | CLASS ZCL_TIMEM_SYNTAX_HIGHLIGHTER IMPLEMENTATION. 83 | 84 | 85 | METHOD add_rule. 86 | 87 | DATA ls_rule LIKE LINE OF mt_rules. 88 | 89 | ls_rule-regex = NEW #( pattern = iv_regex 90 | ignore_case = abap_true ). 91 | 92 | ls_rule-token = iv_token. 93 | ls_rule-style = iv_style. 94 | ls_rule-relevant_submatch = iv_submatch. 95 | APPEND ls_rule TO mt_rules. 96 | 97 | ENDMETHOD. 98 | 99 | 100 | METHOD apply_style. 101 | 102 | DATA lv_escaped TYPE string. 103 | 104 | lv_escaped = escape( val = iv_line format = cl_abap_format=>e_html_attr ). 105 | IF iv_class IS NOT INITIAL. 106 | result = |{ lv_escaped }|. 107 | ELSE. 108 | result = lv_escaped. 109 | ENDIF. 110 | 111 | ENDMETHOD. 112 | 113 | 114 | METHOD create. 115 | 116 | " Create instance of highighter dynamically dependent on syntax type 117 | IF iv_filename CP '*.abap'. 118 | ro_instance = NEW zcl_timem_syntax_abap( ). 119 | ELSE. 120 | CLEAR ro_instance. 121 | ENDIF. 122 | 123 | ENDMETHOD. 124 | 125 | 126 | METHOD extend_matches. 127 | 128 | DATA lv_line_len TYPE i. 129 | DATA lv_last_pos TYPE i VALUE 0. 130 | DATA lv_length TYPE i. 131 | DATA ls_match TYPE ty_match. 132 | 133 | lv_line_len = strlen( iv_line ). 134 | 135 | SORT ct_matches BY offset ASCENDING. 136 | 137 | " Add entries refering to parts of text that should not be formatted 138 | LOOP AT ct_matches ASSIGNING field-symbol(). 139 | IF -offset > lv_last_pos. 140 | lv_length = -offset - lv_last_pos. 141 | ls_match-token = c_token_none. 142 | ls_match-offset = lv_last_pos. 143 | ls_match-length = lv_length. 144 | INSERT ls_match INTO ct_matches INDEX sy-tabix. 145 | ENDIF. 146 | lv_last_pos = -offset + -length. 147 | ENDLOOP. 148 | 149 | " Add remainder of the string 150 | IF lv_line_len > lv_last_pos. 151 | lv_length = lv_line_len - lv_last_pos. 152 | ls_match-token = c_token_none. 153 | ls_match-offset = lv_last_pos. 154 | ls_match-length = lv_length. 155 | APPEND ls_match TO ct_matches. 156 | ENDIF. 157 | 158 | ENDMETHOD. 159 | 160 | 161 | METHOD format_line. 162 | 163 | DATA lv_chunk TYPE string. 164 | DATA ls_rule LIKE LINE OF mt_rules. 165 | 166 | LOOP AT it_matches ASSIGNING field-symbol(). 167 | lv_chunk = substring( val = iv_line off = -offset len = -length ). 168 | 169 | " Failed read equals no style 170 | CLEAR ls_rule. 171 | READ TABLE mt_rules INTO ls_rule WITH KEY token = -token. "#EC CI_SUBRC 172 | 173 | lv_chunk = me->apply_style( iv_line = lv_chunk 174 | iv_class = ls_rule-style ). 175 | 176 | result = result && lv_chunk. 177 | ENDLOOP. 178 | 179 | ENDMETHOD. 180 | 181 | 182 | METHOD parse_line. 183 | 184 | DATA lo_regex TYPE REF TO cl_abap_regex. 185 | DATA lo_matcher TYPE REF TO cl_abap_matcher. 186 | DATA lt_result TYPE match_result_tab. 187 | DATA ls_match TYPE ty_match. 188 | 189 | " Process syntax-dependent regex table and find all matches 190 | LOOP AT mt_rules ASSIGNING FIELD-SYMBOL(). 191 | lo_regex = -regex. 192 | lo_matcher = lo_regex->create_matcher( text = iv_line ). 193 | lt_result = lo_matcher->find_all( ). 194 | 195 | " Save matches into custom table with predefined tokens 196 | LOOP AT lt_result ASSIGNING FIELD-SYMBOL(). 197 | CLEAR: ls_match. 198 | IF -relevant_submatch = 0. 199 | ls_match-token = -token. 200 | ls_match-offset = -offset. 201 | ls_match-length = -length. 202 | APPEND ls_match TO result. 203 | ELSE. 204 | READ TABLE -submatches ASSIGNING FIELD-SYMBOL() INDEX -relevant_submatch. 205 | "submatch might be empty if only discarted parts matched 206 | IF sy-subrc = 0 AND -offset >= 0 AND -length > 0. 207 | ls_match-token = -token. 208 | ls_match-offset = -offset. 209 | ls_match-length = -length. 210 | APPEND ls_match TO result. 211 | ENDIF. 212 | ENDIF. 213 | ENDLOOP. 214 | ENDLOOP. 215 | 216 | ENDMETHOD. 217 | 218 | 219 | METHOD process_line. 220 | 221 | DATA: lt_matches TYPE ty_match_tt. 222 | 223 | IF strlen( iv_line ) = 0. 224 | RETURN. 225 | ENDIF. 226 | 227 | lt_matches = me->parse_line( iv_line ). 228 | 229 | order_matches( EXPORTING iv_line = iv_line 230 | CHANGING ct_matches = lt_matches ). 231 | 232 | extend_matches( EXPORTING iv_line = iv_line 233 | CHANGING ct_matches = lt_matches ). 234 | 235 | result = format_line( iv_line = iv_line 236 | it_matches = lt_matches ). 237 | 238 | ENDMETHOD. 239 | ENDCLASS. 240 | -------------------------------------------------------------------------------- /src/zcl_timem_syntax_highlighter.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_SYNTAX_HIGHLIGHTER 7 | E 8 | abapTimeMachine Syntax highlighter 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zcl_timem_userexit_default.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_userexit_default DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES zif_timem_userexit . 9 | PROTECTED SECTION. 10 | PRIVATE SECTION. 11 | CONSTANTS: 12 | BEGIN OF c_return_code, 13 | warning TYPE sysubrc VALUE 4, 14 | END OF c_return_code. 15 | 16 | METHODS modify_summary_author 17 | CHANGING 18 | !summary TYPE ztimem_summary 19 | RAISING 20 | zcx_timem. 21 | 22 | METHODS modify_summary_request 23 | CHANGING 24 | !summary TYPE ztimem_summary 25 | RAISING 26 | zcx_timem. 27 | 28 | METHODS build_request_imported_systems 29 | IMPORTING 30 | request TYPE REF TO zcl_timem_request 31 | RETURNING 32 | VALUE(result) TYPE string. 33 | ENDCLASS. 34 | 35 | 36 | 37 | CLASS zcl_timem_userexit_default IMPLEMENTATION. 38 | 39 | 40 | METHOD build_request_imported_systems. 41 | LOOP AT request->get_imported_systems( ) INTO DATA(system) WHERE sysid <> sy-sysid. 42 | DATA(one_system) = |{ system-sysid }|. 44 | IF system-subrc > c_return_code-warning. 45 | one_system = |{ one_system }|. 46 | ENDIF. 47 | result = |{ result } { one_system }|. 48 | ENDLOOP. 49 | ENDMETHOD. 50 | 51 | 52 | METHOD modify_summary_author. 53 | summary-title = 'Contributors' ##NO_TEXT. 54 | summary-value_title = 'Username' ##NO_TEXT. 55 | summary-text1_title = 'Name' ##NO_TEXT. 56 | LOOP AT summary-lines REFERENCE INTO DATA(line). 57 | line->text1 = NEW zcl_timem_author( )->get_name( CONV #( line->value ) ). 58 | line->value = |{ line->value }|. 59 | ENDLOOP. 60 | ENDMETHOD. 61 | 62 | 63 | METHOD modify_summary_request. 64 | summary-title = 'Requests' ##NO_TEXT. 65 | summary-value_title = 'Request' ##NO_TEXT. 66 | summary-text1_title = 'Description' ##NO_TEXT. 67 | summary-text2_title = 'Systems' ##NO_TEXT. 68 | LOOP AT summary-lines REFERENCE INTO DATA(line). 69 | TRY. 70 | DATA(request) = NEW zcl_timem_request( CONV #( line->value ) ). 71 | line->text1 = request->description. 72 | line->text2 = build_request_imported_systems( request ). 73 | line->value = |{ line->value }|. 74 | CATCH zcx_timem. 75 | line->text1 = 'N/A'. 76 | line->text2 = space. 77 | line->value = space. 78 | ENDTRY. 79 | ENDLOOP. 80 | ENDMETHOD. 81 | 82 | 83 | METHOD zif_timem_userexit~before_rendering. 84 | RETURN. 85 | ENDMETHOD. 86 | 87 | 88 | METHOD zif_timem_userexit~modify_asset_content. 89 | RETURN. 90 | ENDMETHOD. 91 | 92 | 93 | METHOD zif_timem_userexit~modify_parts. 94 | RETURN. 95 | ENDMETHOD. 96 | 97 | 98 | METHOD zif_timem_userexit~modify_tadir_list. 99 | RETURN. 100 | ENDMETHOD. 101 | 102 | 103 | METHOD zif_timem_userexit~modify_summary. 104 | CASE summary-fieldname. 105 | WHEN zcl_timem_consts=>fieldname-author. 106 | modify_summary_author( CHANGING summary = summary ). 107 | WHEN zcl_timem_consts=>fieldname-request. 108 | modify_summary_request( CHANGING summary = summary ). 109 | ENDCASE. 110 | ENDMETHOD. 111 | 112 | 113 | METHOD zif_timem_userexit~on_sapevent. 114 | RETURN. 115 | ENDMETHOD. 116 | ENDCLASS. 117 | -------------------------------------------------------------------------------- /src/zcl_timem_userexit_default.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_USEREXIT_DEFAULT 7 | E 8 | ZCL_TIMEM_USEREXIT_DEFAULT 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | MODIFY_SUMMARY_REQUEST 17 | SUMMARY 18 | E 19 | ZTIMEM_SUMMARY 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/zcl_timem_userexits.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_userexits DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | CLASS-METHODS class_constructor . 9 | 10 | METHODS constructor . 11 | 12 | METHODS before_rendering 13 | CHANGING 14 | !data TYPE ztimem_data . 15 | 16 | METHODS modify_parts 17 | CHANGING 18 | !parts TYPE ztimem_part_source_t . 19 | 20 | METHODS modify_summary 21 | CHANGING 22 | !summary TYPE ztimem_summary 23 | RAISING 24 | zcx_timem. 25 | 26 | METHODS on_sapevent 27 | IMPORTING 28 | !action TYPE c 29 | !getdata TYPE c . 30 | 31 | METHODS modify_tadir_list 32 | CHANGING 33 | !tadir_list TYPE ztimem_part_t 34 | RAISING 35 | zcx_timem. 36 | 37 | METHODS modify_asset_content 38 | IMPORTING 39 | !subtype TYPE c 40 | CHANGING 41 | !content TYPE string . 42 | 43 | PROTECTED SECTION. 44 | PRIVATE SECTION. 45 | TYPES ty_userexits TYPE STANDARD TABLE OF REF TO zif_timem_userexit WITH KEY table_line. 46 | CLASS-DATA instances TYPE ty_userexits. 47 | DATA options TYPE REF TO zcl_timem_options. 48 | 49 | CLASS-METHODS load_instances. 50 | ENDCLASS. 51 | 52 | 53 | 54 | CLASS zcl_timem_userexits IMPLEMENTATION. 55 | 56 | 57 | METHOD before_rendering. 58 | LOOP AT instances INTO DATA(instance). 59 | TRY. 60 | instance->before_rendering( 61 | EXPORTING 62 | options = options 63 | CHANGING 64 | data = data ). 65 | CATCH cx_sy_dyn_call_illegal_method. 66 | " Not implemented? Carry on. 67 | ASSERT 1 = 1. 68 | ENDTRY. 69 | ENDLOOP. 70 | ENDMETHOD. 71 | 72 | 73 | METHOD class_constructor. 74 | load_instances( ). 75 | ENDMETHOD. 76 | 77 | 78 | METHOD constructor. 79 | options = zcl_timem_options=>get_instance( ). 80 | ENDMETHOD. 81 | 82 | 83 | METHOD load_instances. 84 | DATA impkeys TYPE seor_implementing_keys. 85 | DATA(impkey) = VALUE seoclskey( clsname = 'ZIF_TIMEM_USEREXIT' ). 86 | CALL FUNCTION 'SEO_INTERFACE_IMPLEM_GET_ALL' 87 | EXPORTING 88 | intkey = impkey 89 | IMPORTING 90 | impkeys = impkeys 91 | EXCEPTIONS 92 | not_existing = 1 93 | OTHERS = 2. 94 | IF sy-subrc <> 0. 95 | RETURN. 96 | ENDIF. 97 | 98 | DATA o TYPE REF TO zif_timem_userexit. 99 | LOOP AT impkeys INTO DATA(classdata). 100 | CREATE OBJECT o TYPE (classdata-clsname). "#EC PREF_NEW 101 | INSERT o INTO TABLE instances. 102 | ENDLOOP. 103 | ENDMETHOD. 104 | 105 | 106 | METHOD modify_asset_content. 107 | LOOP AT instances INTO DATA(instance). 108 | TRY. 109 | instance->modify_asset_content( 110 | EXPORTING 111 | options = options 112 | subtype = subtype 113 | CHANGING 114 | content = content ). 115 | CATCH cx_sy_dyn_call_illegal_method. 116 | " Not implemented? Carry on. 117 | ASSERT 1 = 1. 118 | ENDTRY. 119 | ENDLOOP. 120 | ENDMETHOD. 121 | 122 | 123 | METHOD modify_parts. 124 | LOOP AT instances INTO DATA(instance). 125 | TRY. 126 | instance->modify_parts( 127 | EXPORTING 128 | options = options 129 | CHANGING 130 | parts = parts ). 131 | CATCH cx_sy_dyn_call_illegal_method. 132 | " Not implemented? Carry on. 133 | ASSERT 1 = 1. 134 | ENDTRY. 135 | ENDLOOP. 136 | ENDMETHOD. 137 | 138 | 139 | METHOD modify_tadir_list. 140 | LOOP AT instances INTO DATA(instance). 141 | TRY. 142 | instance->modify_tadir_list( 143 | EXPORTING 144 | options = options 145 | CHANGING 146 | tadir_list = tadir_list ). 147 | CATCH cx_sy_dyn_call_illegal_method. 148 | " Not implemented? Carry on. 149 | ASSERT 1 = 1. 150 | ENDTRY. 151 | ENDLOOP. 152 | ENDMETHOD. 153 | 154 | 155 | METHOD modify_summary. 156 | LOOP AT instances INTO DATA(instance). 157 | TRY. 158 | instance->modify_summary( 159 | EXPORTING 160 | options = options 161 | CHANGING 162 | summary = summary ). 163 | CATCH cx_sy_dyn_call_illegal_method. 164 | " Not implemented? Carry on. 165 | ASSERT 1 = 1. 166 | ENDTRY. 167 | ENDLOOP. 168 | ENDMETHOD. 169 | 170 | 171 | METHOD on_sapevent. 172 | LOOP AT instances INTO DATA(instance). 173 | TRY. 174 | instance->on_sapevent( 175 | options = options 176 | action = action 177 | getdata = getdata ). 178 | CATCH cx_sy_dyn_call_illegal_method. 179 | " Not implemented? Carry on. 180 | ASSERT 1 = 1. 181 | ENDTRY. 182 | ENDLOOP. 183 | ENDMETHOD. 184 | ENDCLASS. 185 | -------------------------------------------------------------------------------- /src/zcl_timem_userexits.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_USEREXITS 7 | E 8 | ZCL_TIMEM_USEREXIT 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | CLASS_CONSTRUCTOR 17 | E 18 | CLASS_CONSTRUCTOR 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/zcl_timem_version.clas.abap: -------------------------------------------------------------------------------- 1 | "! Represents a version of a part of an object, including its source code 2 | "! and several other attributes like author, request, etc. 3 | CLASS zcl_timem_version DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | 10 | CONSTANTS: 11 | BEGIN OF c_version, 12 | latest_db TYPE versno VALUE 0, 13 | latest TYPE versno VALUE 99998, 14 | active TYPE versno VALUE 99998, 15 | modified TYPE versno VALUE 99999, 16 | END OF c_version . 17 | 18 | "! Version number from the VRSD table 19 | DATA version_number TYPE versno READ-ONLY . 20 | 21 | "! Transport request ID 22 | DATA request TYPE verskorrno READ-ONLY . 23 | 24 | "! Task ID (if exists) 25 | DATA task TYPE verskorrno READ-ONLY . 26 | 27 | " Username 28 | DATA author TYPE versuser READ-ONLY . 29 | 30 | " Name of the user (or username if no longer exists) 31 | DATA author_name TYPE ad_namtext READ-ONLY . 32 | 33 | " Date of version 34 | DATA date TYPE versdate READ-ONLY . 35 | 36 | " Time of version 37 | DATA time TYPE verstime READ-ONLY . 38 | 39 | "! Loading source event 40 | EVENTS loading_source 41 | EXPORTING 42 | VALUE(type) TYPE versobjtyp 43 | VALUE(name) TYPE versobjnam 44 | VALUE(version_number) TYPE versno . 45 | 46 | "! Takes a line of the VRSD table and fills all the attributes, including 47 | "! the source code already with blame information. 48 | METHODS constructor 49 | IMPORTING 50 | !vrsd TYPE vrsd 51 | RAISING 52 | zcx_timem . 53 | 54 | "! Returns the version source code including blame information. 55 | METHODS get_source 56 | RETURNING 57 | VALUE(result) TYPE ztimem_line_t 58 | RAISING 59 | zcx_timem . 60 | 61 | METHODS retrieve 62 | RAISING 63 | zcx_timem. 64 | 65 | PROTECTED SECTION. 66 | PRIVATE SECTION. 67 | DATA vrsd TYPE vrsd. 68 | DATA gt_source TYPE abaptxt255_tab. 69 | 70 | METHODS load_attributes 71 | RAISING zcx_timem. 72 | 73 | METHODS load_source 74 | RAISING zcx_timem. 75 | 76 | "! Try to find the object in the request tasks because sometimes the request was created 77 | "! by someone who was not the actual developer. The tasks better reflects the object's author. 78 | "! If we find a task, we overwrite the author. We choose to pick the latest task. 79 | METHODS load_latest_task 80 | RAISING zcx_timem. 81 | 82 | METHODS load_author_name 83 | RAISING zcx_timem. 84 | ENDCLASS. 85 | 86 | 87 | 88 | CLASS zcl_timem_version IMPLEMENTATION. 89 | METHOD constructor. 90 | me->vrsd = vrsd. 91 | load_attributes( ). 92 | load_latest_task( ). 93 | load_author_name( ). 94 | ENDMETHOD. 95 | 96 | 97 | METHOD get_source. 98 | DATA: s_line LIKE LINE OF result. 99 | 100 | s_line-version_number = me->version_number. 101 | s_line-request = me->request. 102 | s_line-task = me->task. 103 | s_line-author = me->author. 104 | s_line-author_name = me->author_name. 105 | s_line-date = me->date. 106 | s_line-time = me->time. 107 | s_line-timestamp = |{ me->date }{ me->time }|. 108 | 109 | load_source( ). 110 | 111 | LOOP AT gt_source INTO DATA(source_int). 112 | s_line-line_num = sy-tabix. 113 | s_line-source = source_int. 114 | INSERT s_line INTO TABLE result. 115 | ENDLOOP. 116 | ENDMETHOD. 117 | 118 | 119 | METHOD load_attributes. 120 | me->version_number = vrsd-versno. 121 | me->author = vrsd-author. 122 | me->date = vrsd-datum. 123 | me->time = vrsd-zeit. 124 | me->request = vrsd-korrnum. 125 | ENDMETHOD. 126 | 127 | 128 | METHOD load_latest_task. 129 | IF me->request IS INITIAL. 130 | RETURN. 131 | ENDIF. 132 | DATA(request) = NEW zcl_timem_request( me->request ). 133 | DATA(e070) = request->get_task_for_object( 134 | object_type = vrsd-objtype 135 | object_name = vrsd-objname ). 136 | me->task = e070-trkorr. 137 | me->author = e070-as4user. 138 | me->date = e070-as4date. 139 | me->time = e070-as4time. 140 | ENDMETHOD. 141 | 142 | 143 | METHOD load_author_name. 144 | me->author_name = NEW zcl_timem_author( )->get_name( me->author ). 145 | ENDMETHOD. 146 | 147 | 148 | METHOD load_source. 149 | DATA t_trdir TYPE trdir_it. 150 | 151 | " If already loaded, skip it 152 | IF gt_source IS NOT INITIAL. 153 | RETURN. 154 | ENDIF. 155 | 156 | RAISE EVENT loading_source 157 | EXPORTING 158 | type = vrsd-objtype 159 | name = vrsd-objname 160 | version_number = me->version_number. 161 | 162 | CALL FUNCTION 'SVRS_GET_REPS_FROM_OBJECT' 163 | EXPORTING 164 | object_name = vrsd-objname 165 | object_type = vrsd-objtype 166 | versno = zcl_timem_versno=>to_internal( me->version_number ) 167 | TABLES 168 | repos_tab = gt_source 169 | trdir_tab = t_trdir 170 | EXCEPTIONS 171 | no_version = 1 172 | OTHERS = 2. 173 | IF sy-subrc <> 0. 174 | " Ignore errors, just exit. 175 | ASSERT 1 = 1. 176 | ENDIF. 177 | ENDMETHOD. 178 | 179 | 180 | METHOD retrieve. 181 | DATA(db_versno) = zcl_timem_versno=>to_internal( me->version_number ). 182 | SUBMIT rsedtve1 AND RETURN "#EC CI_SUBMIT 183 | WITH objtype = vrsd-objtype 184 | WITH objname = vrsd-objname 185 | WITH versno = db_versno. 186 | ENDMETHOD. 187 | ENDCLASS. 188 | -------------------------------------------------------------------------------- /src/zcl_timem_version.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_VERSION 7 | E 8 | abapTimeMachine Version 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_versno.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_timem_versno DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PRIVATE . 5 | 6 | PUBLIC SECTION. 7 | CLASS-METHODS to_internal 8 | IMPORTING 9 | versno TYPE versno 10 | RETURNING VALUE(result) TYPE versno. 11 | 12 | CLASS-METHODS to_external 13 | IMPORTING 14 | versno TYPE versno 15 | RETURNING VALUE(result) TYPE versno. 16 | PROTECTED SECTION. 17 | PRIVATE SECTION. 18 | ENDCLASS. 19 | 20 | 21 | 22 | CLASS zcl_timem_versno IMPLEMENTATION. 23 | METHOD to_internal. 24 | " Technically the current version is 0 but in order to keep them properly sorted we're 25 | " setting it to magic number 99997 (because 'ACTIVE' is 99998 and 'MODIFIED' is 99999. 26 | " But when we're going to fetch it from the database we must use 0. 27 | result = COND #( 28 | WHEN versno = zcl_timem_version=>c_version-latest THEN zcl_timem_version=>c_version-latest_db 29 | ELSE versno ). 30 | ENDMETHOD. 31 | 32 | 33 | METHOD to_external. 34 | " We consider the latest version to be 99998 instead of 0 for sorting reasons 35 | result = COND #( 36 | WHEN versno = zcl_timem_version=>c_version-latest_db THEN zcl_timem_version=>c_version-latest 37 | ELSE versno ). 38 | ENDMETHOD. 39 | ENDCLASS. 40 | -------------------------------------------------------------------------------- /src/zcl_timem_versno.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_VERSNO 7 | E 8 | ZCL_TIMEM_VERSNO 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_timem_vrsd.clas.abap: -------------------------------------------------------------------------------- 1 | "! List of VRSD lines for existing versions of a given object. 2 | CLASS zcl_timem_vrsd DEFINITION 3 | PUBLIC 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | 9 | "! List of relevant lines of VRSD table (plus artificial lines created 10 | "! for the active and modified versions). 11 | DATA vrsd_list TYPE vrsd_tab READ-ONLY . 12 | 13 | "! Constructor which takes an object type and name and loads all the VRSD 14 | "! data, as well as the eventual artificial lines for the active and modified 15 | "! versions. 16 | METHODS constructor 17 | IMPORTING 18 | !type TYPE versobjtyp 19 | !name TYPE versobjnam 20 | ignore_unreleased TYPE boolean 21 | RAISING 22 | zcx_timem . 23 | 24 | PROTECTED SECTION. 25 | PRIVATE SECTION. 26 | DATA type TYPE versobjtyp. 27 | DATA name TYPE versobjnam. 28 | DATA request_active_modif TYPE trkorr. 29 | 30 | METHODS load_from_table 31 | IMPORTING 32 | ignore_unreleased TYPE boolean. 33 | 34 | METHODS load_active_or_modified 35 | IMPORTING 36 | versno TYPE versno 37 | RAISING zcx_timem. 38 | 39 | METHODS get_request_active_modif 40 | RETURNING VALUE(result) TYPE trkorr 41 | RAISING zcx_timem. 42 | 43 | METHODS determine_request_active_modif 44 | RETURNING VALUE(result) TYPE trkorr 45 | RAISING zcx_timem. 46 | 47 | METHODS get_versionable_object 48 | RETURNING VALUE(result) TYPE svrs2_versionable_object. 49 | 50 | METHODS get_versionable_object_mode 51 | IMPORTING 52 | versno TYPE versno 53 | RETURNING VALUE(result) TYPE char1. 54 | 55 | METHODS read_vrsd 56 | IMPORTING 57 | versno TYPE versno 58 | RETURNING VALUE(result) TYPE vrsd 59 | RAISING zcx_timem. 60 | ENDCLASS. 61 | 62 | 63 | 64 | CLASS zcl_timem_vrsd IMPLEMENTATION. 65 | 66 | 67 | METHOD constructor. 68 | me->type = type. 69 | me->name = name. 70 | load_from_table( ignore_unreleased ). 71 | IF ignore_unreleased = abap_false. 72 | " Even released parts have an active version. We know it is unreleased if the 73 | " request is not empty. Otherwise we will disregard it. 74 | IF get_request_active_modif( ) IS NOT INITIAL. 75 | load_active_or_modified( zcl_timem_version=>c_version-active ). 76 | ENDIF. 77 | load_active_or_modified( zcl_timem_version=>c_version-modified ). 78 | ENDIF. 79 | SORT me->vrsd_list BY versno ASCENDING. 80 | ENDMETHOD. 81 | 82 | 83 | METHOD determine_request_active_modif. 84 | DATA s_ko100 TYPE ko100. 85 | DATA locked TYPE trparflag. 86 | DATA s_tlock_key TYPE tlock_int. 87 | DATA s_tlock TYPE tlock. 88 | 89 | CALL FUNCTION 'TR_GET_PGMID_FOR_OBJECT' 90 | EXPORTING 91 | iv_object = me->type 92 | IMPORTING 93 | es_type = s_ko100 94 | EXCEPTIONS 95 | illegal_object = 1 96 | OTHERS = 2. 97 | IF sy-subrc <> 0. 98 | RAISE EXCEPTION TYPE zcx_timem. 99 | ENDIF. 100 | 101 | DATA(s_e071) = VALUE e071( pgmid = s_ko100-pgmid 102 | object = me->type 103 | obj_name = me->name ). 104 | CALL FUNCTION 'TR_CHECK_TYPE' 105 | EXPORTING 106 | wi_e071 = s_e071 107 | IMPORTING 108 | pe_result = locked 109 | we_lock_key = s_tlock_key. 110 | IF locked <> 'L'. 111 | RETURN. 112 | ENDIF. 113 | 114 | CALL FUNCTION 'TRINT_CHECK_LOCKS' 115 | EXPORTING 116 | wi_lock_key = s_tlock_key 117 | IMPORTING 118 | we_lockflag = locked 119 | we_tlock = s_tlock 120 | EXCEPTIONS 121 | empty_key = 1 122 | OTHERS = 2. 123 | IF sy-subrc <> 0. 124 | zcx_timem=>raise_from_syst( ). 125 | ENDIF. 126 | 127 | IF locked IS INITIAL. 128 | RETURN. 129 | ENDIF. 130 | 131 | result = s_tlock-trkorr. 132 | ENDMETHOD. 133 | 134 | 135 | METHOD get_request_active_modif. 136 | IF me->request_active_modif IS INITIAL. 137 | me->request_active_modif = determine_request_active_modif( ). 138 | ENDIF. 139 | result = me->request_active_modif. 140 | ENDMETHOD. 141 | 142 | 143 | METHOD read_vrsd. 144 | CALL FUNCTION 'SVRS_INITIALIZE_DATAPOINTER' 145 | CHANGING 146 | objtype = me->type 147 | data_pointer = me->type. 148 | 149 | DATA(obj) = get_versionable_object( ). 150 | CALL FUNCTION 'SVRS_GET_VERSION_REPOSITORY' 151 | EXPORTING 152 | mode = get_versionable_object_mode( versno ) 153 | CHANGING 154 | obj = obj 155 | EXCEPTIONS 156 | not_found = 1 157 | OTHERS = 2. 158 | IF sy-subrc <> 0. 159 | RETURN. 160 | ENDIF. 161 | 162 | CALL FUNCTION 'SVRS_EXTRACT_INFO_FROM_OBJECT' 163 | EXPORTING 164 | object = obj 165 | CHANGING 166 | vrsd_info = result. 167 | ENDMETHOD. 168 | 169 | 170 | METHOD load_active_or_modified. 171 | DATA(vrsd) = read_vrsd( versno ). 172 | 173 | IF vrsd IS INITIAL. 174 | RETURN. 175 | ENDIF. 176 | 177 | IF vrsd-author IS INITIAL. 178 | RAISE EXCEPTION TYPE zcx_timem. 179 | ENDIF. 180 | 181 | " Unreleased versions will be set to current date and time because, while 182 | " different parts will most probably have different date+time creation date, 183 | " each one is not really a version. At least not yet. And without this hack 184 | " we'd get one version moment for each unreleased part, which is not realistic. 185 | vrsd-datum = sy-datum. 186 | vrsd-zeit = sy-uzeit. 187 | 188 | vrsd-versno = versno. 189 | vrsd-objtype = me->type. 190 | vrsd-objname = me->name. 191 | vrsd-korrnum = get_request_active_modif( ). 192 | 193 | INSERT vrsd INTO TABLE me->vrsd_list. 194 | ENDMETHOD. 195 | 196 | 197 | METHOD load_from_table. 198 | DATA: versno_range TYPE RANGE OF versno. 199 | 200 | IF ignore_unreleased = abap_true. 201 | versno_range = VALUE #( 202 | option = 'NE' 203 | sign = 'I' 204 | ( low = '00000' ) ). 205 | ENDIF. 206 | 207 | SELECT * INTO TABLE me->vrsd_list 208 | FROM vrsd 209 | WHERE objtype = me->type 210 | AND objname = me->name 211 | AND versno IN versno_range 212 | ORDER BY PRIMARY KEY. 213 | 214 | LOOP AT me->vrsd_list REFERENCE INTO DATA(vrsd). 215 | vrsd->versno = zcl_timem_versno=>to_external( vrsd->versno ). 216 | ENDLOOP. 217 | ENDMETHOD. 218 | 219 | 220 | METHOD get_versionable_object. 221 | result = VALUE #( 222 | objtype = me->type 223 | data_pointer = me->type 224 | objname = me->name 225 | header_only = abap_true ). 226 | ENDMETHOD. 227 | 228 | 229 | METHOD get_versionable_object_mode. 230 | result = SWITCH #( 231 | versno 232 | WHEN zcl_timem_version=>c_version-active THEN 'A' 233 | WHEN zcl_timem_version=>c_version-modified THEN 'M' ). 234 | ENDMETHOD. 235 | ENDCLASS. 236 | -------------------------------------------------------------------------------- /src/zcl_timem_vrsd.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_TIMEM_VRSD 7 | E 8 | abapTimeMachine VRSD 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcx_timem.clas.abap: -------------------------------------------------------------------------------- 1 | "! Exception class for all the ZBLAME classes 2 | class ZCX_TIMEM definition 3 | public 4 | inheriting from CX_STATIC_CHECK 5 | create public . 6 | 7 | public section. 8 | 9 | interfaces IF_T100_MESSAGE . 10 | 11 | constants: 12 | begin of OBJECT_NOT_FOUND, 13 | msgid type symsgid value 'ZTIMEMACHINE', 14 | msgno type symsgno value '000', 15 | attr1 type scx_attrname value '', 16 | attr2 type scx_attrname value '', 17 | attr3 type scx_attrname value '', 18 | attr4 type scx_attrname value '', 19 | end of OBJECT_NOT_FOUND . 20 | 21 | methods CONSTRUCTOR 22 | importing 23 | !TEXTID like IF_T100_MESSAGE=>T100KEY optional 24 | !PREVIOUS like PREVIOUS optional . 25 | class-methods RAISE_FROM_SYST 26 | raising 27 | ZCX_TIMEM . 28 | 29 | methods IF_MESSAGE~GET_LONGTEXT 30 | redefinition . 31 | methods IF_MESSAGE~GET_TEXT 32 | redefinition . 33 | protected section. 34 | private section. 35 | ENDCLASS. 36 | 37 | 38 | 39 | CLASS ZCX_TIMEM IMPLEMENTATION. 40 | 41 | 42 | method CONSTRUCTOR ##ADT_SUPPRESS_GENERATION. 43 | CALL METHOD SUPER->CONSTRUCTOR 44 | EXPORTING 45 | PREVIOUS = PREVIOUS 46 | . 47 | clear me->textid. 48 | if textid is initial. 49 | IF_T100_MESSAGE~T100KEY = IF_T100_MESSAGE=>DEFAULT_TEXTID. 50 | else. 51 | IF_T100_MESSAGE~T100KEY = TEXTID. 52 | endif. 53 | endmethod. 54 | 55 | 56 | METHOD if_message~get_longtext. 57 | " Get deepest long text from an exception chain 58 | IF me->previous IS BOUND. 59 | result = me->previous->get_longtext( preserve_newlines ). 60 | ELSE. 61 | result = super->if_message~get_longtext( preserve_newlines ). 62 | ENDIF. 63 | ENDMETHOD. 64 | 65 | 66 | METHOD if_message~get_text. 67 | " Get deepest text from an exception chain 68 | IF me->previous IS BOUND. 69 | result = me->previous->get_text( ). 70 | ELSE. 71 | result = super->if_message~get_text( ). 72 | ENDIF. 73 | ENDMETHOD. 74 | 75 | 76 | METHOD raise_from_syst. 77 | TRY. 78 | cx_proxy_t100=>raise_from_sy_msg( ). 79 | CATCH cx_proxy_t100 INTO DATA(exc_t100). 80 | RAISE EXCEPTION TYPE zcx_timem 81 | EXPORTING 82 | previous = exc_t100. 83 | ENDTRY. 84 | ENDMETHOD. 85 | ENDCLASS. 86 | -------------------------------------------------------------------------------- /src/zcx_timem.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCX_TIMEM 7 | E 8 | abapTimeMachine Exception 9 | 40 10 | 1 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | CONSTRUCTOR 18 | E 19 | CONSTRUCTOR 20 | 21 | 22 | 23 | 24 | RAISE_FROM_SYST 25 | ZCX_TIMEM 26 | E 27 | abapTimeMachine Exception 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/zif_timem_asset.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_timem_asset 2 | PUBLIC . 3 | 4 | "! Return the filename 5 | METHODS get_url 6 | RETURNING 7 | VALUE(result) TYPE w3url . 8 | 9 | "! Return the asset type (html or css) 10 | METHODS get_subtype 11 | RETURNING 12 | VALUE(result) TYPE char20. 13 | 14 | "! Return the actual content 15 | METHODS get_content 16 | RETURNING 17 | VALUE(result) TYPE string . 18 | ENDINTERFACE. 19 | -------------------------------------------------------------------------------- /src/zif_timem_asset.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_TIMEM_ASSET 7 | E 8 | abapBlame HTML asset 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_timem_object.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_timem_object 2 | PUBLIC . 3 | 4 | 5 | TYPES: 6 | ty_t_part_ref TYPE STANDARD TABLE OF REF TO zcl_timem_part WITH KEY table_line . 7 | 8 | "! Returns a list of references to part instances 9 | METHODS get_tadir_list 10 | RETURNING 11 | VALUE(result) TYPE ztimem_part_t 12 | RAISING 13 | zcx_timem . 14 | 15 | "! Returns the object name 16 | METHODS get_name 17 | RETURNING 18 | VALUE(result) TYPE string . 19 | 20 | "! Checks if the object exists in the system 21 | METHODS check_exists 22 | RETURNING 23 | VALUE(result) TYPE boolean . 24 | ENDINTERFACE. 25 | -------------------------------------------------------------------------------- /src/zif_timem_object.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_TIMEM_OBJECT 7 | E 8 | abapBlame Object 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_timem_userexit.intf.abap: -------------------------------------------------------------------------------- 1 | INTERFACE zif_timem_userexit 2 | PUBLIC . 3 | 4 | 5 | METHODS before_rendering 6 | IMPORTING 7 | !options TYPE REF TO zcl_timem_options 8 | CHANGING 9 | !data TYPE ztimem_data . 10 | 11 | METHODS modify_parts 12 | IMPORTING 13 | !options TYPE REF TO zcl_timem_options 14 | CHANGING 15 | !parts TYPE ztimem_part_source_t. 16 | 17 | METHODS modify_summary 18 | IMPORTING 19 | options TYPE REF TO zcl_timem_options 20 | CHANGING 21 | summary TYPE ztimem_summary 22 | RAISING 23 | zcx_timem. 24 | 25 | METHODS on_sapevent 26 | IMPORTING 27 | !options TYPE REF TO zcl_timem_options 28 | !action TYPE c 29 | !getdata TYPE c . 30 | 31 | METHODS modify_tadir_list 32 | IMPORTING 33 | !options TYPE REF TO zcl_timem_options 34 | CHANGING 35 | !tadir_list TYPE ztimem_part_t 36 | RAISING 37 | zcx_timem. 38 | 39 | METHODS modify_asset_content 40 | IMPORTING 41 | !options TYPE REF TO zcl_timem_options 42 | !subtype TYPE c 43 | CHANGING 44 | !content TYPE string . 45 | ENDINTERFACE. 46 | -------------------------------------------------------------------------------- /src/zif_timem_userexit.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_TIMEM_USEREXIT 7 | E 8 | ZIF_TIMEM_USEREXIT 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | BEFORE_RENDERING 16 | DATA 17 | E 18 | abapTimeMachine Parts 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_css_main.xslt.source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | body { margin:0; padding:0; } 7 | div.abaptimemachine { background-color: #f9f9f9; } 8 | div, table, h1, h2, h3 {font-family: Consolas, Courier, monospace; } 9 | table { border-collapse: collapse; } 10 | div, table { font-size: 10pt; } 11 | div.header_text { font-style: italic; } 12 | div.footer_text { font-style: italic; } 13 | pre { display: inline; } 14 | table th { text-align: left; } 15 | table .num { text-align: right; } 16 | table.blame { width: 100%; } 17 | table td,th { 18 | padding-left: 0.5em; 19 | padding-right: 0.5em; 20 | padding-top: 3px; 21 | padding-bottom: 3px; 22 | white-space:nowrap; 23 | vertical-align: top; 24 | } 25 | table td.hide,th.hide {display:none;} 26 | table td.line {width:1%;} 27 | table td.code {width:99%;} 28 | #footer { font-size: 6pt; } 29 | 30 | table.blame tr.moment_past { background-color: #fff9f9; } 31 | table.blame tr.moment_present { background-color: #f9f9ff; } 32 | table.blame tr.moment_future { background-color: #f9fff9; } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/ztimem_css_main.xslt.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_CSS_MAIN 7 | E 8 | abapTimeMachine Main CSS 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/ztimem_css_theme_dark.xslt.source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | table.blame tr.versionfirstrow td { border-top: 1pt dotted #707070; } 7 | table th, table td { color: #707070; } 8 | table td.code { color: white; width: 80%; } 9 | table td.code span.keyword { color: #0a69ce; } 10 | table td.code span.text { color: #48ce4f; } 11 | table td.code span.comment { color: #808080; font-style: italic; } 12 | table.contributors th,table.requests th { border-bottom: 1pt dotted #707070; } 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/ztimem_css_theme_dark.xslt.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_CSS_THEME_DARK 7 | E 8 | abapTimeMachine Dark CSS 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/ztimem_css_theme_light.xslt.source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | table.blame tr.versionfirstrow td { border-top: 1pt dotted #707070; } 7 | table th, table td { color: #707070; } 8 | table td.code { color: black; width: 80%; } 9 | table td.code span.keyword { color: #0a69ce; } 10 | table td.code span.text { color: #48ce4f; } 11 | table td.code span.comment { color: #808080; font-style: italic; } 12 | table.contributors th,table.requests th { border-bottom: 1pt dotted #707070; } 13 | #footer { color: #707070; } 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/ztimem_css_theme_light.xslt.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_CSS_THEME_LIGHT 7 | E 8 | abapTimeMachine Light CSS 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/ztimem_custom_field.dtel.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_CUSTOM_FIELD 7 | E 8 | TEXT255 9 | 55 10 | 10 11 | 20 12 | 40 13 | ZTIMEM_CUSTOM_FIELD 14 | Custom field 15 | CustomFld 16 | Custom field 17 | Custom field 18 | E 19 | D 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_data.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_DATA 7 | E 8 | INTTAB 9 | abapTimeMachine Parts 10 | E 11 | 1 12 | 13 | 14 | 15 | TYPE 16 | ZTIMEM_OBJECT_TYPE 17 | 0 18 | X 19 | F 20 | E 21 | 22 | 23 | NAME 24 | SOBJ_NAME 25 | 0 26 | E 27 | 28 | 29 | VERSION 30 | CHAR10 31 | 0 32 | E 33 | 34 | 35 | TIMESTAMPS 36 | ZTIMEM_TIMESTAMP_T 37 | 0 38 | TTYP 39 | TTYPL 40 | L 41 | 42 | 43 | PARTS 44 | ZTIMEM_PART_SOURCE_T 45 | 0 46 | TTYP 47 | TTYPL 48 | L 49 | 50 | 51 | STATS 52 | ZTIMEM_STATS 53 | 0 54 | STRU 55 | STRUS 56 | S 57 | 58 | 59 | TIMESTAMP 60 | TIMESTAMP 61 | 0 62 | E 63 | 64 | 65 | IGNORE_CASE 66 | FLAG 67 | 0 68 | X 69 | F 70 | E 71 | 72 | 73 | IGNORE_INDENTATION 74 | FLAG 75 | 0 76 | X 77 | F 78 | E 79 | 80 | 81 | SUMMARIES 82 | ZTIMEM_SUMMARY_T 83 | 0 84 | TTYP 85 | TTYPL 86 | L 87 | 88 | 89 | HEADER_TEXT 90 | CHAR1024 91 | 0 92 | E 93 | 94 | 95 | FOOTER_TEXT 96 | CHAR1024 97 | 0 98 | E 99 | 100 | 101 | CUSTOM1_TITLE 102 | TEXT100 103 | 0 104 | E 105 | 106 | 107 | CUSTOM2_TITLE 108 | TEXT100 109 | 0 110 | E 111 | 112 | 113 | CUSTOM3_TITLE 114 | TEXT100 115 | 0 116 | E 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /src/ztimem_html_blame.xslt.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_HTML_BLAME 7 | E 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/ztimem_html_timemachine.xslt.source.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ABAP Time Machine 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |

25 | 26 | Class 27 | Program 28 | Function group 29 | Function module 30 | Transport request 31 | 32 | 33 | 34 |

35 |
&nbsp;
36 |
37 |
&nbsp;
38 |
39 |
40 | 41 | 42 | 43 | 64 | 65 | 66 | 67 | 68 |

Table of contents

69 |
70 |
71 | 81 |
82 |
83 | 91 |
92 |
93 |
94 | 95 | 96 | 97 | 98 |

99 | 100 | 101 | 102 | 103 |

104 | 105 | 106 | 107 | 108 | 114 | 115 | 116 | 117 | 118 | versionfirstrow 119 | 120 | 121 | 122 | 123 |
Line 109 | 110 | SAPEVENT:source?| 111 | Source 112 | 113 |
124 |
125 |
126 | 127 | 128 | 129 |

130 | 131 | stats 132 | Statistics 133 | 134 |

135 | 136 | 137 | 138 | 139 | 142 | 143 | 144 | 145 | 152 | 153 | 154 | 155 | 162 | 163 | 164 | 165 | 173 | 174 | 175 | 176 | 181 | 182 |
Total lines: 140 | 141 |
SLOC: 146 | 147 | 148 | ( 149 | 150 | ) 151 |
Comment lines: 156 | 157 | 158 | ( 159 | 160 | ) 161 |
Empty lines: 166 | 167 | 168 | 169 | ( 170 | 171 | ) 172 |
Activity interval: 177 | 178 | to 179 | 180 |
183 |
184 |
185 | 186 | 187 | 188 | 197 | 198 | 199 |
200 | -------------------------------------------------------------------------------- /src/ztimem_html_timemachine.xslt.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_HTML_TIMEMACHINE 7 | E 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/ztimem_line.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_LINE 7 | E 8 | INTTAB 9 | abapTimeMachine Line 10 | E 11 | 1 12 | 13 | 14 | 15 | LINE_NUM 16 | NUMC05 17 | 0 18 | E 19 | 20 | 21 | VERSION_NUMBER 22 | VERSNO 23 | 0 24 | E 25 | 26 | 27 | REQUEST 28 | VERSKORRNO 29 | 0 30 | E 31 | 32 | 33 | TASK 34 | VERSKORRNO 35 | 0 36 | E 37 | 38 | 39 | AUTHOR 40 | VERSUSER 41 | 0 42 | E 43 | 44 | 45 | AUTHOR_NAME 46 | XUNAME1 47 | 0 48 | E 49 | 50 | 51 | CUSTOM1 52 | ZTIMEM_CUSTOM_FIELD 53 | 0 54 | E 55 | 56 | 57 | CUSTOM2 58 | ZTIMEM_CUSTOM_FIELD 59 | 0 60 | E 61 | 62 | 63 | CUSTOM3 64 | ZTIMEM_CUSTOM_FIELD 65 | 0 66 | E 67 | 68 | 69 | DATE 70 | VERSDATE 71 | 0 72 | T 73 | E 74 | 75 | 76 | TIME 77 | VERSTIME 78 | 0 79 | T 80 | E 81 | 82 | 83 | TIMESTAMP 84 | TIMESTAMP 85 | 0 86 | E 87 | 88 | 89 | SOURCE 90 | TEXT1000 91 | 0 92 | E 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/ztimem_line_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_LINE_T 7 | E 8 | ZTIMEM_LINE 9 | S 10 | STRU 11 | T 12 | D 13 | N 14 | abapTimeMachine Line table 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/ztimem_mode.doma.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_MODE 7 | E 8 | CHAR 9 | 000001 10 | 000001 11 | X 12 | abapTimeMachine Mode 13 | 14 | 15 | 16 | 0001 17 | E 18 | T 19 | Time Machine 20 | 21 | 22 | 0002 23 | E 24 | B 25 | Blame 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/ztimem_mode.dtel.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_MODE 7 | E 8 | ZTIMEM_MODE 9 | 55 10 | 10 11 | 20 12 | 40 13 | abapTimeMachine Mode 14 | Mode 15 | Mode 16 | Mode 17 | Mode 18 | E 19 | D 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_object_type.doma.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_OBJECT_TYPE 7 | E 8 | CHAR 9 | 000004 10 | 000004 11 | X 12 | abapTimeMachine Object type 13 | 14 | 15 | 16 | 0001 17 | E 18 | CLAS 19 | Class 20 | 21 | 22 | 0002 23 | E 24 | PROG 25 | Program 26 | 27 | 28 | 0003 29 | E 30 | FUGR 31 | Function group 32 | 33 | 34 | 0004 35 | E 36 | FUNC 37 | Function module 38 | 39 | 40 | 0005 41 | E 42 | PRGI 43 | Program with includes 44 | 45 | 46 | 0006 47 | E 48 | TR 49 | Transport request 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/ztimem_object_type.dtel.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_OBJECT_TYPE 7 | E 8 | ZTIMEM_OBJECT_TYPE 9 | 55 10 | 10 11 | 20 12 | 40 13 | abapTimeMachine object type 14 | Object type 15 | ObjectType 16 | Object type 17 | Object type 18 | E 19 | D 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_part.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_PART 7 | E 8 | INTTAB 9 | abapTimeMachine Part 10 | E 11 | 1 12 | 13 | 14 | 15 | NAME 16 | 0 17 | g 18 | 000008 19 | STRG 20 | STRG 21 | 22 | 23 | TYPE 24 | VERSOBJTYP 25 | 0 26 | E 27 | 28 | 29 | OBJECT_NAME 30 | VERSOBJNAM 31 | 0 32 | E 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/ztimem_part_source.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_PART_SOURCE 7 | E 8 | INTTAB 9 | X 10 | abapTimeMachine Part 11 | E 12 | 1 13 | 14 | 15 | 16 | .INCLUDE 17 | 0 18 | ZTIMEM_PART 19 | S 20 | abapTimeMachine Part 21 | S 22 | 23 | 24 | LINES 25 | ZTIMEM_LINE_T 26 | 0 27 | TTYP 28 | TTYPL 29 | L 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/ztimem_part_source_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_PART_SOURCE_T 7 | E 8 | ZTIMEM_PART_SOURCE 9 | S 10 | STRU 11 | T 12 | D 13 | N 14 | abapTimeMachine Part list 15 | C 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/ztimem_part_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_PART_T 7 | E 8 | ZTIMEM_PART 9 | S 10 | STRU 11 | T 12 | D 13 | N 14 | abapTimeMachine Part list 15 | C 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/ztimem_percentage.dtel.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_PERCENTAGE 7 | E 8 | DECV2_2 9 | 55 10 | 10 11 | 20 12 | 40 13 | abapTimeMachine percentage 14 | Percentage 15 | Percentage 16 | Percentage 17 | Percentage 18 | E 19 | D 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_stats.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_STATS 7 | E 8 | INTTAB 9 | abapTimeMachine Stats 10 | E 11 | 1 12 | 13 | 14 | 15 | TOTAL_LINES 16 | INT4 17 | 0 18 | E 19 | 20 | 21 | COMMENT_LINES 22 | INT4 23 | 0 24 | E 25 | 26 | 27 | EMPTY_LINES 28 | INT4 29 | 0 30 | E 31 | 32 | 33 | VERSION_COUNT 34 | INT4 35 | 0 36 | E 37 | 38 | 39 | DATE_OLDEST 40 | DATUM 41 | 0 42 | T 43 | E 44 | 45 | 46 | DATE_LATEST 47 | DATUM 48 | 0 49 | T 50 | E 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/ztimem_summary.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_SUMMARY 7 | E 8 | INTTAB 9 | X 10 | ZTIMEM_SUMMARY 11 | 1 12 | 13 | 14 | 15 | FIELDNAME 16 | NAME_FELD 17 | 0 18 | E 19 | 20 | 21 | .INCLUDE 22 | 0 23 | ZTIMEM_SUMMARY_TITLES 24 | S 25 | ZTIMEM_SUMMARY_TITLES 26 | S 27 | 28 | 29 | LINES 30 | ZTIMEM_SUMMARY_LINE_T 31 | 0 32 | TTYP 33 | TTYPL 34 | L 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/ztimem_summary_line.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_SUMMARY_LINE 7 | E 8 | INTTAB 9 | ZTIMEM_SUMMARY_LINE 10 | E 11 | 1 12 | 13 | 14 | 15 | VALUE 16 | TEXT1024 17 | 0 18 | E 19 | 20 | 21 | TEXT1 22 | TEXT1024 23 | 0 24 | E 25 | 26 | 27 | TEXT2 28 | TEXT1024 29 | 0 30 | E 31 | 32 | 33 | TEXT3 34 | TEXT1024 35 | 0 36 | E 37 | 38 | 39 | LINE_COUNT 40 | INT4 41 | 0 42 | E 43 | 44 | 45 | PERCENTAGE 46 | ZTIMEM_PERCENTAGE 47 | 0 48 | E 49 | 50 | 51 | REQUEST_COUNT 52 | INT2 53 | 0 54 | E 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/ztimem_summary_line_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_SUMMARY_LINE_T 7 | E 8 | ZTIMEM_SUMMARY_LINE 9 | S 10 | STRU 11 | T 12 | K 13 | N 14 | 0001 15 | ZTIMEM_SUMMARY_LINE_T 16 | 17 | 18 | 19 | ZTIMEM_SUMMARY_LINE_T 20 | 0001 21 | 0001 22 | VALUE 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/ztimem_summary_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_SUMMARY_T 7 | E 8 | ZTIMEM_SUMMARY 9 | S 10 | STRU 11 | T 12 | D 13 | N 14 | ZTIMEM_summary_T 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/ztimem_summary_titles.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_SUMMARY_TITLES 7 | E 8 | INTTAB 9 | ZTIMEM_SUMMARY_TITLES 10 | 1 11 | 12 | 13 | 14 | TITLE 15 | AS4TEXT 16 | 0 17 | E 18 | 19 | 20 | VALUE_TITLE 21 | TEXT255 22 | 0 23 | E 24 | 25 | 26 | TEXT1_TITLE 27 | TEXT255 28 | 0 29 | E 30 | 31 | 32 | TEXT2_TITLE 33 | TEXT255 34 | 0 35 | E 36 | 37 | 38 | TEXT3_TITLE 39 | TEXT255 40 | 0 41 | E 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/ztimem_theme.doma.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_THEME 7 | E 8 | CHAR 9 | 000010 10 | 000010 11 | X 12 | abapTimeMachine theme 13 | 14 | 15 | 16 | 0001 17 | E 18 | LIGHT 19 | Light 20 | 21 | 22 | 0002 23 | E 24 | DARK 25 | Dark 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/ztimem_theme.dtel.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_THEME 7 | E 8 | ZTIMEM_THEME 9 | 10 10 | 10 11 | 20 12 | 40 13 | abapTimeMachine theme 14 | Theme 15 | Theme 16 | Theme 17 | Theme 18 | E 19 | D 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/ztimem_timestamp_t.ttyp.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEM_TIMESTAMP_T 7 | E 8 | TIMESTAMP 9 | E 10 | DEC 11 | 000015 12 | T 13 | D 14 | N 15 | abapTimeMachine Timestamp list 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/ztimemachine.msag.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEMACHINE 7 | E 8 | abapBlame 9 | 10 | 11 | 12 | E 13 | ZTIMEMACHINE 14 | 000 15 | Object not found. 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/ztimemachine.prog.abap: -------------------------------------------------------------------------------- 1 | "! Takes an object type and name, calculates the blame information for the source 2 | "! code of all its parts and displays it as HTML. 3 | REPORT ztimemachine. 4 | 5 | SELECTION-SCREEN BEGIN OF BLOCK sel WITH FRAME TITLE TEXT-sel. 6 | PARAMETERS p_otype TYPE ztimem_object_type OBLIGATORY DEFAULT 'PROG' AS LISTBOX VISIBLE LENGTH 25. 7 | PARAMETERS p_name TYPE sobj_name OBLIGATORY. " TODO MATCHCODE OBJECT ztimem_object_name. 8 | SELECTION-SCREEN END OF BLOCK sel. 9 | 10 | SELECTION-SCREEN BEGIN OF BLOCK filters WITH FRAME TITLE TEXT-flt. 11 | PARAMETERS p_date TYPE datum OBLIGATORY DEFAULT sy-datum. 12 | PARAMETERS p_time TYPE uzeit OBLIGATORY DEFAULT '235959'. 13 | SELECTION-SCREEN END OF BLOCK filters. 14 | 15 | SELECTION-SCREEN BEGIN OF BLOCK mode WITH FRAME TITLE TEXT-mde. 16 | PARAMETERS p_mtimem RADIOBUTTON GROUP mode USER-COMMAND mode. 17 | PARAMETERS p_mblame RADIOBUTTON GROUP mode. 18 | SELECTION-SCREEN SKIP. 19 | SELECTION-SCREEN BEGIN OF BLOCK options WITH FRAME TITLE TEXT-opt. 20 | PARAMETERS p_iunre AS CHECKBOX. 21 | PARAMETERS p_icase AS CHECKBOX MODIF ID bla. 22 | PARAMETERS p_iinde AS CHECKBOX MODIF ID bla. 23 | SELECTION-SCREEN END OF BLOCK options. 24 | SELECTION-SCREEN END OF BLOCK mode. 25 | 26 | SELECTION-SCREEN COMMENT /1(83) link. 27 | 28 | SELECTION-SCREEN BEGIN OF SCREEN 1001. 29 | " dummy for triggering screen on Java SAP GUI 30 | SELECTION-SCREEN END OF SCREEN 1001. 31 | 32 | *SELECTION-SCREEN BEGIN OF BLOCK output WITH FRAME TITLE TEXT-out. 33 | *PARAMETERS p_theme TYPE zblame_theme AS LISTBOX VISIBLE LENGTH 15 DEFAULT 'LIGHT'. 34 | *SELECTION-SCREEN END OF BLOCK output. 35 | 36 | INITIALIZATION. 37 | IF sy-tcode CS 'BLAME'. 38 | p_mtimem = abap_false. 39 | p_mblame = abap_true. 40 | ENDIF. 41 | link = 'More details at https://github.com/abapinho/abapTimeMachine' ##NO_TEXT. 42 | NEW zcl_timem_dynpro( '1001' )->remove_toolbar( ). 43 | 44 | AT SELECTION-SCREEN OUTPUT. 45 | LOOP AT SCREEN. 46 | IF screen-group1 = 'BLA' AND p_mblame IS INITIAL. 47 | screen-active = '0'. 48 | MODIFY SCREEN. 49 | ENDIF. 50 | ENDLOOP. 51 | 52 | NEW zcl_timem_dynpro( '1001' )->hide_buttons( ). 53 | 54 | START-OF-SELECTION. 55 | " Convert radio button to mode 56 | DATA(mode) = SWITCH ztimem_mode( 57 | p_mblame 58 | WHEN abap_true THEN zcl_timem_consts=>mode-blame 59 | ELSE zcl_timem_consts=>mode-time_machine ). 60 | 61 | TRY. 62 | zcl_timem_options=>get_instance( )->set( mode = mode 63 | ignore_case = p_icase 64 | ignore_indentation = p_iinde 65 | timestamp = CONV #( |{ p_date }{ p_time }| ) 66 | ignore_unreleased = p_iunre ). 67 | NEW zcl_timem_run( )->go( object_type = p_otype 68 | object_name = p_name ). 69 | PERFORM java_gui_f3_workaround. 70 | CATCH zcx_timem INTO DATA(exc). 71 | DATA(text) = exc->get_text( ). 72 | MESSAGE text TYPE 'I' DISPLAY LIKE 'E'. 73 | ENDTRY. 74 | 75 | 76 | FORM java_gui_f3_workaround. 77 | DATA gui_type TYPE string. 78 | CALL FUNCTION 'RSAN_WB_TEST_GET_GUI_TYPE' 79 | IMPORTING 80 | e_gui_type = gui_type. 81 | IF gui_type <> 'WIN_GUI'. 82 | CALL SCREEN 9000. 83 | ENDIF. 84 | ENDFORM. 85 | 86 | *&---------------------------------------------------------------------* 87 | *& Module USER_COMMAND_9000 INPUT 88 | *&---------------------------------------------------------------------* 89 | * text 90 | *----------------------------------------------------------------------* 91 | MODULE user_command_9000 INPUT. 92 | CASE sy-ucomm. 93 | WHEN 'E' OR 'ENDE' OR 'ECAN'. 94 | LEAVE TO SCREEN 0. 95 | ENDCASE. 96 | ENDMODULE. 97 | -------------------------------------------------------------------------------- /src/ztimemachine.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEMACHINE 7 | 1 8 | * 9 | K 10 | E 11 | X 12 | X 13 | 14 | 15 | 16 |
17 | ZTIMEMACHINE 18 | 9000 19 | E 20 | HTML output 21 | N 22 | 9000 23 | 027 24 | 120 25 |
26 | 27 | 28 | SCREEN 29 | SCREEN 30 | 31 | 32 | CUST_CTRL 33 | CONTAINER 34 | SCREEN 35 | 001 36 | 001 37 | 120 38 | 027 39 | 40 | 41 | 42 | 43 | SCREEN 44 | SCREEN 45 | OKCODE 46 | OKCODE 47 | ____________________ 48 | 020 49 | 020 50 | 001 51 | CHAR 52 | X 53 | 54 | 55 | 56 | 57 | PROCESS BEFORE OUTPUT. 58 | 59 | 60 | * MODULE STATUS_9000. 61 | 62 | 63 | * 64 | 65 | 66 | PROCESS AFTER INPUT. 67 | 68 | 69 | MODULE USER_COMMAND_9000. 70 | 71 | 72 |
73 |
74 | 75 | 76 | I 77 | FLT 78 | Filters 79 | 17 80 | 81 | 82 | I 83 | MDE 84 | Output mode 85 | 21 86 | 87 | 88 | I 89 | OPT 90 | Options 91 | 18 92 | 93 | 94 | I 95 | OUT 96 | Output options 97 | 24 98 | 99 | 100 | I 101 | SEL 102 | Selection 103 | 19 104 | 105 | 106 | R 107 | ABAP Time Machine 108 | 17 109 | 110 | 111 | S 112 | P_DATE 113 | . 114 | 12 115 | D 116 | 117 | 118 | S 119 | P_ICASE 120 | Ignore case 121 | 19 122 | 123 | 124 | S 125 | P_IINDE 126 | Ignore indentation 127 | 26 128 | 129 | 130 | S 131 | P_IUNRE 132 | Ignore unreleased requests 133 | 34 134 | 135 | 136 | S 137 | P_MBLAME 138 | Blame 139 | 13 140 | 141 | 142 | S 143 | P_MTIMEM 144 | Time machine 145 | 21 146 | 147 | 148 | S 149 | P_NAME 150 | . 151 | 19 152 | D 153 | 154 | 155 | S 156 | P_OTYPE 157 | . 158 | 19 159 | D 160 | 161 | 162 | S 163 | P_TIME 164 | . 165 | 12 166 | D 167 | 168 | 169 |
170 |
171 |
172 | -------------------------------------------------------------------------------- /src/ztimemachine.tran.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTIMEMACHINE 7 | ZTIMEMACHINE 8 | 1000 9 | gA== 10 | 11 | 12 | ZTIMEMACHINE 13 | 1 14 | X 15 | X 16 | 17 | 18 | E 19 | ZTIMEMACHINE 20 | ABAP Time Machine 21 | 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------