├── .abapgit.xml ├── LICENSE ├── LICENSES └── Apache-2.0.txt ├── README.md ├── REUSE.toml └── src ├── package.devc.xml ├── z_alv_oa2c_config_extension.enho.xml ├── z_alv_oa2c_specifics.enho.xml ├── z_googlepoc_drive_api.prog.abap ├── z_googlepoc_drive_api.prog.xml ├── z_salv_enh_google_sheets.enho.xml ├── zcl_googlepoc_cert_validation.clas.abap ├── zcl_googlepoc_cert_validation.clas.testclasses.abap ├── zcl_googlepoc_cert_validation.clas.xml ├── zcl_googlepoc_drive_impl.clas.abap ├── zcl_googlepoc_drive_impl.clas.xml ├── zcl_googlepoc_drive_log_impl.clas.abap ├── zcl_googlepoc_drive_log_impl.clas.xml ├── zcl_googlepoc_drive_ui2_json.clas.abap ├── zcl_googlepoc_drive_ui2_json.clas.xml ├── zcl_googlepoc_rfc3339_datetime.clas.abap ├── zcl_googlepoc_rfc3339_datetime.clas.xml ├── zcl_oa2c_ce_zgoogle.clas.abap ├── zcl_oa2c_ce_zgoogle.clas.xml ├── zcl_oa2c_specifics_zgoogle.clas.abap ├── zcl_oa2c_specifics_zgoogle.clas.xml ├── zcl_salv_enh_google_sheets.clas.abap ├── zcl_salv_enh_google_sheets.clas.xml ├── zcl_salv_wd_google_redirect.clas.abap ├── zcl_salv_wd_google_redirect.clas.xml ├── zif_googlepoc_drive_api.intf.abap ├── zif_googlepoc_drive_api.intf.xml ├── zif_googlepoc_drive_json_api.intf.abap ├── zif_googlepoc_drive_json_api.intf.xml ├── zif_googlepoc_drive_log_api.intf.abap ├── zif_googlepoc_drive_log_api.intf.xml ├── zwd_google_token_redirect.wdya.xml └── zwd_google_token_redirect.wdyn.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | FULL 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | /NOTICE 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | @@ -0,0 +1,208 @@ 2 | Apache License 3 | 4 | Version 2.0, January 2004 5 | 6 | http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, 7 | AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, and distribution 14 | as defined by Sections 1 through 9 of this document. 15 | 16 | 17 | 18 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 19 | owner that is granting the License. 20 | 21 | 22 | 23 | "Legal Entity" shall mean the union of the acting entity and all other entities 24 | that control, are controlled by, or are under common control with that entity. 25 | For the purposes of this definition, "control" means (i) the power, direct 26 | or indirect, to cause the direction or management of such entity, whether 27 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or more 28 | of the outstanding shares, or (iii) beneficial ownership of such entity. 29 | 30 | 31 | 32 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions 33 | granted by this License. 34 | 35 | 36 | 37 | "Source" form shall mean the preferred form for making modifications, including 38 | but not limited to software source code, documentation source, and configuration 39 | files. 40 | 41 | 42 | 43 | "Object" form shall mean any form resulting from mechanical transformation 44 | or translation of a Source form, including but not limited to compiled object 45 | code, generated documentation, and conversions to other media types. 46 | 47 | 48 | 49 | "Work" shall mean the work of authorship, whether in Source or Object form, 50 | made available under the License, as indicated by a copyright notice that 51 | is included in or attached to the work (an example is provided in the Appendix 52 | below). 53 | 54 | 55 | 56 | "Derivative Works" shall mean any work, whether in Source or Object form, 57 | that is based on (or derived from) the Work and for which the editorial revisions, 58 | annotations, elaborations, or other modifications represent, as a whole, an 59 | original work of authorship. For the purposes of this License, Derivative 60 | Works shall not include works that remain separable from, or merely link (or 61 | bind by name) to the interfaces of, the Work and Derivative Works thereof. 62 | 63 | 64 | 65 | "Contribution" shall mean any work of authorship, including the original version 66 | of the Work and any modifications or additions to that Work or Derivative 67 | Works thereof, that is intentionally submitted to Licensor for inclusion in 68 | the Work by the copyright owner or by an individual or Legal Entity authorized 69 | to submit on behalf of the copyright owner. For the purposes of this definition, 70 | "submitted" means any form of electronic, verbal, or written communication 71 | sent to the Licensor or its representatives, including but not limited to 72 | communication on electronic mailing lists, source code control systems, and 73 | issue tracking systems that are managed by, or on behalf of, the Licensor 74 | for the purpose of discussing and improving the Work, but excluding communication 75 | that is conspicuously marked or otherwise designated in writing by the copyright 76 | owner as "Not a Contribution." 77 | 78 | 79 | 80 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 81 | of whom a Contribution has been received by Licensor and subsequently incorporated 82 | within the Work. 83 | 84 | 2. Grant of Copyright License. Subject to the terms and conditions of this 85 | License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 86 | no-charge, royalty-free, irrevocable copyright license to reproduce, prepare 87 | Derivative Works of, publicly display, publicly perform, sublicense, and distribute 88 | the Work and such Derivative Works in Source or Object form. 89 | 90 | 3. Grant of Patent License. Subject to the terms and conditions of this License, 91 | each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 92 | no-charge, royalty-free, irrevocable (except as stated in this section) patent 93 | license to make, have made, use, offer to sell, sell, import, and otherwise 94 | transfer the Work, where such license applies only to those patent claims 95 | licensable by such Contributor that are necessarily infringed by their Contribution(s) 96 | alone or by combination of their Contribution(s) with the Work to which such 97 | Contribution(s) was submitted. If You institute patent litigation against 98 | any entity (including a cross-claim or counterclaim in a lawsuit) alleging 99 | that the Work or a Contribution incorporated within the Work constitutes direct 100 | or contributory patent infringement, then any patent licenses granted to You 101 | under this License for that Work shall terminate as of the date such litigation 102 | is filed. 103 | 104 | 4. Redistribution. You may reproduce and distribute copies of the Work or 105 | Derivative Works thereof in any medium, with or without modifications, and 106 | in Source or Object form, provided that You meet the following conditions: 107 | 108 | (a) You must give any other recipients of the Work or Derivative Works a copy 109 | of this License; and 110 | 111 | (b) You must cause any modified files to carry prominent notices stating that 112 | You changed the files; and 113 | 114 | (c) You must retain, in the Source form of any Derivative Works that You distribute, 115 | all copyright, patent, trademark, and attribution notices from the Source 116 | form of the Work, excluding those notices that do not pertain to any part 117 | of the Derivative Works; and 118 | 119 | (d) If the Work includes a "NOTICE" text file as part of its distribution, 120 | then any Derivative Works that You distribute must include a readable copy 121 | of the attribution notices contained within such NOTICE file, excluding those 122 | notices that do not pertain to any part of the Derivative Works, in at least 123 | one of the following places: within a NOTICE text file distributed as part 124 | of the Derivative Works; within the Source form or documentation, if provided 125 | along with the Derivative Works; or, within a display generated by the Derivative 126 | Works, if and wherever such third-party notices normally appear. The contents 127 | of the NOTICE file are for informational purposes only and do not modify the 128 | License. You may add Your own attribution notices within Derivative Works 129 | that You distribute, alongside or as an addendum to the NOTICE text from the 130 | Work, provided that such additional attribution notices cannot be construed 131 | as modifying the License. 132 | 133 | You may add Your own copyright statement to Your modifications and may provide 134 | additional or different license terms and conditions for use, reproduction, 135 | or distribution of Your modifications, or for any such Derivative Works as 136 | a whole, provided Your use, reproduction, and distribution of the Work otherwise 137 | complies with the conditions stated in this License. 138 | 139 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 140 | Contribution intentionally submitted for inclusion in the Work by You to the 141 | Licensor shall be under the terms and conditions of this License, without 142 | any additional terms or conditions. Notwithstanding the above, nothing herein 143 | shall supersede or modify the terms of any separate license agreement you 144 | may have executed with Licensor regarding such Contributions. 145 | 146 | 6. Trademarks. This License does not grant permission to use the trade names, 147 | trademarks, service marks, or product names of the Licensor, except as required 148 | for reasonable and customary use in describing the origin of the Work and 149 | reproducing the content of the NOTICE file. 150 | 151 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to 152 | in writing, Licensor provides the Work (and each Contributor provides its 153 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 154 | KIND, either express or implied, including, without limitation, any warranties 155 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR 156 | A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness 157 | of using or redistributing the Work and assume any risks associated with Your 158 | exercise of permissions under this License. 159 | 160 | 8. Limitation of Liability. In no event and under no legal theory, whether 161 | in tort (including negligence), contract, or otherwise, unless required by 162 | applicable law (such as deliberate and grossly negligent acts) or agreed to 163 | in writing, shall any Contributor be liable to You for damages, including 164 | any direct, indirect, special, incidental, or consequential damages of any 165 | character arising as a result of this License or out of the use or inability 166 | to use the Work (including but not limited to damages for loss of goodwill, 167 | work stoppage, computer failure or malfunction, or any and all other commercial 168 | damages or losses), even if such Contributor has been advised of the possibility 169 | of such damages. 170 | 171 | 9. Accepting Warranty or Additional Liability. While redistributing the Work 172 | or Derivative Works thereof, You may choose to offer, and charge a fee for, 173 | acceptance of support, warranty, indemnity, or other liability obligations 174 | and/or rights consistent with this License. However, in accepting such obligations, 175 | You may act only on Your own behalf and on Your sole responsibility, not on 176 | behalf of any other Contributor, and only if You agree to indemnify, defend, 177 | and hold each Contributor harmless for any liability incurred by, or claims 178 | asserted against, such Contributor by reason of your accepting any such warranty 179 | or additional liability. END OF TERMS AND CONDITIONS 180 | 181 | APPENDIX: How to apply the Apache License to your work. 182 | 183 | To apply the Apache License to your work, attach the following boilerplate 184 | notice, with the fields enclosed by brackets "[]" replaced with your own identifying 185 | information. (Don't include the brackets!) The text should be enclosed in 186 | the appropriate comment syntax for the file format. We also recommend that 187 | a file or class name and description of purpose be included on the same "printed 188 | page" as the copyright notice for easier identification within third-party 189 | archives. 190 | 191 | Copyright [yyyy] [name of copyright owner] 192 | 193 | Licensed under the Apache License, Version 2.0 (the "License"); 194 | 195 | you may not use this file except in compliance with the License. 196 | 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | 203 | distributed under the License is distributed on an "AS IS" BASIS, 204 | 205 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 206 | 207 | See the License for the specific language governing permissions and 208 | 209 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/abap-alv-google-upload-sheet)](https://api.reuse.software/info/github.com/SAP-samples/abap-alv-google-upload-sheet) 2 | 3 | # Integration of Google Sheets into ABAP List Viewer 4 | 5 | ## Important note before starting your project setup/configuration 6 | We are happy to announce that Google Cloud and SAP have expanded their partnership to enable a native integration between Google Workspace and SAP S/4HANA. Our customers now have the possibility to export data from all important UI Tables to Google Sheets as well as a table import from Google Sheets to the Upload General Journal Entries application. This initial set of features is included in **SAP S/4HANA Cloud 2208 and S/4HANA 2022**, leveraging an SAP Business Technology Platform service (additional license required: SAP Document Management Service, integration option). 7 | 8 | Please feel free to check out our [public documentation and set-up guide](https://help.sap.com/docs/DOCUMENT_MANAGEMENT/f6e70dd4bffa4b65965b43feed4c9429/594bf95dbab64358aef97a73296b6054.html) as well as our 9 | blog posts: 10 | - [Seamless integration between SAP S/4HANA & Google Workspace](https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/seamless-integration-between-sap-s-4hana-google-workspace/ba-p/13535025) 11 | - [SAP’s UI Technologies enabling Google Workspace](https://community.sap.com/t5/technology-blogs-by-sap/sap-s-ui-technologies-enabling-google-workspace/ba-p/13540756) 12 | 13 | ## Project Description 14 | This project comprises an archive containing sample source code for the integration of Google Sheets into the ABAP List Viewer (ALV) component. Thus, this sample code helps you to implement and configure the export of ALV grid data from SAP GUI directly to Google Drive and display exported data snapshots automatically in Google Sheets. 15 | 16 | ## Minimum Requirements 17 | 18 | - This functionality is only available for certain SAP NetWeaver support packages, see [note 2592115](http://service.sap.com/sap/support/notes/2592115). 19 | - After installation of the corresponding Support Package, it is **mandatory** to implement [note 2624404](http://service.sap.com/sap/support/notes/2624404) (ALV GUI: BAdi Export Integration Corrections). 20 | 21 | ## Download and Installation 22 | 23 | ### Proceed as follows to make best use of the sample code: 24 | 25 | 1. Clone the repository or use the [abapGit client](https://docs.abapgit.org/) to [import](https://docs.abapgit.org/guide-import-zip.html) the sources into your SAP system. 26 | 2. Setup the Google API Endpoint (see chapter 2.2 in [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html) ) 27 | 3. Create a Service Provider Type for Google (see chapter 2.3.1 [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html)) 28 | 4. Create an OAuth 2.0 Client Profile (see chapter 2.3.6 [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html)) 29 | 5. Configure the Access to Google APIs (see chapter 2.4 [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html)) 30 | 6. Check the Connection (see chapter 2.5. [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html)) 31 | 7. ALV ABAP administration (see chapter 3.2 [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html)) 32 | 33 | ## Configuration Guide 34 | 35 | See the full documentation [Export of ALV Grid Data to Google Sheets](https://www.sap.com/documents/2018/07/56e0dd6d-0f7d-0010-87a3-c30de2ffd8ff.html) available in the SAP Community. 36 | 37 | ## Limitations 38 | 39 | - The redirect URL called by Google requires a public top level domain server. 40 | - There is no way to use an Enterprise account or logon to Google Drive via SSO – every end user needs a regular Google account. 41 | 42 | ## Known Issues 43 | 44 | None. 45 | 46 | ## How to obtain support 47 | 48 | **No SAP standard support** provided: Consult **SAP [note 2896606](http://service.sap.com/sap/support/notes/2896606) for details**. 49 | 50 | You can ask your questions concerning this functionality in the [SAP Community](https://www.sap.com/community.html). Please, use _ABAP Development_ as primary tag and choose _alv_ as additional user tag. 51 | 52 | You find an overview of all ALV questions under: [https://answers.sap.com/topics/alv.html](https://answers.sap.com/topics/alv.html). 53 | 54 | ## Contribution 55 | 56 | An SAP Code Sample such as this is open software but is not quite a typical full-blown open source project. If you come across a problem, we’d encourage you to check the project’s [issue tracker](https://github.com/SAP-samples/abap-alv-google-upload-sheet/issues) and to [file a new issue](https://github.com/SAP-samples/abap-alv-google-upload-sheet/issues/new) if needed. If you are especially passionate about something you’d like to improve, you are welcome to fork the repository and submit improvements or changes as a pull request. 57 | 58 | ## License 59 | Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file. 60 | 61 | Note that the sample code includes calls to the Google Drive APIs which calls are licensed under the Creative Commons Attribution 3.0 License _(_[_https://creativecommons.org/licenses/by/3.0/_](https://creativecommons.org/licenses/by/3.0/)_)_ in accordance with Google's Developer Site Policies _(_[_https://developers.google.com/terms/site-policies_](https://developers.google.com/terms/site-policies)_)._ Furthermore, the use of the Google Drive service is subject to applicable agreements with Google Inc. 62 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | SPDX-PackageName = "abap-alv-google-upload-sheet" 3 | SPDX-PackageSupplier = "Klaus-Dieter Scherer " 4 | SPDX-PackageDownloadLocation = "https://github.com/SAP-samples/abap-alv-google-upload-sheet" 5 | SPDX-PackageComment = "The code in this project may include calls to APIs (“API Calls”) of\n SAP or third-party products or services developed outside of this project\n (“External Products”).\n “APIs” means application programming interfaces, as well as their respective\n specifications and implementing code that allows software to communicate with\n other software.\n API Calls to External Products are not licensed under the open source license\n that governs this project. The use of such API Calls and related External\n Products are subject to applicable additional agreements with the relevant\n provider of the External Products. In no event shall the open source license\n that governs this project grant any rights in or to any External Products,or\n alter, expand or supersede any terms of the applicable additional agreements.\n If you have a valid license agreement with SAP for the use of a particular SAP\n External Product, then you may make use of any API Calls included in this\n project’s code for that SAP External Product, subject to the terms of such\n license agreement. If you do not have a valid license agreement for the use of\n a particular SAP External Product, then you may only make use of any API Calls\n in this project for that SAP External Product for your internal, non-productive\n and non-commercial test and evaluation of such API Calls. Nothing herein grants\n you any rights to use or access any SAP External Product, or provide any third\n parties the right to use of access any SAP External Product, through API Calls." 6 | 7 | [[annotations]] 8 | path = "**" 9 | precedence = "aggregate" 10 | SPDX-FileCopyrightText = "2021 SAP SE or an SAP affiliate company and abap-alv-google-upload-sheet" 11 | SPDX-License-Identifier = "Apache-2.0" 12 | -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Test Google Sheets Integration 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/z_alv_oa2c_config_extension.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | BADI_IMPL 6 | ALV OAuth 2.0 Client Configuration Extension Implementation 7 | OA2C_CONFIG_EXTENSION 8 | 9 | 10 | OA2C_CONFIG_EXTENSION 11 | OA2C_CONFIG_EXTENSION_BADI_DEF 12 | Z_ALV_OA2C_CE_ZGOOGLE 13 | ZCL_OA2C_CE_ZGOOGLE 14 | X 15 | 16 | 17 | 1 18 | 19 | 20 | CONFIG_EXTENSION 21 | 1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | CONFIG_EXTENSION 30 | C 31 | = 32 | ZGOOGLE 33 | 34 | 35 | 36 | 37 | 1 38 | 1 39 | CONFIG_EXTENSION 40 | C 41 | = 42 | ZGOOGLE 43 | 44 | 45 | Implementation: OAuth 2.0 Client Configuration Extension 46 | 00505695007C1EE7A29BA343BEC29218 47 | 48 | 49 | 50 | 51 |
52 | 005056AB5B8D1ED98FCD49067568323A 53 | E 54 | 1 55 | AAI= 56 |
57 | 58 | 59 | 005056AB5B8D1ED98FCD49067568323A 60 | E 61 | 0001 62 | X 63 | R 64 | 089 65 | ALV OAuth 2.0 Client Configuration Extension Implementation 66 | 67 | 68 |
69 |
70 | 71 | 72 | R3TR 73 | ENHO 74 | Z_ALV_OA2C_CONFIG_EXTENSION 75 | 005056AB5B8D1ED98FCD49067568323A 76 | 0001 77 | 78 | 79 |
80 |
81 |
82 | -------------------------------------------------------------------------------- /src/z_alv_oa2c_specifics.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | BADI_IMPL 6 | ALV OAuth 2.0 Client Specific Implementation 7 | OA2C_SPECIFICS 8 | 9 | 10 | OA2C_SPECIFICS 11 | OA2C_SPECIFICS_BADI_DEF 12 | Z_ALV_OA2C_SPECIFICS_ZGOOGLE 13 | ZCL_OA2C_SPECIFICS_ZGOOGLE 14 | X 15 | 16 | 17 | 1 18 | 19 | 20 | IMPLEMENTATION_NAME 21 | 1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 1 29 | IMPLEMENTATION_NAME 30 | C 31 | = 32 | ZGOOGLE 33 | 34 | 35 | 36 | 37 | 1 38 | 1 39 | IMPLEMENTATION_NAME 40 | C 41 | = 42 | ZGOOGLE 43 | 44 | 45 | Implementation: OAuth 2.0 Client Service Provider Specific Settings 46 | 00505695007C1EE7A29B806E3441F17A 47 | 48 | 49 | 50 | 51 |
52 | 005056AB5B8D1ED98FCD495F9CDD123A 53 | E 54 | 1 55 | AAI= 56 |
57 | 58 | 59 | 005056AB5B8D1ED98FCD495F9CDD123A 60 | E 61 | 0001 62 | X 63 | R 64 | 066 65 | ALV OAuth 2.0 Client Specific Implementation 66 | 67 | 68 |
69 |
70 | 71 | 72 | R3TR 73 | ENHO 74 | Z_ALV_OA2C_SPECIFICS 75 | 005056AB5B8D1ED98FCD495F9CDD123A 76 | 0001 77 | 78 | 79 |
80 |
81 |
82 | -------------------------------------------------------------------------------- /src/z_googlepoc_drive_api.prog.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Example program that invokes the Google Drive REST API. The 3 | "! authentication is done via an ABAP OAuth 2.0 Client with a Google specific configuration profile. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | report z_googlepoc_drive_api. 25 | 26 | parameters profile type oa2c_profile 27 | default zcl_googlepoc_drive_impl=>default_oauth_20_profile. 28 | 29 | "!

30 | "! Sample Google Drive application for demonstration purpose. 31 | "!

32 | "! 33 | "!

34 | "! See https://developers.google.com/drive/ 35 | "!

36 | "! 37 | "!

38 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 39 | "!
40 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 41 | "! the LICENSE FILE 42 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 43 | "!
44 | "!
45 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 46 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 47 | "! accordance with Google's Developer Site Policies 48 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 49 | "! service is subject to applicable agreements with Google Inc. 50 | "!

51 | class lcl_google_drive_app definition 52 | create public 53 | final. 54 | 55 | 56 | public section. 57 | 58 | "! The name of the default target Google Drive folder to upload to. 59 | constants target_folder type zif_googlepoc_drive_api=>file_resource_name 60 | value `SAP Exports` ##NO_TEXT. 61 | 62 | "! Constructs a new Google Drive App instance. 63 | "! 64 | "! @parameter oa2c_profile_name | The name of the OAuth 2.0 profile to use. 65 | "! 66 | "! @raising cx_oa2c | In case the internally used OAuth 2.0 client could not be created. 67 | methods constructor 68 | importing 69 | oa2c_profile_name type oa2c_profile optional 70 | raising 71 | cx_oa2c. 72 | 73 | "! Application main method. 74 | methods main. 75 | 76 | "!

77 | "! Determines if this instance has a valid OAuth 2.0 token, i.e. if access is allowed. If a 78 | "! valid access token exists, this method returns abap_true. Otherwise it 79 | "! tries to request a refresh token. If a valid refresh token was received, 80 | "! abap_true is returned. 81 | "!

82 | "!

83 | "! In all other cases abap_false is returned. 84 | "!

85 | "!

86 | "! This method can be leveraged prior to any REST API calls in order to test if an access is 87 | "! allowed at all. 88 | "!

89 | "! 90 | "! @parameter result | abap_true if a valid OAuth 2.0 exists; abap_false 91 | "! otherwise. 92 | methods has_valid_token 93 | returning 94 | value(result) type abap_bool. 95 | 96 | "! Determines if a valid Google certificate in the Personal Security Environment (PSE) exists. 97 | "! 98 | "! @parameter is_valid | abap_true if a valid certificate has been found; 99 | "! abap_false otherwise. 100 | "! @parameter message | A message describing the validation error in case the validation failed. 101 | methods validate_certificate 102 | exporting 103 | is_valid type abap_bool 104 | message type string. 105 | 106 | "! Lists all files in the Google Drive. 107 | methods list_all_files. 108 | 109 | "! Outputs the log entries of the Google Drive API. 110 | methods output_log. 111 | 112 | 113 | private section. 114 | 115 | "! The Google Drive Client API. 116 | data drive_api type ref to zif_googlepoc_drive_api. 117 | 118 | "! Gets the ID of the folder with the given name from the Google Drive. 119 | "! 120 | "! @parameter folder_name | The name of the folder. 121 | "! @parameter create_if_not_existing | abap_true to create the folder if it does not 122 | "! exist yet; abap_false to not create it. 123 | "! @parameter result | The ID of the folder; initial if no folder with that name 124 | "! exists. 125 | methods get_drive_folder_id 126 | importing 127 | folder_name type zif_googlepoc_drive_api=>file_resource_name 128 | default target_folder 129 | create_if_not_existing type abap_bool default abap_true 130 | returning 131 | value(result) type zif_googlepoc_drive_api=>file_resource_id. 132 | 133 | 134 | endclass. 135 | 136 | 137 | class lcl_google_drive_app implementation. 138 | 139 | 140 | method constructor. 141 | me->drive_api = new zcl_googlepoc_drive_impl( 142 | oa2c_profile_name = oa2c_profile_name 143 | json_api = new zcl_googlepoc_drive_ui2_json( ) ). 144 | endmethod. 145 | 146 | 147 | method main. 148 | write `OAuth Client Access Token` ##NO_TEXT. 149 | new-line. 150 | write `-------------------------` ##NO_TEXT. 151 | new-line. 152 | 153 | data(has_valid_token) = me->has_valid_token( ). 154 | if has_valid_token = abap_true. 155 | write `A valid access token exists.` ##NO_TEXT. 156 | skip 1. 157 | 158 | me->list_all_files( ). 159 | me->output_log( ). 160 | 161 | skip 1. 162 | write `Google Certificate Validation` ##NO_TEXT. 163 | new-line. 164 | write `-----------------------------` ##NO_TEXT. 165 | new-line. 166 | 167 | me->validate_certificate( 168 | importing 169 | is_valid = data(is_certificate_valid) 170 | message = data(validation_message) ). 171 | write validation_message. 172 | else. 173 | write `No valid access token exists.` ##NO_TEXT. 174 | new-line. 175 | endif. 176 | endmethod. 177 | 178 | 179 | method has_valid_token. 180 | result = me->drive_api->has_valid_token( ). 181 | endmethod. 182 | 183 | 184 | method validate_certificate. 185 | clear: is_valid, message. 186 | 187 | data(certificate_validation) = new zcl_googlepoc_cert_validation( ). 188 | if certificate_validation->is_available( ) = abap_true. 189 | message = `Google certificate was found in PSE.` ##NO_TEXT. 190 | if certificate_validation->is_valid( ) = abap_true. 191 | is_valid = abap_true. 192 | message = message && ` Google certificate in PSE is valid.` ##NO_TEXT. 193 | else. 194 | message = `Google certificate in PSE has expired and needs to be replaced.` ##NO_TEXT. 195 | endif. 196 | else. 197 | message = `Google certificate was not found in PSE.` ##NO_TEXT. 198 | endif. 199 | endmethod. 200 | 201 | 202 | method list_all_files. 203 | write `Listing all files in Google Drive` ##NO_TEXT. 204 | new-line. 205 | write `---------------------------------` ##NO_TEXT. 206 | new-line. 207 | 208 | data(files) = me->drive_api->list_all_files( ). 209 | loop at files assigning field-symbol(). 210 | write |File # { sy-tabix }| ##NO_TEXT. 211 | new-line. 212 | write |ID: { -id }| ##NO_TEXT. 213 | new-line. 214 | write |Name: { -name }| ##NO_TEXT. 215 | new-line. 216 | write |Mime Type: { -mime_type }| ##NO_TEXT. 217 | new-line. 218 | write |Web View Link: { -web_view_link }| ##NO_TEXT. 219 | new-line. 220 | 221 | loop at -parents assigning field-symbol(). 222 | write |Parent ID [{ sy-tabix }]: { }| ##NO_TEXT. 223 | new-line. 224 | endloop. 225 | skip. 226 | endloop. 227 | 228 | new-line. 229 | endmethod. 230 | 231 | 232 | method output_log. 233 | write `Log entries` ##NO_TEXT. 234 | new-line. 235 | write `-----------` ##NO_TEXT. 236 | new-line. 237 | 238 | me->drive_api->get_log( 239 | importing 240 | result = data(log_entries) ). 241 | loop at log_entries assigning field-symbol(). 242 | write -date dd/mm/yyyy. 243 | write -time environment time format. 244 | write |{ -message }|. 245 | new-line. 246 | endloop. 247 | endmethod. 248 | 249 | 250 | method get_drive_folder_id. 251 | data folder type zif_googlepoc_drive_api=>file_resource. 252 | 253 | data(folder_resources) = me->drive_api->get_files_metadata( 254 | name = folder_name 255 | mime_type = zif_googlepoc_drive_api=>supported_mime_types-folder ). 256 | if folder_resources is initial. 257 | if create_if_not_existing = abap_true. 258 | folder = me->drive_api->create_file_metadata( 259 | name = folder_name 260 | mime_type = zif_googlepoc_drive_api=>supported_mime_types-folder ). 261 | endif. 262 | else. 263 | folder = folder_resources[ 1 ]. 264 | endif. 265 | 266 | result = folder-id. 267 | endmethod. 268 | 269 | 270 | endclass. 271 | 272 | 273 | at selection-screen. 274 | 275 | start-of-selection. 276 | try. 277 | data(app) = new lcl_google_drive_app( profile ). 278 | app->main( ). 279 | catch cx_oa2c into data(oa2c_exc). 280 | write |Error creating Google Drive client: { oa2c_exc->get_text( ) }| ##NO_TEXT. 281 | new-line. 282 | endtry. 283 | -------------------------------------------------------------------------------- /src/z_googlepoc_drive_api.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Z_GOOGLEPOC_DRIVE_API 7 | S 8 | 1 9 | X 10 | D$S 11 | X 12 | 13 | 14 | 15 | R 16 | Demo program invoking the Google Drive API 17 | 42 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/z_salv_enh_google_sheets.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | BADI_IMPL 6 | Enhancement Implementation Google Sheets 7 | SALV_JBP_ENH_DATA_PUBLISHER 8 | 9 | 10 | SALV_JBP_ENH_DATA_PUBLISHER 11 | SALV_JPB_BADI_DATA_PUBLISHER 12 | Z_SALV_BADI_GOOGLE_SHEETS 13 | ZCL_SALV_ENH_GOOGLE_SHEETS 14 | X 15 | X 16 | Implementation: BAdi Definition ALV Data Publisher 17 | 00505695007C1EE7BDBC29D65134BA60 18 | X 19 | 20 | 21 | 22 | 23 |
24 | 005056AB5B8D1ED98FCD49B32BA6523A 25 | E 26 | 1 27 | AAI= 28 |
29 | 30 | 31 | 005056AB5B8D1ED98FCD49B32BA6523A 32 | E 33 | 0001 34 | X 35 | R 36 | 060 37 | Enhancement Implementation Google Sheets 38 | 39 | 40 |
41 | 42 |
43 | 7CFE90B75C001EEBA6F3DB7BF0395365 44 | E 45 | 1 46 | AAI= 47 |
48 | 49 | 50 | 7CFE90B75C001EEBA6F3DB7BF0395365 51 | E 52 | 0001 53 | X 54 | R 55 | 255 56 | Implementation for SAP Document Management Service 57 | 58 | 59 |
60 |
61 | 62 | 63 | R3TR 64 | ENHO 65 | Z_SALV_ENH_GOOGLE_SHEETS 66 | 005056AB5B8D1ED98FCD49B32BA6523A 67 | 0001 68 | 69 | 70 | R3TR 71 | ENHO 72 | Z_SALV_ENH_GOOGLE_SHEETS 73 | 7CFE90B75C001EEBA6F3DB7BF0395365 74 | 0001 75 | 76 | 77 |
78 |
79 |
80 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_cert_validation.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Validates a Google certificate in the Personal Security Environment (PSE). The validation only 3 | "! comprises measures to test the availability of the certificate in the PSE and ensure that it is 4 | "! still valid, i.e. has not expired yet. It does not ensure the trust and 5 | "! acceptance by a Google Server. 6 | "!

7 | "! 8 | "!

9 | "! See https://developers.google.com/drive/ 10 | "!

11 | "! 12 | "!

13 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 14 | "!
15 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 16 | "! the LICENSE FILE 17 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 18 | "!
19 | "!
20 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 21 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 22 | "! accordance with Google's Developer Site Policies 23 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 24 | "! service is subject to applicable agreements with Google Inc. 25 | "!

26 | class zcl_googlepoc_cert_validation definition 27 | public 28 | final 29 | create public. 30 | 31 | 32 | public section. 33 | 34 | "! Constructs a new Google certificate validation instance. 35 | methods constructor. 36 | 37 | "! Determines if a Google certificate is available in the PSE. 38 | "! 39 | "! @parameter result | abap_true if a Google certificate is available; 40 | "! abap_false otherwise. 41 | methods is_available 42 | returning 43 | value(result) type abap_bool. 44 | 45 | "! Determines if a Google certificate in the PSE is valid, i.e. has not expired. 46 | "! 47 | "! @parameter result | abap_true if a Google certificate is valid; abap_false 48 | "! otherwise. 49 | methods is_valid 50 | returning 51 | value(result) type abap_bool. 52 | 53 | 54 | private section. 55 | 56 | "! The PSE Application to use for validation. 57 | constants default_pse_application type ssfappl value `ANONYM` ##NO_TEXT. 58 | 59 | "! The PSE Context to use for validation. 60 | constants default_pse_context type psecontext value `SSLC` ##NO_TEXT. 61 | 62 | "! The common name (cn) of the Google certificate to address. 63 | constants google_cn type string value `Google` ##NO_TEXT. 64 | 65 | "! The stored certificate. 66 | data certificate type ref to cl_abap_x509_certificate. 67 | 68 | "! Gets the certificate. 69 | "! 70 | "! @parameter result | The retrieved certificate. 71 | methods get_certificate 72 | returning 73 | value(result) type ref to cl_abap_x509_certificate. 74 | 75 | "! Determines if the Personal Security Environment (PSE) is available. 76 | "! 77 | "! @parameter result | abap_true if the PSE is available; abap_false 78 | "! otherwise. 79 | methods is_pse_available 80 | returning 81 | value(result) type abap_bool. 82 | 83 | 84 | endclass. 85 | 86 | 87 | class zcl_googlepoc_cert_validation implementation. 88 | 89 | 90 | method constructor. 91 | if me->is_pse_available( ) = abap_true. 92 | me->certificate = me->get_certificate( ). 93 | endif. 94 | endmethod. 95 | 96 | 97 | method get_certificate. 98 | try. 99 | data(pse) = new cl_abap_pse( iv_context = default_pse_context 100 | iv_application = default_pse_application ). 101 | pse->get_trusted_certificates( 102 | importing 103 | et_certificate_list = data(certificate_binaries) 104 | et_certificate_list_typed = data(certificates) ). 105 | 106 | data certificate_index type syst_tabix. 107 | loop at certificates assigning field-symbol() 108 | where subject cp |CN=*{ google_cn }*| ##NO_TEXT. 109 | certificate_index = sy-tabix. 110 | exit. 111 | endloop. 112 | 113 | field-symbols type xstring. 114 | if certificate_index is not initial. 115 | try. 116 | result = cl_abap_x509_certificate=>get_instance( 117 | certificate_binaries[ certificate_index ] ). 118 | catch cx_abap_x509_certificate ##NO_HANDLER. 119 | endtry. 120 | endif. 121 | catch cx_abap_pse ##NO_HANDLER. 122 | endtry. 123 | endmethod. 124 | 125 | 126 | method is_available. 127 | result = cond #( when me->certificate is bound 128 | then abap_true 129 | else abap_false ). 130 | endmethod. 131 | 132 | 133 | method is_pse_available. 134 | result = abap_false. 135 | 136 | try. 137 | cl_abap_pse=>get_pse_info( 138 | exporting 139 | iv_context = default_pse_context 140 | iv_application = default_pse_application ). 141 | result = abap_true. 142 | catch cx_abap_pse ##NO_HANDLER. 143 | endtry. 144 | endmethod. 145 | 146 | 147 | method is_valid. 148 | result = abap_false. 149 | 150 | data valid_to_date type d. 151 | data valid_to_time type t. 152 | if me->certificate is bound. 153 | try. 154 | me->certificate->get_valid_to( 155 | importing 156 | ef_date = valid_to_date 157 | ef_time = valid_to_time ). 158 | if sy-datum <= valid_to_date. 159 | result = abap_true. 160 | elseif sy-datum = valid_to_date 161 | and sy-uzeit <= valid_to_time. 162 | result = abap_true. 163 | endif. 164 | catch cx_abap_x509_certificate ##NO_HANDLER. 165 | endtry. 166 | endif. 167 | endmethod. 168 | 169 | 170 | endclass. 171 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_cert_validation.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | class ltc_google_cert_validation definition 2 | create public 3 | final 4 | for testing 5 | duration short 6 | risk level harmless. 7 | 8 | 9 | private section. 10 | 11 | "! The certificate validation instance to put under test. 12 | data validation type ref to zcl_googlepoc_cert_validation. 13 | 14 | 15 | "----- TEST FIXTURE LIFECYCLE METHODS 16 | "! Sets up a unit test fixture. 17 | methods setup. 18 | 19 | 20 | "----- TEST METHODS 21 | methods is_available for testing. 22 | methods is_valid for testing. 23 | 24 | 25 | endclass. 26 | 27 | 28 | class ltc_google_cert_validation implementation. 29 | 30 | 31 | method setup. 32 | me->validation = new zcl_googlepoc_cert_validation( ). 33 | endmethod. 34 | 35 | 36 | method is_available. 37 | data(act_is_available) = me->validation->is_available( ). 38 | cl_abap_unit_assert=>assert_true( 39 | act = act_is_available 40 | msg = `Expected the Google Certificate to be available, but was not` ##NO_TEXT 41 | level = if_aunit_constants=>tolerable ). 42 | endmethod. 43 | 44 | 45 | method is_valid. 46 | data(act_is_valid) = me->validation->is_valid( ). 47 | cl_abap_unit_assert=>assert_true( 48 | act = act_is_valid 49 | msg = `Expected the Google Certificate to be valid, but was not` ##NO_TEXT 50 | level = if_aunit_constants=>tolerable ). 51 | endmethod. 52 | 53 | 54 | endclass. 55 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_cert_validation.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_GOOGLEPOC_CERT_VALIDATION 7 | E 8 | Validates a Google certificate in the PSE 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_impl.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Invokes the Google Drive REST API. Authentication is done via ABAP OAuth 2.0 Client with Google 3 | "! specific configuration profile. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | class zcl_googlepoc_drive_impl definition 25 | public 26 | create public 27 | final. 28 | 29 | 30 | public section. 31 | 32 | interfaces zif_googlepoc_drive_api. 33 | 34 | aliases has_valid_token 35 | for zif_googlepoc_drive_api~has_valid_token. 36 | aliases list_all_files 37 | for zif_googlepoc_drive_api~list_all_files. 38 | aliases simple_upload 39 | for zif_googlepoc_drive_api~simple_upload. 40 | aliases multipart_upload 41 | for zif_googlepoc_drive_api~multipart_upload. 42 | aliases create_file_metadata 43 | for zif_googlepoc_drive_api~create_file_metadata. 44 | aliases get_files_metadata 45 | for zif_googlepoc_drive_api~get_files_metadata. 46 | aliases get_log 47 | for zif_googlepoc_drive_api~get_log. 48 | 49 | "! The default OAuth 2.0 profile to use. 50 | constants default_oauth_20_profile type oa2c_profile value 'Z_GOOGLE_SHEETS' ##NO_TEXT. 51 | 52 | "! Constructs a new Google Drive REST API instance. 53 | "! 54 | "! @parameter oa2c_profile_name | The name of the OAuth 2.0 profile to use. 55 | "! @parameter json_api | The Google Drive JSON API to use for creating and parsing JSON content 56 | "! sent respectively received using this Google Drive REST API. 57 | "! 58 | "! @raising cx_oa2c_config_not_found | In case the OAuth 2.0 client configuration was not found. 59 | "! @raising cx_oa2c_config_profile_assign | In case the given profile was not assigned to an 60 | "! OAuth 2.0 client configuration. 61 | "! @raising cx_oa2c_kernel_too_old | In case the system kernel is too old - meaning that the 62 | "! OAuth 2.0 backend support does not exist or is not sufficient. 63 | "! @raising cx_oa2c_missing_authorization | In case the required authorization (S_OA2C_USE) for 64 | "! creating and using an OAuth 2.0 client were not granted. 65 | "! @raising cx_oa2c_config_profile_multi | In case the OAuth 2.0 Client Configuration Profile 66 | "! was assigned multiple times. 67 | methods constructor 68 | importing 69 | oa2c_profile_name type oa2c_profile optional 70 | json_api type ref to zif_googlepoc_drive_json_api 71 | raising 72 | cx_oa2c_config_not_found 73 | cx_oa2c_config_profile_assign 74 | cx_oa2c_kernel_too_old 75 | cx_oa2c_missing_authorization 76 | cx_oa2c_config_profile_multi. 77 | 78 | 79 | private section. 80 | 81 | types: 82 | "! Describes a HTTP response. 83 | begin of http_response, 84 | "! The status code. 85 | status_code type i, 86 | 87 | "! The content type. 88 | content_type type string, 89 | 90 | "! The received data. 91 | data type string, 92 | 93 | "! The header fields in shape of name/value pairs. 94 | header_fields type tihttpnvp, 95 | end of http_response. 96 | 97 | "! The SSL id to use for creating HTTP clients. 98 | constants default_ssl_id type ssfapplssl value 'ANONYM' ##NO_TEXT. 99 | 100 | "! The UTF-8 encoding representation. 101 | constants utf8_encoding type string value `UTF-8` ##NO_TEXT. 102 | 103 | "! The HTTP status code SUCCESS_OK. 104 | constants http_status_success_ok type i value 200 ##NO_TEXT. 105 | 106 | constants: 107 | "! Enumeration of the supported content types. 108 | begin of supported_content_types, 109 | "! The JSON content type. 110 | json type string value `application/json` ##NO_TEXT, 111 | 112 | "! The multi part content type. 113 | multipart type string value `multipart/related` ##NO_TEXT, 114 | end of supported_content_types. 115 | 116 | constants: 117 | "! Enumeration of the supported available Google Drive query parameters of the Files: list 118 | "! REST API. 119 | begin of files_query_parameters, 120 | "! The name of the Google Drive fields query parameter to request a partial 121 | "! response. 122 | "! 123 | "!

124 | "! See https://developers.google.com/drive/v3/web/performance#partial 125 | "!

126 | fields type string value `fields` ##NO_TEXT, 127 | 128 | "! The name of the parameter to query for filtering the file results. 129 | "! 130 | "!

131 | "! See https://developers.google.com/drive/v3/web/search-parameters 132 | "!

133 | query type string value `q` ##NO_TEXT, 134 | end of files_query_parameters. 135 | 136 | constants: 137 | "! Enumeration of the supported available Google Drive query parameters of the Files: list 138 | "! REST API. 139 | begin of files_search_fields, 140 | "! The name of the file. 141 | name type string value `name` ##NO_TEXT, 142 | 143 | "! The mime type of the file. 144 | mime_type type string value `mimeType` ##NO_TEXT, 145 | end of files_search_fields. 146 | 147 | constants: 148 | "! Enumeration of the supported available Google Drive REST API target URIs. 149 | begin of google_drive_rest_api_uris, 150 | list_files type string value `https://www.googleapis.com/drive/v3/files` ##NO_TEXT, 151 | 152 | file_metadata type string value `https://www.googleapis.com/drive/v3/files` ##NO_TEXT, 153 | 154 | simple_upload type string value 155 | `https://www.googleapis.com/upload/drive/v3/files?uploadType=media` ##NO_TEXT, 156 | 157 | multipart_upload type string value 158 | `https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart` ##NO_TEXT, 159 | end of google_drive_rest_api_uris. 160 | 161 | "! The OAuth 2.0 Client used by this Drive API. 162 | data oauth_client type ref to if_oauth2_client. 163 | 164 | "! The HTPP Client used by this Drive API. 165 | data http_client type ref to if_http_client. 166 | 167 | "! The OA2C profile name. 168 | data oa2c_profile_name type oa2c_profile. 169 | 170 | "! The used Google Drive JSON API. 171 | data json_api type ref to zif_googlepoc_drive_json_api. 172 | 173 | "! The used Logging API. 174 | data log_api type ref to zif_googlepoc_drive_log_api. 175 | 176 | "! Determines if the given HTTP(S) request has succeeded. 177 | "! 178 | "! @parameter http_status_code | The HTTP status code to verify. 179 | "! @parameter result | abap_true if the request has succeeded; abap_false if 180 | "! it has failed. 181 | class-methods has_request_succeeded 182 | importing 183 | http_status_code type i 184 | returning 185 | value(result) type abap_bool. 186 | 187 | "! Creates the OAuth 2.0 Client instance. 188 | "! 189 | "! @raising cx_oa2c_config_not_found | In case the OAuth 2.0 client configuration was not found. 190 | "! @raising cx_oa2c_config_profile_assign | In case the given profile was not assigned to an 191 | "! OAuth 2.0 client configuration. 192 | "! @raising cx_oa2c_kernel_too_old | In case the system kernel is too old - meaning that the 193 | "! OAuth 2.0 backend support does not exist or is not sufficient. 194 | "! @raising cx_oa2c_missing_authorization | In case the required authorization (S_OA2C_USE) for 195 | "! creating and using an OAuth 2.0 client were not granted. 196 | "! @raising cx_oa2c_config_profile_multi | In case the OAuth 2.0 Client Configuration Profile 197 | "! was assigned multiple times. 198 | methods create_oauth_client 199 | raising 200 | cx_oa2c_config_not_found 201 | cx_oa2c_config_profile_assign 202 | cx_oa2c_kernel_too_old 203 | cx_oa2c_missing_authorization 204 | cx_oa2c_config_profile_multi . 205 | 206 | "! Gets the OAuth 2.0 profile to use for creating the OAuth 2.0 Client. 207 | "! 208 | "! @parameter result | The determined profile. 209 | methods get_oauth_profile 210 | returning 211 | value(result) type oa2c_profile. 212 | 213 | "! Sets the OAuth 2.0 token on the previously established HTTP(S) connection. 214 | "! 215 | "! @parameter result | abap_true if the token has been successfully set; 216 | "! abap_false if the operation failed. 217 | methods set_oauth_token 218 | returning 219 | value(result) type abap_bool. 220 | 221 | "! Opens a HTTP(S) connection to the given URL using the specified method. 222 | "! 223 | "! @parameter url | The URL to connect to. 224 | "! @parameter method | The method (GET, POST, PUT, DELETE, OPTIONS) to use. 225 | "! @parameter header_fields | The header fields to set on the request. 226 | "! @parameter form_fields | The form fields to set on the request. 227 | "! @parameter result | abap_true if the connection has been successfully established; 228 | "! abap_false if the connection attempt failed. 229 | methods open_connection 230 | importing 231 | url type string 232 | method type string 233 | header_fields type tihttpnvp optional 234 | form_fields type tihttpnvp optional 235 | returning 236 | value(result) type abap_bool. 237 | 238 | "! Closes a previously opened HTTP(S) connection. 239 | methods close_connection. 240 | 241 | "! Prepares a request for the previously opened HTTP(S) connection. 242 | "! 243 | "! @parameter method | The method (GET, POST, PUT, DELETE, OPTIONS) to use. 244 | "! @parameter header_fields | The header fields to set on the request. 245 | "! @parameter form_fields | The form fields to set on the request. 246 | methods prepare_request 247 | importing 248 | method type string 249 | header_fields type tihttpnvp optional 250 | form_fields type tihttpnvp optional. 251 | 252 | "! Sends the HTTP(S) request and receives the response. 253 | "! 254 | "! @parameter response | The received response. 255 | methods send_receive 256 | returning 257 | value(response) type http_response. 258 | 259 | 260 | endclass. 261 | 262 | 263 | class zcl_googlepoc_drive_impl implementation. 264 | 265 | 266 | method constructor. 267 | me->oa2c_profile_name = oa2c_profile_name. 268 | me->json_api = json_api. 269 | 270 | me->log_api = new zcl_googlepoc_drive_log_impl( ). 271 | me->json_api->set_log_api( me->log_api ). 272 | 273 | me->create_oauth_client( ). 274 | endmethod. 275 | 276 | 277 | method zif_googlepoc_drive_api~create_file_metadata. 278 | data metadata type string. 279 | data response type http_response. 280 | 281 | data(is_connection_open) = 282 | me->open_connection( 283 | url = google_drive_rest_api_uris-file_metadata 284 | && |?{ files_query_parameters-fields }=| 285 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-id },| 286 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-web_view_link }| 287 | method = if_http_entity=>co_request_method_post ). 288 | if is_connection_open = abap_true. 289 | me->http_client->request->set_content_type( 290 | |{ supported_content_types-json };charset={ utf8_encoding }| ) ##NO_TEXT. 291 | metadata = me->json_api->create_file_resource( name = name 292 | mime_type = mime_type ). 293 | me->http_client->request->set_cdata( metadata ). 294 | 295 | response = me->send_receive( ). 296 | me->close_connection( ). 297 | 298 | if has_request_succeeded( response-status_code ) = abap_true. 299 | result = me->json_api->parse_file_resource( response-data ). 300 | if result is not initial. 301 | result-name = name. 302 | result-mime_type = mime_type. 303 | endif. 304 | endif. 305 | endif. 306 | endmethod. 307 | 308 | 309 | method zif_googlepoc_drive_api~get_files_metadata. 310 | data search_parameters type string. 311 | if name is not initial. 312 | search_parameters = escape( val = |{ files_search_fields-name }='{ name }'| 313 | format = cl_abap_format=>e_url_full ) ##NO_TEXT. 314 | endif. 315 | 316 | if mime_type is not initial. 317 | if search_parameters is not initial. 318 | search_parameters = search_parameters && ` and ` ##NO_TEXT. 319 | endif. 320 | search_parameters = search_parameters 321 | && escape( val = |{ files_search_fields-mime_type }='{ mime_type }'| 322 | format = cl_abap_format=>e_url_full ) ##NO_TEXT. 323 | endif. 324 | 325 | data(url) = google_drive_rest_api_uris-list_files 326 | && |?{ files_query_parameters-fields }=| 327 | && |{ zif_googlepoc_drive_json_api=>file_resource_list_fields-files }(| 328 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-id },| 329 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-name },| 330 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-mime_type },| 331 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-web_view_link },| 332 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-parents })| ##NO_TEXT. 333 | 334 | if search_parameters is not initial. 335 | url = |{ url }&{ files_query_parameters-query }={ search_parameters }| ##NO_TEXT. 336 | endif. 337 | 338 | data response type http_response. 339 | data(is_connection_open) = me->open_connection( 340 | url = url 341 | method = if_http_entity=>co_request_method_get ). 342 | if is_connection_open = abap_true. 343 | response = me->send_receive( ). 344 | me->close_connection( ). 345 | 346 | if has_request_succeeded( response-status_code ) = abap_true. 347 | me->json_api->parse_file_resource_list( 348 | exporting 349 | file_resource_list_json = response-data 350 | importing 351 | result = result 352 | ). 353 | endif. 354 | endif. 355 | endmethod. 356 | 357 | 358 | method zif_googlepoc_drive_api~get_log. 359 | clear result. 360 | result = me->log_api->entries. 361 | endmethod. 362 | 363 | 364 | method zif_googlepoc_drive_api~has_valid_token. 365 | result = me->open_connection( 366 | url = google_drive_rest_api_uris-list_files 367 | && |?{ files_query_parameters-fields }=| 368 | && |{ zif_googlepoc_drive_json_api=>file_resource_list_fields-files }(| 369 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-id },| 370 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-name })| 371 | method = if_http_entity=>co_request_method_get ) ##NO_TEXT. 372 | me->close_connection( ). 373 | endmethod. 374 | 375 | 376 | method zif_googlepoc_drive_api~list_all_files. 377 | data response type http_response. 378 | 379 | data(is_connection_open) = 380 | me->open_connection( 381 | url = google_drive_rest_api_uris-list_files 382 | && |?{ files_query_parameters-fields }=| 383 | && |{ zif_googlepoc_drive_json_api=>file_resource_list_fields-files }(| 384 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-id },| 385 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-name },| 386 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-mime_type },| 387 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-web_view_link },| 388 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-parents })| 389 | method = if_http_entity=>co_request_method_get ) ##NO_TEXT. 390 | if is_connection_open = abap_true. 391 | response = me->send_receive( ). 392 | me->close_connection( ). 393 | 394 | if has_request_succeeded( response-status_code ) = abap_true. 395 | me->json_api->parse_file_resource_list( 396 | exporting 397 | file_resource_list_json = response-data 398 | importing 399 | result = result 400 | ). 401 | endif. 402 | endif. 403 | endmethod. 404 | 405 | 406 | method zif_googlepoc_drive_api~multipart_upload. 407 | data metadata type string. 408 | data response type http_response. 409 | 410 | data(is_connection_open) = 411 | me->open_connection( 412 | url = google_drive_rest_api_uris-multipart_upload 413 | && |&{ files_query_parameters-fields }=| 414 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-id },| 415 | && |{ zif_googlepoc_drive_json_api=>file_resource_fields-web_view_link }| 416 | method = if_http_entity=>co_request_method_post ) ##NO_TEXT. 417 | if is_connection_open = abap_true. 418 | me->http_client->request->set_content_type( supported_content_types-multipart ). 419 | 420 | data(lo_entity) = me->http_client->request->add_multipart( ). 421 | lo_entity->set_content_type( 422 | |{ supported_content_types-json };charset={ utf8_encoding }| ) ##NO_TEXT. 423 | metadata = me->json_api->create_file_resource( name = name 424 | mime_type = mime_type 425 | parents = parents ). 426 | lo_entity->set_cdata( metadata ). 427 | 428 | lo_entity = me->http_client->request->add_multipart( ). 429 | lo_entity->set_content_type( content_type ). 430 | lo_entity->set_data( data = data->* ). 431 | 432 | response = me->send_receive( ). 433 | me->close_connection( ). 434 | 435 | if has_request_succeeded( response-status_code ) = abap_true. 436 | result = me->json_api->parse_file_resource( response-data ). 437 | if result is not initial. 438 | result-name = name. 439 | result-mime_type = mime_type. 440 | result-parents = parents. 441 | endif. 442 | endif. 443 | endif. 444 | endmethod. 445 | 446 | 447 | method zif_googlepoc_drive_api~simple_upload. 448 | data response type http_response. 449 | 450 | data(is_connection_open) = me->open_connection( 451 | url = google_drive_rest_api_uris-simple_upload 452 | method = if_http_entity=>co_request_method_post ). 453 | if is_connection_open = abap_true. 454 | me->http_client->request->set_content_type( content_type ). 455 | me->http_client->request->set_data( data->* ). 456 | 457 | response = me->send_receive( ). 458 | me->close_connection( ). 459 | 460 | result = has_request_succeeded( response-status_code ). 461 | endif. 462 | endmethod. 463 | 464 | 465 | method close_connection. 466 | if me->http_client is bound. 467 | me->http_client->close( 468 | exceptions 469 | http_invalid_state = 1 470 | others = 2 ). 471 | if sy-subrc <> 0. 472 | me->log_api->log( |Error closing HTTP connection: Error Code ({ sy-subrc })| ) ##NO_TEXT. 473 | endif. 474 | endif. 475 | 476 | clear: me->http_client. 477 | endmethod. 478 | 479 | 480 | method create_oauth_client. 481 | data(profile) = me->get_oauth_profile( ). 482 | me->oauth_client = cl_oauth2_client=>create( profile ). 483 | endmethod. 484 | 485 | 486 | method get_oauth_profile. 487 | result = me->oa2c_profile_name. 488 | 489 | if result is initial. 490 | result = default_oauth_20_profile. 491 | endif. 492 | endmethod. 493 | 494 | 495 | method has_request_succeeded. 496 | result = cond #( when http_status_code = http_status_success_ok 497 | then abap_true 498 | else abap_false ). 499 | endmethod. 500 | 501 | 502 | method open_connection. 503 | cl_http_client=>create_by_url( 504 | exporting 505 | url = url 506 | ssl_id = default_ssl_id 507 | importing 508 | client = me->http_client 509 | exceptions 510 | argument_not_found = 1 511 | plugin_not_active = 2 512 | internal_error = 3 513 | others = 4 ). 514 | if sy-subrc = 0. 515 | me->prepare_request( method = method 516 | header_fields = header_fields 517 | form_fields = form_fields ). 518 | result = me->set_oauth_token( ). 519 | else. 520 | me->log_api->log( |Error creating HTTP connection: Error Code ({ sy-subrc })| ) ##NO_TEXT. 521 | result = abap_false. 522 | endif. 523 | endmethod. 524 | 525 | 526 | method prepare_request. 527 | "Turn off logon popup. Detect authentication errors. 528 | me->http_client->propertytype_logon_popup = 0. 529 | me->http_client->request->set_method( method ). 530 | 531 | if header_fields is supplied 532 | and header_fields is not initial. 533 | me->http_client->request->set_header_fields( header_fields ). 534 | endif. 535 | 536 | if form_fields is supplied 537 | and form_fields is not initial. 538 | me->http_client->request->set_form_fields( form_fields ). 539 | endif. 540 | endmethod. 541 | 542 | 543 | method send_receive. 544 | clear response. 545 | 546 | me->http_client->send( 547 | exceptions 548 | http_communication_failure = 1 549 | http_invalid_state = 2 550 | http_processing_failed = 3 551 | http_invalid_timeout = 4 552 | others = 5 ). 553 | if sy-subrc <> 0. 554 | me->log_api->log( |Error sending HTTP request: Error Code ({ sy-subrc })| ) ##NO_TEXT. 555 | endif. 556 | 557 | me->http_client->receive( 558 | exceptions 559 | http_communication_failure = 1 560 | http_invalid_state = 2 561 | http_processing_failed = 3 562 | others = 4 ). 563 | if sy-subrc <> 0. 564 | me->log_api->log( |Error receiving HTTP request: Error Code ({ sy-subrc })| ) ##NO_TEXT. 565 | endif. 566 | 567 | "Fill response structure. 568 | me->http_client->response->get_status( 569 | importing 570 | code = response-status_code ). 571 | response-data = me->http_client->response->get_cdata( ). 572 | response-content_type = me->http_client->response->get_content_type( ). 573 | me->http_client->response->get_header_fields( 574 | changing 575 | fields = response-header_fields ). 576 | 577 | me->log_api->log( |HTTP request sent: Status Code ({ response-status_code })| ) ##NO_TEXT. 578 | endmethod. 579 | 580 | 581 | method set_oauth_token. 582 | try. 583 | me->oauth_client->set_token( io_http_client = me->http_client 584 | i_param_kind = if_oauth2_client=>c_param_kind_form_field ). 585 | catch cx_oa2c into data(oauth_exc). 586 | try. 587 | me->oauth_client->execute_refresh_flow( ). 588 | catch cx_oa2c into oauth_exc. 589 | me->log_api->log( |Error executing OAuth 2.0 refresh flow: | 590 | && |{ oauth_exc->get_text( ) }| ) ##NO_TEXT. 591 | result = abap_false. 592 | return. 593 | endtry. 594 | 595 | try. 596 | me->oauth_client->set_token( 597 | io_http_client = me->http_client 598 | i_param_kind = if_oauth2_client=>c_param_kind_form_field ). 599 | catch cx_oa2c into oauth_exc. 600 | me->log_api->log( |Error setting OAuth 2.0 token: | 601 | && |{ oauth_exc->get_text( ) }| ) ##NO_TEXT. 602 | result = abap_false. 603 | return. 604 | endtry. 605 | endtry. 606 | 607 | result = abap_true. 608 | endmethod. 609 | 610 | 611 | endclass. 612 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_impl.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_GOOGLEPOC_DRIVE_IMPL 7 | E 8 | Default Google Drive REST API implementation 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_log_impl.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Default implementation of the Logging API in the context of the 3 | "! Google Drive REST API, which writes the entries to an internal table buffer. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | class zcl_googlepoc_drive_log_impl definition 25 | public 26 | create public 27 | final. 28 | 29 | 30 | public section. 31 | 32 | interfaces zif_googlepoc_drive_log_api. 33 | 34 | aliases entries 35 | for zif_googlepoc_drive_log_api~entries. 36 | aliases log 37 | for zif_googlepoc_drive_log_api~log ##SHADOW[LOG]. 38 | 39 | endclass. 40 | 41 | 42 | class zcl_googlepoc_drive_log_impl implementation. 43 | 44 | 45 | method zif_googlepoc_drive_log_api~log. 46 | append value #( date = sy-datum 47 | time = sy-uzeit 48 | message = message ) to me->entries. 49 | endmethod. 50 | 51 | 52 | endclass. 53 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_log_impl.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_GOOGLEPOC_DRIVE_LOG_IMPL 7 | E 8 | Default Google Drive logging API implementation 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_ui2_json.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Implementation of the Google Drive JSON API that utilizes the 3 | "! UI2 (/UI2/CL_JSON) library for parsing and producing content in JSON format. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | class zcl_googlepoc_drive_ui2_json definition 25 | public 26 | create public 27 | final. 28 | 29 | 30 | public section. 31 | 32 | interfaces zif_googlepoc_drive_json_api. 33 | 34 | aliases create_file_resource 35 | for zif_googlepoc_drive_json_api~create_file_resource. 36 | aliases parse_file_resource 37 | for zif_googlepoc_drive_json_api~parse_file_resource. 38 | aliases parse_file_resource_list 39 | for zif_googlepoc_drive_json_api~parse_file_resource_list. 40 | aliases set_log_api 41 | for zif_googlepoc_drive_json_api~set_log_api. 42 | 43 | 44 | private section. 45 | 46 | "! The used logging API. 47 | data log_api type ref to zif_googlepoc_drive_log_api. "#EC NEEDED 48 | 49 | types: 50 | "! Describes a Google File Resource response. 51 | begin of file_resource_response, 52 | files type zif_googlepoc_drive_api=>file_resources, 53 | end of file_resource_response. 54 | 55 | 56 | endclass. 57 | 58 | 59 | class zcl_googlepoc_drive_ui2_json implementation. 60 | 61 | 62 | method zif_googlepoc_drive_json_api~create_file_resource. 63 | data(date_time_converter) = new zcl_googlepoc_rfc3339_datetime( ). 64 | data(create_date_time) = date_time_converter->convert( 65 | value #( date = sy-datum 66 | time = sy-uzeit 67 | local_to_utc_difference = sy-tzone div 60 ) ). 68 | 69 | data(escaped_name) = escape( val = name 70 | format = cl_abap_format=>e_json_string ). 71 | data(escaped_mime_type) = escape( val = mime_type 72 | format = cl_abap_format=>e_json_string ). 73 | data(escaped_create_date_time) = escape( val = create_date_time 74 | format = cl_abap_format=>e_json_string ). 75 | 76 | result = |\{"name":"{ escaped_name }","mimeType":"{ escaped_mime_type }",| 77 | && |"createdTime":"{ escaped_create_date_time }"| ##NO_TEXT. 78 | 79 | data lv_parents_array type /ui2/cl_json=>json. 80 | if parents is not initial. 81 | lv_parents_array = /ui2/cl_json=>serialize( data = parents ). 82 | if lv_parents_array is not initial. 83 | result = result && |,"parents":{ lv_parents_array }| ##NO_TEXT. 84 | endif. 85 | endif. 86 | 87 | result = result && |\}| ##NO_TEXT. 88 | endmethod. 89 | 90 | 91 | method zif_googlepoc_drive_json_api~parse_file_resource. 92 | /ui2/cl_json=>deserialize( 93 | exporting 94 | json = file_resource_json 95 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case 96 | changing 97 | data = result ). 98 | endmethod. 99 | 100 | 101 | method zif_googlepoc_drive_json_api~parse_file_resource_list. 102 | clear result. 103 | 104 | data response type file_resource_response. 105 | /ui2/cl_json=>deserialize( 106 | exporting 107 | json = file_resource_list_json 108 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case 109 | changing 110 | data = response 111 | ). 112 | 113 | result = response-files. 114 | endmethod. 115 | 116 | 117 | method zif_googlepoc_drive_json_api~set_log_api. 118 | me->log_api = api. 119 | endmethod. 120 | 121 | 122 | endclass. 123 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_drive_ui2_json.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_GOOGLEPOC_DRIVE_UI2_JSON 7 | E 8 | Deals with Google Drive JSON data using the UI2 JSON libary 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_rfc3339_datetime.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Converts ABAP Date/Time values with optional UTC offset to RFC 3339 3 | "! compliant Date/Time values. 4 | "!

5 | "! 6 | "!

7 | "! See RFC 3339 at https://tools.ietf.org/html/rfc3339 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | class zcl_googlepoc_rfc3339_datetime definition 25 | public 26 | create public 27 | final. 28 | 29 | 30 | public section. 31 | 32 | types: 33 | "! Type describing a Date/Time value. 34 | begin of date_time, 35 | "! The date part. 36 | date type d, 37 | 38 | "! The time part. 39 | time type t, 40 | 41 | "! The time difference from the UTC reference time in minutes, e.g. -90 for a local to UTC 42 | "! difference of -1:30 hours. 43 | local_to_utc_difference type i, 44 | end of date_time. 45 | 46 | "! Converts the given ABAP Date/Time to an RFC 3339 Date/Time 47 | "! value. 48 | "! 49 | "! @parameter input | The input ABAP Date/Time value. 50 | "! @parameter result | The output RFC 3339 Date/Time value. 51 | methods convert 52 | importing 53 | input type date_time 54 | returning 55 | value(result) type string. 56 | 57 | 58 | private section. 59 | 60 | "! The number of minutes in one hour. 61 | constants minutes_per_hour type i value 60. 62 | 63 | 64 | endclass. 65 | 66 | 67 | class zcl_googlepoc_rfc3339_datetime implementation. 68 | 69 | 70 | method convert. 71 | data hours type string. 72 | data minutes type string. 73 | 74 | result = |{ input-date(4) }-{ input-date+4(2) }-{ input-date+6(2) }| ##NO_TEXT. 75 | 76 | if input-time is not initial. 77 | result = result 78 | && |T{ input-time(2) }:{ input-time+2(2) }:{ input-time+4(2) }| ##NO_TEXT. 79 | 80 | if input-local_to_utc_difference is initial. 81 | result = result && `Z` ##NO_TEXT. 82 | else. 83 | hours = |{ abs( input-local_to_utc_difference div minutes_per_hour ) }|. 84 | minutes = |{ abs( input-local_to_utc_difference mod minutes_per_hour ) }|. 85 | 86 | if input-local_to_utc_difference < 0. 87 | result = result 88 | && |-{ hours alpha = in width = 2 }:{ minutes alpha = in width = 2 }| ##NO_TEXT. 89 | else. 90 | result = result 91 | && |+{ hours alpha = in width = 2 }:{ minutes alpha = in width = 2 }| ##NO_TEXT. 92 | endif. 93 | endif. 94 | endif. 95 | endmethod. 96 | 97 | 98 | endclass. 99 | -------------------------------------------------------------------------------- /src/zcl_googlepoc_rfc3339_datetime.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_GOOGLEPOC_RFC3339_DATETIME 7 | E 8 | Converts to RFC 3339 Date/Time 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_oa2c_ce_zgoogle.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! BAdI implementation of the OAuth 2.0 Google configuration extension. 3 | "!

4 | "! 5 | "!

6 | "! See https://developers.google.com/drive/ 7 | "!

8 | "! 9 | "!

10 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 11 | "!
12 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 13 | "! the LICENSE FILE 14 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 15 | "!
16 | "!
17 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 18 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 19 | "! accordance with Google's Developer Site Policies 20 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 21 | "! service is subject to applicable agreements with Google Inc. 22 | "!

23 | class zcl_oa2c_ce_zgoogle definition 24 | public 25 | create public 26 | final. 27 | 28 | 29 | public section. 30 | 31 | interfaces if_badi_interface. 32 | interfaces if_oa2c_config_extension. 33 | 34 | 35 | endclass. 36 | 37 | 38 | class zcl_oa2c_ce_zgoogle implementation. 39 | 40 | 41 | method if_oa2c_config_extension~get_ac_auth_requ_params. 42 | clear et_additional_params. 43 | et_additional_params = value #( ( name = `access_type` 44 | value = `offline` ) 45 | ( name = `approval_prompt` 46 | value = `force` ) ) ##NO_TEXT. 47 | endmethod. 48 | 49 | 50 | method if_oa2c_config_extension~get_saml20_at_requ_params ##NEEDED. 51 | "Nothing to do in here. 52 | endmethod. 53 | 54 | 55 | endclass. 56 | -------------------------------------------------------------------------------- /src/zcl_oa2c_ce_zgoogle.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OA2C_CE_ZGOOGLE 7 | E 8 | Google Configuration Extension 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_oa2c_specifics_zgoogle.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! BAdI implementation of the OAuth 2.0 Google specific settings. 3 | "!

4 | "! 5 | "!

6 | "! See https://developers.google.com/drive/ 7 | "!

8 | "! 9 | "!

10 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 11 | "!
12 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 13 | "! the LICENSE FILE 14 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 15 | "!
16 | "!
17 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 18 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 19 | "! accordance with Google's Developer Site Policies 20 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 21 | "! service is subject to applicable agreements with Google Inc. 22 | "!

23 | class zcl_oa2c_specifics_zgoogle definition 24 | public 25 | create public 26 | inheriting from 27 | cl_oa2c_specifics_abstract 28 | final. 29 | 30 | 31 | public section. 32 | 33 | methods if_oa2c_specifics~get_config_extension redefinition. 34 | methods if_oa2c_specifics~get_endpoint_settings redefinition. 35 | methods if_oa2c_specifics~get_supported_grant_types redefinition. 36 | methods if_oa2c_specifics~get_ac_auth_requ_param_names redefinition. 37 | 38 | 39 | endclass. 40 | 41 | 42 | class zcl_oa2c_specifics_zgoogle implementation. 43 | 44 | 45 | method if_oa2c_specifics~get_ac_auth_requ_param_names. 46 | clear: et_add_param_names, e_client_id, e_redirect_uri, e_response_type, e_response_type_value, 47 | e_scope. 48 | 49 | super->if_oa2c_specifics~get_ac_auth_requ_param_names( 50 | importing 51 | e_client_id = e_client_id 52 | e_redirect_uri = e_redirect_uri 53 | e_response_type = e_response_type 54 | e_response_type_value = e_response_type_value 55 | e_scope = e_scope ). 56 | 57 | et_add_param_names = value #( ( name = `access_type` ) 58 | ( name = `approval_prompt` ) 59 | ( name = `login_hint` ) ) ##NO_TEXT. 60 | endmethod. 61 | 62 | 63 | method if_oa2c_specifics~get_config_extension. 64 | r_config_extension = `ZGOOGLE` ##NO_TEXT. 65 | endmethod. 66 | 67 | 68 | method if_oa2c_specifics~get_endpoint_settings. 69 | clear: e_authorization_endpoint_path, e_changeable, e_revocation_endpoint_path, 70 | e_token_endpoint_path. 71 | 72 | e_changeable = abap_false. 73 | e_authorization_endpoint_path = `accounts.google.com/o/oauth2/v2/auth` ##NO_TEXT. 74 | e_token_endpoint_path = `oauth2.googleapis.com/token` ##NO_TEXT. 75 | e_revocation_endpoint_path = `oauth2.googleapis.com/revoke` ##NO_TEXT. 76 | endmethod. 77 | 78 | 79 | method if_oa2c_specifics~get_supported_grant_types. 80 | clear: e_authorization_code, e_refresh, e_revocation, e_saml20_assertion. 81 | 82 | e_authorization_code = abap_true. 83 | e_saml20_assertion = abap_false. 84 | e_refresh = abap_true. 85 | e_revocation = abap_true. 86 | endmethod. 87 | 88 | 89 | endclass. 90 | -------------------------------------------------------------------------------- /src/zcl_oa2c_specifics_zgoogle.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OA2C_SPECIFICS_ZGOOGLE 7 | E 8 | Google specific OAuth 2.0 Settings 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_salv_enh_google_sheets.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Example BAdi-Implementation if_salv_jpb_badi_data_publish. 3 | "!

4 | "! 5 | "!

6 | "! See https://developers.google.com/drive/ 7 | "!

8 | "! 9 | "!

10 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 11 | "!
12 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 13 | "! the LICENSE FILE 14 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 15 | "!
16 | "!
17 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 18 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 19 | "! accordance with Google's Developer Site Policies 20 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 21 | "! service is subject to applicable agreements with Google Inc. 22 | "!

23 | class zcl_salv_enh_google_sheets definition 24 | public 25 | create public 26 | final. 27 | 28 | 29 | public section. 30 | 31 | interfaces if_badi_interface. 32 | interfaces if_salv_jpb_badi_data_publish. 33 | 34 | aliases get_authentication_type 35 | for if_salv_jpb_badi_data_publish~get_authentication_type. 36 | aliases get_binary_data_to_publish 37 | for if_salv_jpb_badi_data_publish~get_binary_data_to_publish. 38 | aliases get_destination_type 39 | for if_salv_jpb_badi_data_publish~get_destination_type. 40 | aliases get_executable_location 41 | for if_salv_jpb_badi_data_publish~get_executable_location. 42 | aliases get_file_download_info 43 | for if_salv_jpb_badi_data_publish~get_file_download_info. 44 | aliases get_item_descriptor 45 | for if_salv_jpb_badi_data_publish~get_item_descriptor. 46 | aliases get_oa2c_auth_ingredients 47 | for if_salv_jpb_badi_data_publish~get_oa2c_auth_ingredients. 48 | aliases get_target_url_to_launch 49 | for if_salv_jpb_badi_data_publish~get_target_url_to_launch. 50 | aliases is_connection_established 51 | for if_salv_jpb_badi_data_publish~is_connection_established. 52 | 53 | 54 | private section. 55 | 56 | "! The name of the default target Google Drive folder to upload to. 57 | constants target_folder type zif_googlepoc_drive_api=>file_resource_name value 58 | `SAP Exports` ##NO_TEXT. 59 | 60 | "! The mime type of an Office Open XML Spreadsheet file. 61 | constants xlsx_mime_type type string value 62 | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` ##NO_TEXT. 63 | 64 | "! The default OAuth 2.0 profile to use. 65 | data oa2c_profile_name type oa2c_profile value 'Z_GOOGLE_SHEETS' ##NO_TEXT. 66 | 67 | "! The OAuth 2.0 authorization grant application URL. 68 | data oa2c_auth_application type string 69 | value `https://dev.sap.com:44333/sap/bc/sec/oauth2/client/grant/authorization` ##NO_TEXT. 70 | 71 | "! The binary data to publish. 72 | data binary_data_to_publish type ref to xstring. 73 | 74 | "! The Google Drive Client API. 75 | data drive_api type ref to zif_googlepoc_drive_api. 76 | 77 | "! Gets the ID of the folder with the given name from the Google Drive. 78 | "! 79 | "! @parameter folder_name | The name of the folder. 80 | "! @parameter create_if_not_existing | abap_true to create the folder if it does not 81 | "! exist yet; abap_false to not create it. 82 | "! @parameter result | The ID of the folder; initial if no folder with that name 83 | "! exists. 84 | methods get_drive_folder_id 85 | importing 86 | folder_name type zif_googlepoc_drive_api=>file_resource_name 87 | default target_folder 88 | create_if_not_existing type abap_bool default abap_true 89 | returning 90 | value(result) type zif_googlepoc_drive_api=>file_resource_id. 91 | 92 | 93 | endclass. 94 | 95 | 96 | class zcl_salv_enh_google_sheets implementation. 97 | 98 | 99 | method get_drive_folder_id. 100 | data folder type zif_googlepoc_drive_api=>file_resource. 101 | data(folder_resources) = me->drive_api->get_files_metadata( 102 | name = folder_name 103 | mime_type = zif_googlepoc_drive_api=>supported_mime_types-folder ). 104 | if folder_resources is initial. 105 | if create_if_not_existing = abap_true. 106 | folder = me->drive_api->create_file_metadata( 107 | name = folder_name 108 | mime_type = zif_googlepoc_drive_api=>supported_mime_types-folder ). 109 | endif. 110 | else. 111 | folder = folder_resources[ 1 ]. 112 | endif. 113 | 114 | result = folder-id. 115 | endmethod. 116 | 117 | 118 | method if_salv_jpb_badi_data_publish~get_binary_data_to_publish. 119 | me->binary_data_to_publish = r_binary_data_to_publish. 120 | endmethod. 121 | 122 | 123 | method if_salv_jpb_badi_data_publish~get_destination_type. 124 | destination_type = if_salv_jpb_data_publisher=>cs_destination_type-cloud. 125 | endmethod. 126 | 127 | 128 | method if_salv_jpb_badi_data_publish~get_item_descriptor. 129 | "Please take branding aspects into account. 130 | "See https://developers.google.com/drive/v3/web/branding for more information. 131 | text = |Google Sheets| ##NO_TEXT. 132 | frontend = if_salv_jpb_data_publisher=>cs_frontend-google_sheets. 133 | is_default_for_format = abap_true. 134 | xml_type = if_salv_bs_xml=>c_type_xlsx. 135 | output_format = if_salv_jpb_data_publisher=>cs_output_format-xlsx. 136 | endmethod. 137 | 138 | 139 | method if_salv_jpb_badi_data_publish~get_oa2c_auth_ingredients. 140 | profile_name = me->oa2c_profile_name. 141 | grant_auth_application_url = me->oa2c_auth_application. 142 | endmethod. 143 | 144 | 145 | method if_salv_jpb_badi_data_publish~get_target_url_to_launch. 146 | data parent_folder_id type zif_googlepoc_drive_api=>file_resource_id. 147 | data parent_folder_ids type zif_googlepoc_drive_api=>file_resource_ids. 148 | data file type zif_googlepoc_drive_api=>file_resource. 149 | data timestamp type timestamp. 150 | 151 | data is_connection_established type abap_bool. 152 | me->is_connection_established( changing is_connection_established = is_connection_established ). 153 | if is_connection_established = abap_true. 154 | parent_folder_id = me->get_drive_folder_id( ). 155 | if parent_folder_id is not initial. 156 | append parent_folder_id to parent_folder_ids. 157 | endif. 158 | 159 | get time stamp field timestamp. 160 | file = me->drive_api->multipart_upload( 161 | data = me->binary_data_to_publish 162 | name = |ALV_EXPORT_{ conv string( timestamp ) }| 163 | mime_type = zif_googlepoc_drive_api=>supported_mime_types-spreadsheet 164 | content_type = xlsx_mime_type 165 | parents = parent_folder_ids ) ##NO_TEXT. 166 | target_url_to_launch = file-web_view_link. 167 | endif. 168 | endmethod. 169 | 170 | 171 | method if_salv_jpb_badi_data_publish~is_connection_established. 172 | if me->drive_api is initial. 173 | try. 174 | me->drive_api = new zcl_googlepoc_drive_impl( 175 | oa2c_profile_name = me->oa2c_profile_name 176 | json_api = new zcl_googlepoc_drive_ui2_json( ) ). 177 | catch cx_oa2c_config_not_found 178 | cx_oa2c_config_profile_assign 179 | cx_oa2c_missing_authorization 180 | cx_oa2c_config_profile_multi 181 | cx_oa2c_kernel_too_old into data(oa2c_exc). 182 | raise exception type cx_salv_connection_error 183 | exporting 184 | previous = oa2c_exc. 185 | endtry. 186 | endif. 187 | 188 | is_connection_established = me->drive_api->has_valid_token( ). 189 | endmethod. 190 | 191 | 192 | method if_salv_jpb_badi_data_publish~get_authentication_type ##NEEDED. 193 | endmethod. 194 | 195 | 196 | method if_salv_jpb_badi_data_publish~get_executable_location ##NEEDED. 197 | endmethod. 198 | 199 | 200 | method if_salv_jpb_badi_data_publish~get_file_download_info ##NEEDED. 201 | endmethod. 202 | 203 | 204 | endclass. 205 | -------------------------------------------------------------------------------- /src/zcl_salv_enh_google_sheets.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_SALV_ENH_GOOGLE_SHEETS 7 | E 8 | Class for BAdI: SALV_JPB_BADI_DATA_PUBLISHER 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zcl_salv_wd_google_redirect.clas.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Assistance class of the custom Web Dynpro ABAP Redirect Handler for an OAuth Redirect URI 3 | "! Workflow. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | class zcl_salv_wd_google_redirect definition 25 | public 26 | create public 27 | inheriting from 28 | cl_wd_component_assistance 29 | final. 30 | 31 | 32 | public section. 33 | 34 | aliases get_text 35 | for if_wd_component_assistance~get_text. 36 | 37 | "! Sets the received URL parameters. 38 | "! 39 | "! @parameter url_parameters | The list of received URL parameters. 40 | methods set_url_parameters 41 | importing 42 | url_parameters type tihttpnvp. 43 | 44 | "! Evaluates the beforehand set URL parameters and produces a human readable message from it. 45 | "! 46 | "! @parameter message | The evaluation message. 47 | "! @parameter message_icon | A path to either a success or error image. 48 | methods get_message 49 | exporting 50 | message type string 51 | message_icon type string. 52 | 53 | 54 | private section. 55 | 56 | "! The list of received URL parameters. 57 | data url_parameters type tihttpnvp. 58 | 59 | 60 | endclass. 61 | 62 | 63 | class zcl_salv_wd_google_redirect implementation. 64 | 65 | 66 | method get_message. 67 | clear: message, message_icon. 68 | 69 | loop at me->url_parameters assigning field-symbol(). 70 | case -name. 71 | when `ERROR`. 72 | message = |Error { -value } received. | 73 | && `lease contact your system administrator.` ##NO_TEXT. 74 | message_icon = `~IconLarge/ErrorMessage` ##NO_TEXT. 75 | exit. 76 | when others. 77 | message = `Access token successfully received from Google. Please repeat your Export To ` 78 | && `Spreadsheet (Google Sheets) action` ##NO_TEXT. 79 | message_icon = `~IconLarge/SuccessMessage` ##NO_TEXT. 80 | endcase. 81 | endloop. 82 | endmethod. 83 | 84 | 85 | method set_url_parameters. 86 | me->url_parameters = url_parameters. 87 | endmethod. 88 | 89 | 90 | endclass. 91 | -------------------------------------------------------------------------------- /src/zcl_salv_wd_google_redirect.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_SALV_WD_GOOGLE_REDIRECT 7 | E 8 | Assistance Class for ZWD_GOOGLE_TOKEN_REDIRECT 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_api.intf.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Interface to the Google Drive REST API. 3 | "!

4 | "! 5 | "!

6 | "! See https://developers.google.com/drive/ 7 | "!

8 | "! 9 | "!

10 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 11 | "!
12 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 13 | "! the LICENSE FILE 14 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 15 | "!
16 | "!
17 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 18 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 19 | "! accordance with Google's Developer Site Policies 20 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 21 | "! service is subject to applicable agreements with Google Inc. 22 | "!

23 | interface zif_googlepoc_drive_api 24 | public. 25 | 26 | 27 | "! Describes an identifier of a file resource. 28 | types file_resource_id type string. 29 | 30 | "! Describes a list of file resource identifiers. 31 | types file_resource_ids type standard table 32 | of file_resource_id 33 | with empty key. 34 | 35 | "! Describes a name of a file resource. 36 | types file_resource_name type string. 37 | 38 | "! Describes a link for opening a file resource. 39 | types web_view_link type string. 40 | 41 | "! Describes a mime type classifying a file content. 42 | types mime_type type string. 43 | 44 | "! Describes a content type, i.e. the type of a body. 45 | types content_type type string. 46 | 47 | types: 48 | "! Describes a Google Drive file resource. 49 | begin of file_resource, 50 | "! The id of the file resource. 51 | id type file_resource_id, 52 | 53 | "! The name of the file resource. 54 | name type file_resource_name, 55 | 56 | "! The mime type of the file resource. 57 | mime_type type mime_type, 58 | 59 | "! A link for opening the file in a relevant Google editor or viewer in a browser. 60 | web_view_link type web_view_link, 61 | 62 | "! The IDs of the parent folders containing the file. 63 | parents type file_resource_ids, 64 | end of file_resource. 65 | 66 | "! Describes a list of Google File resources. 67 | types file_resources type standard table 68 | of file_resource 69 | with empty key. 70 | 71 | "! The Mime Type of a Google Spreadsheet document. 72 | "! 73 | "!

74 | "! See https://developers.google.com/drive/v3/web/mime-types 75 | "!

76 | constants google_spreadsheet_mime_type type mime_type value 77 | `application/vnd.google-apps.spreadsheet` ##NO_TEXT. 78 | 79 | constants: 80 | "! The enumeration of mime types supported by Google Drive. 81 | "! 82 | "!

83 | "! See https://developers.google.com/drive/v3/web/mime-types 84 | "!

85 | begin of supported_mime_types, 86 | "! The mime type of a folder in a Google Drive. 87 | folder type mime_type value `application/vnd.google-apps.folder` ##NO_TEXT, 88 | 89 | "! The mime type of a Google Spreadsheet document. 90 | spreadsheet type mime_type value `application/vnd.google-apps.spreadsheet` ##NO_TEXT, 91 | end of supported_mime_types. 92 | 93 | "!

94 | "! Determines if this API has a valid OAuth 2.0 token, i.e. if access is allowed. If a valid 95 | "! access token exists, this method returns abap_true. Otherwise it tries to 96 | "! request a refresh token. If a valid refresh token was received, abap_true is 97 | "! returned. 98 | "!

99 | "!

100 | "! In all other cases abap_false is returned. 101 | "!

102 | "!

103 | "! This method can be utilized prior to any API calls in order to test if an access is allowed at 104 | "! all. 105 | "!

106 | "! 107 | "! @parameter result | abap_true if a valid OAuth 2.0 exists; abap_false 108 | "! otherwise. 109 | methods has_valid_token 110 | returning 111 | value(result) type abap_bool. 112 | 113 | "! Lists all files in a Google Drive. 114 | "! 115 | "! @parameter result | The retrieved file resources; initial in case the operation failed 116 | "! or no files were found. 117 | methods list_all_files 118 | returning 119 | value(result) type file_resources. 120 | 121 | "! Performs a simple file upload into a Google Drive. 122 | "! 123 | "! @parameter data | The data to upload. 124 | "! @parameter name | The name of the file. 125 | "! @parameter content_type | The content type of the message body. 126 | "! @parameter result | abap_true if the upload succeeded; abap_false if it 127 | "! failed. 128 | methods simple_upload 129 | importing 130 | data type ref to xstring 131 | name type string 132 | content_type type content_type 133 | returning 134 | value(result) type abap_bool. 135 | 136 | "! Performs a multi part - including metadata and content - file upload into a Google Drive. 137 | "! 138 | "! @parameter data | The data to upload. 139 | "! @parameter name | The name of the file. 140 | "! @parameter content_type | The content type of the message body. 141 | "! @parameter mime_type | The mime type of the file in the message payload. 142 | "! @parameter parents | The IDs of the parent folders containing the file. 143 | "! @parameter result | The response data of the file resource; initial in case the 144 | "! operation failed. 145 | methods multipart_upload 146 | importing 147 | data type ref to xstring 148 | name type string 149 | content_type type content_type 150 | mime_type type mime_type 151 | parents type file_resource_ids optional 152 | returning 153 | value(result) type file_resource. 154 | 155 | "! Creates the metadata of a file. 156 | "! 157 | "! @parameter name | The name of the file. 158 | "! @parameter mime_type | The mime type of the file. 159 | "! @parameter result | The response data of the file resource; initial in case the 160 | "! operation failed. 161 | methods create_file_metadata 162 | importing 163 | name type file_resource_name 164 | mime_type type mime_type 165 | returning 166 | value(result) type file_resource. 167 | 168 | "! Gets the metadata of files matching the given criteria. The given search criteria are - 169 | "! if populated - combined with the AND operator. 170 | "! 171 | "! @parameter name | The name of the file. 172 | "! @parameter mime_type | The mime type of the file. 173 | "! @parameter result | The response data of the file resources; initial in case the 174 | "! operation failed or no matching files were found. 175 | methods get_files_metadata 176 | importing 177 | name type file_resource_name optional 178 | mime_type type mime_type optional 179 | returning 180 | value(result) type file_resources. 181 | 182 | "! Gets the log written by this Google Drive API. 183 | "! 184 | "! @parameter result | The written log entries. 185 | methods get_log 186 | exporting 187 | result type zif_googlepoc_drive_log_api=>log_entries. 188 | 189 | 190 | endinterface. 191 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_api.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_GOOGLEPOC_DRIVE_API 7 | E 8 | Google POC: Drive API interface 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_json_api.intf.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Interface to the JSON API to deal with requests and responses sent respectively 3 | "! received from the Google Drive REST API. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | interface zif_googlepoc_drive_json_api 25 | public. 26 | 27 | 28 | constants: 29 | "! Enumeration of the field names in a Google Drive File Resource. 30 | "! 31 | "!

32 | "! See https://developers.google.com/drive/v3/reference/files?hl=de#resource 33 | "!

34 | begin of file_resource_fields, 35 | "! The id of the file. 36 | id type string value `id` ##NO_TEXT, 37 | 38 | "! The name of the file. This is not necessarily unique within a folder. Note that for 39 | "! immutable items such as the top level folders of Team Drives, My Drive root folder, and 40 | "! Application Data folder the name is constant. 41 | name type string value `name` ##NO_TEXT, 42 | 43 | "! The MIME type of the file. Drive will attempt to automatically detect an appropriate value 44 | "! from uploaded content if no value is provided. The value cannot be changed unless a new 45 | "! revision is uploaded. If a file is created with a Google Doc MIME type, the uploaded 46 | "! content will be imported if possible. The supported import formats are published in the 47 | "! About resource. 48 | mime_type type string value `mimeType` ##NO_TEXT, 49 | 50 | "! The time at which the file was created (RFC 3339 date-time). 51 | created_time type string value `createdTime` ##NO_TEXT, 52 | 53 | "! A link for opening the file in a relevant Google editor or viewer in a browser. 54 | web_view_link type string value `webViewLink` ##NO_TEXT, 55 | 56 | "! The IDs of the parent folders which contain the file. 57 | parents type string value `parents` ##NO_TEXT, 58 | end of file_resource_fields. 59 | 60 | constants: 61 | "! Enumeration of the field names in a Google Drive Files Resource 62 | "! List. 63 | "! 64 | "!

65 | "! See https://developers.google.com/drive/v3/reference/files?hl=de#resource 66 | "!

67 | begin of file_resource_list_fields, 68 | "! Identifies what kind of resource this is. Value: the fixed string "drive#fileList". 69 | kind type string value `kind` ##NO_TEXT, 70 | 71 | "! The page token for the next page of files. This will be absent if the end of the files list 72 | "! has been reached. If the token is rejected for any reason, it should be discarded, and 73 | "! pagination should be restarted from the first page of results. 74 | next_page_token type string value `nextPageToken` ##NO_TEXT, 75 | 76 | "! Whether the search process was incomplete. If true, then some search results may be 77 | "! missing, since all documents were not searched. This may occur when searching multiple Team 78 | "! Drives with the "user, allTeamDrives" corpora, but all corpora could not be searched. When 79 | "! this happens, it is suggested that clients narrow their query by choosing a different 80 | "! corpus such as "user" or "teamDrive". 81 | incomplete_search type string value `incompleteSearch` ##NO_TEXT, 82 | 83 | "! The list of files. If nextPageToken is populated, then this list may be incomplete and an 84 | "! additional page of results should be fetched. 85 | files type string value `files` ##NO_TEXT, 86 | end of file_resource_list_fields. 87 | 88 | "! Creates a Drive File Resource meta data in JSON format. 89 | "! 90 | "! @parameter id | The ID of the file resource. 91 | "! @parameter name | The name of the file resource. 92 | "! @parameter mime_type | The mime type of the file resource. 93 | "! @parameter parents | The IDs of the parent folders containing the file. 94 | "! @parameter result | The created meta data in JSON format. 95 | methods create_file_resource 96 | importing 97 | id type zif_googlepoc_drive_api=>file_resource_id optional 98 | name type zif_googlepoc_drive_api=>file_resource_name 99 | mime_type type zif_googlepoc_drive_api=>mime_type 100 | parents type zif_googlepoc_drive_api=>file_resource_ids optional 101 | returning 102 | value(result) type string. 103 | 104 | "! Parses a Drive File Resource response in JSON format. 105 | "! 106 | "! @parameter file_resource_json | The response to parse. 107 | "! @parameter result | The parsed file resource. 108 | methods parse_file_resource 109 | importing 110 | file_resource_json type string 111 | returning 112 | value(result) type zif_googlepoc_drive_api=>file_resource. 113 | 114 | "! Parses a Drive File Resource List response in JSON format. 115 | "! 116 | "! @parameter file_resource_list_json | The response to parse. 117 | "! @parameter result | The parsed list of file resources. 118 | methods parse_file_resource_list 119 | importing 120 | file_resource_list_json type string 121 | exporting 122 | result type zif_googlepoc_drive_api=>file_resources. 123 | 124 | "! Sets the logging API. 125 | "! 126 | "! @parameter api | The logging API to use. 127 | methods set_log_api 128 | importing 129 | api type ref to zif_googlepoc_drive_log_api. 130 | 131 | 132 | endinterface. 133 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_json_api.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_GOOGLEPOC_DRIVE_JSON_API 7 | E 8 | API for dealing with Google Drive JSON request / response 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_log_api.intf.abap: -------------------------------------------------------------------------------- 1 | "!

2 | "! Interface to the Logging API in the context of the 3 | "! Google Drive REST API. 4 | "!

5 | "! 6 | "!

7 | "! See https://developers.google.com/drive/ 8 | "!

9 | "! 10 | "!

11 | "! Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. 12 | "!
13 | "! This file is licensed under the SAP SAMPLE CODE LICENSE AGREEMENT except as noted otherwise in 14 | "! the LICENSE FILE 15 | "! (https://github.com/SAP-samples/abap-alv-google-upload-sheet/blob/master/LICENSES/Apache-2.0.txt). 16 | "!
17 | "!
18 | "! Note that the sample code includes calls to the Google Drive APIs which calls are licensed under 19 | "! the Creative Commons Attribution 3.0 License (https://creativecommons.org/licenses/by/3.0/) in 20 | "! accordance with Google's Developer Site Policies 21 | "! (https://developers.google.com/terms/site-policies). Furthermore, the use of the Google Drive 22 | "! service is subject to applicable agreements with Google Inc. 23 | "!

24 | interface zif_googlepoc_drive_log_api 25 | public. 26 | 27 | 28 | types: 29 | "! Describes a log entry. 30 | begin of log_entry, 31 | "! The date the entry was created on. 32 | date type d, 33 | 34 | "! The time the entry was created at. 35 | time type t, 36 | 37 | "! The message of the entry. 38 | message type string, 39 | end of log_entry. 40 | 41 | "! Describes a list of log entries. 42 | types log_entries type standard table 43 | of log_entry 44 | with empty key. 45 | 46 | "! The logging entries. 47 | data entries type log_entries read-only. 48 | 49 | "! Logs the given message. 50 | "! 51 | "! @parameter message | The message to log. 52 | methods log 53 | importing 54 | message type string. 55 | 56 | 57 | endinterface. 58 | -------------------------------------------------------------------------------- /src/zif_googlepoc_drive_log_api.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_GOOGLEPOC_DRIVE_LOG_API 7 | E 8 | API for creating log entries in the context of Google Drive 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/zwd_google_token_redirect.wdya.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZWD_GOOGLE_TOKEN_REDIRECT 7 | ZWD_GOOGLE_TOKEN_REDIRECT 8 | WINDOW 9 | DEFAULT 10 | ZWD_GOOGLE_TOKEN_REDIRECT 11 | 12 | 13 | 14 | ZWD_GOOGLE_TOKEN_REDIRECT 15 | WDPREFERREDRENDERING 16 | STAND_ONLY 17 | 18 | 19 | ZWD_GOOGLE_TOKEN_REDIRECT 20 | WDUIGUIDELINE 21 | FIORI 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/zwd_google_token_redirect.wdyn.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | ZWD_GOOGLE_TOKEN_REDIRECT 9 | A 10 | COMPONENTCONTROLLER 11 | COMPONENTINTERFACE 12 | ZWD_GOOGLE_TOKEN_REDIRECT 13 | ZCL_SALV_WD_GOOGLE_REDIRECT 14 | 15 | 16 | 17 | ZWD_GOOGLE_TOKEN_REDIRECT 18 | E 19 | Redirect Target Page for Google Access Token 20 | 21 | 22 | 23 | 24 | 25 | 26 | ZWD_GOOGLE_TOKEN_REDIRECT 27 | EMPTYVIEW 28 | A 29 | CL_WDY_MD_EMPTY_VIEW 30 | EMPTYVIEW 31 | EMPTYVIEW 32 | 33 | 34 | 35 | ZWD_GOOGLE_TOKEN_REDIRECT 36 | EMPTYVIEW 37 | SHOWEMPTYVIEW 38 | A 39 | CL_WDY_MD_INBOUND_PLUG 40 | SHOWEMPTYVIEW 41 | 42 | 43 | 44 | 45 | 46 | ZWD_GOOGLE_TOKEN_REDIRECT 47 | WINDOW 48 | A 49 | CL_WDY_MD_WINDOW 50 | WINDOW 51 | WINDOW 52 | MAIN_USAGE_0 53 | 54 | 55 | 56 | ZWD_GOOGLE_TOKEN_REDIRECT 57 | WINDOW 58 | DEFAULT 59 | A 60 | CL_WDY_MD_INBOUND_PLUG 61 | 1 62 | DEFAULT 63 | X 64 | 65 | 66 | 67 | 68 | ZWD_GOOGLE_TOKEN_REDIRECT 69 | WINDOW 70 | MAIN_USAGE_0 71 | A 72 | CL_WDY_MD_VIEW_USAGE 73 | MAIN 74 | MAIN_USAGE_0 75 | 76 | 77 | 78 | 79 | 80 | ZWD_GOOGLE_TOKEN_REDIRECT 81 | MAIN 82 | A 83 | CL_WDY_MD_VIEW 84 | MAIN 85 | ROOTUIELEMENTCONTAINER 86 | E 87 | MAIN 88 | 89 | 90 | 91 | ZWD_GOOGLE_TOKEN_REDIRECT 92 | MAIN 93 | E 94 | Web Dynpro View 95 | 96 | 97 | 98 | 99 | ZWD_GOOGLE_TOKEN_REDIRECT 100 | MAIN 101 | MY_MESSAGE_ICON 102 | A 103 | 1 104 | CL_WDY_MD_IMAGE 105 | MY_MESSAGE_ICON 106 | STANDARD 107 | IMAGE 108 | ROOTUIELEMENTCONTAINER 109 | CHILDREN 110 | 111 | 112 | ZWD_GOOGLE_TOKEN_REDIRECT 113 | MAIN 114 | MY_MESSAGE_ICON_LD 115 | A 116 | 1 117 | CL_WDY_MD_FLOW_DATA 118 | MY_MESSAGE_ICON_LD 119 | STANDARD 120 | FLOW_DATA 121 | MY_MESSAGE_ICON 122 | LAYOUT_DATA 123 | 124 | 125 | ZWD_GOOGLE_TOKEN_REDIRECT 126 | MAIN 127 | MY_MESSAGE_TEXT 128 | A 129 | 2 130 | CL_WDY_MD_TEXT_VIEW 131 | MY_MESSAGE_TEXT 132 | STANDARD 133 | TEXT_VIEW 134 | ROOTUIELEMENTCONTAINER 135 | CHILDREN 136 | 137 | 138 | ZWD_GOOGLE_TOKEN_REDIRECT 139 | MAIN 140 | MY_MESSAGE_TEXT_LD 141 | A 142 | 1 143 | CL_WDY_MD_FLOW_DATA 144 | MY_MESSAGE_TEXT_LD 145 | STANDARD 146 | FLOW_DATA 147 | MY_MESSAGE_TEXT 148 | LAYOUT_DATA 149 | 150 | 151 | ZWD_GOOGLE_TOKEN_REDIRECT 152 | MAIN 153 | ROOTUIELEMENTCONTAINER 154 | A 155 | CL_WDY_MD_TRANSP_CONTAINER 156 | ROOTUIELEMENTCONTAINER 157 | STANDARD 158 | TRANSPARENT_CONTAINER 159 | 160 | 161 | ZWD_GOOGLE_TOKEN_REDIRECT 162 | MAIN 163 | ROOTUIELEMENTCONTAINER_LAYOUT 164 | A 165 | 1 166 | CL_WDY_MD_FLOW_LAYOUT 167 | ROOTUIELEMENTCONTAINER_LAYOUT 168 | STANDARD 169 | FLOW_LAYOUT 170 | ROOTUIELEMENTCONTAINER 171 | LAYOUT 172 | 173 | 174 | 175 | 176 | ZWD_GOOGLE_TOKEN_REDIRECT 177 | MAIN 178 | MY_MESSAGE_TEXT 179 | TEXT 180 | A 181 | TEXT 182 | CONTEXT 183 | MESSAGE 184 | 185 | 186 | ZWD_GOOGLE_TOKEN_REDIRECT 187 | MAIN 188 | MY_MESSAGE_ICON 189 | SOURCE 190 | A 191 | SOURCE 192 | CONTEXT 193 | MESSAGE_ICON 194 | 195 | 196 | 197 | 198 | ZWD_GOOGLE_TOKEN_REDIRECT 199 | MAIN 200 | MY_MESSAGE_ICON 201 | A 202 | ADJUST_IMAGE_SIZE 203 | 204 | 205 | ZWD_GOOGLE_TOKEN_REDIRECT 206 | MAIN 207 | MY_MESSAGE_ICON 208 | A 209 | BORDER 210 | 0 211 | 212 | 213 | ZWD_GOOGLE_TOKEN_REDIRECT 214 | MAIN 215 | MY_MESSAGE_ICON 216 | A 217 | CONTEXT_MENU_BEHAVIOUR 218 | 00 219 | 220 | 221 | ZWD_GOOGLE_TOKEN_REDIRECT 222 | MAIN 223 | MY_MESSAGE_ICON 224 | A 225 | ENABLED 226 | X 227 | 228 | 229 | ZWD_GOOGLE_TOKEN_REDIRECT 230 | MAIN 231 | MY_MESSAGE_ICON 232 | A 233 | IS_DECORATIVE 234 | 235 | 236 | ZWD_GOOGLE_TOKEN_REDIRECT 237 | MAIN 238 | MY_MESSAGE_ICON 239 | A 240 | IS_DRAG_HANDLE 241 | 242 | 243 | ZWD_GOOGLE_TOKEN_REDIRECT 244 | MAIN 245 | MY_MESSAGE_ICON 246 | A 247 | SOURCE 248 | 249 | 250 | ZWD_GOOGLE_TOKEN_REDIRECT 251 | MAIN 252 | MY_MESSAGE_ICON 253 | A 254 | STRETCHMODE 255 | 00 256 | 257 | 258 | ZWD_GOOGLE_TOKEN_REDIRECT 259 | MAIN 260 | MY_MESSAGE_ICON 261 | A 262 | STYLE_CLASS_NAME 263 | 264 | 265 | ZWD_GOOGLE_TOKEN_REDIRECT 266 | MAIN 267 | MY_MESSAGE_ICON 268 | A 269 | TOOLTIP 270 | 271 | 272 | ZWD_GOOGLE_TOKEN_REDIRECT 273 | MAIN 274 | MY_MESSAGE_ICON 275 | A 276 | VISIBLE 277 | 02 278 | 279 | 280 | ZWD_GOOGLE_TOKEN_REDIRECT 281 | MAIN 282 | MY_MESSAGE_ICON 283 | A 284 | V_ALIGN 285 | 01 286 | 287 | 288 | ZWD_GOOGLE_TOKEN_REDIRECT 289 | MAIN 290 | MY_MESSAGE_ICON_LD 291 | A 292 | CELL_DESIGN 293 | 04 294 | 295 | 296 | ZWD_GOOGLE_TOKEN_REDIRECT 297 | MAIN 298 | MY_MESSAGE_ICON_LD 299 | A 300 | V_GUTTER 301 | 00 302 | 303 | 304 | ZWD_GOOGLE_TOKEN_REDIRECT 305 | MAIN 306 | MY_MESSAGE_TEXT 307 | A 308 | CONTEXT_MENU_BEHAVIOUR 309 | 00 310 | 311 | 312 | ZWD_GOOGLE_TOKEN_REDIRECT 313 | MAIN 314 | MY_MESSAGE_TEXT 315 | A 316 | DESIGN 317 | 09 318 | 319 | 320 | ZWD_GOOGLE_TOKEN_REDIRECT 321 | MAIN 322 | MY_MESSAGE_TEXT 323 | A 324 | ENABLED 325 | X 326 | 327 | 328 | ZWD_GOOGLE_TOKEN_REDIRECT 329 | MAIN 330 | MY_MESSAGE_TEXT 331 | A 332 | H_ALIGN 333 | 03 334 | 335 | 336 | ZWD_GOOGLE_TOKEN_REDIRECT 337 | MAIN 338 | MY_MESSAGE_TEXT 339 | A 340 | LAYOUT 341 | 01 342 | 343 | 344 | ZWD_GOOGLE_TOKEN_REDIRECT 345 | MAIN 346 | MY_MESSAGE_TEXT 347 | A 348 | MENU_INDICATOR 349 | 03 350 | 351 | 352 | ZWD_GOOGLE_TOKEN_REDIRECT 353 | MAIN 354 | MY_MESSAGE_TEXT 355 | A 356 | SEMANTIC_COLOR 357 | 00 358 | 359 | 360 | ZWD_GOOGLE_TOKEN_REDIRECT 361 | MAIN 362 | MY_MESSAGE_TEXT 363 | A 364 | TEXT 365 | 366 | 367 | ZWD_GOOGLE_TOKEN_REDIRECT 368 | MAIN 369 | MY_MESSAGE_TEXT 370 | A 371 | TEXT_DIRECTION 372 | 02 373 | 374 | 375 | ZWD_GOOGLE_TOKEN_REDIRECT 376 | MAIN 377 | MY_MESSAGE_TEXT 378 | A 379 | VERTICAL_SPACING 380 | 00 381 | 382 | 383 | ZWD_GOOGLE_TOKEN_REDIRECT 384 | MAIN 385 | MY_MESSAGE_TEXT 386 | A 387 | VISIBLE 388 | 02 389 | 390 | 391 | ZWD_GOOGLE_TOKEN_REDIRECT 392 | MAIN 393 | MY_MESSAGE_TEXT 394 | A 395 | WRAPPING 396 | 397 | 398 | ZWD_GOOGLE_TOKEN_REDIRECT 399 | MAIN 400 | MY_MESSAGE_TEXT_LD 401 | A 402 | CELL_DESIGN 403 | 04 404 | 405 | 406 | ZWD_GOOGLE_TOKEN_REDIRECT 407 | MAIN 408 | MY_MESSAGE_TEXT_LD 409 | A 410 | V_GUTTER 411 | 00 412 | 413 | 414 | ZWD_GOOGLE_TOKEN_REDIRECT 415 | MAIN 416 | ROOTUIELEMENTCONTAINER 417 | A 418 | ARIA_LANDMARK 419 | 10 420 | 421 | 422 | ZWD_GOOGLE_TOKEN_REDIRECT 423 | MAIN 424 | ROOTUIELEMENTCONTAINER 425 | A 426 | CONTEXT_MENU_BEHAVIOUR 427 | 00 428 | 429 | 430 | ZWD_GOOGLE_TOKEN_REDIRECT 431 | MAIN 432 | ROOTUIELEMENTCONTAINER 433 | A 434 | ENABLED 435 | X 436 | 437 | 438 | ZWD_GOOGLE_TOKEN_REDIRECT 439 | MAIN 440 | ROOTUIELEMENTCONTAINER 441 | A 442 | HANDLE_HOTKEYS 443 | 444 | 445 | ZWD_GOOGLE_TOKEN_REDIRECT 446 | MAIN 447 | ROOTUIELEMENTCONTAINER 448 | A 449 | IS_LAYOUT_CONTAINER 450 | X 451 | 452 | 453 | ZWD_GOOGLE_TOKEN_REDIRECT 454 | MAIN 455 | ROOTUIELEMENTCONTAINER 456 | A 457 | SCROLLING_MODE 458 | 02 459 | 460 | 461 | ZWD_GOOGLE_TOKEN_REDIRECT 462 | MAIN 463 | ROOTUIELEMENTCONTAINER 464 | A 465 | SCROLL_LEFT 466 | 0 467 | 468 | 469 | ZWD_GOOGLE_TOKEN_REDIRECT 470 | MAIN 471 | ROOTUIELEMENTCONTAINER 472 | A 473 | SCROLL_TOP 474 | 0 475 | 476 | 477 | ZWD_GOOGLE_TOKEN_REDIRECT 478 | MAIN 479 | ROOTUIELEMENTCONTAINER 480 | A 481 | VISIBLE 482 | 02 483 | 484 | 485 | ZWD_GOOGLE_TOKEN_REDIRECT 486 | MAIN 487 | ROOTUIELEMENTCONTAINER_LAYOUT 488 | A 489 | WRAPPING 490 | X 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | ZWD_GOOGLE_TOKEN_REDIRECT 499 | COMPONENTCONTROLLER 500 | A 501 | 02 502 | CONTEXT 503 | COMPONENTCONTROLLER 504 | ZIWCI_WD_GOOGLE_TOKEN_REDIRECT 505 | 506 | 507 | 508 | ZWD_GOOGLE_TOKEN_REDIRECT 509 | COMPONENTCONTROLLER 510 | WDDOAPPLICATIONSTATECHANGE 511 | E 512 | Handling for Suspending and Resuming an Application 513 | 514 | 515 | ZWD_GOOGLE_TOKEN_REDIRECT 516 | COMPONENTCONTROLLER 517 | WDDOBEFORENAVIGATION 518 | E 519 | Error Handling by Application Before Navigation 520 | 521 | 522 | ZWD_GOOGLE_TOKEN_REDIRECT 523 | COMPONENTCONTROLLER 524 | WDDOEXIT 525 | E 526 | Controller Clean-Up Method 527 | 528 | 529 | ZWD_GOOGLE_TOKEN_REDIRECT 530 | COMPONENTCONTROLLER 531 | WDDOINIT 532 | E 533 | Controller Initialization Method 534 | 535 | 536 | ZWD_GOOGLE_TOKEN_REDIRECT 537 | COMPONENTCONTROLLER 538 | WDDOPOSTPROCESSING 539 | E 540 | Preparation of Output 541 | 542 | 543 | 544 | 545 | ZWD_GOOGLE_TOKEN_REDIRECT 546 | COMPONENTCONTROLLER 547 | WDDOAPPLICATIONSTATECHANGE 548 | STATE_CHANGE 549 | A 550 | 1 551 | 1 552 | IF_WD_APPLICATION_STATE_CHANGE 553 | STATE_CHANGE 554 | 555 | 556 | ZWD_GOOGLE_TOKEN_REDIRECT 557 | COMPONENTCONTROLLER 558 | WDDOBEFORENAVIGATION 559 | IS_CURRENT_ROOT 560 | A 561 | 1 562 | WDY_BOOLEAN 563 | IS_CURRENT_ROOT 564 | 565 | 566 | ZWD_GOOGLE_TOKEN_REDIRECT 567 | COMPONENTCONTROLLER 568 | WDDOEXIT 569 | REASON 570 | A 571 | 1 572 | WDR_APPL_EXIT_REASON 573 | REASON 574 | 575 | 576 | ZWD_GOOGLE_TOKEN_REDIRECT 577 | COMPONENTCONTROLLER 578 | WDDOPOSTPROCESSING 579 | IS_CURRENT_ROOT 580 | A 581 | 1 582 | WDY_BOOLEAN 583 | IS_CURRENT_ROOT 584 | 585 | 586 | 587 | 588 | ZWD_GOOGLE_TOKEN_REDIRECT 589 | COMPONENTCONTROLLER 590 | CONTEXT 591 | A 592 | CL_WDY_MD_CONTEXT_VALUE_NODE 593 | 03 594 | 01 595 | 01 596 | X 597 | CONTEXT 598 | X 599 | X 600 | 601 | 602 | 603 | 604 | 605 | ZWD_GOOGLE_TOKEN_REDIRECT 606 | EMPTYVIEW 607 | A 608 | 01 609 | EMPTYVIEW 610 | 611 | 612 | 613 | 614 | ZWD_GOOGLE_TOKEN_REDIRECT 615 | MAIN 616 | A 617 | 01 618 | CONTEXT 619 | MAIN 620 | 621 | 622 | 623 | ZWD_GOOGLE_TOKEN_REDIRECT 624 | MAIN 625 | 00O2TO38YKWRIDSQ6RF7Z7FI3 626 | A 627 | COMPONENTCONTROLLER 628 | 629 | 630 | 631 | 632 | ZWD_GOOGLE_TOKEN_REDIRECT 633 | MAIN 634 | WDDOAFTERACTION 635 | E 636 | Method for non-action specific operations before navigation 637 | 638 | 639 | ZWD_GOOGLE_TOKEN_REDIRECT 640 | MAIN 641 | WDDOBEFOREACTION 642 | E 643 | Method for Validation of User Input 644 | 645 | 646 | ZWD_GOOGLE_TOKEN_REDIRECT 647 | MAIN 648 | WDDOEXIT 649 | E 650 | Controller Clean-Up Method 651 | 652 | 653 | ZWD_GOOGLE_TOKEN_REDIRECT 654 | MAIN 655 | WDDOINIT 656 | E 657 | Controller Initialization Method 658 | 659 | 660 | ZWD_GOOGLE_TOKEN_REDIRECT 661 | MAIN 662 | WDDOMODIFYVIEW 663 | E 664 | Method for Modifying the View Before Rendering 665 | 666 | 667 | ZWD_GOOGLE_TOKEN_REDIRECT 668 | MAIN 669 | WDDOONCONTEXTMENU 670 | E 671 | Method for Modifying the Context Menu 672 | 673 | 674 | 675 | 676 | ZWD_GOOGLE_TOKEN_REDIRECT 677 | MAIN 678 | WDDOMODIFYVIEW 679 | FIRST_TIME 680 | A 681 | 1 682 | WDY_BOOLEAN 683 | FIRST_TIME 684 | 685 | 686 | ZWD_GOOGLE_TOKEN_REDIRECT 687 | MAIN 688 | WDDOMODIFYVIEW 689 | VIEW 690 | A 691 | 2 692 | 1 693 | IF_WD_VIEW 694 | VIEW 695 | 696 | 697 | ZWD_GOOGLE_TOKEN_REDIRECT 698 | MAIN 699 | WDDOONCONTEXTMENU 700 | CONTEXT_MENU_EVENT 701 | A 702 | 1 703 | 1 704 | IF_WD_CONTEXT_MENU_EVENT 705 | CONTEXT_MENU_EVENT 706 | 707 | 708 | ZWD_GOOGLE_TOKEN_REDIRECT 709 | MAIN 710 | WDDOONCONTEXTMENU 711 | CONTEXT_MENU_MANAGER 712 | A 713 | 2 714 | 1 715 | IF_WD_CONTEXT_MENU_MANAGER 716 | CONTEXT_MENU_MANAGER 717 | 718 | 719 | ZWD_GOOGLE_TOKEN_REDIRECT 720 | MAIN 721 | WDDOONCONTEXTMENU 722 | MENU 723 | A 724 | 3 725 | 3 726 | 1 727 | CL_WD_MENU 728 | MENU 729 | 730 | 731 | 732 | 733 | ZWD_GOOGLE_TOKEN_REDIRECT 734 | MAIN 735 | CONTEXT 736 | A 737 | CL_WDY_MD_CONTEXT_VALUE_NODE 738 | 03 739 | 01 740 | 01 741 | X 742 | CONTEXT 743 | X 744 | 745 | 746 | 747 | 748 | ZWD_GOOGLE_TOKEN_REDIRECT 749 | MAIN 750 | CONTEXT 751 | MESSAGE 752 | A 753 | CL_WDY_MD_CTX_VALUE_ATTRIBUTE 754 | 1 755 | STRING 756 | MESSAGE 757 | 758 | 759 | ZWD_GOOGLE_TOKEN_REDIRECT 760 | MAIN 761 | CONTEXT 762 | MESSAGE_ICON 763 | A 764 | CL_WDY_MD_CTX_VALUE_ATTRIBUTE 765 | 2 766 | STRING 767 | MESSAGE_ICON 768 | 769 | 770 | 771 | 772 | 773 | ZWD_GOOGLE_TOKEN_REDIRECT 774 | WINDOW 775 | A 776 | 06 777 | CONTEXT 778 | WINDOW 779 | 780 | 781 | 782 | ZWD_GOOGLE_TOKEN_REDIRECT 783 | WINDOW 784 | 00O2TO38YKWRIDSQ6RF7Z796J 785 | A 786 | COMPONENTCONTROLLER 787 | 788 | 789 | 790 | 791 | ZWD_GOOGLE_TOKEN_REDIRECT 792 | WINDOW 793 | WDDOEXIT 794 | E 795 | Controller Clean-Up Method 796 | 797 | 798 | ZWD_GOOGLE_TOKEN_REDIRECT 799 | WINDOW 800 | WDDOINIT 801 | E 802 | Controller Initialization Method 803 | 804 | 805 | ZWD_GOOGLE_TOKEN_REDIRECT 806 | WINDOW 807 | WDDOONCLOSE 808 | E 809 | Handling When Closing the Window 810 | 811 | 812 | ZWD_GOOGLE_TOKEN_REDIRECT 813 | WINDOW 814 | WDDOONOPEN 815 | E 816 | Handling When Opening the Window 817 | 818 | 819 | 820 | 821 | ZWD_GOOGLE_TOKEN_REDIRECT 822 | WINDOW 823 | WDDOONOPEN 824 | WINDOW_DESCR 825 | A 826 | 1 827 | 1 828 | IF_WD_WINDOW_DESCRIPTION 829 | WINDOW_DESCR 830 | 831 | 832 | 833 | 834 | ZWD_GOOGLE_TOKEN_REDIRECT 835 | WINDOW 836 | CONTEXT 837 | A 838 | CL_WDY_MD_CONTEXT_VALUE_NODE 839 | 03 840 | 01 841 | 01 842 | X 843 | CONTEXT 844 | X 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | ZWD_GOOGLE_TOKEN_REDIRECT 853 | COMPONENTCONTROLLER 854 | WDDOAPPLICATIONSTATECHANGE 855 | A 856 | CL_WDY_MD_CONTROLLER_METHOD 857 | 2 858 | WDDOAPPLICATIONSTATECHANGE 859 | 860 | 861 | ZWD_GOOGLE_TOKEN_REDIRECT 862 | COMPONENTCONTROLLER 863 | WDDOBEFORENAVIGATION 864 | A 865 | CL_WDY_MD_CONTROLLER_METHOD 866 | 2 867 | WDDOBEFORENAVIGATION 868 | 869 | 870 | ZWD_GOOGLE_TOKEN_REDIRECT 871 | COMPONENTCONTROLLER 872 | WDDOEXIT 873 | A 874 | CL_WDY_MD_CONTROLLER_METHOD 875 | 2 876 | WDDOEXIT 877 | 878 | 879 | ZWD_GOOGLE_TOKEN_REDIRECT 880 | COMPONENTCONTROLLER 881 | WDDOINIT 882 | A 883 | CL_WDY_MD_CONTROLLER_METHOD 884 | 2 885 | WDDOINIT 886 | 887 | 888 | ZWD_GOOGLE_TOKEN_REDIRECT 889 | COMPONENTCONTROLLER 890 | WDDOPOSTPROCESSING 891 | A 892 | CL_WDY_MD_CONTROLLER_METHOD 893 | 2 894 | WDDOPOSTPROCESSING 895 | 896 | 897 | ZWD_GOOGLE_TOKEN_REDIRECT 898 | MAIN 899 | WDDOAFTERACTION 900 | A 901 | CL_WDY_MD_CONTROLLER_METHOD 902 | 2 903 | WDDOAFTERACTION 904 | 905 | 906 | ZWD_GOOGLE_TOKEN_REDIRECT 907 | MAIN 908 | WDDOBEFOREACTION 909 | A 910 | CL_WDY_MD_CONTROLLER_METHOD 911 | 2 912 | WDDOBEFOREACTION 913 | 914 | 915 | ZWD_GOOGLE_TOKEN_REDIRECT 916 | MAIN 917 | WDDOEXIT 918 | A 919 | CL_WDY_MD_CONTROLLER_METHOD 920 | 2 921 | WDDOEXIT 922 | 923 | 924 | ZWD_GOOGLE_TOKEN_REDIRECT 925 | MAIN 926 | WDDOINIT 927 | A 928 | CL_WDY_MD_CONTROLLER_METHOD 929 | 2 930 | WDDOINIT 931 | 932 | 933 | ZWD_GOOGLE_TOKEN_REDIRECT 934 | MAIN 935 | WDDOMODIFYVIEW 936 | A 937 | CL_WDY_MD_CONTROLLER_METHOD 938 | 2 939 | WDDOMODIFYVIEW 940 | 941 | 942 | ZWD_GOOGLE_TOKEN_REDIRECT 943 | MAIN 944 | WDDOONCONTEXTMENU 945 | A 946 | CL_WDY_MD_CONTROLLER_METHOD 947 | 2 948 | WDDOONCONTEXTMENU 949 | 950 | 951 | ZWD_GOOGLE_TOKEN_REDIRECT 952 | WINDOW 953 | HANDLEDEFAULT 954 | A 955 | CL_WDY_MD_CTLR_EVENT_HANDLER 956 | 2 957 | WINDOW 958 | DEFAULT 959 | HANDLEDEFAULT 960 | 961 | 962 | ZWD_GOOGLE_TOKEN_REDIRECT 963 | WINDOW 964 | WDDOEXIT 965 | A 966 | CL_WDY_MD_CONTROLLER_METHOD 967 | 2 968 | WDDOEXIT 969 | 970 | 971 | ZWD_GOOGLE_TOKEN_REDIRECT 972 | WINDOW 973 | WDDOINIT 974 | A 975 | CL_WDY_MD_CONTROLLER_METHOD 976 | 2 977 | WDDOINIT 978 | 979 | 980 | ZWD_GOOGLE_TOKEN_REDIRECT 981 | WINDOW 982 | WDDOONCLOSE 983 | A 984 | CL_WDY_MD_CONTROLLER_METHOD 985 | 2 986 | WDDOONCLOSE 987 | 988 | 989 | ZWD_GOOGLE_TOKEN_REDIRECT 990 | WINDOW 991 | WDDOONOPEN 992 | A 993 | CL_WDY_MD_CONTROLLER_METHOD 994 | 2 995 | WDDOONOPEN 996 | 997 | 998 | 999 | 1000 | ZWD_GOOGLE_TOKEN_REDIRECT 1001 | COMPONENTCONTROLLER 1002 | WDDOAPPLICATIONSTATECHANGE 1003 | 1 1004 | method WDDOAPPLICATIONSTATECHANGE . 1005 | 1006 | 1007 | ZWD_GOOGLE_TOKEN_REDIRECT 1008 | COMPONENTCONTROLLER 1009 | WDDOAPPLICATIONSTATECHANGE 1010 | 2 1011 | endmethod. 1012 | 1013 | 1014 | ZWD_GOOGLE_TOKEN_REDIRECT 1015 | COMPONENTCONTROLLER 1016 | WDDOBEFORENAVIGATION 1017 | 1 1018 | method WDDOBEFORENAVIGATION . 1019 | 1020 | 1021 | ZWD_GOOGLE_TOKEN_REDIRECT 1022 | COMPONENTCONTROLLER 1023 | WDDOBEFORENAVIGATION 1024 | 2 1025 | endmethod. 1026 | 1027 | 1028 | ZWD_GOOGLE_TOKEN_REDIRECT 1029 | COMPONENTCONTROLLER 1030 | WDDOEXIT 1031 | 1 1032 | method WDDOEXIT . 1033 | 1034 | 1035 | ZWD_GOOGLE_TOKEN_REDIRECT 1036 | COMPONENTCONTROLLER 1037 | WDDOEXIT 1038 | 2 1039 | endmethod. 1040 | 1041 | 1042 | ZWD_GOOGLE_TOKEN_REDIRECT 1043 | COMPONENTCONTROLLER 1044 | WDDOINIT 1045 | 1 1046 | method WDDOINIT . 1047 | 1048 | 1049 | ZWD_GOOGLE_TOKEN_REDIRECT 1050 | COMPONENTCONTROLLER 1051 | WDDOINIT 1052 | 2 1053 | endmethod. 1054 | 1055 | 1056 | ZWD_GOOGLE_TOKEN_REDIRECT 1057 | COMPONENTCONTROLLER 1058 | WDDOPOSTPROCESSING 1059 | 1 1060 | method WDDOPOSTPROCESSING . 1061 | 1062 | 1063 | ZWD_GOOGLE_TOKEN_REDIRECT 1064 | COMPONENTCONTROLLER 1065 | WDDOPOSTPROCESSING 1066 | 2 1067 | endmethod. 1068 | 1069 | 1070 | ZWD_GOOGLE_TOKEN_REDIRECT 1071 | MAIN 1072 | WDDOAFTERACTION 1073 | 1 1074 | method WDDOAFTERACTION . 1075 | 1076 | 1077 | ZWD_GOOGLE_TOKEN_REDIRECT 1078 | MAIN 1079 | WDDOAFTERACTION 1080 | 2 1081 | endmethod. 1082 | 1083 | 1084 | ZWD_GOOGLE_TOKEN_REDIRECT 1085 | MAIN 1086 | WDDOBEFOREACTION 1087 | 1 1088 | method WDDOBEFOREACTION . 1089 | 1090 | 1091 | ZWD_GOOGLE_TOKEN_REDIRECT 1092 | MAIN 1093 | WDDOBEFOREACTION 1094 | 2 1095 | endmethod. 1096 | 1097 | 1098 | ZWD_GOOGLE_TOKEN_REDIRECT 1099 | MAIN 1100 | WDDOEXIT 1101 | 1 1102 | method WDDOEXIT . 1103 | 1104 | 1105 | ZWD_GOOGLE_TOKEN_REDIRECT 1106 | MAIN 1107 | WDDOEXIT 1108 | 2 1109 | endmethod. 1110 | 1111 | 1112 | ZWD_GOOGLE_TOKEN_REDIRECT 1113 | MAIN 1114 | WDDOINIT 1115 | 1 1116 | method WDDOINIT . 1117 | 1118 | 1119 | ZWD_GOOGLE_TOKEN_REDIRECT 1120 | MAIN 1121 | WDDOINIT 1122 | 2 1123 | endmethod. 1124 | 1125 | 1126 | ZWD_GOOGLE_TOKEN_REDIRECT 1127 | MAIN 1128 | WDDOMODIFYVIEW 1129 | 1 1130 | method WDDOMODIFYVIEW . 1131 | 1132 | 1133 | ZWD_GOOGLE_TOKEN_REDIRECT 1134 | MAIN 1135 | WDDOMODIFYVIEW 1136 | 2 1137 | wd_assist->get_message( 1138 | 1139 | 1140 | ZWD_GOOGLE_TOKEN_REDIRECT 1141 | MAIN 1142 | WDDOMODIFYVIEW 1143 | 3 1144 | importing 1145 | 1146 | 1147 | ZWD_GOOGLE_TOKEN_REDIRECT 1148 | MAIN 1149 | WDDOMODIFYVIEW 1150 | 4 1151 | message = data(message) 1152 | 1153 | 1154 | ZWD_GOOGLE_TOKEN_REDIRECT 1155 | MAIN 1156 | WDDOMODIFYVIEW 1157 | 5 1158 | message_icon = data(message_icon) ). 1159 | 1160 | 1161 | ZWD_GOOGLE_TOKEN_REDIRECT 1162 | MAIN 1163 | WDDOMODIFYVIEW 1164 | 6 1165 | wd_context->set_attribute( name = `MESSAGE` 1166 | 1167 | 1168 | ZWD_GOOGLE_TOKEN_REDIRECT 1169 | MAIN 1170 | WDDOMODIFYVIEW 1171 | 7 1172 | value = message ) ##NO_TEXT. 1173 | 1174 | 1175 | ZWD_GOOGLE_TOKEN_REDIRECT 1176 | MAIN 1177 | WDDOMODIFYVIEW 1178 | 8 1179 | 1180 | 1181 | ZWD_GOOGLE_TOKEN_REDIRECT 1182 | MAIN 1183 | WDDOMODIFYVIEW 1184 | 9 1185 | wd_context->set_attribute( name = `MESSAGE_ICON` 1186 | 1187 | 1188 | ZWD_GOOGLE_TOKEN_REDIRECT 1189 | MAIN 1190 | WDDOMODIFYVIEW 1191 | 10 1192 | value = message_icon ) ##NO_TEXT. 1193 | 1194 | 1195 | ZWD_GOOGLE_TOKEN_REDIRECT 1196 | MAIN 1197 | WDDOMODIFYVIEW 1198 | 11 1199 | endmethod. 1200 | 1201 | 1202 | ZWD_GOOGLE_TOKEN_REDIRECT 1203 | MAIN 1204 | WDDOONCONTEXTMENU 1205 | 1 1206 | method WDDOONCONTEXTMENU . 1207 | 1208 | 1209 | ZWD_GOOGLE_TOKEN_REDIRECT 1210 | MAIN 1211 | WDDOONCONTEXTMENU 1212 | 2 1213 | endmethod. 1214 | 1215 | 1216 | ZWD_GOOGLE_TOKEN_REDIRECT 1217 | WINDOW 1218 | HANDLEDEFAULT 1219 | 1 1220 | method handledefault . 1221 | 1222 | 1223 | ZWD_GOOGLE_TOKEN_REDIRECT 1224 | WINDOW 1225 | HANDLEDEFAULT 1226 | 2 1227 | data all_url_params type tihttpnvp. 1228 | 1229 | 1230 | ZWD_GOOGLE_TOKEN_REDIRECT 1231 | WINDOW 1232 | HANDLEDEFAULT 1233 | 3 1234 | wdevent->get_data( 1235 | 1236 | 1237 | ZWD_GOOGLE_TOKEN_REDIRECT 1238 | WINDOW 1239 | HANDLEDEFAULT 1240 | 4 1241 | exporting 1242 | 1243 | 1244 | ZWD_GOOGLE_TOKEN_REDIRECT 1245 | WINDOW 1246 | HANDLEDEFAULT 1247 | 5 1248 | name = if_wd_application=>all_url_parameters 1249 | 1250 | 1251 | ZWD_GOOGLE_TOKEN_REDIRECT 1252 | WINDOW 1253 | HANDLEDEFAULT 1254 | 6 1255 | importing 1256 | 1257 | 1258 | ZWD_GOOGLE_TOKEN_REDIRECT 1259 | WINDOW 1260 | HANDLEDEFAULT 1261 | 7 1262 | value = all_url_params ). 1263 | 1264 | 1265 | ZWD_GOOGLE_TOKEN_REDIRECT 1266 | WINDOW 1267 | HANDLEDEFAULT 1268 | 8 1269 | wd_assist->set_url_parameters( all_url_params ). 1270 | 1271 | 1272 | ZWD_GOOGLE_TOKEN_REDIRECT 1273 | WINDOW 1274 | HANDLEDEFAULT 1275 | 9 1276 | endmethod. 1277 | 1278 | 1279 | ZWD_GOOGLE_TOKEN_REDIRECT 1280 | WINDOW 1281 | WDDOEXIT 1282 | 1 1283 | method WDDOEXIT . 1284 | 1285 | 1286 | ZWD_GOOGLE_TOKEN_REDIRECT 1287 | WINDOW 1288 | WDDOEXIT 1289 | 2 1290 | endmethod. 1291 | 1292 | 1293 | ZWD_GOOGLE_TOKEN_REDIRECT 1294 | WINDOW 1295 | WDDOINIT 1296 | 1 1297 | method WDDOINIT . 1298 | 1299 | 1300 | ZWD_GOOGLE_TOKEN_REDIRECT 1301 | WINDOW 1302 | WDDOINIT 1303 | 2 1304 | endmethod. 1305 | 1306 | 1307 | ZWD_GOOGLE_TOKEN_REDIRECT 1308 | WINDOW 1309 | WDDOONCLOSE 1310 | 1 1311 | method WDDOONCLOSE . 1312 | 1313 | 1314 | ZWD_GOOGLE_TOKEN_REDIRECT 1315 | WINDOW 1316 | WDDOONCLOSE 1317 | 2 1318 | endmethod. 1319 | 1320 | 1321 | ZWD_GOOGLE_TOKEN_REDIRECT 1322 | WINDOW 1323 | WDDOONOPEN 1324 | 1 1325 | method WDDOONOPEN . 1326 | 1327 | 1328 | ZWD_GOOGLE_TOKEN_REDIRECT 1329 | WINDOW 1330 | WDDOONOPEN 1331 | 2 1332 | endmethod. 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | --------------------------------------------------------------------------------