├── SUPPORT.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── abap ├── Z_ABAPTOGIT_HEATMAP.prog.abap ├── Z_ABAPTOGIT_CATCHUPSYNC.prog.abap ├── Z_ABAPTOGIT_LOCALSYNC.prog.abap ├── ZCL_IM__BADI_ABAPTOGIT_SYNC.clas.abap ├── Z_ABAPTOGIT_SCHEDULE_JOB.prog.abap ├── ZCL_UTILITY_AUCV_RUNNER.clas.abap ├── ZCL_UTILITY_ABAPTOGIT_PCR.CLAS.abap ├── ZCL_UTILITY_AUTLISTENER.clas.abap └── ZCL_UTILITY_ABAPTOGIT_FMT.clas.abap ├── SECURITY.md ├── README.md └── .gitignore /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | ## Microsoft Support Policy 10 | 11 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 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 | -------------------------------------------------------------------------------- /abap/Z_ABAPTOGIT_HEATMAP.prog.abap: -------------------------------------------------------------------------------- 1 | *&---------------------------------------------------------------------* 2 | *& Report z_abaptogit_heatmap 3 | *&---------------------------------------------------------------------* 4 | *& Program to collect heatmap of code changes for transport requests 5 | *&---------------------------------------------------------------------* 6 | REPORT z_abaptogit_heatmap. 7 | 8 | PARAMETERS: 9 | p_pname TYPE devclass LOWER CASE OBLIGATORY, 10 | p_frdat TYPE d OBLIGATORY, 11 | p_todat TYPE d OBLIGATORY, 12 | p_file TYPE string OBLIGATORY. 13 | 14 | START-OF-SELECTION. 15 | 16 | PERFORM f_heatmap. 17 | 18 | FORM f_heatmap. 19 | WRITE / |Start heatmap at { sy-uzeit }|. 20 | DATA lo_pcrsch TYPE REF TO ZCL_HRPY_UTILITY_ABAPTOGIT_PCR. 21 | DATA lo_abaptogit TYPE REF TO ZCL_HRPY_UTILITY_ABAPTOGIT. 22 | CREATE OBJECT lo_pcrsch. 23 | CREATE OBJECT lo_abaptogit 24 | EXPORTING 25 | io_objpcrsch = lo_pcrsch 26 | iv_methpcrschall = 'GET_HR_SCHEMAPCRS' 27 | iv_methpcrschcnt = 'BUILD_PCRSCHEMA_CONTENT'. 28 | DATA lv_pname TYPE string. 29 | lv_pname = p_pname. 30 | lo_abaptogit->heatmap_trs( 31 | EXPORTING 32 | iv_packagenames = lv_pname 33 | iv_fromdat = p_frdat 34 | iv_todat = p_todat 35 | iv_resultfile = p_file 36 | ). 37 | WRITE / |Finish heatmap at { sy-uzeit }|. 38 | ENDFORM. -------------------------------------------------------------------------------- /abap/Z_ABAPTOGIT_CATCHUPSYNC.prog.abap: -------------------------------------------------------------------------------- 1 | *&---------------------------------------------------------------------* 2 | *& Report z_abaptogit_catchupsync 3 | *&---------------------------------------------------------------------* 4 | *& Program to catch up transport requests of ABAP objects for a system 5 | *& to Git repo 6 | *& this is to ensure the Git sync continuous after a break. 7 | *& we will save the last successfully synced tr # in the local config file. 8 | *&---------------------------------------------------------------------* 9 | REPORT z_abaptogit_catchupsync. 10 | 11 | parameters: 12 | " package name(s) split by comma 13 | p_pname type devclass LOWER CASE OBLIGATORY, 14 | " ADO organization name 15 | p_orgid type string LOWER CASE OBLIGATORY, 16 | " ADO project name 17 | p_proj type string LOWER CASE OBLIGATORY, 18 | " ADO Git repo GUID ID 19 | p_repoid type string LOWER CASE OBLIGATORY, 20 | " Git branch name prefix 21 | p_prefix type string LOWER CASE DEFAULT 'users/system/' OBLIGATORY, 22 | " ADO user name 23 | p_usrnam type string LOWER CASE OBLIGATORY, 24 | " ADO personal access token 25 | p_pat type string LOWER CASE OBLIGATORY, 26 | " Folder structure 27 | p_struct TYPE string DEFAULT 'eclipse' LOWER CASE OBLIGATORY, 28 | " Email domain 29 | p_domain TYPE string DEFAULT '' LOWER CASE. 30 | 31 | START-OF-SELECTION. 32 | 33 | PERFORM f_catchup. 34 | 35 | FORM f_catchup. 36 | WRITE / |Start catchup at { sy-uzeit }|. 37 | DATA lo_abaptogit TYPE REF TO ZCL_UTILITY_ABAPTOGIT. 38 | CREATE OBJECT lo_abaptogit. 39 | lo_abaptogit->setup_ado( 40 | EXPORTING 41 | iv_username = p_usrnam 42 | iv_pat = p_pat 43 | iv_orgid = p_orgid 44 | iv_repoid = p_repoid 45 | iv_project = p_proj 46 | ). 47 | DATA lv_branch TYPE string. 48 | lo_abaptogit->prepare_landscape_branch( EXPORTING iv_prefix = p_prefix IMPORTING ev_branch = lv_branch ). 49 | DATA lv_pname TYPE string. 50 | lv_pname = p_pname. 51 | lo_abaptogit->catchup_trs( 52 | EXPORTING 53 | iv_branch = lv_branch 54 | iv_packagenames = lv_pname 55 | iv_domain = p_domain 56 | iv_folder_structure = p_struct 57 | ). 58 | WRITE / |Finish catchup at { sy-uzeit }|. 59 | ENDFORM. -------------------------------------------------------------------------------- /abap/Z_ABAPTOGIT_LOCALSYNC.prog.abap: -------------------------------------------------------------------------------- 1 | *&---------------------------------------------------------------------* 2 | *& Report z_abaptogit_localsync 3 | *&---------------------------------------------------------------------* 4 | *& Program to download source code or statistics of ABAP objects for a system 5 | *& in given package(s) to file(s) on your local disk. 6 | *&---------------------------------------------------------------------* 7 | REPORT z_abaptogit_localsync. 8 | 9 | PARAMETERS: 10 | " package name(s) split by comma 11 | p_pname TYPE devclass LOWER CASE OBLIGATORY, 12 | " local folder to save downloaded ABAP object code files 13 | p_folder TYPE string OBLIGATORY, 14 | " Sync mode: active/latest 15 | p_mode TYPE string DEFAULT 'latest' LOWER CASE OBLIGATORY, 16 | " TR ID to sync up to, if blank sync to default latest version 17 | p_uttrid TYPE string LOWER CASE, 18 | " Folder structure 19 | p_struct TYPE string DEFAULT 'eclipse' LOWER CASE OBLIGATORY, 20 | " Download PCR/schame 21 | p_pcrsch AS CHECKBOX DEFAULT 'X'. 22 | 23 | START-OF-SELECTION. 24 | 25 | PERFORM f_download. 26 | 27 | FORM f_download. 28 | 29 | WRITE / |Sync mode { p_mode }|. 30 | WRITE / |Start download at { sy-uzeit }|. 31 | 32 | DATA lo_pcrsch TYPE REF TO ZCL_HRPY_UTILITY_ABAPTOGIT_PCR. 33 | DATA lo_abaptogit TYPE REF TO ZCL_HRPY_UTILITY_ABAPTOGIT. 34 | CREATE OBJECT lo_pcrsch. 35 | CREATE OBJECT lo_abaptogit 36 | EXPORTING 37 | io_objpcrsch = lo_pcrsch 38 | iv_methpcrschall = 'GET_HR_SCHEMAPCRS' 39 | iv_methpcrschcnt = 'BUILD_PCRSCHEMA_CONTENT'. 40 | 41 | IF p_pcrsch = 'X'. 42 | " schema/PCR has no old versions kept thus up-to TR ID not applicable 43 | lo_abaptogit->get_hr_schemapcrs( 44 | EXPORTING 45 | iv_folder = p_folder 46 | iv_folder_structure = p_struct 47 | ). 48 | ENDIF. 49 | 50 | " source code and data table schema download 51 | DATA lv_packages TYPE string. 52 | lv_packages = p_pname. 53 | IF p_uttrid IS INITIAL. 54 | lo_abaptogit->get_packages_codes( 55 | EXPORTING 56 | iv_packages = lv_packages 57 | iv_folder = p_folder 58 | iv_mode = p_mode 59 | iv_folder_structure = p_struct 60 | ). 61 | ELSE. 62 | lo_abaptogit->get_packages_codes( 63 | EXPORTING 64 | iv_packages = lv_packages 65 | iv_folder = p_folder 66 | iv_mode = p_mode 67 | iv_uptotrid = p_uttrid 68 | iv_folder_structure = p_struct 69 | ). 70 | ENDIF. 71 | 72 | WRITE / |Finish download at { sy-uzeit }|. 73 | 74 | ENDFORM. -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /abap/ZCL_IM__BADI_ABAPTOGIT_SYNC.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_im__badi_abaptogit_sync DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES if_ex_cts_request_check . 9 | 10 | PROTECTED SECTION. 11 | 12 | PRIVATE SECTION. 13 | 14 | METHODS perform_spotsync_abaptogit 15 | IMPORTING 16 | iv_package_names TYPE string 17 | iv_trid TYPE trkorr. 18 | ENDCLASS. 19 | 20 | CLASS zcl_im__badi_abaptogit_sync IMPLEMENTATION. 21 | 22 | 23 | METHOD if_ex_cts_request_check~check_before_add_objects. 24 | ENDMETHOD. 25 | 26 | 27 | METHOD if_ex_cts_request_check~check_before_changing_owner. 28 | ENDMETHOD. 29 | 30 | 31 | METHOD if_ex_cts_request_check~check_before_creation. 32 | ENDMETHOD. 33 | 34 | 35 | METHOD if_ex_cts_request_check~check_before_release. 36 | 37 | TYPES: 38 | ty_devclass TYPE STANDARD TABLE OF devclass WITH DEFAULT KEY, 39 | ty_list_string TYPE STANDARD TABLE OF string WITH DEFAULT KEY. 40 | 41 | DATA lv_package_names TYPE string. 42 | 43 | " sync only when workbench/customizing request is to release 44 | DATA(lt_eligible_tr_types) = VALUE ty_list_string( ( `K` ), ( `W` ) ). 45 | 46 | TRY. 47 | " Check if workbench/customizing transport request type 48 | IF NOT line_exists( lt_eligible_tr_types[ table_line = type ] ). 49 | EXIT. 50 | ENDIF. 51 | 52 | " no simple way to find out package an ABAP object belongs, leave to abap2git to determine 53 | 54 | " TODO: specify package names to sync ABAP objects in a TR 55 | DATA: lt_package_list TYPE ty_devclass. 56 | 57 | CONCATENATE LINES OF lt_package_list INTO lv_package_names SEPARATED BY ','. 58 | me->perform_spotsync_abaptogit( iv_package_names = lv_package_names iv_trid = request ). 59 | 60 | CATCH cx_root INTO DATA(lx_root). 61 | 62 | ENDTRY. 63 | ENDMETHOD. 64 | 65 | 66 | METHOD if_ex_cts_request_check~check_before_release_slin. 67 | ENDMETHOD. 68 | 69 | METHOD perform_spotsync_abaptogit. 70 | 71 | " Be noted that this BAdI is called BEFORE a transport request is released, 72 | " the request may not be able to release after the BAdI, due to many reasons 73 | " say containing unreleased task, failed ATC unit tests, failed virtual forge checks, etc. 74 | " It's unsafe to call abap2git for spot sync directly here, 75 | " Suggested option is to start a background job after a while (say 15~60 seconds) 76 | " to run program calling the abap2git class method with following code example, 77 | " abap2git class method will check whether the transport request is released upon sync-ing. 78 | " However due to background job delay, race condition may happen among multiple transport 79 | " requests occur in a short time so that background job(s) for earlier transport requests 80 | " may start later than the one(s) for later transport requests and consequently mess up 81 | " the Git commit history, esp. when these transport requests contain changes to the same 82 | " SAP objects. Additional queuing logic is required to sequentially line up these background 83 | " jobs and it's not provided by abap2git. Check out FAQ.md for more details on options. 84 | 85 | " TODO: wrap following code snippets into a background job 86 | 87 | " TODO: specify organization for ADO REST API 88 | DATA lv_orgid TYPE string. 89 | 90 | " TODO: specify Git repository ID for ADO REST API 91 | DATA lv_repoid TYPE string. 92 | 93 | " TODO: specify project name for ADO REST API 94 | DATA lv_project TYPE string. 95 | 96 | " TODO: specify the Git branch name prefix, usually users/system/, 97 | " for the branch holding the ABAP objects 98 | DATA lv_baseprefix TYPE string. 99 | 100 | " TODO: specify user name for ADO REST API 101 | DATA lv_username TYPE string. 102 | 103 | " TODO: specify personal access token of the user name above for ADO REST API 104 | DATA lv_pat TYPE string. 105 | 106 | DATA lo_abaptogit TYPE REF TO zcl_utility_abaptogit. 107 | CREATE OBJECT lo_abaptogit. 108 | lo_abaptogit->setup_ado( 109 | EXPORTING 110 | iv_username = lv_username 111 | iv_pat = lv_pat 112 | iv_orgid = lv_orgid 113 | iv_repoid = lv_repoid 114 | iv_project = lv_project 115 | ). 116 | DATA lv_trid TYPE string. 117 | lv_trid = iv_trid. 118 | lo_abaptogit->spotsync_tr( 119 | EXPORTING 120 | iv_trid = lv_trid 121 | iv_packagenames = iv_package_names 122 | iv_prefix = lv_baseprefix 123 | ). 124 | 125 | ENDMETHOD. 126 | 127 | ENDCLASS. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abap2git 2 | 3 | **abap2git** is a simplified sync tool written in ABAP code to one-way sync ABAP and configuration objects from an SAP system to Git repository with Azure DevOps REST API with following benefits: 4 | * Support multiple packages in a Git branch, packages don't have to be super package of one another 5 | * Support multiple SAP systems in the same Git repo, each in their respective branches, fit for code review the diffs across systems in the landscape 6 | * Sync ABAP objects in an active/released workbench/customizing/transport of copies transport request (shortened as TR below) to specific Git branch 7 | * Support configuration changes in customizing TR for 1380 object types specified in OBJH table and object types like TABU/CDAT/VDAT/TDAT 8 | * Support HR/Payroll schemas/personnel calculation rules (PCR) in customizing TR 9 | * The sync for the TR only accesses the objects contained in TR object list and not other unchanged ones, fit for code review the diffs 10 | 11 | ## Features 12 | 1. Download ABAP objects in specific package(s) of an SAP system to local folder, each package a folder. 13 | 2. Download ABAP objects in all Y*/Z* customization packages to local folder. 14 | 3. Support active version mode and latest version mode. In active version mode, for each ABAP object, active version, if any, otherwise latest version, will be downloaded; in latest version mode, for each ABAP object, only latest version will be downloaded or a released version no later than an optional released TR (to sync to that specific snapshot of the system), if not available the object will not be downloaded. Active version mode is best to download all current version of the ABAP objects for code inspection and analysis; latest version mode is best for continuous integration purpose. 15 | 4. Sync a specific released TR to specific Git repo branch, provided the ABAP objects in that branch are downloaded in latest version mode above. 16 | 5. Catchup: sync the Git repo branch to latest TR by generating commit for each TR between last sync-ed one and latest one, this helps you bring the git repo in sync. 17 | 18 | ## How To 19 | * Add the classes and reports in abap folder to the target SAP system. 20 | * Create a branch for target SAP system in the Git repository, suggested branch name is "users/system/system id", for example, users/system/sy1. 21 | * Run the report Z_ABAPTOGIT_LOCALSYNC to download initial ABAP objects with active or latest version mode. 22 | * Use git command/CLI/... to push the initial objects. 23 | * Run the report Z_ABAPTOGIT_CATCHUPSYNC to "catch up" the TRs as mentioned in feature #5. 24 | 25 | ## FAQ 26 | ### Why is BAdI CTS_REQUEST_CHECK~CHECK_BEFORE_RELEASE not a good place to sync code to Azure DevOps? 27 | The BAdI class is called before releasing the TR, the release process may fail afterwards due to many reasons, containing unreleased tasks, failed ATC rules, failed virtual forge checks, failed ATC unit tests, etc., then the request will end up with unreleased state, in this case the request is not supposed to sync to Git. 28 | 29 | ### Why use background job to call abap2git? 30 | Given the BAdI above with improper timing to sync to Git, scheduled background job with delay would be a solution to ensure the TR release process is completed when the job starts. 31 | 32 | ### What if ABAP developer doesn't have the privilege to schedule background job in SAP? 33 | Contact security team to add a customized role with authorize objects required to schedule job and have ABAP developer apply for that role. 34 | 35 | ### What if security cannot approve customized role for scheduling background job? 36 | Check out next question for options and pros/cons. 37 | 38 | ### What are the options and pros/cons for background job solution? 39 | 1. In BAdI class schedule background job to call abap2git spot sync method. The pros is the short turnaround time between TR release and Git sync, which ensures rapid continuous integration right after TR. The cons are privilege needed to schedule background job, and the race condition upon multiple TRs released in short time causing earlier TR got sync after later TR due to uncertain start time of their corresponding background jobs. A sequential queuing mechanism is required to eliminate this race condition and it's not provided by abap2git. 40 | 2. In BAdI class schedule background job but manage a time window (say 1 hour) that only one job is scheduled within the window. Also requires background job privilege. This reduces but doesn't eliminate the race condition given the events (TR is acutally released; abap2git checks if that TR is in released status) may race when the events happen at the time window boundary. Worst case a TR is not sync-ed when there's no further TR followed. 41 | 3. Use SM36 to schedule recurring background job in specific frequency which fetches configurations/secrets (ADO PAT) and calls Z_ABAPTOGIT_CATCHUPSYNC program catching up released TRs since last sync. This is best but relies on your security/BASIS policy. 42 | 4. Use Z_ABAPTOGIT_SCHEDULE_JOB program to schedule 28 days \* 24 jobs (1 per hour) at a time, requiring a developer with background job privilege to run it every 4 weeks. This doesn't require all ABAP developers with the privilege. 43 | 44 | ### Why configuration changes look the same across multiple Git commits? 45 | Currently configuration changes in a specific data table are captured with current data rows in the table when the TR is sync-ed, thus if multiple TRs are sync-ed in catching up or changes are made before catching up, the configuration changes captured for the TRs will be the same and don't reflect the actual changes released by the TR. Future release of abap2git will attempt to fetch the actual changes from audit log or TR export file. 46 | 47 | ## Contributing 48 | 49 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 50 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 51 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 52 | 53 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 54 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 55 | provided by the bot. You will only need to do this once across all repos using our CLA. 56 | 57 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 58 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 59 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 60 | 61 | ## Trademarks 62 | 63 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 64 | trademarks or logos is subject to and must follow 65 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 66 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 67 | Any use of third-party trademarks or logos are subject to those third-party's policies. 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /abap/Z_ABAPTOGIT_SCHEDULE_JOB.prog.abap: -------------------------------------------------------------------------------- 1 | *&---------------------------------------------------------------------* 2 | *& Report z_abaptogit_schedule_job 3 | *&---------------------------------------------------------------------* 4 | *& This program will schedule job based on how many days in advance 5 | *& and what the interval in hours you want to schedule the job 6 | *& for example co_schedule_days is 1 days in advance 7 | *& and co_interval_in_hour is 1. It means we will schedule a job to run every hour 8 | *& in next 24 hours(1 day) 9 | *&---------------------------------------------------------------------* 10 | REPORT z_abaptogit_schedule_job. 11 | 12 | " TODO: specify organization for ADO REST API 13 | DATA lv_orgid TYPE string. 14 | 15 | " TODO: specify Git repository ID for ADO REST API 16 | DATA lv_repoid TYPE string. 17 | 18 | " TODO: specify project name for ADO REST API 19 | DATA lv_project TYPE string. 20 | 21 | " TODO: specify the Git branch name prefix, usually users/system/, 22 | " for the branch holding the ABAP objects 23 | DATA lv_baseprefix TYPE string. 24 | 25 | " TODO: specify user name for ADO REST API 26 | DATA lv_username TYPE string. 27 | 28 | " TODO: specify personal access token of the user name above for ADO REST API 29 | DATA lv_pat TYPE string. 30 | 31 | CONSTANTS co_interval_in_hour TYPE i VALUE 1. 32 | CONSTANTS co_times_in_one_day TYPE i VALUE 24. 33 | CONSTANTS co_schedule_days TYPE i VALUE 28. " 4 weeks 4 * 7 = 28 34 | 35 | TYPES : BEGIN OF schedule, 36 | sdate TYPE btcsdate, 37 | stime TYPE t, 38 | END OF schedule. 39 | 40 | DATA: 41 | gv_package_names TYPE string, 42 | gt_values_tab TYPE zvales_tab, 43 | gv_orgid TYPE string, 44 | gv_repoid TYPE string, 45 | gv_project TYPE string, 46 | gv_baseprefix TYPE string, 47 | gv_username TYPE string, 48 | gv_pat TYPE string. 49 | 50 | PERFORM f_initiliaztion. 51 | PERFORM f_main. 52 | 53 | FORM f_main. 54 | DATA lv_query TYPE string. 55 | DATA lv_current_time_string(6) TYPE c. 56 | DATA lv_start_time_string(6) TYPE c. 57 | DATA lv_two_day_ago TYPE sy-datum. 58 | DATA lv_system_date TYPE btcsdate. 59 | DATA lv_system_time TYPE btcstime. 60 | DATA lv_schedule_hour_str(2) TYPE c. 61 | DATA lv_start_time TYPE i. 62 | DATA lv_start_time_offset TYPE i. 63 | DATA lv_start_date_offset TYPE i. 64 | 65 | DATA lv_scheduled_time TYPE t. 66 | DATA lv_scheduled_date TYPE btcsdldate. 67 | DATA: 68 | wa_schedule TYPE schedule, 69 | itab TYPE TABLE OF schedule. 70 | 71 | lv_system_date = sy-datum. 72 | lv_system_time = sy-uzeit. 73 | 74 | DATA(lv_loop_times) = co_times_in_one_day / co_interval_in_hour * co_schedule_days + 1. 75 | 76 | DO lv_loop_times TIMES. 77 | " Calculate scheduled time 78 | lv_current_time_string = lv_system_time. 79 | CONCATENATE lv_current_time_string(2) '0000' INTO lv_start_time_string. 80 | lv_start_time = lv_current_time_string(2). 81 | 82 | lv_start_time_offset = ( lv_start_time + ( sy-index - 1 ) * co_interval_in_hour ) MOD 24. 83 | UNPACK lv_start_time_offset TO lv_schedule_hour_str. " 0 to 00 84 | CONCATENATE lv_schedule_hour_str '0000' INTO lv_scheduled_time. 85 | 86 | " Calculate scheduled date 87 | lv_start_date_offset = ( lv_start_time + ( sy-index - 1 ) * co_interval_in_hour ) DIV 24. 88 | lv_scheduled_date = lv_system_date + lv_start_date_offset. 89 | 90 | wa_schedule-sdate = lv_scheduled_date. 91 | wa_schedule-stime = lv_scheduled_time. 92 | 93 | APPEND wa_schedule TO itab. 94 | ENDDO. 95 | 96 | lv_two_day_ago = sy-datum - 2. 97 | 98 | SELECT sdlstrtdt, sdlstrttm 99 | FROM tbtco 100 | WHERE status = 'S' " S is released 101 | AND jobname = @co_title 102 | AND sdlstrtdt > @lv_two_day_ago 103 | ORDER BY sdlstrtdt DESCENDING, sdlstrttm DESCENDING 104 | INTO @DATA(ws_job) 105 | UP TO 1 ROWS. 106 | ENDSELECT. 107 | 108 | " If there is job exists 109 | IF ws_job-sdlstrtdt IS NOT INITIAL AND ws_job-sdlstrttm IS NOT INITIAL. 110 | DELETE itab WHERE ( sdate < ws_job-sdlstrtdt OR ( sdate = ws_job-sdlstrtdt AND stime <= ws_job-sdlstrttm ) ). 111 | ENDIF. 112 | 113 | LOOP AT itab INTO DATA(schedule_item). 114 | PERFORM schedule_catchup_abaptogit 115 | USING schedule_item-sdate 116 | schedule_item-stime 117 | gv_package_names 118 | gv_orgid 119 | gv_project 120 | gv_repoid 121 | gv_baseprefix 122 | gv_username 123 | gv_pat. 124 | ENDLOOP. 125 | WRITE:/ | Successful Scheduled { lines( itab ) } jobs |. 126 | ENDFORM. 127 | 128 | " TODO: Initiliaze required variables 129 | FORM f_initiliaztion. 130 | " TODO: specify organization for ADO REST API 131 | lv_orgid = "". 132 | " TODO: specify Git repository ID for ADO REST API 133 | lv_repoid = "". 134 | 135 | " TODO: specify project name for ADO REST API 136 | lv_project = "". 137 | 138 | " TODO: specify the Git branch name prefix, usually users/system/, 139 | " for the branch holding the ABAP objects 140 | lv_baseprefix = "". 141 | 142 | " TODO: specify user name for ADO REST API 143 | lv_username = "". 144 | 145 | " TODO: specify personal access token of the user name above for ADO REST API 146 | lv_pat = "". 147 | ENDFORM. 148 | 149 | FORM schedule_catchup_abaptogit USING iv_schedule_date TYPE btcsdldate 150 | iv_schedule_time TYPE t 151 | iv_package_names TYPE string 152 | iv_orgid TYPE string 153 | iv_project TYPE string 154 | iv_repoid TYPE string 155 | iv_baseprefix TYPE string 156 | iv_username TYPE string 157 | iv_pat TYPE string. 158 | DATA: 159 | lv_system_date TYPE btcsdate, 160 | lv_system_time TYPE btcstime, 161 | lv_jobname TYPE btcjob, 162 | lv_jobcount TYPE btcjobcnt. 163 | 164 | lv_jobname = co_title. 165 | 166 | CALL FUNCTION 'JOB_OPEN' 167 | EXPORTING 168 | jobname = lv_jobname 169 | sdlstrtdt = sy-datum 170 | sdlstrttm = sy-uzeit 171 | IMPORTING 172 | jobcount = lv_jobcount 173 | EXCEPTIONS 174 | cant_create_job = 1 175 | invalid_job_data = 2 176 | jobname_missing = 3 177 | OTHERS = 4. 178 | 179 | IF sy-subrc <> 0. 180 | WRITE:/ 'Error Opening job : ', lv_jobname. 181 | EXIT. 182 | ENDIF. 183 | 184 | SUBMIT z_abaptogit_catchupsync VIA JOB lv_jobname 185 | NUMBER lv_jobcount 186 | WITH p_pname = iv_package_names 187 | WITH p_orgid = iv_orgid 188 | WITH p_proj = iv_project 189 | WITH p_repoid = iv_repoid 190 | WITH p_prefix = iv_baseprefix 191 | WITH p_usrnam = iv_username 192 | WITH p_pat = iv_pat 193 | AND RETURN. 194 | IF sy-subrc <> 0. 195 | WRITE:/ |Error on submitting job : { lv_jobname }, number { lv_jobcount }, schedule date : { iv_schedule_date }, schedule time { iv_schedule_time }|. 196 | EXIT. 197 | ENDIF. 198 | 199 | 200 | CALL FUNCTION 'JOB_CLOSE' 201 | EXPORTING 202 | jobcount = lv_jobcount 203 | jobname = lv_jobname 204 | sdlstrtdt = iv_schedule_date 205 | sdlstrttm = iv_schedule_time 206 | EXCEPTIONS 207 | cant_start_immediate = 1 208 | invalid_startdate = 2 209 | jobname_missing = 3 210 | job_close_failed = 4 211 | job_nosteps = 5 212 | job_notex = 6 213 | lock_failed = 7 214 | OTHERS = 8. 215 | 216 | IF sy-subrc <> 0. 217 | WRITE:/ |Error on Closing job : { lv_jobname }, number { lv_jobcount }, schedule date : { iv_schedule_date }, schedule time { iv_schedule_time }|. 218 | EXIT. 219 | ENDIF. 220 | ENDFORM. -------------------------------------------------------------------------------- /abap/ZCL_UTILITY_AUCV_RUNNER.clas.abap: -------------------------------------------------------------------------------- 1 | " Utility class to execute ABAP Unit Test (AUT) suite and collect code coverage 2 | " OOB program RS_AUCV_RUNNER either reports unit test result and code coverage in IDE 3 | " or sends email with unit test result only, SCI rule ABAP Unit runs unit tests only 4 | " without code coverage reported 5 | " This class works together with abap2git to fetch allowed list in Git repo file defining 6 | " classes with real harmless test class testing system-to-test without read/write access to SAP 7 | " data thus stable enough to repetitively run agnostic to SAP data updates by other engineers 8 | " and configuration changes. It produces result structure with unit test results and 9 | " statement/procedure/branch code coverage like OOB offerings so that one could further 10 | " report with customized email format, dump to storage or display UI with customized outlook 11 | CLASS ZCL_UTILITY_AUCV_RUNNER DEFINITION 12 | PUBLIC 13 | FINAL 14 | CREATE PUBLIC . 15 | 16 | PUBLIC section. 17 | 18 | " test and code coverage result of a unit test run 19 | TYPES: BEGIN OF ts_method_result, 20 | name TYPE string, 21 | pass TYPE abap_bool, 22 | text TYPE string, 23 | END OF ts_method_result. 24 | TYPES: tty_method_result TYPE TABLE OF ts_method_result WITH KEY name. 25 | TYPES: BEGIN OF ts_test_result, 26 | name TYPE string, 27 | sut TYPE string, 28 | total TYPE i, 29 | pass TYPE i, 30 | fail TYPE i, 31 | methods TYPE tty_method_result, 32 | END OF ts_test_result. 33 | TYPES: tty_test_result TYPE TABLE OF ts_test_result WITH KEY name. 34 | TYPES: BEGIN OF ts_statement, 35 | start_line TYPE i, 36 | start_column TYPE i, 37 | end_line TYPE i, 38 | end_column TYPE i, 39 | hit TYPE abap_bool, 40 | END OF ts_statement. 41 | TYPES: tty_statement TYPE TABLE OF ts_statement WITH KEY start_line start_column. 42 | TYPES: BEGIN OF ts_cov_method_result, 43 | name TYPE string, 44 | total TYPE i, 45 | hit TYPE i, 46 | miss TYPE i, 47 | percent TYPE DECFLOAT16, 48 | statements TYPE tty_statement, 49 | END OF ts_cov_method_result. 50 | TYPES: tty_cov_method_result TYPE TABLE OF ts_cov_method_result WITH KEY name. 51 | TYPES: BEGIN OF ts_cov_result, 52 | name TYPE string, 53 | total TYPE i, 54 | hit TYPE i, 55 | miss TYPE i, 56 | percent TYPE DECFLOAT16, 57 | methods TYPE tty_cov_method_result, 58 | END OF ts_cov_result. 59 | TYPES: tty_cov_result TYPE TABLE OF ts_cov_result WITH KEY name. 60 | TYPES: BEGIN OF ts_aucv_result, 61 | tests TYPE tty_test_result, 62 | brancovs TYPE tty_cov_result, 63 | proccovs TYPE tty_cov_result, 64 | stmtcovs TYPE tty_cov_result, 65 | startdat TYPE string, 66 | starttim TYPE string, 67 | stopdat TYPE string, 68 | stoptim TYPE string, 69 | END OF ts_aucv_result. 70 | 71 | " allow class list as system-to-test 72 | TYPES: tty_allowed_classes TYPE STANDARD TABLE OF string WITH DEFAULT KEY. 73 | 74 | " run specific classes' unit tests specified by Git repo file 75 | " iv_branch - Git branch following abap2git protocol 76 | " iv_username - VSO user name as email address 77 | " iv_pat - VSO personal access token, could be generated from VSO portal per user with code change permission 78 | " iv_orgid - organization ID, like the name "org" in .visualstudio.com 79 | " iv_repoid - Git repo ID 80 | " iv_project - project name in your VSO portal 81 | " ev_result - unit test and code coverage result of the test run 82 | CLASS-METHODS run_with_listfile 83 | IMPORTING 84 | iv_branch TYPE string 85 | iv_username TYPE string 86 | iv_pat TYPE string 87 | iv_orgid TYPE string 88 | iv_repoid TYPE string 89 | iv_project TYPE string 90 | EXPORTING 91 | ev_result TYPE ts_aucv_result. 92 | 93 | " run specific classes' unit tests specified by internal table 94 | " it_allowlist - allowed class names to run unit tests 95 | " ev_result - unit test and code coverage result of the test run 96 | CLASS-METHODS run_with_list 97 | IMPORTING 98 | it_allowlist TYPE tty_allowed_classes 99 | EXPORTING 100 | ev_result TYPE ts_aucv_result. 101 | 102 | PROTECTED section. 103 | 104 | PRIVATE section. 105 | 106 | " Git repo file for AUT run settings 107 | CONSTANTS co_runsettings TYPE string VALUE '/nonSap/tools/aut.runsettings.json'. 108 | 109 | " AUT run settings JSON format 110 | TYPES: BEGIN OF ty_runsettings, 111 | allowed_classes TYPE tty_allowed_classes, 112 | END OF ty_runsettings. 113 | 114 | " fetch run settings file content from ADO 115 | CLASS-METHODS get_runsettings 116 | IMPORTING 117 | iv_branch TYPE string 118 | iv_username TYPE string 119 | iv_pat TYPE string 120 | iv_orgid TYPE string 121 | iv_repoid TYPE string 122 | iv_project TYPE string 123 | EXPORTING 124 | ev_runsettings TYPE ty_runsettings 125 | RETURNING VALUE(rv_success) TYPE string. 126 | 127 | " fetch method code coverage metrics 128 | CLASS-METHODS get_methods_coverage 129 | IMPORTING 130 | ioref_Coverage_Result TYPE REF TO if_Scv_Result 131 | EXPORTING 132 | et_methods TYPE tty_cov_method_result. 133 | 134 | ENDCLASS. 135 | 136 | CLASS ZCL_UTILITY_AUCV_RUNNER IMPLEMENTATION. 137 | 138 | METHOD RUN_WITH_LISTFILE. 139 | 140 | DATA ls_runsettings TYPE ty_runsettings. 141 | DATA lv_result TYPE string. 142 | 143 | " fetch unit test run settings from Git branch 144 | lv_result = GET_RUNSETTINGS( 145 | EXPORTING 146 | iv_branch = iv_branch 147 | iv_username = iv_username 148 | iv_pat = iv_pat 149 | iv_orgid = iv_orgid 150 | iv_repoid = iv_repoid 151 | iv_project = iv_project 152 | IMPORTING 153 | ev_runsettings = ls_runsettings 154 | ). 155 | CHECK lv_result = abap_true. 156 | 157 | run_with_list( 158 | EXPORTING 159 | it_allowlist = ls_runsettings-allowed_classes 160 | IMPORTING 161 | ev_result = ev_result 162 | ). 163 | 164 | ENDMETHOD. 165 | 166 | METHOD RUN_WITH_LIST. 167 | 168 | DATA lt_classes TYPE RANGE OF seoaliases-clsname. 169 | DATA oref_listener TYPE REF TO ZCL_UTILITY_AUTLISTENER. 170 | DATA lt_programs TYPE ZCL_UTILITY_AUTLISTENER=>ty_programs. 171 | DATA lt_syntax_errors TYPE ZCL_UTILITY_AUTLISTENER=>ty_syntax_errors. 172 | DATA oref_au_factory TYPE REF TO cl_aunit_factory. 173 | DATA oref_task TYPE REF TO cl_Aucv_Task. 174 | DATA lv_converted_Key TYPE cl_Aucv_Task=>ty_Object_Directory_Element. 175 | DATA lt_converted_Keys TYPE cl_Aucv_Task=>ty_Object_Directory_Elements. 176 | DATA oref_Coverage_Measurement TYPE REF TO if_Scv_Measurement. 177 | DATA oref_Coverage_Result TYPE REF TO if_Scv_Result. 178 | DATA lv_class TYPE string. 179 | DATA lv_cov_name TYPE string. 180 | DATA lt_coverages TYPE IF_SCV_COVERAGE=>TAB. 181 | DATA oref_coverage TYPE REF TO if_scv_coverage. 182 | DATA lv_cov_id TYPE string. 183 | DATA lv_coverage TYPE ts_cov_result. 184 | DATA lt_stats TYPE ZCL_UTILITY_AUTLISTENER=>ty_statistics. 185 | DATA lv_testclass TYPE ts_test_result. 186 | DATA lv_method TYPE ts_method_result. 187 | 188 | FIELD-SYMBOLS: 189 | TYPE ZCL_UTILITY_AUTLISTENER=>ty_program, 190 | TYPE ZCL_UTILITY_AUTLISTENER=>ty_test_class, 191 | TYPE ZCL_UTILITY_AUTLISTENER=>ty_test_method. 192 | 193 | " prepare for listener program list 194 | LOOP AT it_allowlist INTO lv_class. 195 | APPEND VALUE #( sign = 'I' option = 'EQ' low = lv_class ) TO lt_classes. 196 | ENDLOOP. 197 | 198 | " query class objects from allow list 199 | SELECT ##TOO_MANY_ITAB_FIELDS 200 | object as obj_type "#EC CI_GENBUFF 201 | obj_name 202 | devclass as package 203 | FROM tadir 204 | APPENDING CORRESPONDING FIELDS OF TABLE lt_programs 205 | WHERE 206 | pgmid = 'R3TR' AND 207 | object = 'CLAS' AND 208 | obj_name in lt_classes. 209 | 210 | " look up test class for each system-to-test class 211 | LOOP AT lt_programs ASSIGNING . 212 | -name = cl_aunit_prog_info=>tadir_to_progname( 213 | obj_type = -obj_type 214 | obj_name = -obj_name 215 | ). 216 | ENDLOOP. 217 | 218 | " create unit test result listener 219 | CREATE OBJECT oref_au_factory. 220 | oref_listener = ZCL_UTILITY_AUTLISTENER=>create_listener( 221 | i_programs = lt_programs 222 | i_syntax_errors = lt_syntax_errors 223 | i_au_factory = oref_au_factory 224 | ). 225 | 226 | " prepare for unit test run task 227 | oref_task = cl_Aucv_Task=>create( 228 | i_Listener = oref_listener 229 | i_Measure_Coverage = abap_true 230 | i_Max_Risk_Level = 11 231 | i_Max_Duration_Category = 12 232 | ). 233 | 234 | LOOP AT it_allowlist INTO lv_class. 235 | lv_converted_key-object = 'CLAS'. 236 | lv_converted_key-obj_Name = lv_class. 237 | APPEND lv_converted_key TO lt_converted_Keys. 238 | ENDLOOP. 239 | 240 | oref_task->add_Associated_unit_Tests( lt_converted_Keys ). 241 | 242 | " execute unit tests 243 | oref_task->run( if_Aunit_Task=>c_Run_Mode-catch_Short_Dump ). 244 | 245 | " collect code coverage result 246 | TRY. 247 | 248 | oref_Coverage_Measurement = oref_task->get_coverage_measurement( ). 249 | 250 | LOOP AT lt_programs ASSIGNING . 251 | oref_Coverage_Result = oref_Coverage_Measurement->build_program_result( -name ). 252 | lv_cov_name = -obj_name. 253 | lt_coverages = oref_Coverage_Result->get_coverages( ). 254 | LOOP AT lt_coverages INTO oref_coverage. 255 | CLEAR lv_coverage. 256 | lv_coverage-name = lv_cov_name. 257 | lv_coverage-total = oref_coverage->get_total( ). 258 | lv_coverage-hit = oref_coverage->get_executed( ). 259 | lv_coverage-miss = oref_coverage->get_not_executed( ). 260 | lv_coverage-percent = oref_coverage->get_percentage( ). 261 | lv_cov_id = oref_coverage->type->id. 262 | IF lv_cov_id = 'BRAN'. 263 | APPEND lv_coverage to ev_result-brancovs. 264 | ELSEIF lv_cov_id = 'PROC'. 265 | APPEND lv_coverage to ev_result-proccovs. 266 | ELSE. 267 | get_methods_coverage( 268 | EXPORTING 269 | ioref_Coverage_Result = oref_Coverage_Result 270 | IMPORTING 271 | et_methods = lv_coverage-methods 272 | ). 273 | APPEND lv_coverage to ev_result-stmtcovs. 274 | ENDIF. 275 | CLEAR oref_coverage. 276 | ENDLOOP. 277 | CLEAR lt_coverages. 278 | CLEAR oref_Coverage_Result. 279 | ENDLOOP. 280 | 281 | CATCH cx_scv_execution_error INTO DATA(lx_error). 282 | EXIT. 283 | ENDTRY. 284 | 285 | " collect test result 286 | oref_listener->get_result( 287 | IMPORTING 288 | e_programs = lt_programs 289 | e_statistic = lt_stats 290 | ). 291 | LOOP AT lt_programs ASSIGNING . 292 | LOOP AT -test_classes ASSIGNING . 293 | CLEAR lv_testclass. 294 | lv_testclass-name = -name. 295 | lv_testclass-sut = -obj_name. 296 | LOOP AT -test_methods ASSIGNING . 297 | CLEAR lv_method. 298 | lv_method-name = -name. 299 | IF -alert IS INITIAL. 300 | lv_method-pass = abap_true. 301 | ADD 1 TO lv_testclass-pass. 302 | ELSE. 303 | lv_method-pass = abap_false. 304 | lv_method-text = -alert-description. 305 | ADD 1 TO lv_testclass-fail. 306 | ENDIF. 307 | ADD 1 TO lv_testclass-total. 308 | APPEND lv_method TO lv_testclass-methods. 309 | ENDLOOP. 310 | APPEND lv_testclass TO ev_result-tests. 311 | ENDLOOP. 312 | ENDLOOP. 313 | 314 | ENDMETHOD. 315 | 316 | METHOD GET_RUNSETTINGS. 317 | DATA oref_ado TYPE REF TO ZCL_UTILITY_ABAPTOGIT_ADO. 318 | DATA lv_runsettings TYPE string. 319 | CREATE OBJECT oref_ado 320 | EXPORTING 321 | iv_username = iv_username 322 | iv_pat = iv_pat 323 | iv_orgid = iv_orgid 324 | iv_repoid = iv_repoid 325 | iv_project = iv_project. 326 | rv_success = oref_ado->get_item_ado( 327 | EXPORTING 328 | iv_branch = iv_branch 329 | iv_itempath = co_runsettings 330 | IMPORTING 331 | ev_content = lv_runsettings 332 | ). 333 | CHECK rv_success = abap_true. 334 | /ui2/cl_json=>deserialize( 335 | EXPORTING 336 | json = lv_runsettings 337 | CHANGING 338 | data = ev_runsettings 339 | ). 340 | ENDMETHOD. 341 | 342 | METHOD GET_METHODS_COVERAGE. 343 | DATA ls_method TYPE ts_cov_method_result. 344 | DATA ls_statement TYPE ts_statement. 345 | DATA(oref_root_node) = ioref_Coverage_Result->get_root_node( ). 346 | CHECK oref_root_node->has_children( ) = abap_true. 347 | DATA(lt_children) = oref_root_node->get_children( ). 348 | LOOP AT lt_children INTO DATA(wachild). 349 | CHECK wachild->has_children( ) = abap_true. 350 | DATA(lt_methods) = wachild->get_children( ). 351 | LOOP AT lt_methods INTO DATA(wamethod). 352 | CLEAR ls_method. 353 | LOOP AT wamethod->get_coverages( ) INTO DATA(wacov). 354 | DATA(lv_cov_id) = wacov->type->id. 355 | CHECK lv_cov_id = 'STAT'. 356 | ls_method-name = wamethod->name. 357 | ls_method-total = wacov->get_total( ). 358 | ls_method-hit = wacov->get_executed( ). 359 | ls_method-miss = wacov->get_not_executed( ). 360 | ls_method-percent = wacov->get_percentage( ). 361 | ENDLOOP. 362 | APPEND ls_method TO et_methods. 363 | ENDLOOP. 364 | ENDLOOP. 365 | ENDMETHOD. 366 | 367 | ENDCLASS. 368 | -------------------------------------------------------------------------------- /abap/ZCL_UTILITY_ABAPTOGIT_PCR.CLAS.abap: -------------------------------------------------------------------------------- 1 | " Utility class for HR/payroll PCR/schema 2 | class ZCL_UTILITY_ABAPTOGIT_PCR definition 3 | public 4 | final 5 | create public . 6 | 7 | public section. 8 | 9 | " constructor 10 | " io_objtelemetry - class object for telemetry 11 | " iv_methtelemetry - method name for telemetry 12 | " for telemetry, the method will be invoked with parameters 13 | " iv_message as string (for message content) and iv_kind as string (for category) 14 | METHODS constructor 15 | IMPORTING 16 | io_objtelemetry TYPE REF TO object OPTIONAL 17 | iv_methtelemetry TYPE string OPTIONAL. 18 | 19 | " fetch HR/payroll schema/PCR language code lines into files 20 | " iv_folder - local folder name to save the files 21 | " iv_folder_structure - 'flat' or 'eclipse' 22 | METHODS get_hr_schemapcrs 23 | IMPORTING 24 | iv_folder TYPE string 25 | iv_folder_structure TYPE string DEFAULT 'eclipse' 26 | RETURNING VALUE(rv_success) TYPE abap_bool. 27 | 28 | " build PCR/schema content 29 | " iv_objname - object name 30 | " iv_objtype - object type 31 | " it_trobjcontent - TR object file content 32 | " it_commit_objects - TR object list 33 | METHODS build_pcrschema_content 34 | IMPORTING 35 | iv_objname TYPE string 36 | iv_objtype TYPE string 37 | CHANGING 38 | it_trobjcontent TYPE zcl_utility_abaptogit_tr=>tty_abaptext 39 | it_commit_objects TYPE zcl_utility_abaptogit_tr=>tty_commit_object. 40 | 41 | protected section. 42 | private section. 43 | 44 | " telemetry callback 45 | DATA oref_telemetry TYPE REF TO object. 46 | DATA method_name_telemetry TYPE string. 47 | 48 | " remark: OOB program RPDASC00 also dumps schema/PCR but takes background job privilege to run 49 | " and then fetch spools log from WRITE output and wait for job finish -- complicated and error prone 50 | " remark: upon releasing customizing TR the snapshot of schema/PCR is kept though SAP doesn't keep 51 | " all old versions, it's reliable to keep the snapshot as Git commit at the same time to reflect 52 | " what version the TR keeps and transports later 53 | 54 | " construct HR/payroll schema language code content 55 | " iv_schemaname - schema name 56 | " iv_indented - indented for instruction part or not 57 | " et_filecontent - schema code content lines 58 | METHODS build_schema_content_active 59 | IMPORTING 60 | iv_schemaname TYPE string 61 | iv_indented TYPE abap_bool DEFAULT abap_true 62 | EXPORTING 63 | et_filecontent TYPE zcl_utility_abaptogit_tr=>tty_abaptext. 64 | 65 | " construct HR/payroll personnel calculation rule code content 66 | " iv_pcrname - PCR name 67 | " et_filecontent - PCR code content lines 68 | METHODS build_pcr_content_active 69 | IMPORTING 70 | iv_pcrname TYPE string 71 | EXPORTING 72 | et_filecontent TYPE zcl_utility_abaptogit_tr=>tty_abaptext. 73 | 74 | " wrapper to write telemetry with the callback registered 75 | METHODS write_telemetry 76 | IMPORTING 77 | iv_message TYPE string 78 | iv_kind TYPE string DEFAULT 'error'. 79 | 80 | ENDCLASS. 81 | 82 | 83 | 84 | CLASS ZCL_UTILITY_ABAPTOGIT_PCR IMPLEMENTATION. 85 | 86 | METHOD constructor. 87 | 88 | IF io_objtelemetry IS SUPPLIED. 89 | me->oref_telemetry = io_objtelemetry. 90 | ENDIF. 91 | 92 | IF iv_methtelemetry IS SUPPLIED. 93 | me->method_name_telemetry = iv_methtelemetry. 94 | ENDIF. 95 | 96 | ENDMETHOD. 97 | 98 | 99 | METHOD get_hr_schemapcrs. 100 | DATA wacode TYPE zcl_utility_abaptogit=>ts_code_object. 101 | DATA lt_schemas TYPE STANDARD TABLE OF zcl_utility_abaptogit=>ts_code_object. 102 | DATA lt_pcrs TYPE STANDARD TABLE OF zcl_utility_abaptogit=>ts_code_object. 103 | DATA lt_filecontent TYPE zcl_utility_abaptogit_tr=>tty_abaptext. 104 | DATA lv_basefolder TYPE string. 105 | DATA lv_commit_object TYPE zcl_utility_abaptogit_tr=>ts_commit_object. 106 | DATA lv_code_name TYPE string. 107 | DATA lv_path TYPE string. 108 | DATA lv_folder TYPE rlgrap-filename. 109 | DATA lv_codefolder TYPE string. 110 | DATA lv_filefolder TYPE string. 111 | DATA lt_filefolders TYPE TABLE OF string WITH DEFAULT KEY. 112 | DATA lv_success TYPE abap_bool. 113 | DATA lv_schpcrname TYPE string. 114 | DATA lv_progcls TYPE t52ba-pwert. 115 | 116 | IF iv_folder NP '*\'. 117 | lv_basefolder = iv_folder && '\'. 118 | ELSE. 119 | lv_basefolder = iv_folder. 120 | ENDIF. 121 | 122 | " root folder for a package like \src\.schemapcr\ 123 | lv_folder = |{ lv_basefolder }{ zcl_utility_abaptogit_tr=>c_schemapcr }{ zcl_utility_abaptogit=>c_delim }|. 124 | lv_codefolder = lv_folder. 125 | CALL FUNCTION 'GUI_CREATE_DIRECTORY' 126 | EXPORTING 127 | dirname = lv_folder 128 | EXCEPTIONS 129 | failed = 1 130 | OTHERS = 2. 131 | IF sy-subrc <> 0. 132 | me->write_telemetry( iv_message = |GET_HR_SCHEMAPCRS creates existing folder { lv_folder }| ). 133 | ENDIF. 134 | 135 | " download schemas 136 | SELECT sname, 'PSCC', 'PSCC', ' ' INTO TABLE @lt_schemas FROM t52cc WHERE sname LIKE 'Z%' OR sname LIKE 'Y%'. 137 | 138 | LOOP AT lt_schemas INTO wacode. 139 | 140 | CLEAR lt_filecontent. 141 | 142 | lv_schpcrname = wacode-obj_name. 143 | me->build_schema_content_active( 144 | EXPORTING 145 | iv_schemaname = lv_schpcrname 146 | IMPORTING 147 | et_filecontent = lt_filecontent 148 | ). 149 | SELECT SINGLE pwert FROM t52ba INTO @lv_progcls WHERE potyp = 'SCHE' AND ponam = @lv_schpcrname AND pattr = 'PCL'. "#EC WARNOK 150 | 151 | lv_commit_object-objname = wacode-obj_name. 152 | lv_commit_object-objtype = 'PSCC'. 153 | lv_commit_object-progcls = lv_progcls. 154 | lv_code_name = zcl_utility_abaptogit_ado=>build_code_name( 155 | EXPORTING 156 | iv_commit_object = lv_commit_object 157 | iv_local_folder = abap_true 158 | iv_base_folder = lv_codefolder 159 | iv_folder_structure = iv_folder_structure 160 | IMPORTING 161 | ev_file_folder = lv_filefolder 162 | ). 163 | IF NOT line_exists( lt_filefolders[ table_line = lv_filefolder ] ). 164 | APPEND lv_filefolder TO lt_filefolders. 165 | lv_folder = lv_filefolder. 166 | CALL FUNCTION 'GUI_CREATE_DIRECTORY' 167 | EXPORTING 168 | dirname = lv_folder 169 | EXCEPTIONS 170 | failed = 1 171 | OTHERS = 2. "#EC FB_RC 172 | IF sy-subrc <> 0. 173 | me->write_telemetry( iv_message = |GET_HR_SCHEMAPCRS creates existing folder { lv_folder }| ). 174 | ENDIF. 175 | ENDIF. 176 | lv_path = |{ lv_basefolder }{ zcl_utility_abaptogit_tr=>c_schemapcr }{ zcl_utility_abaptogit=>c_delim }{ lv_code_name }|. 177 | CALL FUNCTION 'GUI_DOWNLOAD' 178 | EXPORTING 179 | filename = lv_path 180 | filetype = 'ASC' 181 | write_field_separator = 'X' 182 | TABLES 183 | data_tab = lt_filecontent 184 | EXCEPTIONS 185 | OTHERS = 1. 186 | IF sy-subrc <> 0. 187 | me->write_telemetry( iv_message = |GET_HR_SCHEMAPCRS fails to save local file { lv_path }| ). 188 | rv_success = abap_false. 189 | ENDIF. 190 | 191 | ENDLOOP. 192 | 193 | CLEAR: lt_schemas, lt_filecontent. 194 | 195 | " download PCRs 196 | SELECT cname, 'PCYC', 'PCYC', ' ' INTO TABLE @lt_pcrs FROM t52ce WHERE cname LIKE 'Z%' OR cname LIKE 'Y%'. 197 | 198 | LOOP AT lt_pcrs INTO wacode. 199 | 200 | CLEAR lt_filecontent. 201 | 202 | lv_schpcrname = wacode-obj_name. 203 | me->build_pcr_content_active( 204 | EXPORTING 205 | iv_pcrname = lv_schpcrname 206 | IMPORTING 207 | et_filecontent = lt_filecontent 208 | ). 209 | SELECT SINGLE pwert FROM t52ba INTO @lv_progcls WHERE potyp = 'CYCL' AND ponam = @lv_schpcrname AND pattr = 'PCL'. "#EC WARNOK 210 | 211 | lv_commit_object-objname = wacode-obj_name. 212 | lv_commit_object-objtype = 'PCYC'. 213 | lv_commit_object-progcls = lv_progcls. 214 | lv_code_name = zcl_utility_abaptogit_ado=>build_code_name( 215 | EXPORTING 216 | iv_commit_object = lv_commit_object 217 | iv_local_folder = abap_true 218 | iv_base_folder = lv_codefolder 219 | iv_folder_structure = iv_folder_structure 220 | IMPORTING 221 | ev_file_folder = lv_filefolder 222 | ). 223 | IF NOT line_exists( lt_filefolders[ table_line = lv_filefolder ] ). 224 | APPEND lv_filefolder TO lt_filefolders. 225 | lv_folder = lv_filefolder. 226 | CALL FUNCTION 'GUI_CREATE_DIRECTORY' 227 | EXPORTING 228 | dirname = lv_folder 229 | EXCEPTIONS 230 | failed = 1 231 | OTHERS = 2. "#EC FB_RC 232 | IF sy-subrc <> 0. 233 | me->write_telemetry( iv_message = |GET_HR_SCHEMAPCRS creates existing folder { lv_folder }| ). 234 | ENDIF. 235 | ENDIF. 236 | lv_path = |{ lv_basefolder }{ zcl_utility_abaptogit_tr=>c_schemapcr }{ zcl_utility_abaptogit=>c_delim }{ lv_code_name }|. 237 | 238 | CALL FUNCTION 'GUI_DOWNLOAD' 239 | EXPORTING 240 | filename = lv_path 241 | filetype = 'ASC' 242 | write_field_separator = 'X' 243 | TABLES 244 | data_tab = lt_filecontent 245 | EXCEPTIONS 246 | OTHERS = 1. 247 | IF sy-subrc <> 0. 248 | me->write_telemetry( iv_message = |GET_HR_SCHEMAPCRS fails to save local file { lv_path }| ). 249 | rv_success = abap_false. 250 | ENDIF. 251 | 252 | ENDLOOP. 253 | 254 | ENDMETHOD. 255 | 256 | 257 | METHOD build_pcrschema_content. 258 | 259 | DATA lt_filecontent TYPE zcl_utility_abaptogit_tr=>tty_abaptext. 260 | DATA lv_cdate TYPE cdate. 261 | DATA lv_udate TYPE aedat. 262 | DATA lv_progcls TYPE t52ba-pwert. 263 | DATA lv_version_no TYPE i. 264 | DATA lv_filecontent TYPE string. 265 | DATA lv_filelines TYPE i. 266 | DATA lv_objname TYPE string. 267 | lv_objname = iv_objname. 268 | 269 | IF iv_objtype = 'PSCC'. 270 | me->build_schema_content_active( 271 | EXPORTING 272 | iv_schemaname = iv_objname 273 | IMPORTING 274 | et_filecontent = lt_filecontent 275 | ). 276 | SELECT SINGLE cdate FROM t52cc INTO @lv_cdate WHERE sname = @iv_objname. 277 | SELECT SINGLE udate FROM t52cc INTO @lv_udate WHERE sname = @iv_objname. 278 | SELECT SINGLE pwert FROM t52ba INTO @lv_progcls WHERE potyp = 'SCHE' AND ponam = @iv_objname AND pattr = 'PCL'. "#EC WARNOK 279 | ELSE. 280 | me->build_pcr_content_active( 281 | EXPORTING 282 | iv_pcrname = iv_objname 283 | IMPORTING 284 | et_filecontent = lt_filecontent 285 | ). 286 | SELECT SINGLE cdate FROM t52ce INTO @lv_cdate WHERE cname = @iv_objname. 287 | SELECT SINGLE udate FROM t52ce INTO @lv_udate WHERE cname = @iv_objname. 288 | SELECT SINGLE pwert FROM t52ba INTO @lv_progcls WHERE potyp = 'CYCL' AND ponam = @iv_objname AND pattr = 'PCL'. "#EC WARNOK 289 | ENDIF. 290 | 291 | " schema/PCR has no reliable version upon releasing TR, have to use dates to determine add or update 292 | IF lv_udate IS INITIAL OR lv_cdate = lv_udate. 293 | lv_version_no = 1. 294 | ELSE. 295 | lv_version_no = 2. 296 | ENDIF. 297 | 298 | " stitch to string from source code lines 299 | lv_filecontent = concat_lines_of( table = lt_filecontent sep = cl_abap_char_utilities=>cr_lf ). 300 | 301 | " align with GUI_DOWNLOAD which adds a blank line 302 | lv_filecontent = lv_filecontent && cl_abap_char_utilities=>cr_lf. 303 | 304 | lv_filelines = lines( lt_filecontent ). 305 | it_trobjcontent[ lines( it_trobjcontent ) ] = it_trobjcontent[ lines( it_trobjcontent ) ]-line && |, lines { lv_filelines }|. 306 | 307 | TRANSLATE lv_objname TO UPPER CASE. 308 | 309 | APPEND VALUE zcl_utility_abaptogit_tr=>ts_commit_object( 310 | devclass = zcl_utility_abaptogit_tr=>c_schemapcr 311 | objname = lv_objname 312 | objtype = iv_objtype 313 | objtype2 = iv_objtype 314 | fugr = '' 315 | progcls = lv_progcls 316 | delflag = abap_false 317 | verno = lv_version_no 318 | filecontent = lv_filecontent 319 | ) TO it_commit_objects. 320 | 321 | ENDMETHOD. 322 | 323 | 324 | METHOD build_schema_content_active. 325 | 326 | TYPES ts_comment TYPE t52c3. 327 | DATA lv_ltext TYPE t52cc_t-ltext. 328 | DATA ls_desc TYPE t52cc. 329 | DATA lv_cnt TYPE t52ba-pwert. 330 | DATA lt_comments TYPE TABLE OF ts_comment. 331 | DATA lv_line TYPE c LENGTH 72. 332 | DATA lv_text TYPE string. 333 | DATA lv_maxindent TYPE i. 334 | DATA lv_indent TYPE i. 335 | DATA lv_funco TYPE string. 336 | 337 | " fetch schema's meta data 338 | SELECT SINGLE * FROM t52cc INTO @ls_desc WHERE sname = @iv_schemaname. 339 | SELECT SINGLE pwert FROM t52ba INTO @lv_cnt WHERE potyp = 'SCHE' AND ponam = @iv_schemaname AND pattr = 'CNT'. "#EC WARNOK 340 | 341 | " fetch schema's description text 342 | SELECT SINGLE ltext FROM t52cc_t INTO @lv_ltext WHERE sname = @iv_schemaname. "#EC WARNOK "#EC CI_SGLSELECT 343 | 344 | " meta data for this schema, don't want to bother to add an additional XML/JSON description file 345 | APPEND '* Schema header part is auto generated and not part of engineer changes.' TO et_filecontent. 346 | APPEND |* Schema : { iv_schemaname }| TO et_filecontent. 347 | APPEND |* Description : { lv_ltext }| TO et_filecontent. 348 | APPEND |* Executable : { ls_desc-execu }| TO et_filecontent. 349 | APPEND |* Country Grouping : { lv_cnt }| TO et_filecontent. 350 | APPEND |* Owner : { ls_desc-respu }| TO et_filecontent. 351 | APPEND |* Creation Date : { ls_desc-cdate }| TO et_filecontent. 352 | APPEND |* Only Changed by Owner : { ls_desc-execu }| TO et_filecontent. 353 | APPEND |* Version : { ls_desc-uvers }| TO et_filecontent. 354 | * APPEND |* Last Changed By : { ls_desc-uname }| TO et_filecontent. 355 | APPEND |* Last Changed Date : { ls_desc-udate }| TO et_filecontent. 356 | APPEND |* Last Changed Time : { ls_desc-utime }| TO et_filecontent. 357 | 358 | " fetch schema instructions' comments 359 | SELECT * FROM t52c3 INTO TABLE @lt_comments 360 | WHERE schem = @iv_schemaname AND spras = @zcl_utility_abaptogit_tr=>c_en. 361 | 362 | IF iv_indented = abap_true. 363 | 364 | " calculate max indents 365 | lv_indent = 0. 366 | lv_maxindent = 0. 367 | SELECT * FROM t52c1 INTO @DATA(wa_instr1) WHERE schem = @iv_schemaname. 368 | IF wa_instr1-delet = '*'. 369 | CONTINUE. 370 | ENDIF. 371 | CASE wa_instr1-funco. 372 | WHEN 'IF' OR 'BINI' OR 'BEND' OR 'BDAY' OR 'LPBEG'. 373 | lv_indent = lv_indent + 2. 374 | IF lv_maxindent < lv_indent. 375 | lv_maxindent = lv_indent. 376 | ENDIF. 377 | WHEN 'ENDIF' OR 'EINI' OR 'EEND' OR 'EDAY' OR 'LPEND'. 378 | lv_indent = lv_indent - 2. 379 | WHEN OTHERS. 380 | " no action 381 | ENDCASE. 382 | ENDSELECT. 383 | 384 | " instruction table header 385 | DATA lv_header TYPE string VALUE 'Par1 Par2 Par3 Par4 D Text'. 386 | DO lv_maxindent TIMES. 387 | lv_header = ` ` && lv_header. 388 | ENDDO. 389 | lv_header = `Func. ` && lv_header. 390 | APPEND lv_header TO et_filecontent. 391 | 392 | lv_indent = 0. 393 | 394 | " fetch schema instructions 395 | SELECT * FROM t52c1 INTO @DATA(wa_instr2) WHERE schem = @iv_schemaname. 396 | CLEAR lv_line. 397 | lv_line+0 = wa_instr2-parm1. 398 | lv_line+6 = wa_instr2-parm2. 399 | lv_line+12 = wa_instr2-parm3. 400 | lv_line+18 = wa_instr2-parm4. 401 | lv_line+24 = wa_instr2-delet. 402 | lv_line+26 = lt_comments[ seqno = wa_instr2-textid ]-scdes. 403 | CLEAR lv_funco. 404 | lv_funco = wa_instr2-funco. 405 | CASE wa_instr2-funco. 406 | WHEN 'IF' OR 'BINI' OR 'BEND' OR 'BDAY' OR 'LPBEG'. 407 | DO lv_indent TIMES. 408 | lv_funco = ` ` && lv_funco. 409 | ENDDO. 410 | IF wa_instr2-delet <> '*'. 411 | lv_indent = lv_indent + 2. 412 | ENDIF. 413 | WHEN 'ELSE'. 414 | IF wa_instr2-delet <> '*'. 415 | lv_indent = lv_indent - 2. 416 | ENDIF. 417 | DO lv_indent TIMES. 418 | lv_funco = ` ` && lv_funco. 419 | ENDDO. 420 | IF wa_instr2-delet <> '*'. 421 | lv_indent = lv_indent + 2. 422 | ENDIF. 423 | WHEN 'ENDIF' OR 'EINI' OR 'EEND' OR 'EDAY' OR 'LPEND'. 424 | IF wa_instr2-delet <> '*'. 425 | lv_indent = lv_indent - 2. 426 | ENDIF. 427 | DO lv_indent TIMES. 428 | lv_funco = ` ` && lv_funco. 429 | ENDDO. 430 | WHEN OTHERS. 431 | DO lv_indent TIMES. 432 | lv_funco = ` ` && lv_funco. 433 | ENDDO. 434 | ENDCASE. 435 | DATA(lv_length) = strlen( lv_funco ). 436 | DO lv_maxindent + 6 - lv_length TIMES. 437 | lv_funco = lv_funco && ` `. 438 | ENDDO. 439 | APPEND |{ lv_funco }{ lv_line }| TO et_filecontent. 440 | ENDSELECT. 441 | 442 | ELSE. 443 | 444 | " instruction table header 445 | APPEND 'Func. Par1 Par2 Par3 Par4 D Text' TO et_filecontent. 446 | 447 | " fetch schema instructions 448 | SELECT * FROM t52c1 INTO @DATA(wa_instr3) WHERE schem = @iv_schemaname. 449 | CLEAR lv_line. 450 | lv_line+0 = wa_instr3-funco. 451 | lv_line+6 = wa_instr3-parm1. 452 | lv_line+12 = wa_instr3-parm2. 453 | lv_line+18 = wa_instr3-parm3. 454 | lv_line+24 = wa_instr3-parm4. 455 | lv_line+30 = wa_instr3-delet. 456 | lv_line+32 = lt_comments[ seqno = wa_instr3-textid ]-scdes. 457 | APPEND lv_line TO et_filecontent. 458 | ENDSELECT. 459 | 460 | ENDIF. 461 | 462 | ENDMETHOD. 463 | 464 | 465 | METHOD build_pcr_content_active. 466 | 467 | DATA lv_line TYPE c LENGTH 91. 468 | DATA lv_index TYPE i. 469 | DATA lv_text TYPE string. 470 | DATA lv_t TYPE c. 471 | DATA lv_ltext TYPE t52ce_t-ltext. 472 | DATA ls_desc TYPE t52ce. 473 | DATA lv_esg TYPE string. 474 | DATA lv_wgt TYPE string. 475 | DATA lv_cnt TYPE t52ba-pwert. 476 | DATA lv_first TYPE c VALUE abap_true. 477 | 478 | " fetch PCR's meta data 479 | SELECT SINGLE * FROM t52ce INTO @ls_desc WHERE cname = @iv_pcrname. 480 | SELECT SINGLE pwert FROM t52ba INTO @lv_cnt WHERE potyp = 'CYCL' AND ponam = @iv_pcrname AND pattr = 'CNT'. "#EC WARNOK 481 | 482 | " fetch PCR's description text 483 | SELECT SINGLE ltext FROM t52ce_t INTO @lv_ltext WHERE cname = @iv_pcrname AND sprsl = @zcl_utility_abaptogit_tr=>c_en. 484 | 485 | " meta data for this PCR, don't want to bother to add an additional XML/JSON description file 486 | APPEND '* PCR header part is auto generated and not part of engineer changes.' TO et_filecontent. 487 | APPEND |* PCR : { iv_pcrname }| TO et_filecontent. 488 | APPEND |* Description : { lv_ltext }| TO et_filecontent. 489 | APPEND |* Country Grouping : { lv_cnt }| TO et_filecontent. 490 | APPEND |* Owner : { ls_desc-respu }| TO et_filecontent. 491 | APPEND |* Creation Date : { ls_desc-cdate }| TO et_filecontent. 492 | APPEND |* Only Changed by Owner : { ls_desc-relea }| TO et_filecontent. 493 | * APPEND |* Last Changed By : { ls_desc-uname }| TO et_filecontent. 494 | APPEND |* Last Changed Date : { ls_desc-udate }| TO et_filecontent. 495 | APPEND |* Last Changed Time : { ls_desc-utime }| TO et_filecontent. 496 | 497 | " fetch PCR instructions 498 | lv_index = 1. 499 | SELECT * FROM t52c5 INTO @DATA(wa_instr) WHERE ccycl = @iv_pcrname. 500 | IF lv_first = abap_true OR wa_instr-abart <> lv_esg OR wa_instr-lgart <> lv_wgt. 501 | APPEND '' TO et_filecontent. 502 | " show ES group and wage type 503 | * APPEND |* ES Group { wa_instr-abart }, Wage/Time Type { wa_instr-lgart }| TO et_filecontent. 504 | " instruction table header 505 | APPEND 'Var.Key CL T Operation Operation Operation Operation Operation Operation *' TO et_filecontent. 506 | lv_first = abap_false. 507 | lv_esg = wa_instr-abart. 508 | lv_wgt = wa_instr-lgart. 509 | lv_index = 1. 510 | ENDIF. 511 | 512 | CLEAR lv_line. 513 | lv_line+0 = wa_instr-vargt. 514 | lv_line+8 = wa_instr-seqno. 515 | lv_text = wa_instr-vinfo. 516 | IF strlen( lv_text ) > 0. 517 | lv_t = lv_text+0(1). 518 | lv_text = lv_text+1. 519 | ELSE. 520 | lv_t = space. 521 | ENDIF. 522 | lv_line+11 = lv_t. 523 | lv_line+13 = lv_text. 524 | APPEND lv_line TO et_filecontent. 525 | lv_index = lv_index + 1. 526 | ENDSELECT. 527 | 528 | ENDMETHOD. 529 | 530 | 531 | METHOD write_telemetry. 532 | IF me->oref_telemetry IS NOT INITIAL AND me->method_name_telemetry IS NOT INITIAL. 533 | DATA(oref) = me->oref_telemetry. 534 | DATA(meth) = me->method_name_telemetry. 535 | CALL METHOD oref->(meth) 536 | EXPORTING 537 | iv_message = iv_message 538 | iv_kind = iv_kind. 539 | ELSE. 540 | WRITE / |{ iv_kind }: { iv_message }|. 541 | ENDIF. 542 | ENDMETHOD. 543 | 544 | ENDCLASS. -------------------------------------------------------------------------------- /abap/ZCL_UTILITY_AUTLISTENER.clas.abap: -------------------------------------------------------------------------------- 1 | " AUT test runner listener to collect unit test result 2 | " working together with class ZCL_UTILITY_AUCV_RUNNER 3 | " Mostly from RS_AUCV_RUNNER excluding skipping, timeout, time statistics and alert level logics 4 | CLASS ZCL_UTILITY_AUTLISTENER DEFINITION 5 | PUBLIC 6 | FINAL 7 | CREATE PUBLIC. 8 | 9 | PUBLIC SECTION. 10 | 11 | TYPES: BEGIN OF ty_context, 12 | package TYPE string, 13 | program TYPE string, 14 | obj_type TYPE string, 15 | obj_name TYPE string, 16 | test_class TYPE string, 17 | test_method TYPE string, 18 | adt_resource_uri TYPE string, 19 | END OF ty_context. 20 | 21 | TYPES: ty_alert_level TYPE c LENGTH 6. 22 | 23 | TYPES: BEGIN OF ty_alert, 24 | context TYPE ty_context, 25 | kind TYPE string, 26 | description TYPE string, 27 | level TYPE ty_alert_level, 28 | apply_zebra TYPE abap_bool, 29 | END OF ty_alert. 30 | TYPES: ty_alerts TYPE STANDARD TABLE OF ty_alert WITH DEFAULT KEY. 31 | 32 | TYPES: BEGIN OF ty_test_method, 33 | name TYPE string, 34 | alert TYPE ty_alert, 35 | BEGIN OF state, 36 | has_been_started TYPE abap_bool, 37 | has_been_skipped TYPE abap_bool, 38 | END OF state, 39 | END OF ty_test_method. 40 | TYPES: ty_methods TYPE STANDARD TABLE OF ty_test_method WITH NON-UNIQUE KEY name. 41 | 42 | TYPES: BEGIN OF ty_test_class, 43 | name TYPE string, 44 | handle TYPE REF TO if_aunit_test_class_handle, 45 | test_methods TYPE ty_methods, 46 | BEGIN OF state, 47 | has_been_started TYPE abap_bool, 48 | BEGIN OF issue, 49 | has_been_skipped TYPE abap_bool, 50 | has_rt_failure TYPE abap_bool, 51 | has_timeout TYPE abap_bool, 52 | has_failure TYPE abap_bool, 53 | END OF issue, 54 | count_exec_methods TYPE i, 55 | count_skipped_methods TYPE i, 56 | count_skipped_over_methods TYPE i, 57 | count_no_permission TYPE i, 58 | END OF state, 59 | END OF ty_test_class. 60 | TYPES: ty_test_classes TYPE STANDARD TABLE OF ty_test_class WITH NON-UNIQUE KEY name. 61 | 62 | TYPES: BEGIN OF ty_program, 63 | name TYPE progname, 64 | obj_type TYPE tadir-object, 65 | obj_name TYPE tadir-obj_name, 66 | package TYPE tadir-devclass, 67 | adt_resource_uri TYPE string, 68 | test_classes TYPE ty_test_classes, 69 | is_permitted TYPE abap_Bool, 70 | BEGIN OF state, 71 | has_been_started TYPE abap_bool, 72 | has_issue TYPE abap_bool, 73 | END OF state, 74 | END OF ty_program. 75 | 76 | TYPES: ty_programs TYPE STANDARD TABLE OF ty_program WITH NON-UNIQUE KEY obj_name obj_type 77 | WITH unique sorted KEY sorted components obj_name obj_type. 78 | 79 | TYPES: BEGIN OF ty_syntax_error, 80 | obj_type TYPE tadir-object, 81 | obj_name TYPE tadir-obj_name, 82 | adt_resource_uri TYPE string, 83 | message TYPE string, 84 | line TYPE i, 85 | token TYPE string, 86 | END OF ty_syntax_error. 87 | TYPES: ty_syntax_errors TYPE STANDARD TABLE OF ty_syntax_error WITH KEY obj_name obj_type. 88 | 89 | TYPES: BEGIN OF ty_stat_package, 90 | name TYPE string, 91 | new_line TYPE abap_bool, 92 | BEGIN OF state, 93 | executed_classes TYPE i, 94 | executed_methods TYPE i, 95 | skipped_methods TYPE i, 96 | END OF state, 97 | END OF ty_stat_package. 98 | 99 | TYPES: ty_stat_packages TYPE STANDARD TABLE OF ty_stat_package WITH NON-UNIQUE KEY name. 100 | 101 | TYPES: BEGIN OF ty_statistics, 102 | cnt_packages TYPE i, 103 | cnt_programs TYPE i, 104 | cnt_test_classes TYPE i, 105 | cnt_test_methods TYPE i, 106 | 107 | BEGIN OF cnt_method, 108 | passed TYPE i, 109 | with_fatal TYPE i, 110 | with_critical TYPE i, 111 | with_tolerable TYPE i, 112 | skipped TYPE i, 113 | END OF cnt_method, 114 | 115 | " message 116 | has_timeout_only TYPE abap_bool, 117 | BEGIN OF cnt_failure, 118 | syntax_error TYPE i, 119 | fatal TYPE i, 120 | critical TYPE i, 121 | tolerable TYPE i, 122 | total TYPE i, 123 | END OF cnt_failure, 124 | 125 | packages TYPE ty_stat_packages, 126 | 127 | END OF ty_statistics. 128 | 129 | INTERFACES: if_aunit_listener. 130 | 131 | CLASS-METHODS create_listener 132 | IMPORTING i_programs TYPE ty_programs 133 | i_syntax_errors TYPE ty_syntax_errors OPTIONAL 134 | i_au_factory TYPE REF TO cl_aunit_factory 135 | RETURNING VALUE(result) TYPE REF TO ZCL_UTILITY_AUTLISTENER. 136 | 137 | METHODS get_result 138 | EXPORTING e_programs TYPE ty_programs 139 | e_statistic TYPE ty_statistics. 140 | 141 | PRIVATE SECTION. 142 | 143 | METHODS: 144 | init, 145 | 146 | handle_failure 147 | IMPORTING i_kind TYPE string 148 | i_ref_failure TYPE REF TO if_aunit_info_failure, 149 | 150 | initialize_program_entry 151 | IMPORTING i_program_name TYPE csequence, 152 | 153 | finish_statistics, 154 | 155 | add_devc_uri_syntax_errors, 156 | 157 | extract_test_class. 158 | 159 | CONSTANTS: 160 | BEGIN OF c_on_miss, 161 | ignore TYPE c LENGTH 6 VALUE 'ignore' ##no_Text, 162 | assert TYPE c LENGTH 6 VALUE 'assert' ##no_Text, 163 | create TYPE c LENGTH 6 VALUE 'create' ##no_Text, 164 | END OF c_on_miss. 165 | 166 | CONSTANTS: 167 | BEGIN OF c_kind, 168 | assert_failure TYPE string VALUE 'Assertion Failure' ##no_Text, 169 | warning TYPE string VALUE 'Warning' ##no_Text, 170 | cx_failure TYPE string VALUE 'Exception' ##no_Text, 171 | rt_failure TYPE string VALUE 'Runtime Abortion' ##no_Text, 172 | skipped TYPE string VALUE 'Skipped' ##no_Text, 173 | timeout TYPE string VALUE 'Timeout' ##no_Text, 174 | END OF c_kind. 175 | 176 | CONSTANTS: 177 | BEGIN OF c_level, 178 | skipped TYPE ty_alert_level VALUE '1-SKIP' ##no_Text, 179 | tolerable TYPE ty_alert_level VALUE '2-TOLE' ##no_Text, 180 | critical TYPE ty_alert_level VALUE '3-CRIT' ##no_Text, 181 | fatal TYPE ty_alert_level VALUE '4-FATA' ##no_Text, 182 | END OF c_level. 183 | 184 | DATA: 185 | f_programs TYPE ty_programs, 186 | f_syntax_errors TYPE ty_syntax_errors, 187 | f_statistic TYPE ty_statistics, 188 | f_alerts TYPE ty_alerts, 189 | f_test_context TYPE ty_context, 190 | f_au_factory TYPE REF TO cl_aunit_factory, 191 | f_text_api TYPE REF TO if_aunit_text_description. 192 | 193 | ENDCLASS. 194 | 195 | 196 | 197 | CLASS ZCL_UTILITY_AUTLISTENER IMPLEMENTATION. 198 | 199 | METHOD create_listener. 200 | 201 | DATA: oref_listener TYPE REF TO ZCL_UTILITY_AUTLISTENER. 202 | 203 | create object oref_listener. 204 | oref_listener->f_programs = i_programs. 205 | oref_listener->f_syntax_errors = i_syntax_errors. 206 | oref_listener->f_statistic-cnt_failure-syntax_error = lines( i_syntax_errors ). 207 | 208 | IF ( i_au_factory IS BOUND ). 209 | oref_listener->f_au_factory = i_au_factory. 210 | ELSE. 211 | create object oref_listener->f_au_factory. 212 | ENDIF. 213 | oref_listener->init( ). 214 | oref_listener->extract_test_class( ). 215 | result = oref_listener. 216 | 217 | ENDMETHOD. 218 | 219 | METHOD add_devc_uri_syntax_errors. 220 | DATA: 221 | devclass TYPE tadir-devclass, 222 | package TYPE ty_stat_package, 223 | escaped_name TYPE string. 224 | FIELD-SYMBOLS: 225 | TYPE ty_syntax_error. 226 | 227 | check me->f_syntax_errors IS NOT INITIAL. 228 | LOOP AT me->f_syntax_errors ASSIGNING . 229 | SELECT SINGLE devclass 230 | FROM tadir INTO devclass 231 | WHERE 232 | pgmid = 'R3TR' AND 233 | object = -obj_type AND 234 | obj_name = -obj_name. "#EC CI_GENBUFF 235 | READ TABLE me->f_statistic-packages 236 | WITH KEY name = devclass transporting NO FIELDS. 237 | IF ( 0 ne sy-subrc ). 238 | package-name = devclass. 239 | INSERT package INTO TABLE me->f_statistic-packages. 240 | ADD 1 TO me->f_statistic-cnt_packages. 241 | ENDIF. 242 | ENDLOOP. 243 | ENDMETHOD. 244 | 245 | METHOD init. 246 | FIELD-SYMBOLS: 247 | TYPE ty_test_class, 248 | TYPE ty_test_method, 249 | TYPE ty_program. 250 | 251 | me->f_text_api = me->f_au_factory->get_text_converter( language = 'E' ). 252 | 253 | LOOP AT me->f_programs ASSIGNING . 254 | CLEAR -state. 255 | LOOP AT -test_classes ASSIGNING . 256 | CLEAR -state. 257 | LOOP AT -test_methods ASSIGNING . 258 | CLEAR -state. 259 | ENDLOOP. 260 | ENDLOOP. 261 | ENDLOOP. 262 | ENDMETHOD. 263 | 264 | 265 | METHOD if_aunit_listener~task_start. 266 | CLEAR: 267 | me->f_test_context, 268 | me->f_statistic, 269 | me->f_alerts. 270 | ENDMETHOD. 271 | 272 | 273 | METHOD if_aunit_listener~program_start. 274 | DATA: 275 | descr TYPE if_aunit_text_description=>ty_s_description, 276 | package TYPE ty_stat_package, 277 | message_text TYPE string. 278 | FIELD-SYMBOLS: 279 | TYPE ty_program. 280 | 281 | CLEAR me->f_test_context-test_METHOD. 282 | 283 | descr = info->get_description( ). 284 | READ TABLE descr-params index 1 INTO 285 | me->f_test_context-program. 286 | 287 | initialize_program_entry( me->f_test_context-program ). 288 | 289 | READ TABLE me->f_Programs 290 | ASSIGNING WITH KEY 291 | name = me->f_Test_Context-program. 292 | 293 | -state-has_been_started = abap_true. 294 | me->f_test_context-obj_name = -obj_name. 295 | me->f_test_context-obj_type = -obj_type. 296 | me->f_test_context-package = -package. 297 | 298 | ADD 1 TO me->f_statistic-cnt_programs. 299 | READ TABLE me->f_statistic-packages 300 | WITH KEY name = -package transporting NO FIELDS. 301 | IF ( 0 ne sy-subrc ). 302 | package-name = -package. 303 | INSERT package INTO TABLE me->f_statistic-packages. 304 | ENDIF. 305 | ENDMETHOD. 306 | 307 | 308 | METHOD if_aunit_listener~class_start. 309 | DATA: 310 | descr TYPE if_aunit_text_description=>ty_s_description. 311 | FIELD-SYMBOLS: 312 | TYPE ty_test_class, 313 | TYPE ty_program. 314 | 315 | CLEAR me->f_test_context-test_class. 316 | CLEAR me->f_test_context-test_METHOD. 317 | 318 | descr = info->get_description( ). 319 | READ TABLE descr-params 320 | index 1 INTO me->f_test_context-test_class. 321 | 322 | READ TABLE me->f_Programs 323 | ASSIGNING WITH KEY 324 | name = me->f_Test_Context-program. 325 | 326 | READ TABLE -test_Classes ASSIGNING 327 | WITH KEY name = me->f_Test_Context-test_Class. 328 | IF sy-subrc <> 0. 329 | INSERT INITIAL line INTO TABLE -test_Classes ASSIGNING . 330 | -name = me->f_Test_Context-test_Class. 331 | ENDIF. 332 | 333 | -state-has_been_started = abap_true. 334 | ADD 1 TO me->f_statistic-cnt_test_classes. 335 | ENDMETHOD. 336 | 337 | 338 | METHOD if_aunit_listener~method_start. 339 | DATA: 340 | descr TYPE if_aunit_text_description=>ty_s_description. 341 | FIELD-SYMBOLS: 342 | TYPE ty_test_method, 343 | TYPE ty_test_class, 344 | TYPE ty_program. 345 | 346 | CLEAR me->f_test_context-test_METHOD. 347 | 348 | descr = info->get_description( ). 349 | READ TABLE descr-params index 1 INTO 350 | me->f_test_context-test_METHOD. 351 | 352 | READ TABLE me->f_Programs 353 | ASSIGNING WITH KEY 354 | name = me->f_Test_Context-program. 355 | 356 | READ TABLE -test_Classes ASSIGNING 357 | WITH KEY name = me->f_Test_Context-test_Class. 358 | IF sy-subrc <> 0. 359 | INSERT INITIAL line INTO TABLE -test_Classes ASSIGNING . 360 | -name = me->f_Test_Context-test_Class. 361 | ENDIF. 362 | 363 | READ TABLE -test_Methods ASSIGNING 364 | WITH KEY name = me->f_Test_Context-test_Method. 365 | IF sy-subrc <> 0. 366 | INSERT INITIAL line INTO TABLE -test_Methods ASSIGNING . 367 | -name = me->f_Test_Context-test_Method. 368 | ENDIF. 369 | 370 | -state-has_been_started = abap_true. 371 | ADD 1 TO -state-count_exec_methods. 372 | ENDMETHOD. 373 | 374 | 375 | METHOD if_aunit_listener~method_end. 376 | FIELD-SYMBOLS: 377 | TYPE ty_program, 378 | TYPE ty_test_class, 379 | TYPE ty_test_method. 380 | 381 | READ TABLE me->f_Programs 382 | ASSIGNING WITH KEY 383 | name = me->f_Test_Context-program. 384 | 385 | READ TABLE -test_Classes ASSIGNING 386 | WITH KEY name = me->f_Test_Context-test_Class. 387 | IF sy-subrc <> 0. 388 | INSERT INITIAL line INTO TABLE -test_Classes ASSIGNING . 389 | -name = me->f_Test_Context-test_Class. 390 | ENDIF. 391 | 392 | READ TABLE -test_Methods ASSIGNING 393 | WITH KEY name = me->f_Test_Context-test_Method. 394 | IF sy-subrc <> 0. 395 | INSERT INITIAL line INTO TABLE -test_Methods ASSIGNING . 396 | -name = me->f_Test_Context-test_Method. 397 | ENDIF. 398 | 399 | IF ( -alert IS INITIAL ). 400 | ADD 1 TO me->f_statistic-cnt_method-passed. 401 | ELSE. 402 | CASE -alert-level. 403 | WHEN c_level-skipped. 404 | ADD 1 TO me->f_statistic-cnt_method-skipped. 405 | ADD 1 TO -state-count_skipped_methods. 406 | WHEN c_level-fatal. 407 | ADD 1 TO me->f_statistic-cnt_method-with_fatal. 408 | WHEN c_level-critical. 409 | ADD 1 TO me->f_statistic-cnt_method-with_critical. 410 | WHEN c_level-tolerable. 411 | ADD 1 TO me->f_statistic-cnt_method-with_tolerable. 412 | WHEN OTHERS. 413 | CLEAR sy-subrc. 414 | ENDCASE. 415 | ENDIF. 416 | 417 | CLEAR: 418 | me->f_test_context-test_METHOD. 419 | ENDMETHOD. 420 | 421 | 422 | METHOD if_aunit_listener~class_end. 423 | FIELD-SYMBOLS: 424 | TYPE ty_program, 425 | TYPE ty_test_class, 426 | TYPE ty_test_METHOD. 427 | 428 | READ TABLE me->f_Programs 429 | ASSIGNING WITH KEY 430 | name = me->f_Test_Context-program. 431 | 432 | READ TABLE -test_Classes ASSIGNING 433 | WITH KEY name = me->f_Test_Context-test_Class. 434 | IF sy-subrc <> 0. 435 | INSERT INITIAL line INTO TABLE -test_Classes ASSIGNING . 436 | -name = me->f_Test_Context-test_Class. 437 | ENDIF. 438 | 439 | CASE abap_true. 440 | WHEN -state-issue-has_been_skipped. 441 | LOOP AT -test_methods ASSIGNING 442 | WHERE 443 | state-has_been_started = abap_false. 444 | -state-has_been_skipped = abap_true. 445 | ADD 1 TO me->f_statistic-cnt_method-skipped. 446 | ADD 1 TO -state-count_skipped_methods. 447 | ADD 1 TO -state-count_skipped_over_methods. 448 | ENDLOOP. 449 | WHEN -state-issue-has_rt_failure or 450 | -state-issue-has_timeout. 451 | IF ( -state-count_exec_methods IS INITIAL ). 452 | " a runtime error or timeout cancels TO test sand box 453 | " without further information. 454 | " Unless the framework IS sick AT least one test method 455 | " must have been started. Align statistics accordingly. 456 | ADD 1 TO -state-count_exec_methods. 457 | ADD 1 TO me->f_statistic-cnt_test_methods. 458 | ENDIF. 459 | ENDCASE. 460 | 461 | CLEAR: 462 | me->f_test_context-test_class, 463 | me->f_test_context-test_METHOD. 464 | ENDMETHOD. 465 | 466 | 467 | METHOD if_aunit_listener~program_end. 468 | FIELD-SYMBOLS: 469 | TYPE ty_program, 470 | TYPE ty_stat_package, 471 | TYPE ty_test_class. 472 | 473 | READ TABLE me->f_Programs 474 | ASSIGNING WITH KEY 475 | name = me->f_Test_Context-program. 476 | 477 | CLEAR me->f_test_context. 478 | READ TABLE me->f_statistic-packages[] 479 | ASSIGNING 480 | WITH KEY name = -package. 481 | ASSERT IS ASSIGNED. 482 | 483 | LOOP AT -test_classes[] 484 | ASSIGNING 485 | WHERE state-has_been_started = abap_true. 486 | -state-executed_classes = 487 | -state-executed_classes + 1. 488 | -state-executed_methods = 489 | -state-executed_methods + -state-count_exec_methods. 490 | -state-skipped_methods = 491 | -state-skipped_methods + -state-count_skipped_methods. 492 | ENDLOOP. 493 | ENDMETHOD. 494 | 495 | 496 | METHOD if_aunit_listener~task_end. 497 | DELETE ADJACENT DUPLICATES FROM me->f_statistic-packages. 498 | finish_statistics( ). 499 | ENDMETHOD. 500 | 501 | 502 | METHOD handle_failure. 503 | DATA: 504 | adjust_method_totals TYPE abap_bool, 505 | native_level TYPE aunit_level, 506 | alert TYPE ty_alert, 507 | descr TYPE if_aunit_text_description=>ty_s_description, 508 | count TYPE i. 509 | FIELD-SYMBOLS: 510 | TYPE ty_program, 511 | TYPE ty_test_class, 512 | TYPE ty_test_method. 513 | 514 | READ TABLE me->f_Programs 515 | ASSIGNING WITH KEY 516 | name = me->f_Test_Context-program. 517 | 518 | READ TABLE -test_Classes ASSIGNING 519 | WITH KEY name = me->f_Test_Context-test_Class. 520 | IF sy-subrc <> 0. 521 | INSERT INITIAL line INTO TABLE -test_Classes ASSIGNING . 522 | -name = me->f_Test_Context-test_Class. 523 | ENDIF. 524 | 525 | READ TABLE -test_Methods ASSIGNING 526 | WITH KEY name = me->f_Test_Context-test_Method. 527 | IF sy-subrc <> 0. 528 | INSERT INITIAL line INTO TABLE -test_Methods ASSIGNING . 529 | -name = me->f_Test_Context-test_Method. 530 | ENDIF. 531 | 532 | IF ( IS ASSIGNED ). 533 | -state-has_issue = abap_true. 534 | ENDIF. 535 | IF ( IS ASSIGNED ). 536 | -state-issue-has_failure = abap_true. 537 | ENDIF. 538 | 539 | descr = i_ref_failure->get_header_description( ). 540 | alert-kind = i_kind. 541 | alert-context = me->f_test_context. 542 | alert-description = me->f_text_api->get_string( descr ). 543 | 544 | IF i_kind = c_kind-skipped. 545 | IF ( IS ASSIGNED ). 546 | -state-has_been_skipped = abap_true. 547 | -state-issue-has_been_skipped = abap_true. 548 | elseif ( IS ASSIGNED ). 549 | -state-issue-has_been_skipped = abap_true. 550 | ENDIF. 551 | ELSE. 552 | native_level = i_ref_failure->get_level( ). 553 | CASE native_level. 554 | WHEN if_aunit_constants=>fatal. 555 | ADD 1 TO me->f_statistic-cnt_failure-fatal. 556 | WHEN if_aunit_constants=>critical. 557 | ADD 1 TO me->f_statistic-cnt_failure-critical. 558 | WHEN OTHERS. 559 | ADD 1 TO me->f_statistic-cnt_failure-tolerable. 560 | ENDCASE. 561 | IF ( IS NOT ASSIGNED AND IS ASSIGNED ). 562 | " a timeout or runtime abortion IS reported on class level 563 | " however it happened within a METHOD. Fix totals in such a CASE 564 | " BY the assumption that AT least one method has been executed 565 | CASE i_kind. 566 | WHEN c_kind-rt_failure. 567 | -state-issue-has_rt_failure = abap_true. 568 | adjust_method_totals = abap_true. 569 | WHEN c_kind-timeout. 570 | -state-issue-has_timeout = abap_true. 571 | adjust_method_totals = abap_true. 572 | WHEN OTHERS. 573 | adjust_method_totals = abap_false. 574 | ENDCASE. 575 | IF ( abap_true = adjust_method_totals ). 576 | CASE native_level. 577 | WHEN if_aunit_constants=>fatal. 578 | ADD 1 TO me->f_statistic-cnt_method-with_fatal. 579 | WHEN if_aunit_constants=>critical. 580 | ADD 1 TO me->f_statistic-cnt_method-with_critical. 581 | WHEN OTHERS. 582 | ADD 1 TO me->f_statistic-cnt_method-with_tolerable. 583 | ENDCASE. 584 | ENDIF. 585 | ENDIF. 586 | ENDIF. 587 | 588 | count = lines( me->f_alerts ). 589 | count = count MOD 2. 590 | IF ( 1 = count ). 591 | alert-apply_zebra = abap_true. 592 | ENDIF. 593 | 594 | INSERT alert INTO TABLE me->f_alerts[]. 595 | 596 | IF IS ASSIGNED. 597 | IF -alert-level < alert-level. 598 | -alert = alert. 599 | ENDIF. 600 | ENDIF. 601 | 602 | ENDMETHOD. 603 | 604 | 605 | METHOD if_aunit_listener~assert_failure. 606 | DATA: 607 | header TYPE if_aunit_text_description=>ty_s_description. 608 | header = failure->get_header_description( ). 609 | CASE header-id. 610 | WHEN OTHERS. 611 | handle_failure( i_kind = c_kind-assert_failure i_ref_failure = failure ). 612 | 613 | ENDCASE. 614 | ENDMETHOD. 615 | 616 | 617 | METHOD if_aunit_listener~warning. 618 | DATA: 619 | header TYPE if_aunit_text_description=>ty_s_description. 620 | header = warning->get_header_description( ). 621 | CASE header-id. 622 | WHEN OTHERS. 623 | handle_failure( i_kind = c_kind-warning i_ref_failure = warning ). 624 | 625 | ENDCASE. 626 | ENDMETHOD. 627 | 628 | 629 | METHOD if_aunit_listener~cx_failure. 630 | handle_failure( i_kind = c_kind-cx_failure i_ref_failure = failure ). 631 | ENDMETHOD. 632 | 633 | 634 | METHOD if_aunit_listener~rt_failure. 635 | handle_failure( i_kind = c_kind-rt_failure i_ref_failure = failure ). 636 | ENDMETHOD. 637 | 638 | 639 | METHOD if_aunit_listener~execution_event ##needed. 640 | ENDMETHOD. 641 | 642 | 643 | METHOD initialize_program_entry. 644 | DATA: 645 | escaped_name TYPE string, 646 | program TYPE ty_program. 647 | FIELD-SYMBOLS: 648 | TYPE ty_program. 649 | 650 | READ TABLE me->f_programs WITH KEY 651 | name = i_program_name 652 | ASSIGNING . 653 | IF ( 0 ne sy-subrc ). 654 | program-name = i_program_name. 655 | cl_aunit_prog_info=>progname_to_tadir( 656 | EXPORTING 657 | progname = program-name 658 | IMPORTING 659 | obj_name = program-obj_name 660 | obj_type = program-obj_type ). 661 | INSERT program INTO TABLE me->f_programs ASSIGNING . 662 | ENDIF. 663 | ENDMETHOD. 664 | 665 | 666 | METHOD finish_statistics. 667 | DATA: 668 | fraction_of_4 TYPE i, 669 | nbr_of_fill_entries TYPE i. 670 | FIELD-SYMBOLS: 671 | TYPE ty_test_class, 672 | TYPE ty_program, 673 | TYPE ty_stat_package. 674 | 675 | me->f_statistic-cnt_failure-syntax_error = lines( me->f_syntax_errors ). 676 | add_devc_uri_syntax_errors( ). 677 | 678 | LOOP AT me->f_programs ASSIGNING WHERE state IS NOT INITIAL. 679 | ADD 1 TO me->f_statistic-cnt_programs. 680 | LOOP AT -test_classes ASSIGNING WHERE state IS NOT INITIAL. 681 | ADD 1 TO me->f_statistic-cnt_test_classes. 682 | LOOP AT -test_methods transporting NO FIELDS WHERE state IS NOT INITIAL. 683 | ADD 1 TO me->f_statistic-cnt_test_methods. 684 | ENDLOOP. 685 | ENDLOOP. 686 | ENDLOOP. 687 | 688 | me->f_statistic-cnt_packages = lines( me->f_statistic-packages ). 689 | 690 | me->f_statistic-cnt_failure-total = 691 | me->f_statistic-cnt_failure-critical + 692 | me->f_statistic-cnt_failure-fatal + 693 | me->f_statistic-cnt_failure-tolerable. 694 | 695 | " prepare package data to ease rendering 696 | SORT me->f_statistic-packages BY name ASCENDING. 697 | IF ( me->f_statistic-packages IS NOT INITIAL ). 698 | LOOP AT me->f_statistic-packages ASSIGNING . 699 | fraction_of_4 = sy-tabix MOD 4. 700 | IF ( 1 eq fraction_of_4 AND sy-tabix <> 1 ). 701 | -new_line = abap_true. 702 | ENDIF. 703 | ENDLOOP. 704 | nbr_of_fill_entries = ( 4 - fraction_of_4 ) MOD 4. 705 | DO nbr_of_fill_entries TIMES. 706 | INSERT INITIAL line INTO TABLE me->f_statistic-packages. 707 | enddo. 708 | ENDIF. 709 | ENDMETHOD. 710 | 711 | METHOD EXTRACT_TEST_CLASS. 712 | 713 | DATA: 714 | syntax_error TYPE ty_syntax_error, 715 | method_names TYPE saunit_t_methods, 716 | method_name TYPE saunit_d_method, 717 | method TYPE ty_test_method, 718 | test_class TYPE ty_test_class, 719 | test_class_handles 720 | TYPE if_aunit_test_class_handle=>ty_t_testclass_handles. 721 | FIELD-SYMBOLS: 722 | TYPE ty_program. 723 | 724 | LOOP AT me->f_programs ASSIGNING . 725 | test_class_handles = 726 | me->f_au_factory->get_test_class_handles( 727 | obj_type = -obj_type 728 | obj_name = -obj_name ). 729 | 730 | CLEAR test_class. 731 | LOOP AT test_class_handles INTO test_class-handle. 732 | 733 | test_class-name = test_class-handle->get_class_name( ). 734 | method_names = test_class-handle->get_test_methods( ). 735 | 736 | LOOP AT method_names INTO method-name. 737 | INSERT method INTO TABLE test_class-test_methods. 738 | ENDLOOP. 739 | 740 | INSERT test_class INTO TABLE -test_classes. 741 | CLEAR test_class. 742 | ENDLOOP. 743 | 744 | ENDLOOP. 745 | 746 | ENDMETHOD. 747 | 748 | METHOD GET_RESULT. 749 | e_programs = me->f_programs. 750 | e_statistic = me->f_statistic. 751 | ENDMETHOD. 752 | 753 | ENDCLASS. -------------------------------------------------------------------------------- /abap/ZCL_UTILITY_ABAPTOGIT_FMT.clas.abap: -------------------------------------------------------------------------------- 1 | " Helper class to generate text for SAP object types 2 | class ZCL_UTILITY_ABAPTOGIT_FMT definition 3 | public 4 | final 5 | create public . 6 | 7 | public section. 8 | 9 | TYPES: tty_abaptext TYPE TABLE OF abaptxt255 INITIAL SIZE 0. 10 | 11 | " get content of SAPScript 12 | " iv_objname - ABAP object name 13 | " ev_filecontent - file content 14 | " et_filecontent - file content lines 15 | CLASS-METHODS get_sapscript_content 16 | IMPORTING 17 | iv_objname TYPE e071-obj_name 18 | EXPORTING 19 | ev_filecontent TYPE string 20 | et_filecontent TYPE tty_abaptext 21 | RETURNING VALUE(rv_success) TYPE abap_bool. 22 | 23 | CLASS-METHODS GET_BRF_XML_CONTENT 24 | IMPORTING 25 | !IV_APPLICATIONID type FDT_UUID 26 | EXPORTING 27 | !EV_XMLCONTENT type STRING 28 | !EV_XMLAPPNAME type STRING 29 | !EV_ERRORMESSAGE type STRING 30 | RETURNING VALUE(rv_success) TYPE abap_bool. 31 | 32 | class-methods GET_WDYC_BY_WDYN 33 | importing 34 | !IV_WDYN_NAME type E071-OBJ_NAME 35 | exporting 36 | !ET_WDYC_NAME type TABLE . 37 | 38 | protected section. 39 | 40 | private section. 41 | 42 | CONSTANTS: 43 | t_meaning VALUE '1', "#EC NOTEXT Bedeutung 44 | t_standard VALUE '2', "#EC NOTEXT Standardattribute 45 | t_print VALUE '3', "#EC NOTEXT Druckattribute 46 | t_pagecounter VALUE '4', "#EC NOTEXT Seitenzähler 47 | t_pagewins VALUE '5', "#EC NOTEXT Seitenfenster 48 | t_title VALUE '6', "#EC NOTEXT Titel 49 | t_after_title VALUE '7'. "#EC NOTEXT Nach Titel 50 | constants C_XML_BRF_VERSION type FDT_XML_VERSION value '1.11' ##NO_TEXT. 51 | constants C_XML_BRF_SCHEMA type STRING value 'http://sap.corp/fdt/Internal.xsd' ##NO_TEXT. 52 | constants C_XML_BRF_URL type STRING value 'http://sap.com/fdt/transport' ##NO_TEXT. 53 | constants C_XML_BRF_APPNAME_PATH type STRING value '/FDT/"http://sap.com/fdt/transport:APPLICATION"/"http://sap.com/fdt/transport:ADMIN_DATA"/"http://sap.com/fdt/transport:NAME"' ##NO_TEXT. 54 | 55 | TYPES: BEGIN OF ts_result, 56 | id(8), 57 | item(20), 58 | attr(20), 59 | value(61), 60 | vol LIKE sy-index, 61 | END OF ts_result. 62 | 63 | TYPES: tty_result TYPE TABLE OF ts_result WITH DEFAULT KEY. 64 | TYPES: tty_dfies TYPE TABLE OF dfies WITH DEFAULT KEY. 65 | TYPES: tty_itctg TYPE TABLE OF itctg WITH DEFAULT KEY. 66 | TYPES: tty_itcth TYPE TABLE OF itcth WITH DEFAULT KEY. 67 | TYPES: tty_itctw TYPE TABLE OF itctw WITH DEFAULT KEY. 68 | TYPES: tty_tline TYPE TABLE OF tline WITH DEFAULT KEY. 69 | TYPES: tty_itcdp TYPE TABLE OF itcdp WITH DEFAULT KEY. 70 | TYPES: tty_itcdq TYPE TABLE OF itcdq WITH DEFAULT KEY. 71 | TYPES: tty_itcds TYPE TABLE OF itcds WITH DEFAULT KEY. 72 | 73 | TYPES: BEGIN OF ty_string_array, 74 | name TYPE string, 75 | END OF ty_string_array. 76 | 77 | " retrieve header content from FORM object in SAPSCRIPT 78 | CLASS-METHODS get_text_header_content 79 | IMPORTING 80 | is_header TYPE thead 81 | CHANGING 82 | cht_filecontent TYPE tty_abaptext. 83 | 84 | " retrieve header content from FORM object in SAPSCRIPT 85 | CLASS-METHODS get_text_form_header_content 86 | IMPORTING 87 | is_header TYPE thead 88 | is_form_header TYPE itcta 89 | CHANGING 90 | cht_filecontent TYPE tty_abaptext. 91 | 92 | " retrieve string content from FORM object in SAPSCRIPT 93 | CLASS-METHODS get_text_string_content 94 | IMPORTING 95 | it_strings TYPE tty_itcds 96 | CHANGING 97 | cht_filecontent TYPE tty_abaptext. 98 | 99 | " retrieve paragraph content from FORM object in SAPSCRIPT 100 | CLASS-METHODS get_text_paragraph_content 101 | IMPORTING 102 | it_paragraphs TYPE tty_itcdp 103 | it_tabs TYPE tty_itcdq 104 | CHANGING 105 | cht_filecontent TYPE tty_abaptext. 106 | 107 | " retrieve windows content from FORM object in SAPSCRIPT 108 | CLASS-METHODS get_text_windows_content 109 | IMPORTING 110 | it_windows TYPE tty_itctw 111 | CHANGING 112 | cht_filecontent TYPE tty_abaptext. 113 | 114 | " retrieve page content from FORM object in SAPSCRIPT 115 | CLASS-METHODS get_text_page_content 116 | IMPORTING 117 | it_pages TYPE tty_itctg 118 | it_page_windows TYPE tty_itcth 119 | CHANGING 120 | cht_filecontent TYPE tty_abaptext. 121 | 122 | " retrieve header content from FORM object in SAPSCRIPT 123 | CLASS-METHODS get_text_txtelement_content 124 | IMPORTING 125 | it_windows TYPE tty_itctw 126 | it_form_lines TYPE tty_tline 127 | CHANGING 128 | cht_filecontent TYPE tty_abaptext. 129 | 130 | CLASS-METHODS CONVERT_XSTRING_TO_STRING 131 | importing 132 | !IV_XSTRING type XSTRING 133 | exporting 134 | !EV_STRING type STRING. 135 | 136 | ENDCLASS. 137 | 138 | 139 | 140 | CLASS ZCL_UTILITY_ABAPTOGIT_FMT IMPLEMENTATION. 141 | 142 | 143 | METHOD CONVERT_XSTRING_TO_STRING. 144 | DATA: lv_length TYPE i, 145 | lt_binary TYPE STANDARD TABLE OF x255. 146 | 147 | CALL FUNCTION 'SCMS_XSTRING_TO_BINARY' 148 | EXPORTING 149 | buffer = iv_xstring 150 | IMPORTING 151 | output_length = lv_length 152 | TABLES 153 | binary_tab = lt_binary. 154 | IF sy-subrc <> 0. 155 | RETURN. 156 | ENDIF. 157 | 158 | CALL FUNCTION 'SCMS_BINARY_TO_STRING' 159 | EXPORTING 160 | input_length = lv_length 161 | IMPORTING 162 | text_buffer = ev_string 163 | TABLES 164 | binary_tab = lt_binary 165 | EXCEPTIONS 166 | failed = 1 167 | OTHERS = 2. 168 | IF sy-subrc <> 0. 169 | RETURN. 170 | ENDIF. 171 | ENDMETHOD. 172 | 173 | 174 | METHOD GET_BRF_XML_CONTENT. 175 | data: 176 | lv_xstring TYPE xstring, 177 | lo_ixml TYPE REF TO if_ixml, 178 | lo_data_exchange TYPE REF TO if_fdt_data_exchange, 179 | lo_factory TYPE REF TO if_fdt_factory, 180 | lr_id_per_application TYPE REF TO cl_fdt_wd_rt_mass_change=>s_id_per_application, 181 | lo_document TYPE REF TO if_ixml_document, 182 | lt_message TYPE if_fdt_types=>t_message, 183 | lts_failed_id TYPE if_fdt_types=>ts_object_id, 184 | lo_utf8 TYPE REF TO if_ixml_encoding, 185 | lo_ostream TYPE REF TO if_ixml_ostream, 186 | lo_streamfactory TYPE REF TO if_ixml_stream_factory, 187 | lo_renderer TYPE REF TO if_ixml_renderer. 188 | 189 | lo_factory = cl_fdt_factory=>if_fdt_factory~get_instance( ). 190 | TRY. 191 | lo_data_exchange = lo_factory->get_data_exchange( ). 192 | lo_data_exchange->export_xml_application( 193 | EXPORTING 194 | iv_application_id = iv_applicationid 195 | iv_schema = c_xml_brf_schema 196 | iv_xml_version = c_xml_brf_version 197 | IMPORTING 198 | eo_dom_tree = lo_document 199 | et_message = lt_message 200 | ets_failure = lts_failed_id ). 201 | CATCH CX_FDT_INPUT INTO DATA(lx_fdt). 202 | rv_success = abap_false. 203 | lt_message = lx_fdt->mt_message. 204 | LOOP AT lt_message into DATA(lw_message). 205 | ev_errormessage = ev_errormessage && CL_ABAP_CHAR_UTILITIES=>NEWLINE && lw_message-text. 206 | ENDLOOP. 207 | RETURN. 208 | ENDTRY. 209 | 210 | IF lo_document IS BOUND AND cl_fdt_services=>contains_eax_message( lt_message ) EQ abap_false. 211 | " Convert Document to an string. 212 | CLEAR: lv_xstring. 213 | lo_ixml = cl_ixml=>create( ). 214 | lo_utf8 = lo_ixml->create_encoding( character_set = 'utf-8' 215 | byte_order = 0 ). 216 | lo_document->set_encoding( encoding = lo_utf8 ). 217 | lo_streamfactory = lo_ixml->create_stream_factory( ). 218 | lo_ostream = lo_streamfactory->create_ostream_xstring( string = lv_xstring ). 219 | lo_ostream->set_encoding( encoding = lo_utf8 ). 220 | lo_ostream->set_pretty_print( abap_true ). 221 | lo_renderer = lo_ixml->create_renderer( ostream = lo_ostream 222 | document = lo_document ). 223 | IF lo_renderer->render( ) NE 0. 224 | CLEAR: lt_message. 225 | rv_success = abap_false. 226 | ELSE. 227 | data(lv_appname_element) = lo_document->find_from_path_ns( EXPORTING default_uri = c_xml_brf_url path = c_xml_brf_appname_path ). 228 | data(lv_appname_value) = lv_appname_element->get_value( ). 229 | convert_xstring_to_string( EXPORTING iv_xstring = lv_xstring IMPORTING ev_string = ev_xmlcontent ). 230 | ev_xmlappname = lv_appname_value. 231 | rv_success = abap_true. 232 | ENDIF. 233 | ELSE. 234 | rv_success = abap_false. 235 | ENDIF. 236 | 237 | ENDMETHOD. 238 | 239 | 240 | METHOD get_sapscript_content. 241 | 242 | DATA lv_form TYPE itcta-tdform. 243 | DATA ls_form_header TYPE itcta. 244 | DATA lv_found TYPE abap_bool. 245 | DATA ls_header TYPE thead. 246 | DATA lv_olanguage TYPE sy-langu. 247 | DATA lt_form_lines TYPE TABLE OF tline. 248 | DATA lt_pages TYPE TABLE OF itctg. 249 | DATA lt_page_windows TYPE TABLE OF itcth. 250 | DATA lt_paragraphs TYPE TABLE OF itcdp. 251 | DATA lt_strings TYPE TABLE OF itcds. 252 | DATA lt_tabs TYPE TABLE OF itcdq. 253 | DATA lt_windows TYPE TABLE OF itctw. 254 | DATA lv_transtat TYPE string. 255 | DATA lv_status TYPE string. 256 | DATA: lv_rcode LIKE sy-subrc. 257 | 258 | lv_form = iv_objname. 259 | CALL FUNCTION 'READ_FORM' 260 | EXPORTING 261 | form = lv_form 262 | IMPORTING 263 | form_header = ls_form_header 264 | found = lv_found 265 | header = ls_header 266 | olanguage = lv_olanguage 267 | TABLES 268 | form_lines = lt_form_lines 269 | pages = lt_pages 270 | page_windows = lt_page_windows 271 | paragraphs = lt_paragraphs 272 | strings = lt_strings 273 | tabs = lt_tabs 274 | windows = lt_windows. 275 | IF lv_found = abap_false. 276 | rv_success = abap_false. 277 | RETURN. 278 | ENDIF. 279 | 280 | get_text_header_content( 281 | EXPORTING 282 | is_header = ls_header 283 | CHANGING 284 | cht_filecontent = et_filecontent 285 | ). 286 | 287 | " form header 288 | APPEND '' TO et_filecontent. 289 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO et_filecontent. 290 | APPEND 'FORMHEADER' TO et_filecontent. 291 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO et_filecontent. 292 | get_text_form_header_content( 293 | EXPORTING 294 | is_header = ls_header 295 | is_form_header = ls_form_header 296 | CHANGING 297 | cht_filecontent = et_filecontent 298 | ). 299 | 300 | APPEND '' TO et_filecontent. 301 | get_text_string_content( 302 | EXPORTING 303 | it_strings = lt_strings 304 | CHANGING 305 | cht_filecontent = et_filecontent 306 | ). 307 | 308 | get_text_paragraph_content( 309 | EXPORTING 310 | it_paragraphs = lt_paragraphs 311 | it_tabs = lt_tabs 312 | CHANGING 313 | cht_filecontent = et_filecontent 314 | ). 315 | 316 | get_text_windows_content( 317 | EXPORTING 318 | it_windows = lt_windows 319 | CHANGING 320 | cht_filecontent = et_filecontent 321 | ). 322 | 323 | get_text_page_content( 324 | EXPORTING 325 | it_pages = lt_pages 326 | it_page_windows = lt_page_windows 327 | CHANGING 328 | cht_filecontent = et_filecontent 329 | ). 330 | 331 | get_text_txtelement_content( 332 | EXPORTING 333 | it_windows = lt_windows 334 | it_form_lines = lt_form_lines 335 | CHANGING 336 | cht_filecontent = et_filecontent 337 | ). 338 | 339 | APPEND '' TO et_filecontent. 340 | 341 | ev_filecontent = concat_lines_of( table = et_filecontent sep = cl_abap_char_utilities=>cr_lf ). 342 | 343 | " align with GUI_DOWNLOAD which adds a blank line 344 | ev_filecontent = ev_filecontent && cl_abap_char_utilities=>cr_lf. 345 | 346 | rv_success = abap_true. 347 | 348 | ENDMETHOD. 349 | 350 | 351 | METHOD get_text_form_header_content. 352 | DATA: lt_formheader_struct TYPE REF TO cl_abap_structdescr. 353 | DATA: lt_formheader_components TYPE abap_compdescr_tab. 354 | DATA: lt_header_struct TYPE REF TO cl_abap_structdescr. 355 | DATA: lt_header_components TYPE abap_compdescr_tab. 356 | DATA: ls_header TYPE thead. 357 | DATA: ls_form_header TYPE itcta. 358 | DATA: lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0. 359 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 360 | 361 | ls_header = is_header. 362 | ls_form_header = is_form_header. 363 | lt_header_struct ?= cl_abap_typedescr=>describe_by_data( ls_header ). 364 | lt_header_components = lt_header_struct->components. 365 | lt_formheader_struct ?= cl_abap_typedescr=>describe_by_data( ls_form_header ). 366 | lt_formheader_components = lt_formheader_struct->components. 367 | 368 | ASSIGN ls_form_header TO . 369 | 370 | LOOP AT lt_header_components INTO DATA(wa_formheader). 371 | ASSIGN wa_formheader-name TO . 372 | ASSIGN COMPONENT OF STRUCTURE TO . 373 | IF line_exists( lt_formheader_components[ name = ] ). 374 | READ TABLE lt_fieldattr INTO DATA(wa_fieldattr) WITH KEY tabname = 'ITCTA' 375 | fieldname = 376 | langu = sy-langu. 377 | APPEND |{ WIDTH = 22 }{ cl_abap_char_utilities=>horizontal_tab }| && 378 | |{ wa_fieldattr-scrtext_m WIDTH = 22 }{ cl_abap_char_utilities=>horizontal_tab }| && 379 | |{ WIDTH = 22 }| TO cht_filecontent. 380 | ENDIF. 381 | CLEAR wa_fieldattr. 382 | ENDLOOP. 383 | ENDMETHOD. 384 | 385 | 386 | METHOD get_text_header_content. 387 | DATA: lt_header_struct TYPE REF TO cl_abap_structdescr, 388 | lt_header_components TYPE abap_compdescr_tab, 389 | lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0, 390 | ls_header TYPE thead, 391 | wa_fieldattr TYPE dfies. 392 | 393 | FIELD-SYMBOLS : TYPE abap_compdescr. 394 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 395 | 396 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 397 | EXPORTING 398 | tabname = 'ITCTA' 399 | TABLES 400 | dfies_tab = lt_fieldattr 401 | EXCEPTIONS 402 | NOT_FOUND = 1 403 | OTHERS = 2. 404 | CHECK sy-subrc = 0. 405 | 406 | ls_header = is_header. 407 | lt_header_struct ?= cl_abap_typedescr=>describe_by_data( ls_header ). 408 | lt_header_components = lt_header_struct->components. 409 | 410 | ASSIGN ls_header TO . 411 | 412 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 413 | APPEND 'HEADER' TO cht_filecontent. 414 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 415 | 416 | LOOP AT lt_header_components INTO DATA(wa_header). 417 | CLEAR wa_fieldattr. 418 | ASSIGN wa_header-name TO . 419 | ASSIGN COMPONENT OF STRUCTURE TO . 420 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCTA' 421 | fieldname = 422 | langu = sy-langu. 423 | APPEND |{ WIDTH = 22 }{ cl_abap_char_utilities=>horizontal_tab }| && 424 | |{ wa_fieldattr-scrtext_m WIDTH = 22 }{ cl_abap_char_utilities=>horizontal_tab }| && 425 | |{ WIDTH = 22 }| TO cht_filecontent. 426 | ENDLOOP. 427 | ENDMETHOD. 428 | 429 | 430 | METHOD get_text_page_content. 431 | TYPES: BEGIN OF ty_page_array, 432 | name TYPE string, 433 | END OF ty_page_array. 434 | DATA: 435 | lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0, 436 | lt_fieldattr2 TYPE STANDARD TABLE OF dfies INITIAL SIZE 0, 437 | lt_pages TYPE tty_itctg, 438 | lt_page_windows TYPE tty_itcth, 439 | wa_fieldattr TYPE dfies, 440 | var1 LIKE sy-index, 441 | var2 LIKE sy-index, 442 | var3 LIKE sy-index, 443 | lt_page_table TYPE REF TO cl_abap_tabledescr, 444 | lt_page_struct TYPE REF TO cl_abap_structdescr, 445 | lt_page_components TYPE abap_compdescr_tab, 446 | lt_page_windows_table TYPE REF TO cl_abap_tabledescr, 447 | lt_page_windows_struct TYPE REF TO cl_abap_structdescr, 448 | lt_page_windows_components TYPE abap_compdescr_tab. 449 | DATA: ls_page_attr TYPE ty_page_array. 450 | DATA: lt_page_printattr TYPE STANDARD TABLE OF ty_page_array. 451 | DATA: lt_page_counter TYPE STANDARD TABLE OF ty_page_array. 452 | DATA: lt_page_sidewindow TYPE STANDARD TABLE OF ty_page_array. 453 | DATA: lt_results TYPE tty_result. 454 | DATA: ls_result TYPE ts_result. 455 | DATA: entry. 456 | FIELD-SYMBOLS : TYPE abap_compdescr. 457 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 458 | 459 | lt_pages = it_pages. 460 | lt_page_windows = it_page_windows. 461 | lt_page_table ?= cl_abap_typedescr=>describe_by_data( lt_pages ). 462 | lt_page_struct ?= lt_page_table->get_table_line_type( ). 463 | lt_page_components = lt_page_struct->components. 464 | lt_page_windows_table ?= cl_abap_typedescr=>describe_by_data( lt_page_windows ). 465 | lt_page_windows_struct ?= lt_page_table->get_table_line_type( ). 466 | lt_page_windows_components = lt_page_struct->components. 467 | 468 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 469 | EXPORTING 470 | tabname = 'ITCTG' 471 | TABLES 472 | dfies_tab = lt_fieldattr 473 | EXCEPTIONS 474 | NOT_FOUND = 1 475 | OTHERS = 2. 476 | CHECK sy-subrc = 0. 477 | 478 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 479 | EXPORTING 480 | tabname = 'ITCTH' 481 | TABLES 482 | dfies_tab = lt_fieldattr2 483 | EXCEPTIONS 484 | NOT_FOUND = 1 485 | OTHERS = 2. 486 | CHECK sy-subrc = 0. 487 | 488 | var2 = 1. 489 | 490 | ************************ Print attribute ***************************** 491 | ls_page_attr-name = 'TDPAPERRES'. 492 | APPEND ls_page_attr TO lt_page_printattr. 493 | ls_page_attr-name = 'TDPRINTMOD'. 494 | APPEND ls_page_attr TO lt_page_printattr. 495 | *************************** page counter ******************************* 496 | ls_page_attr-name = 'TDCMODEPAG'. 497 | APPEND ls_page_attr TO lt_page_counter. 498 | ls_page_attr-name = 'TDNTYPEPAG'. 499 | APPEND ls_page_attr TO lt_page_counter. 500 | ls_page_attr-name = 'TDPAGOUTL'. 501 | APPEND ls_page_attr TO lt_page_counter. 502 | *************************** side window ****************************** 503 | ls_page_attr-name = 'TDWLEFT'. 504 | APPEND ls_page_attr TO lt_page_sidewindow. 505 | ls_page_attr-name = 'TDWTOP'. 506 | APPEND ls_page_attr TO lt_page_sidewindow. 507 | ls_page_attr-name = 'TDWWIDTH'. 508 | APPEND ls_page_attr TO lt_page_sidewindow. 509 | ls_page_attr-name = 'TDWHEIGHT'. 510 | APPEND ls_page_attr TO lt_page_sidewindow. 511 | 512 | 513 | LOOP AT lt_pages INTO DATA(lv_page). 514 | ASSIGN lv_page TO . 515 | 516 | var1 = 0. 517 | MOVE lv_page-tdpage TO ls_result-id. 518 | MOVE t_meaning TO ls_result-item. 519 | MOVE lv_page-tdtext TO ls_result-value. 520 | var3 = var2. 521 | APPEND ls_result TO lt_results. 522 | CLEAR: ls_result-item, ls_result-value. 523 | ADD 1 TO var2. 524 | ************************ Standard attribute ***************************** 525 | IF NOT lv_page-tdnextpage IS INITIAL. 526 | MOVE t_standard TO ls_result-item. 527 | MOVE 'Next Page' TO ls_result-attr. 528 | MOVE lv_page-tdnextpage TO ls_result-value. 529 | APPEND ls_result TO lt_results. 530 | CLEAR: ls_result-item, ls_result-value. 531 | ADD 1 TO var2. 532 | ENDIF. 533 | ************************* Print attribute ****************************** 534 | MOVE t_print TO ls_result-item. 535 | entry = abap_false. 536 | LOOP AT lt_page_printattr INTO DATA(wa_page_printattr_itcdp). 537 | ASSIGN wa_page_printattr_itcdp-name TO . 538 | ASSIGN COMPONENT OF STRUCTURE TO . 539 | 540 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCTG' 541 | fieldname = 542 | langu = sy-langu. 543 | 544 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 545 | 546 | MOVE TO ls_result-value. 547 | APPEND ls_result TO lt_results. 548 | CLEAR: ls_result-attr, ls_result-value. 549 | entry = abap_true. 550 | ADD 1 TO var2. 551 | CLEAR wa_fieldattr. 552 | ENDLOOP. 553 | 554 | *************************** page counter ******************************* 555 | MOVE t_pagecounter TO ls_result-item. 556 | entry = abap_false. 557 | 558 | LOOP AT lt_page_counter INTO DATA(wa_page_counter_itcdp). 559 | ASSIGN wa_page_counter_itcdp-name TO . 560 | ASSIGN COMPONENT OF STRUCTURE TO . 561 | 562 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCTG' 563 | fieldname = 564 | langu = sy-langu. 565 | 566 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 567 | MOVE TO ls_result-value. 568 | APPEND ls_result TO lt_results. 569 | CLEAR: ls_result-attr, ls_result-value. 570 | entry = abap_true. 571 | ADD 1 TO var2. 572 | CLEAR wa_fieldattr. 573 | ENDLOOP. 574 | IF entry = abap_true. 575 | ADD 1 TO var1. 576 | ENDIF. 577 | 578 | *************************** side window ****************************** 579 | CLEAR ls_result-item. 580 | MOVE t_pagewins TO ls_result-item. 581 | APPEND ls_result TO lt_results. 582 | CLEAR ls_result-item. 583 | ADD 1 TO var2. 584 | entry = abap_false. 585 | 586 | LOOP AT lt_page_windows INTO DATA(lv_page_window) WHERE tdpage = lv_page-tdpage. 587 | MOVE t_title TO ls_result-item. 588 | MOVE lv_page_window-tdwindow TO ls_result-attr. 589 | 590 | READ TABLE lt_fieldattr2 INTO DATA(lv_tdwleft_itcth) WITH KEY tabname = 'ITCTH' 591 | fieldname = 'TDWLEFT' 592 | langu = sy-langu. 593 | MOVE lv_tdwleft_itcth-scrtext_m TO ls_result-value+3(20). 594 | MOVE lv_page_window-tdwleft TO ls_result-value+23(6). 595 | MOVE lv_page_window-tdwleftu TO ls_result-value+30(2). 596 | APPEND ls_result TO lt_results. 597 | CLEAR ls_result-item. 598 | MOVE t_after_title TO ls_result-item. 599 | ADD 1 TO var2. 600 | 601 | READ TABLE lt_fieldattr2 INTO DATA(lv_tdwtop_itcth) WITH KEY tabname = 'ITCTH' 602 | fieldname = 'TDWTOP' 603 | langu = sy-langu. 604 | MOVE lv_tdwtop_itcth-scrtext_m TO ls_result-value+3(20). 605 | MOVE lv_page_window-tdwtop TO ls_result-value+23(6). 606 | MOVE lv_page_window-tdwtopu TO ls_result-value+30(2). 607 | APPEND ls_result TO lt_results. 608 | CLEAR ls_result-item. 609 | MOVE t_after_title TO ls_result-item. 610 | ADD 1 TO var2. 611 | 612 | READ TABLE lt_fieldattr2 INTO DATA(lv_tdwwidth_itcth) WITH KEY tabname = 'ITCTH' 613 | fieldname = 'TDWWIDTH' 614 | langu = sy-langu. 615 | MOVE lv_tdwwidth_itcth-scrtext_m TO ls_result-value+3(20). 616 | MOVE lv_page_window-tdwwidth TO ls_result-value+23(6). 617 | MOVE lv_page_window-tdwwidthu TO ls_result-value+30(2). 618 | APPEND ls_result TO lt_results. 619 | CLEAR ls_result-item. 620 | MOVE t_after_title TO ls_result-item. 621 | ADD 1 TO var2. 622 | 623 | READ TABLE lt_fieldattr2 INTO DATA(lv_tdwheight_itcth) WITH KEY tabname = 'ITCTH' 624 | fieldname = 'TDWHEIGHT' 625 | langu = sy-langu. 626 | MOVE lv_tdwheight_itcth-scrtext_m TO ls_result-value+3(20). 627 | MOVE lv_page_window-tdwheight TO ls_result-value+23(6). 628 | MOVE lv_page_window-tdwheightu TO ls_result-value+30(2). 629 | APPEND ls_result TO lt_results. 630 | CLEAR ls_result-item. 631 | ADD 1 TO var2. 632 | 633 | CLEAR: ls_result-item, ls_result-attr. 634 | entry = abap_true. 635 | ENDLOOP. 636 | IF entry = abap_true. 637 | ADD 1 TO var1. 638 | ELSE. 639 | SUBTRACT 1 FROM var2. 640 | DELETE lt_results INDEX var2. 641 | ENDIF. 642 | 643 | READ TABLE lt_results INTO ls_result INDEX var3. 644 | ls_result-vol = var2 - var3 + var1. 645 | MODIFY lt_results FROM ls_result INDEX var3. 646 | CLEAR ls_result-vol. 647 | ENDLOOP. 648 | 649 | LOOP AT lt_results INTO ls_result. 650 | IF sy-tabix = 1. 651 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 652 | APPEND |Pages Attributes| TO cht_filecontent. 653 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 654 | APPEND '' TO cht_filecontent. 655 | ENDIF. 656 | AT NEW id. 657 | APPEND '' TO cht_filecontent. 658 | ENDAT. 659 | 660 | AT NEW item. 661 | CASE ls_result-item. 662 | WHEN t_meaning. 663 | APPEND |{ ls_result-id WIDTH = 3 }| TO cht_filecontent. 664 | WHEN t_pagecounter. 665 | APPEND |{ 'Page Counter' WIDTH = 15 }| TO cht_filecontent. 666 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 667 | WHEN t_print. 668 | APPEND |{ 'Print Attributes' WIDTH = 15 }| TO cht_filecontent. 669 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 670 | WHEN t_pagewins. 671 | APPEND |{ 'Page Window' WIDTH = 15 }| TO cht_filecontent. 672 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 673 | WHEN t_title. 674 | READ TABLE lt_results INTO DATA(lv_title) INDEX sy-tabix. 675 | APPEND |{ lv_title-attr WIDTH = 18 }| TO cht_filecontent. 676 | ENDCASE. 677 | ENDAT. 678 | 679 | CASE ls_result-item. 680 | WHEN t_meaning. 681 | WHEN t_title. 682 | WHEN t_after_title. 683 | APPEND |{ lv_title-value WIDTH = 36 }| TO cht_filecontent. 684 | WHEN t_standard. 685 | APPEND |{ 'Standard Attributes' WIDTH = 15 }| TO cht_filecontent. 686 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 687 | APPEND |{ ls_result-attr WIDTH = 18 }{ cl_abap_char_utilities=>horizontal_tab }{ ls_result-value WIDTH = 36 }| TO cht_filecontent. 688 | WHEN OTHERS. 689 | APPEND |{ ls_result-attr WIDTH = 18 }{ cl_abap_char_utilities=>horizontal_tab }{ ls_result-value WIDTH = 36 }| TO cht_filecontent. 690 | ENDCASE. 691 | 692 | ENDLOOP. 693 | 694 | ENDMETHOD. 695 | 696 | 697 | METHOD get_text_paragraph_content. 698 | DATA: var1 LIKE sy-index. 699 | DATA: var2 LIKE sy-index. 700 | DATA: var3 LIKE sy-index. 701 | DATA: lt_paragraphs TYPE tty_itcdp. 702 | DATA: lt_tabs TYPE tty_itcdq. 703 | DATA: lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0. 704 | DATA: lt_para_table TYPE REF TO cl_abap_tabledescr. 705 | DATA: lt_para_struct TYPE REF TO cl_abap_structdescr. 706 | DATA: lt_para_components TYPE abap_compdescr_tab. 707 | DATA: lt_results TYPE tty_result. 708 | DATA: ls_result TYPE ts_result. 709 | DATA: entry. 710 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 711 | 712 | lt_paragraphs = it_paragraphs. 713 | 714 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 715 | EXPORTING 716 | tabname = 'ITCDP' 717 | TABLES 718 | dfies_tab = lt_fieldattr 719 | EXCEPTIONS 720 | NOT_FOUND = 1 721 | OTHERS = 2. 722 | CHECK sy-subrc = 0. 723 | 724 | var2 = 1. 725 | 726 | lt_para_table ?= cl_abap_typedescr=>describe_by_data( lt_paragraphs ). 727 | lt_para_struct ?= lt_para_table->get_table_line_type( ). 728 | lt_para_components = lt_para_struct->components. 729 | 730 | DATA: ls_para_attr TYPE ty_string_array. 731 | DATA: lt_para_standardattr TYPE STANDARD TABLE OF ty_string_array. 732 | DATA: lt_para_fontattr TYPE STANDARD TABLE OF ty_string_array. 733 | DATA: lt_para_outlineattr TYPE STANDARD TABLE OF ty_string_array. 734 | 735 | ************************ PARAGRAPHS Standard attribute ***************************** 736 | ls_para_attr-name = 'TDPLDIST'. 737 | APPEND ls_para_attr TO lt_para_standardattr. 738 | ls_para_attr-name = 'TDPLDISTU'. 739 | APPEND ls_para_attr TO lt_para_standardattr. 740 | ls_para_attr-name = 'TDNOBLANKS'. 741 | APPEND ls_para_attr TO lt_para_standardattr. 742 | ls_para_attr-name = 'TDPTOP'. 743 | APPEND ls_para_attr TO lt_para_standardattr. 744 | ls_para_attr-name = 'TDPTOPU'. 745 | APPEND ls_para_attr TO lt_para_standardattr. 746 | ls_para_attr-name = 'TDPBOT'. 747 | APPEND ls_para_attr TO lt_para_standardattr. 748 | ls_para_attr-name = 'TDPBOTU'. 749 | APPEND ls_para_attr TO lt_para_standardattr. 750 | ls_para_attr-name = 'TDPLEFT'. 751 | APPEND ls_para_attr TO lt_para_standardattr. 752 | ls_para_attr-name = 'TDPLEFTU'. 753 | APPEND ls_para_attr TO lt_para_standardattr. 754 | ls_para_attr-name = 'TDPRIGHT'. 755 | APPEND ls_para_attr TO lt_para_standardattr. 756 | ls_para_attr-name = 'TDPRIGHTU'. 757 | APPEND ls_para_attr TO lt_para_standardattr. 758 | ls_para_attr-name = 'TDPENTRY'. 759 | APPEND ls_para_attr TO lt_para_standardattr. 760 | ls_para_attr-name = 'TDPENTRYU'. 761 | APPEND ls_para_attr TO lt_para_standardattr. 762 | ls_para_attr-name = 'TDPJUSTIFY'. 763 | APPEND ls_para_attr TO lt_para_standardattr. 764 | ls_para_attr-name = 'TDPPROTNEX'. 765 | APPEND ls_para_attr TO lt_para_standardattr. 766 | ls_para_attr-name = 'TDPPROTPAG'. 767 | APPEND ls_para_attr TO lt_para_standardattr. 768 | 769 | ************************ PARAGRAPHS Font attribute ********************************* 770 | ls_para_attr-name = 'TDFAMILY'. 771 | APPEND ls_para_attr TO lt_para_fontattr. 772 | ls_para_attr-name = 'TDHEIGHT'. 773 | APPEND ls_para_attr TO lt_para_fontattr. 774 | ls_para_attr-name = 'TDBOLD'. 775 | APPEND ls_para_attr TO lt_para_fontattr. 776 | ls_para_attr-name = 'TDITALIC'. 777 | APPEND ls_para_attr TO lt_para_fontattr. 778 | ls_para_attr-name = 'TDUNDERLIN'. 779 | APPEND ls_para_attr TO lt_para_fontattr. 780 | ls_para_attr-name = 'TDULPOS'. 781 | APPEND ls_para_attr TO lt_para_fontattr. 782 | ls_para_attr-name = 'TDULPOSU'. 783 | APPEND ls_para_attr TO lt_para_fontattr. 784 | ls_para_attr-name = 'TDULTHICK'. 785 | APPEND ls_para_attr TO lt_para_fontattr. 786 | ls_para_attr-name = 'TDULTHICKU'. 787 | APPEND ls_para_attr TO lt_para_fontattr. 788 | ls_para_attr-name = 'TDULGREY'. 789 | APPEND ls_para_attr TO lt_para_fontattr. 790 | ls_para_attr-name = 'TDUNDERLIN'. 791 | APPEND ls_para_attr TO lt_para_fontattr. 792 | ************************ PARAGRAPHS outline attribute ********************************* 793 | ls_para_attr-name = 'TDLFIRSTPA'. 794 | APPEND ls_para_attr TO lt_para_outlineattr. 795 | ls_para_attr-name = 'TDLDEPTH'. 796 | APPEND ls_para_attr TO lt_para_outlineattr. 797 | ls_para_attr-name = 'TDLCHAINED'. 798 | APPEND ls_para_attr TO lt_para_outlineattr. 799 | ls_para_attr-name = 'TDNUMBERIN'. 800 | APPEND ls_para_attr TO lt_para_outlineattr. 801 | ls_para_attr-name = 'TDNUMOUTL'. 802 | APPEND ls_para_attr TO lt_para_outlineattr. 803 | ls_para_attr-name = 'TDNUMFIXC'. 804 | APPEND ls_para_attr TO lt_para_outlineattr. 805 | ls_para_attr-name = 'TDLSTRING'. 806 | APPEND ls_para_attr TO lt_para_outlineattr. 807 | ls_para_attr-name = 'TDNUMLEFT'. 808 | APPEND ls_para_attr TO lt_para_outlineattr. 809 | ls_para_attr-name = 'TDNUMLEFTU'. 810 | APPEND ls_para_attr TO lt_para_outlineattr. 811 | ls_para_attr-name = 'TDLFIRSTC'. 812 | APPEND ls_para_attr TO lt_para_outlineattr. 813 | ls_para_attr-name = 'TDLLASTC'. 814 | APPEND ls_para_attr TO lt_para_outlineattr. 815 | 816 | LOOP AT lt_paragraphs INTO DATA(lv_paragraph). 817 | ASSIGN lv_paragraph TO . 818 | var1 = 0. 819 | MOVE lv_paragraph-tdpargraph TO ls_result-id. 820 | MOVE t_meaning TO ls_result-item. 821 | MOVE lv_paragraph-tdtext TO ls_result-value. 822 | var3 = var2. 823 | APPEND ls_result TO lt_results. 824 | CLEAR: ls_result-item, ls_result-value. 825 | ADD 1 TO var2. 826 | 827 | ************************ Standard attribute **************************** 828 | MOVE 'Standard attribute' TO ls_result-item. 829 | LOOP AT lt_para_standardattr INTO DATA(wa_stdattr_itcdp). 830 | ASSIGN wa_stdattr_itcdp-name TO . 831 | ASSIGN COMPONENT OF STRUCTURE TO . 832 | READ TABLE lt_fieldattr INTO DATA(wa_fieldattr) WITH KEY tabname = 'ITCDP' 833 | fieldname = 834 | langu = sy-langu. 835 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 836 | MOVE TO ls_result-value. 837 | APPEND ls_result TO lt_results. 838 | CLEAR: ls_result-attr, ls_result-value. 839 | entry = abap_true. 840 | ADD 1 TO var2. 841 | ENDLOOP. 842 | 843 | CLEAR ls_result-item. 844 | MOVE 'Font Attributes' TO ls_result-item. 845 | entry = abap_false. 846 | LOOP AT lt_para_fontattr INTO DATA(wa_fontattr_itcdp). 847 | ASSIGN wa_fontattr_itcdp-name TO . 848 | ASSIGN COMPONENT OF STRUCTURE TO . 849 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCDP' 850 | fieldname = 851 | langu = sy-langu. 852 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 853 | 854 | MOVE TO ls_result-value. 855 | APPEND ls_result TO lt_results. 856 | CLEAR: ls_result-attr, ls_result-value. 857 | entry = abap_true. 858 | ADD 1 TO var2. 859 | ENDLOOP. 860 | IF entry = abap_true. 861 | ADD 1 TO var1. 862 | ENDIF. 863 | 864 | CLEAR ls_result-item. 865 | MOVE 'Outline Attributes' TO ls_result-item. 866 | entry = abap_false. 867 | LOOP AT lt_para_outlineattr INTO DATA(wa_outlineattr_itcdp). 868 | ASSIGN wa_outlineattr_itcdp-name TO . 869 | ASSIGN COMPONENT OF STRUCTURE TO . 870 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCDP' 871 | fieldname = 872 | langu = sy-langu. 873 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 874 | 875 | MOVE TO ls_result-value. 876 | APPEND ls_result TO lt_results. 877 | CLEAR: ls_result-attr, ls_result-value. 878 | entry = abap_true. 879 | ADD 1 TO var2. 880 | ENDLOOP. 881 | 882 | CLEAR ls_result-item. 883 | MOVE 'Tabs' TO ls_result-item. 884 | entry = abap_false. 885 | LOOP AT lt_tabs INTO DATA(lv_tabs) WHERE tdpargraph = lv_paragraph-tdpargraph. 886 | MOVE lv_tabs-tdtabpos TO ls_result-attr+0(8). 887 | MOVE lv_tabs-tdtabposu TO ls_result-attr+8(2). 888 | CONDENSE ls_result-attr. 889 | MOVE lv_tabs-tdtjustify TO ls_result-value. 890 | APPEND ls_result TO lt_results. 891 | CLEAR: ls_result-attr, ls_result-value. 892 | entry = abap_true. 893 | ADD 1 TO var2. 894 | ENDLOOP. 895 | 896 | ENDLOOP. 897 | IF entry = abap_true. 898 | ADD 1 TO var1. 899 | ENDIF. 900 | READ TABLE lt_results INTO ls_result INDEX var3. 901 | ls_result-vol = var2 - var3 + var1. 902 | MODIFY lt_results FROM ls_result INDEX var3. 903 | CLEAR ls_result-vol. 904 | 905 | APPEND '' TO cht_filecontent. 906 | LOOP AT lt_results INTO ls_result. 907 | IF sy-tabix = 1. 908 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 909 | APPEND |Paragraphs Attributes| TO cht_filecontent. 910 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 911 | APPEND '' TO cht_filecontent. 912 | ENDIF. 913 | AT NEW id. 914 | APPEND '' TO cht_filecontent. 915 | ENDAT. 916 | 917 | AT NEW item. 918 | IF ls_result-item <> t_meaning. 919 | APPEND |{ ls_result-item WIDTH = 15 }| TO cht_filecontent. 920 | ENDIF. 921 | ENDAT. 922 | IF ls_result-item = t_meaning. 923 | APPEND |{ ls_result-id WIDTH = 12 }{ ls_result-value WIDTH = 15 }| TO cht_filecontent. 924 | ELSE. 925 | APPEND |{ ls_result-attr WIDTH = 18 }{ cl_abap_char_utilities=>horizontal_tab }{ ls_result-value WIDTH = 36 }| TO cht_filecontent. 926 | ENDIF. 927 | 928 | ENDLOOP. 929 | 930 | ENDMETHOD. 931 | 932 | 933 | METHOD get_text_string_content. 934 | 935 | DATA: lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0. 936 | DATA: var1 LIKE sy-index. 937 | DATA: var2 LIKE sy-index. 938 | DATA: var3 LIKE sy-index. 939 | DATA: lt_string_table TYPE REF TO cl_abap_tabledescr. 940 | DATA: lt_string_struct TYPE REF TO cl_abap_structdescr. 941 | DATA: lt_string_components TYPE abap_compdescr_tab. 942 | DATA: lt_strings TYPE tty_itcds. 943 | DATA: lt_results TYPE tty_result. 944 | DATA: ls_result TYPE ts_result. 945 | DATA: entry. 946 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 947 | 948 | lt_strings = it_strings. 949 | lt_string_table ?= cl_abap_typedescr=>describe_by_data( lt_strings ). 950 | lt_string_struct ?= lt_string_table->get_table_line_type( ). 951 | lt_string_components = lt_string_struct->components. 952 | 953 | DATA: ls_string_attr TYPE ty_string_array. 954 | DATA: lt_string_standardattr TYPE STANDARD TABLE OF ty_string_array. 955 | DATA: lt_string_fontattr TYPE STANDARD TABLE OF ty_string_array. 956 | 957 | ************************ Standard attribute ***************************** 958 | ls_string_attr-name = 'TDMARK'. 959 | APPEND ls_string_attr TO lt_string_standardattr. 960 | ls_string_attr-name = 'TDPROTLINE'. 961 | APPEND ls_string_attr TO lt_string_standardattr. 962 | ls_string_attr-name = 'TDHIDDEN'. 963 | APPEND ls_string_attr TO lt_string_standardattr. 964 | ls_string_attr-name = 'TDSUPER'. 965 | APPEND ls_string_attr TO lt_string_standardattr. 966 | ls_string_attr-name = 'TDBARCODE'. 967 | APPEND ls_string_attr TO lt_string_standardattr. 968 | 969 | ************************ Font attribute ********************************* 970 | ls_string_attr-name = 'TDFAMILY'. 971 | APPEND ls_string_attr TO lt_string_fontattr. 972 | ls_string_attr-name = 'TDHEIGHT'. 973 | APPEND ls_string_attr TO lt_string_fontattr. 974 | ls_string_attr-name = 'TDBOLD'. 975 | APPEND ls_string_attr TO lt_string_fontattr. 976 | ls_string_attr-name = 'TDITALIC'. 977 | APPEND ls_string_attr TO lt_string_fontattr. 978 | ls_string_attr-name = 'TDUNDERLIN'. 979 | APPEND ls_string_attr TO lt_string_fontattr. 980 | ls_string_attr-name = 'TDULPOS'. 981 | APPEND ls_string_attr TO lt_string_fontattr. 982 | ls_string_attr-name = 'TDULTHICK'. 983 | APPEND ls_string_attr TO lt_string_fontattr. 984 | ls_string_attr-name = 'TDULGREY'. 985 | APPEND ls_string_attr TO lt_string_fontattr. 986 | ls_string_attr-name = 'TDUNDERLIN'. 987 | APPEND ls_string_attr TO lt_string_fontattr. 988 | 989 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 990 | EXPORTING 991 | tabname = 'ITCDS' 992 | TABLES 993 | dfies_tab = lt_fieldattr 994 | EXCEPTIONS 995 | NOT_FOUND = 1 996 | OTHERS = 2. 997 | CHECK sy-subrc = 0. 998 | 999 | var2 = 1. 1000 | 1001 | LOOP AT lt_strings INTO DATA(lv_string). 1002 | ASSIGN lv_string TO . 1003 | 1004 | var1 = 0. 1005 | MOVE lv_string-tdstring TO ls_result-id. 1006 | MOVE t_meaning TO ls_result-item. 1007 | MOVE lv_string-tdtext TO ls_result-value. 1008 | var3 = var2. 1009 | APPEND ls_result TO lt_results. 1010 | CLEAR: ls_result-item, ls_result-value. 1011 | ADD 1 TO var2. 1012 | 1013 | MOVE 'Standard Attributes' TO ls_result-item. 1014 | entry = abap_false. 1015 | LOOP AT lt_string_standardattr INTO DATA(wa_stdattr_itcds). 1016 | ASSIGN wa_stdattr_itcds-name TO . 1017 | ASSIGN COMPONENT OF STRUCTURE TO . 1018 | READ TABLE lt_fieldattr INTO DATA(wa_fieldattr) WITH KEY tabname = 'ITCDS' 1019 | fieldname = 1020 | langu = sy-langu. 1021 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 1022 | MOVE TO ls_result-value. 1023 | APPEND ls_result TO lt_results. 1024 | CLEAR: ls_result-attr, ls_result-value. 1025 | entry = abap_true. 1026 | ADD 1 TO var2. 1027 | ENDLOOP. 1028 | 1029 | MOVE 'Font Attributes' TO ls_result-item. 1030 | entry = abap_false. 1031 | LOOP AT lt_string_fontattr INTO DATA(wa_fontattr_itcds). 1032 | ASSIGN wa_fontattr_itcds-name TO . 1033 | ASSIGN COMPONENT OF STRUCTURE TO . 1034 | READ TABLE lt_fieldattr INTO wa_fieldattr WITH KEY tabname = 'ITCDS' 1035 | fieldname = 1036 | langu = sy-langu. 1037 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 1038 | 1039 | MOVE TO ls_result-value. 1040 | APPEND ls_result TO lt_results. 1041 | CLEAR: ls_result-attr, ls_result-value. 1042 | entry = abap_true. 1043 | ADD 1 TO var2. 1044 | ENDLOOP. 1045 | 1046 | ENDLOOP. 1047 | 1048 | CLEAR ls_result. 1049 | 1050 | LOOP AT lt_results INTO ls_result. 1051 | IF sy-tabix = 1. 1052 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1053 | APPEND |Characters Attributes| TO cht_filecontent. 1054 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1055 | APPEND '' TO cht_filecontent. 1056 | ENDIF. 1057 | AT NEW id. 1058 | APPEND '' TO cht_filecontent. 1059 | ENDAT. 1060 | 1061 | AT NEW item. 1062 | IF ls_result-item <> t_meaning. 1063 | 1064 | APPEND |{ ls_result-item WIDTH = 15 }| TO cht_filecontent. 1065 | ENDIF. 1066 | ENDAT. 1067 | IF ls_result-item = t_meaning. 1068 | APPEND |{ ls_result-id WIDTH = 12 }{ ls_result-value WIDTH = 15 }| TO cht_filecontent. 1069 | ELSE. 1070 | APPEND |{ ls_result-attr WIDTH = 18 }{ cl_abap_char_utilities=>horizontal_tab }{ ls_result-value WIDTH = 36 }| TO cht_filecontent. 1071 | ENDIF. 1072 | 1073 | ENDLOOP. 1074 | 1075 | ENDMETHOD. 1076 | 1077 | 1078 | METHOD get_text_txtelement_content. 1079 | TYPES: BEGIN OF ty_intertab, 1080 | flag(1), 1081 | content(135), 1082 | END OF ty_intertab. 1083 | TYPES: tty_intertab TYPE TABLE OF ty_intertab. 1084 | 1085 | DATA: ls_intertab TYPE ty_intertab. 1086 | DATA: lt_intertab TYPE tty_intertab. 1087 | DATA: prev_flag, 1088 | start. 1089 | DATA: tmpwindow TYPE itctw-tdwindow. 1090 | DATA: lt_windows TYPE tty_itctw. 1091 | DATA lt_form_lines TYPE tty_tline. 1092 | 1093 | lt_windows = it_windows. 1094 | lt_form_lines = it_form_lines. 1095 | 1096 | APPEND '' TO cht_filecontent. 1097 | 1098 | DATA(subtitle) = abap_false. 1099 | LOOP AT lt_windows INTO DATA(wa_window). 1100 | CLEAR ls_intertab-content. 1101 | ls_intertab-flag = 'O'. 1102 | REFRESH lt_intertab. 1103 | start = abap_false. 1104 | LOOP AT lt_form_lines ASSIGNING FIELD-SYMBOL(). 1105 | CASE -tdformat. 1106 | WHEN '/W'. 1107 | tmpwindow = -tdline. 1108 | IF tmpwindow = wa_window-tdwindow. 1109 | IF subtitle = abap_false. 1110 | subtitle = abap_true. 1111 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1112 | APPEND |Text Elements for Following Windows: | TO cht_filecontent. 1113 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1114 | APPEND '' TO cht_filecontent. 1115 | ENDIF. 1116 | start = abap_true. 1117 | ls_intertab-flag = 'T'. 1118 | ls_intertab-content = tmpwindow. 1119 | prev_flag = ls_intertab-flag. 1120 | APPEND ls_intertab TO lt_intertab. 1121 | CLEAR ls_intertab-content. 1122 | ELSE. 1123 | IF start = abap_true. 1124 | EXIT. 1125 | ENDIF. 1126 | ENDIF. 1127 | WHEN '/E'. 1128 | IF start = abap_true. 1129 | CLEAR ls_intertab-content. 1130 | APPEND ls_intertab TO lt_intertab. 1131 | ls_intertab-flag = 'E'. 1132 | MOVE -tdformat TO ls_intertab-content(10). 1133 | MOVE -tdline TO ls_intertab-content+10(59). 1134 | CONDENSE ls_intertab-content. 1135 | prev_flag = ls_intertab-flag. 1136 | APPEND ls_intertab TO lt_intertab. 1137 | CLEAR ls_intertab-content. 1138 | ENDIF. 1139 | WHEN OTHERS. 1140 | IF start = abap_true. 1141 | IF prev_flag = 'T'. 1142 | CLEAR ls_intertab-content. 1143 | APPEND ls_intertab TO lt_intertab. 1144 | ENDIF. 1145 | ls_intertab-flag = 'O'. 1146 | MOVE -tdformat TO ls_intertab-content(2). 1147 | MOVE -tdline TO ls_intertab-content+2(132). 1148 | prev_flag = ls_intertab-flag. 1149 | APPEND ls_intertab TO lt_intertab. 1150 | CLEAR ls_intertab-content. 1151 | ENDIF. 1152 | ENDCASE. 1153 | ENDLOOP. 1154 | 1155 | LOOP AT lt_intertab INTO DATA(wa_intertab). 1156 | CASE wa_intertab-flag. 1157 | WHEN 'T'. 1158 | IF wa_intertab-content IS INITIAL. 1159 | SKIP. 1160 | ELSE. 1161 | APPEND |{ wa_intertab-content WIDTH = 255 }| TO cht_filecontent. 1162 | 1163 | ENDIF. 1164 | WHEN 'E'. 1165 | APPEND |{ wa_intertab-content WIDTH = 255 }| TO cht_filecontent. 1166 | WHEN 'O'. 1167 | APPEND |{ wa_intertab-content(2) } { wa_intertab-content+2 }| TO cht_filecontent. 1168 | 1169 | WHEN OTHERS. 1170 | SKIP. 1171 | ENDCASE. 1172 | ENDLOOP. 1173 | ENDLOOP. 1174 | 1175 | ENDMETHOD. 1176 | 1177 | 1178 | METHOD get_text_windows_content. 1179 | 1180 | DATA: ls_window_attr TYPE ty_string_array. 1181 | DATA: lt_window_attr TYPE STANDARD TABLE OF ty_string_array. 1182 | DATA: lt_fieldattr TYPE STANDARD TABLE OF dfies INITIAL SIZE 0. 1183 | DATA: var1 LIKE sy-index. 1184 | DATA: var2 LIKE sy-index. 1185 | DATA: var3 LIKE sy-index. 1186 | DATA: lt_windows TYPE tty_itctw. 1187 | DATA: lt_results TYPE tty_result. 1188 | DATA: ls_result TYPE ts_result. 1189 | DATA: entry. 1190 | 1191 | FIELD-SYMBOLS: TYPE any, TYPE any, TYPE any. 1192 | 1193 | lt_windows = it_windows. 1194 | ************************ Window attribute ***************************** 1195 | ls_window_attr-name = 'TDWTYPE'. 1196 | APPEND ls_window_attr TO lt_window_attr. 1197 | ls_window_attr-name = 'TDFIRSTPAR'. 1198 | APPEND ls_window_attr TO lt_window_attr. 1199 | ls_window_attr-name = 'TDWTYPE'. 1200 | APPEND ls_window_attr TO lt_window_attr. 1201 | 1202 | 1203 | CALL FUNCTION 'DDIF_FIELDINFO_GET' 1204 | EXPORTING 1205 | tabname = 'ITCTW' 1206 | TABLES 1207 | dfies_tab = lt_fieldattr 1208 | EXCEPTIONS 1209 | NOT_FOUND = 1 1210 | OTHERS = 2. 1211 | CHECK sy-subrc = 0. 1212 | 1213 | var2 = 1. 1214 | 1215 | LOOP AT lt_windows INTO DATA(lv_window). 1216 | ASSIGN lv_window TO . 1217 | MOVE lv_window-tdwindow TO ls_result-id. 1218 | MOVE t_meaning TO ls_result-item. 1219 | MOVE lv_window-tdtext TO ls_result-value. 1220 | var3 = var2. 1221 | APPEND ls_result TO lt_results. 1222 | CLEAR: ls_result-item, ls_result-value. 1223 | ADD 1 TO var2. 1224 | 1225 | LOOP AT lt_window_attr INTO DATA(wa_window_attr_itctw). 1226 | ASSIGN wa_window_attr_itctw-name TO . 1227 | ASSIGN COMPONENT OF STRUCTURE TO . 1228 | READ TABLE lt_fieldattr INTO DATA(wa_fieldattr) WITH KEY tabname = 'ITCTW' 1229 | fieldname = 1230 | langu = sy-langu. 1231 | MOVE wa_fieldattr-scrtext_m TO ls_result-attr. 1232 | MOVE TO ls_result-value. 1233 | APPEND ls_result TO lt_results. 1234 | CLEAR: ls_result-attr, ls_result-value. 1235 | entry = abap_true. 1236 | ADD 1 TO var2. 1237 | ENDLOOP. 1238 | 1239 | READ TABLE lt_results INTO ls_result INDEX var3. 1240 | ls_result-vol = var2 - var3 + var1. 1241 | MODIFY lt_results FROM ls_result INDEX var3. 1242 | CLEAR ls_result-vol. 1243 | 1244 | ENDLOOP. 1245 | 1246 | APPEND '' TO cht_filecontent. 1247 | 1248 | LOOP AT lt_results INTO ls_result. 1249 | IF sy-tabix = 1. 1250 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1251 | APPEND |Windows Attributes| TO cht_filecontent. 1252 | APPEND |{ space WIDTH = 80 PAD = '-' }| TO cht_filecontent. 1253 | APPEND '' TO cht_filecontent. 1254 | ENDIF. 1255 | AT NEW id. 1256 | APPEND '' TO cht_filecontent. 1257 | ENDAT. 1258 | 1259 | AT NEW item. 1260 | IF ls_result-item <> t_meaning. 1261 | * APPEND |{ ls_result-id WIDTH = 3 }{ ls_result-value WIDTH = 40 }| TO et_filecontent. 1262 | * ELSE. 1263 | APPEND |{ ls_result-item WIDTH = 15 }| TO cht_filecontent. 1264 | ENDIF. 1265 | ENDAT. 1266 | IF ls_result-item = t_meaning. 1267 | APPEND |{ ls_result-id WIDTH = 12 }{ ls_result-value WIDTH = 15 }| TO cht_filecontent. 1268 | ELSE. 1269 | APPEND |{ ls_result-attr WIDTH = 18 }{ cl_abap_char_utilities=>horizontal_tab }{ ls_result-value WIDTH = 36 }| TO cht_filecontent. 1270 | ENDIF. 1271 | 1272 | ENDLOOP. 1273 | 1274 | ENDMETHOD. 1275 | 1276 | 1277 | method GET_WDYC_BY_WDYN. 1278 | DATA lt_wdyc_name TYPE TABLE OF wdy_controller. 1279 | select component_name, controller_name, version from wdy_controller where component_name = @iv_wdyn_name and ( controller_type eq 00 or controller_type eq 02 ) 1280 | into table @lt_wdyc_name. 1281 | et_wdyc_name = lt_wdyc_name. 1282 | endmethod. 1283 | ENDCLASS. --------------------------------------------------------------------------------