├── .abapgit.xml
├── LICENSE
├── LICENSES
└── Apache-2.0.txt
├── README.md
├── REUSE.toml
├── images
├── 010_select_function_modules.png
├── 020_specify_options.png
├── 030_result_report.png
├── 040_generated_objects.png
└── README.md
└── src
├── package.devc.xml
├── zcl_gen_rfc_tier2_proxy.clas.abap
├── zcl_gen_rfc_tier2_proxy.clas.xml
├── zr_gen_rfc_tier2_proxy.prog.abap
└── zr_gen_rfc_tier2_proxy.prog.xml
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | TEST_AF_TIER2_RFC_PROXY (report and class)
6 | E
7 | /src/
8 | PREFIX
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/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 | 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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://api.reuse.software/info/github.com/SAP-samples/tier2-rfc-proxy)
2 |
3 | # Tier2 RFC proxy generator
4 |
5 | ## Description
6 |
7 | This repository contains a helper class and a report that helps you to generate a custom wrapper for the ABAP Cloud enablement of an non-released RFC based SAP API.
8 |
9 | It basically uses the same API used by transaction ACO_PROXY. It takes the code that is generated by this API and creates an interface and a factory class and C1-releases those objects. So it basically automates most of the steps described in this repository [RAP640 - Using ABAP Cloud to Build Extensions for SAP S/4HANA Cloud, Private Edition - Mitigating Missing Released SAP APIs in the 3-tier Extensibility Model](https://github.com/SAP-samples/abap-platform-rap640/tree/main).
10 |
11 | The transaction ACO_PROXY and its underlying API now also check if a data element that is used by a non released function module itself has been released. If this is the case, no shadow type will be generated.
12 |
13 | ## Blog Post in SAP Community
14 |
15 | [Blog Post: How to generate a wrapper for function modules (BAPIs) in tier 2](https://community.sap.com/t5/technology-blogs-by-sap/how-to-generate-a-wrapper-for-function-modules-bapis-in-tier-2/ba-p/13692790)
16 |
17 | ## Requirements
18 |
19 | - You have to have a system based on SAP S/4HANA 2022 on premise.
20 | - You have to have enabled Developer extensibility
21 | - You have to apply the following notes
22 | - [SAP Note 3444292 - ACO Proxy creates unnecessary shadow types](https://me.sap.com/notes/3444292)
23 | - [SAP Note 3457580 - SAP ACO - Duplicate Types for Table Parameters](https://me.sap.com/notes/3457580)
24 |
25 |
26 | ## Future Outlook
27 | In future the idea is to provide such a generator as well in the ABAP development tools for Eclipse.
28 | This will be possible with the next S/4HANA release and the ADT generator framework.
29 |
30 | ## How to section
31 |
32 | The tool can be used in short as follows:
33 |
34 | 1. Start report **zr_gen_rfc_tier2_proxy** using transaction **SE38**.
35 | 2. Select one or more function modules that shall be wrapped for the use in ABAP Cloud.
36 |
37 |
38 |
39 | 3. Select remaining parameters
40 |
41 |
42 |
43 | 3.1 **Target Package** : Here you have to select the package in which the wrapper objects shall be generated
44 |
45 | 3.2 **Intf., class and fact.class**: When you select this option the generator will generate a wrapper class, an interface and a factory class (this is recommended)
46 | **Only wrapper class**: When you select this option the generator will only generate a wrapper class, for those that do not want to generate 3 wrapper objects
47 | 3.3 Here you have to specify the repository object names that shall be generated. Depending on the option you have chosen you have to specify the names of three objects or just for one class.
48 | 3.4 You can specify whether the objects if they already exist are being overwritten
49 |
50 | 5. Start the report and check the output.
51 |
52 |
53 |
54 | 6. Check the generated objects in the target package.
55 |
56 |
57 |
58 | 7. What is now left to do is that the developer has to implement the public methods with a call of the respective private methods.
59 |
60 | Here it is possible to change the signature of the public method e.g. by reducing the number of parameters that are exposed.
61 |
62 | By default the public and private methods use the same signature.
63 |
64 | ```ABAP
65 | METHOD zif_wrap_test_003~bapi_pr_create.
66 | "add call to private method bapi_pr_create
67 | "e.g. me->bapi_pr_create( ... )
68 | ENDMETHOD.
69 | ```
70 |
71 | ## Generated code
72 |
73 | ### Wrapper Interface
74 |
75 | ```ABAP
76 | INTERFACE zif_wrap_test_003
77 | PUBLIC .
78 |
79 | TYPES:
80 | banfn TYPE c LENGTH 000010 ##TYPSHADOW .
81 | TYPES:
82 | bsart TYPE c LENGTH 000004 ##TYPSHADOW .
83 | TYPES:
84 | bsakz TYPE c LENGTH 000001 ##TYPSHADOW .
85 | TYPES:
86 | gsfrg TYPE c LENGTH 000001 ##TYPSHADOW .
87 | TYPES:
88 | estkz TYPE c LENGTH 000001 ##TYPSHADOW .
89 |
90 | ....
91 |
92 | TYPES:
93 | BEGIN OF bapimereqheader ,
94 | preq_no TYPE banfn,
95 | pr_type TYPE bsart,
96 | ctrl_ind TYPE bsakz,
97 | general_release TYPE gsfrg,
98 | create_ind TYPE estkz,
99 | item_intvl TYPE pincr,
100 | last_item TYPE lponr,
101 | auto_source TYPE kzzuo,
102 | memory TYPE membf,
103 | hold_complete TYPE bapimereqpostflag,
104 | hold_uncomplete TYPE bapimereqpostflag,
105 | park_complete TYPE bapimereqpostflag,
106 | park_uncomplete TYPE bapimereqpostflag,
107 | memorytype TYPE memorytype,
108 | END OF bapimereqheader ##TYPSHADOW .
109 | TYPES:
110 | BEGIN OF bapimereqheaderx ,
111 | preq_no TYPE bapiupdate,
112 |
113 | ...
114 |
115 | METHODS bapi_pr_create
116 | IMPORTING
117 | !prheader TYPE bapimereqheader OPTIONAL
118 | !prheaderx TYPE bapimereqheaderx OPTIONAL
119 | !testrun TYPE char1 OPTIONAL
120 | !_dest_ TYPE rfcdest DEFAULT 'NONE'
121 | EXPORTING
122 | !number TYPE banfn
123 | !prheaderexp TYPE bapimereqheader
124 | CHANGING
125 | !allversions TYPE _bapimedcm_allversions OPTIONAL
126 | !extensionin TYPE _bapiparex OPTIONAL
127 | !extensionout TYPE _bapiparex OPTIONAL
128 | !praccount TYPE _bapimereqaccount OPTIONAL
129 | !praccountproitsegment TYPE _bapimereqaccountprofitseg OPTIONAL
130 | !praccountx TYPE _bapimereqaccountx OPTIONAL
131 | !praddrdelivery TYPE _bapimerqaddrdelivery OPTIONAL
132 | !prcomponents TYPE _bapimereqcomponent OPTIONAL
133 | !prcomponentsx TYPE _bapimereqcomponentx OPTIONAL
134 | !prheadertext TYPE _bapimereqheadtext OPTIONAL
135 | !pritem TYPE _bapimereqitemimp
136 | !pritemexp TYPE _bapimereqitem OPTIONAL
137 | !pritemsource TYPE _bapimereqsource OPTIONAL
138 | !pritemtext TYPE _bapimereqitemtext OPTIONAL
139 | !pritemx TYPE _bapimereqitemx OPTIONAL
140 | !prversion TYPE _bapimereqdcm OPTIONAL
141 | !prversionx TYPE _bapimereqdcmx OPTIONAL
142 | !return TYPE _bapiret2 OPTIONAL
143 | !serialnumber TYPE _bapimereqserialno OPTIONAL
144 | !serialnumberx TYPE _bapimereqserialnox OPTIONAL
145 | !serviceaccount TYPE _bapi_srv_acc_data OPTIONAL
146 | !serviceaccountx TYPE _bapi_srv_acc_datax OPTIONAL
147 | !servicecontractlimits TYPE _bapi_srv_contract_limits OPTIONAL
148 | !servicecontractlimitsx TYPE _bapi_srv_contract_limitsx OPTIONAL
149 | !servicelimit TYPE _bapi_srv_limit_data OPTIONAL
150 | !servicelimitx TYPE _bapi_srv_limit_datax OPTIONAL
151 | !servicelines TYPE _bapi_srv_service_line OPTIONAL
152 | !servicelinesx TYPE _bapi_srv_service_linex OPTIONAL
153 | !servicelongtexts TYPE _bapi_srv_longtexts OPTIONAL
154 | !serviceoutline TYPE _bapi_srv_outline OPTIONAL
155 | !serviceoutlinex TYPE _bapi_srv_outlinex OPTIONAL
156 | RAISING
157 | cx_aco_application_exception
158 | cx_aco_communication_failure
159 | cx_aco_system_failure .
160 | ENDINTERFACE.
161 |
162 | ```
163 |
164 | ### Wrapper Class
165 |
166 | ```ABAP
167 | CLASS zcl_wrap_test_003 DEFINITION
168 | PUBLIC
169 | FINAL
170 | CREATE PUBLIC .
171 | PUBLIC SECTION.
172 | INTERFACES zif_wrap_test_003.
173 | PROTECTED SECTION.
174 | PRIVATE SECTION.
175 |
176 | METHODS bapi_pr_create
177 | IMPORTING
178 | !prheader TYPE zif_wrap_test_003~bapimereqheader OPTIONAL
179 | !prheaderx TYPE zif_wrap_test_003~bapimereqheaderx OPTIONAL
180 | !testrun TYPE zif_wrap_test_003~char1 OPTIONAL
181 | !_dest_ TYPE rfcdest DEFAULT 'NONE'
182 | EXPORTING
183 | !number TYPE zif_wrap_test_003~banfn
184 | !prheaderexp TYPE zif_wrap_test_003~bapimereqheader
185 |
186 | ...
187 |
188 | ...
189 |
190 | CLASS zcl_wrap_test_003 IMPLEMENTATION.
191 |
192 | METHOD bapi_pr_create.
193 | DATA: _rfc_message_ TYPE aco_proxy_msg_type.
194 | CALL FUNCTION 'BAPI_PR_CREATE' DESTINATION space
195 | EXPORTING
196 | prheader = prheader
197 | prheaderx = prheaderx
198 | testrun = testrun
199 | IMPORTING
200 | number = number
201 | prheaderexp = prheaderexp
202 | TABLES
203 | allversions = allversions
204 | extensionin = extensionin
205 | extensionout = extensionout
206 | praccount = praccount
207 | ...
208 | serviceoutlinex = serviceoutlinex
209 | EXCEPTIONS
210 | communication_failure = 1 MESSAGE _rfc_message_
211 | system_failure = 2 MESSAGE _rfc_message_
212 | OTHERS = 3.
213 | IF sy-subrc NE 0.
214 | DATA __sysubrc TYPE sy-subrc.
215 | DATA __textid TYPE aco_proxy_textid_type.
216 | __sysubrc = sy-subrc.
217 | __textid-msgid = sy-msgid.
218 | __textid-msgno = sy-msgno.
219 | __textid-attr1 = sy-msgv1.
220 | __textid-attr2 = sy-msgv2.
221 | __textid-attr3 = sy-msgv3.
222 | __textid-attr4 = sy-msgv4.
223 | CASE __sysubrc.
224 | WHEN 1 .
225 | RAISE EXCEPTION TYPE cx_aco_communication_failure
226 | EXPORTING
227 | rfc_msg = _rfc_message_.
228 | WHEN 2 .
229 | RAISE EXCEPTION TYPE cx_aco_system_failure
230 | EXPORTING
231 | rfc_msg = _rfc_message_.
232 | WHEN 3 .
233 | RAISE EXCEPTION TYPE cx_aco_application_exception
234 | EXPORTING
235 | exception_id = 'OTHERS'
236 | textid = __textid.
237 | ENDCASE.
238 | ENDIF.
239 |
240 | ENDMETHOD.
241 |
242 |
243 | METHOD zif_wrap_test_003~bapi_pr_create.
244 | "add call to private method bapi_pr_create
245 | "e.g. me->bapi_pr_create( ... )
246 | ENDMETHOD.
247 | ENDCLASS.
248 |
249 | ```
250 |
251 | ### Factory Class
252 |
253 | ```ABAP
254 | CLASS zcl_fact_test_003 DEFINITION
255 | PUBLIC
256 | FINAL
257 | CREATE PRIVATE .
258 | PUBLIC SECTION.
259 | CLASS-METHODS create_instance
260 | RETURNING VALUE(result) TYPE REF TO zif_wrap_test_003.
261 | PROTECTED SECTION.
262 | PRIVATE SECTION.
263 | METHODS constructor.
264 | ENDCLASS.
265 |
266 | CLASS zcl_fact_test_003 IMPLEMENTATION.
267 | METHOD constructor.
268 | ENDMETHOD.
269 | METHOD create_instance.
270 | result = NEW zcl_wrap_test_003( ).
271 | ENDMETHOD.
272 | ENDCLASS.
273 | ```
274 |
275 |
276 | ## Background
277 |
278 | This report uses under the hood the API's that are used by transaction **ACO_PROXY**.
279 |
280 | In principle you can achieve the same result by running the transaction ACO_PROXY which will generated a wrapper class and then perform the following steps:
281 |
282 | - create an interface
283 | - copy the code of the definition part of the class generated by ACO_PROXY to the interface
284 | - replace the CLASS-METHODS statements with METHODS statements in the interface
285 | - replace the defintion part of the wrapper class generated by ACO_PROXY with an INTERFACE statement
286 | - change the __dest__ statements with _space_ statements.
287 | - create a factory class that instantiates the wrapper class
288 | - C1 release the interface and the factory class
289 |
290 |
291 |
292 | ## Further information
293 |
294 | - [ABAP Cloud - How to mitigate missing released SAP APIs in SAP S/4HANA Cloud, private edition and SAP S/4HANA – The new ABAP Cloud API enablement guide](https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/abap-cloud-how-to-mitigate-missing-released-sap-apis-in-sap-s-4hana-cloud/ba-p/13561479)
295 |
296 | - [ABAP Cloud – Mitigate missing released SAP APIs in the 3-tier extensibility model: a tutorial how to wrap a BAPI and integrate it into a custom RAP business object](https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/abap-cloud-mitigate-missing-released-sap-apis-in-the-3-tier-extensibility/ba-p/13580268)
297 |
298 |
299 |
300 | ## Download and Installation
301 |
302 | ## Known Issues
303 | No known issues.
304 |
305 | ## How to obtain support
306 | [Create an issue](https://github.com/SAP-samples/tier2-rfc-proxy/issues) in this repository if you find a bug or have questions about the content.
307 |
308 | For additional support, [ask a question in SAP Community](https://answers.sap.com/questions/ask.html).
309 |
310 | ## Contributing
311 | If you wish to contribute code, offer fixes or improvements, please send a pull request. Due to legal reasons, contributors will be asked to accept a DCO when they create the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/).
312 |
313 | ## License
314 | Copyright (c) 2024 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](LICENSE) file.
315 |
--------------------------------------------------------------------------------
/REUSE.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 | SPDX-PackageName = "sap-samples/tier2-rfc-proxy"
3 | SPDX-PackageSupplier = "andre.fischer@sap.com"
4 | SPDX-PackageDownloadLocation = "https://github.com/sap-samples/tier2-rfc-proxy"
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 = " SAP SE or an SAP affiliate company and contributors"
11 | SPDX-License-Identifier = "Apache-2.0"
12 |
13 | [[annotations]]
14 | path = ""
15 | precedence = "aggregate"
16 | SPDX-FileCopyrightText = ""
17 | SPDX-License-Identifier = ""
18 |
19 | [[annotations]]
20 | path = ""
21 | precedence = "aggregate"
22 | SPDX-FileCopyrightText = ""
23 | SPDX-License-Identifier = ""
24 |
--------------------------------------------------------------------------------
/images/010_select_function_modules.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/tier2-rfc-proxy/a7157e822a66090414a09d15f4c6c492394ceadf/images/010_select_function_modules.png
--------------------------------------------------------------------------------
/images/020_specify_options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/tier2-rfc-proxy/a7157e822a66090414a09d15f4c6c492394ceadf/images/020_specify_options.png
--------------------------------------------------------------------------------
/images/030_result_report.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/tier2-rfc-proxy/a7157e822a66090414a09d15f4c6c492394ceadf/images/030_result_report.png
--------------------------------------------------------------------------------
/images/040_generated_objects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-samples/tier2-rfc-proxy/a7157e822a66090414a09d15f4c6c492394ceadf/images/040_generated_objects.png
--------------------------------------------------------------------------------
/images/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | TEST_AF_TIER2_RFC_PROXY
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/zcl_gen_rfc_tier2_proxy.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_gen_rfc_tier2_proxy DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 |
8 | DATA function_modules TYPE cl_aco_metadata_provider=>t_functions READ-ONLY.
9 | DATA function_module TYPE cl_aco_metadata_provider=>t_function READ-ONLY.
10 |
11 | DATA wrapper_class_name TYPE sxco_class_name READ-ONLY.
12 | DATA wrapper_interface_name TYPE sxco_class_name READ-ONLY.
13 | DATA wrapper_factory_class_name TYPE sxco_class_name READ-ONLY.
14 |
15 | DATA package_name TYPE sxco_package READ-ONLY.
16 |
17 | DATA namespace TYPE string READ-ONLY.
18 |
19 | DATA transport_request TYPE sxco_transport READ-ONLY.
20 |
21 | DATA wrapper_interface_code TYPE rswsourcet READ-ONLY.
22 | DATA wrapper_class_code TYPE rswsourcet READ-ONLY.
23 | DATA wrapper_factory_class_code TYPE rswsourcet READ-ONLY.
24 |
25 | DATA methods_code_definition TYPE rswsourcet READ-ONLY .
26 | DATA methods_code_implementation TYPE rswsourcet READ-ONLY.
27 |
28 | INTERFACES if_oo_adt_classrun .
29 |
30 |
31 | METHODS constructor
32 | IMPORTING
33 | i_package_name TYPE sxco_package
34 | i_transport_request TYPE sxco_transport OPTIONAL
35 | i_generate_intf_and_fact_class TYPE abap_bool DEFAULT abap_true
36 | i_wrapper_class_name TYPE sxco_class_name
37 | i_wrapper_interface_name TYPE sxco_class_name OPTIONAL
38 | i_wrapper_factory_class_name TYPE sxco_class_name OPTIONAL
39 | i_function_modules TYPE cl_aco_metadata_provider=>t_functions
40 | i_overwrite_objects TYPE abap_bool DEFAULT abap_true
41 | RAISING cx_abap_invalid_value.
42 |
43 |
44 | METHODS read_aco_proxy_cls_src_code
45 | * IMPORTING remove_class_method_statements TYPE abap_bool DEFAULT abap_true
46 | RETURNING VALUE(aco_proxy_class_src_code) TYPE rswsourcet.
47 |
48 | METHODS get_wrapper_class_code
49 | IMPORTING I_aco_proxy_class_src_code TYPE rswsourcet
50 | RETURNING VALUE(r_wrapper_class_code) TYPE rswsourcet..
51 |
52 | METHODS get_wrapper_interface_code
53 | IMPORTING I_aco_proxy_class_src_code TYPE rswsourcet
54 | RETURNING VALUE(r_wrapper_interface_code) TYPE rswsourcet.
55 |
56 | METHODS get_private_methods_code
57 | IMPORTING I_aco_proxy_class_src_code TYPE rswsourcet
58 | EXPORTING
59 | r_methods_definition_code TYPE rswsourcet
60 | r_methods_implementation_code TYPE rswsourcet.
61 |
62 | METHODS get_wrapper_factory_class_code
63 | RETURNING VALUE(r_wrapper__factory_class_code) TYPE rswsourcet..
64 |
65 | METHODS generate_wrapper_objects
66 | IMPORTING i_demo_mode TYPE abap_bool DEFAULT abap_false
67 | RETURNING VALUE(r_exception_text) TYPE string.
68 |
69 | METHODS generate_wrapper_interface.
70 |
71 | METHODS generate_factory_class.
72 |
73 | METHODS update_wrapper_objects_code
74 | IMPORTING
75 | i_object_type TYPE trobjtype
76 | i_object_name TYPE trobj_name
77 | i_source_code TYPE rswsourcet.
78 |
79 |
80 | METHODS generate_aco_proxy_class
81 | IMPORTING
82 | i_function_modules TYPE cl_aco_metadata_provider=>t_functions
83 | I_proxy_class_name TYPE sxco_class_name
84 | i_package_name TYPE sxco_package
85 | i_transport_request TYPE sxco_transport
86 | RETURNING VALUE(success) TYPE abap_bool
87 | RAISING cx_aco_exception.
88 |
89 |
90 | METHODS get_namespace
91 | IMPORTING i_package_name TYPE string
92 | RETURNING VALUE(r_namespace) TYPE string.
93 |
94 |
95 | METHODS get_unique_object_name
96 | IMPORTING i_short_object_name TYPE sxco_class_name
97 | * i_namespace TYPE string
98 | i_object_type TYPE trobjtype
99 | RETURNING VALUE(r_object_name) TYPE sxco_class_name.
100 |
101 |
102 | METHODS release_class_and_interface
103 | RAISING cx_abap_api_state.
104 |
105 | METHODS create_transport RETURNING VALUE(r_transport) TYPE sxco_transport.
106 |
107 | PROTECTED SECTION.
108 | PRIVATE SECTION.
109 |
110 | DATA generate_intf_and_fact_class TYPE abap_bool.
111 | DATA overwrite_objects TYPE abap_bool.
112 |
113 |
114 | ENDCLASS.
115 |
116 |
117 |
118 | CLASS zcl_gen_rfc_tier2_proxy IMPLEMENTATION.
119 |
120 | METHOD constructor.
121 |
122 | IF NOT xco_abap_repository=>object->devc->for( i_package_name )->exists( ).
123 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | package { i_package_name } does not exist |.
124 | ENDIF.
125 |
126 | package_name = i_package_name .
127 | namespace = get_namespace( CONV #( package_name ) ).
128 |
129 | IF i_transport_request IS INITIAL.
130 | "create transport checks if the selected package records changes
131 | transport_request = create_transport( ) .
132 | ELSE.
133 | transport_request = i_transport_request .
134 | ENDIF.
135 |
136 | generate_intf_and_fact_class = i_generate_intf_and_fact_class.
137 |
138 | overwrite_objects = i_overwrite_objects.
139 |
140 | IF i_overwrite_objects = abap_false.
141 | IF i_generate_intf_and_fact_class = abap_true.
142 | IF xco_abap_repository=>object->clas->for( i_wrapper_class_name )->exists( ).
143 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Class { i_wrapper_class_name } does already exist |.
144 | ELSEIF xco_abap_repository=>object->intf->for( i_wrapper_interface_name )->exists( ).
145 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Interface { i_wrapper_interface_name } does already exist |.
146 | ELSEIF xco_abap_repository=>object->clas->for( i_wrapper_factory_class_name )->exists( ).
147 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Class { i_wrapper_factory_class_name } does already exist |.
148 | ENDIF.
149 | ELSE.
150 | IF xco_abap_repository=>object->clas->for( i_wrapper_class_name )->exists( ).
151 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Class { i_wrapper_class_name } does already exist |.
152 | ENDIF.
153 | ENDIF.
154 | ENDIF.
155 |
156 | wrapper_class_name = i_wrapper_class_name .
157 | wrapper_interface_name = i_wrapper_interface_name .
158 | wrapper_factory_class_name = i_wrapper_factory_class_name .
159 |
160 | LOOP AT i_function_modules INTO DATA(function_module).
161 |
162 | SELECT SINGLE * FROM tfdir INTO @DATA(function_module_info) WHERE funcname = @function_module-functionname.
163 |
164 | IF function_module_info IS INITIAL.
165 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Function module { function_module-functionname } does not exist.|.
166 | ENDIF.
167 |
168 | IF function_module_info-fmode IS NOT INITIAL.
169 | APPEND function_module TO function_modules.
170 | ELSE.
171 | RAISE EXCEPTION TYPE cx_abap_invalid_value EXPORTING value = | Function module { function_module-functionname } is not remote enabled.|.
172 | ENDIF.
173 |
174 | ENDLOOP.
175 |
176 | ENDMETHOD.
177 |
178 | METHOD generate_wrapper_objects.
179 | TRY.
180 | generate_aco_proxy_class(
181 | i_function_modules = function_modules
182 | i_proxy_class_name = wrapper_class_name
183 | i_package_name = package_name
184 | i_transport_request = transport_request
185 | ).
186 | CATCH cx_aco_exception INTO DATA(aco_exception).
187 | r_exception_text = |ACO error: { aco_exception->get_text( ) }|.
188 | RETURN.
189 | ENDTRY.
190 |
191 | read_aco_proxy_cls_src_code(
192 | * EXPORTING
193 | * remove_class_method_statements = abap_true
194 | RECEIVING
195 | aco_proxy_class_src_code = DATA(aco_proxy_class_code)
196 | ).
197 |
198 | IF aco_proxy_class_code IS INITIAL.
199 | r_exception_text = |No source code found: { wrapper_class_name }|.
200 | RETURN.
201 | ENDIF.
202 |
203 |
204 | IF generate_intf_and_fact_class = abap_true.
205 |
206 | get_wrapper_interface_code(
207 | EXPORTING
208 | i_aco_proxy_class_src_code = aco_proxy_class_code
209 | RECEIVING
210 | r_wrapper_interface_code = wrapper_interface_code
211 | ).
212 |
213 | get_private_methods_code(
214 | EXPORTING
215 | i_aco_proxy_class_src_code = aco_proxy_class_code
216 | IMPORTING
217 | r_methods_definition_code = methods_code_definition
218 | r_methods_implementation_code = methods_code_implementation
219 | ).
220 |
221 | get_wrapper_factory_class_code(
222 | RECEIVING
223 | r_wrapper__factory_class_code = wrapper_factory_class_code
224 | ).
225 |
226 | ENDIF.
227 |
228 | get_wrapper_class_code(
229 | EXPORTING
230 | i_aco_proxy_class_src_code = aco_proxy_class_code
231 | RECEIVING
232 | r_wrapper_class_code = wrapper_class_code
233 | ).
234 |
235 | IF i_demo_mode = abap_false.
236 |
237 | TRY.
238 |
239 | IF generate_intf_and_fact_class = abap_true.
240 |
241 | IF xco_abap_repository=>object->intf->for( wrapper_interface_name )->exists( ) = abap_False.
242 | generate_wrapper_interface( ).
243 | ELSE.
244 | ASSERT overwrite_objects = abap_true.
245 | ENDIF.
246 |
247 | IF xco_abap_repository=>object->clas->for( wrapper_factory_class_name )->exists( ) = abap_False.
248 | generate_factory_class( ).
249 | ELSE.
250 | ASSERT overwrite_objects = abap_true.
251 | ENDIF.
252 |
253 | update_wrapper_objects_code(
254 | i_object_type = 'INTF'
255 | i_object_name = CONV #( wrapper_interface_name )
256 | i_source_code = wrapper_interface_code
257 | ).
258 |
259 | ENDIF.
260 |
261 | update_wrapper_objects_code(
262 | i_object_type = 'CLAS'
263 | i_object_name = CONV #( wrapper_class_name )
264 | i_source_code = wrapper_class_code
265 | ).
266 |
267 | IF generate_intf_and_fact_class = abap_true.
268 |
269 | update_wrapper_objects_code(
270 | i_object_type = 'CLAS'
271 | i_object_name = CONV #( wrapper_factory_class_name )
272 | i_source_code = wrapper_factory_class_code
273 | ).
274 |
275 | ENDIF.
276 |
277 | CATCH cx_oo_class_scan_error INTO DATA(update_wrapper_code_exc).
278 | r_exception_text = |cl_oo_factory error: { update_wrapper_code_exc->get_text( ) }|.
279 | RETURN.
280 | ENDTRY.
281 |
282 | TRY.
283 | release_class_and_interface( ).
284 | CATCH cx_abap_api_state INTO DATA(api_state_exception).
285 | r_exception_text = |api_state error: { api_state_exception->get_text( ) }|.
286 | RETURN.
287 | ENDTRY.
288 |
289 | ENDIF.
290 |
291 | ENDMETHOD.
292 |
293 | METHOD if_oo_adt_classrun~main.
294 |
295 | package_name = 'TEST_AF_GENERATED_OBJECTS_001'.
296 | transport_request = ''.
297 |
298 | DATA number TYPE i VALUE 106.
299 |
300 | DATA(project_name) = 'af_wrapper_t'.
301 |
302 | function_module-functionname = to_upper( 'bapi_epm_product_get_detail' ).
303 | APPEND function_module TO function_modules.
304 | function_module-functionname = to_upper( 'bapi_epm_product_get_list' ).
305 | APPEND function_module TO function_modules.
306 |
307 | wrapper_class_name = to_upper( namespace && 'cl_wrap_' && project_name ).
308 | wrapper_interface_name = to_upper( namespace && 'if_wrap_' && project_name ).
309 | wrapper_factory_class_name = to_upper( namespace && 'cl_fact_' && project_name ) .
310 |
311 |
312 | wrapper_class_name = get_unique_object_name(
313 | i_short_object_name = wrapper_class_name
314 | i_object_type = 'CLAS'
315 | ).
316 |
317 | wrapper_interface_name = get_unique_object_name(
318 | i_short_object_name = wrapper_interface_name
319 | i_object_type = 'INTF'
320 | ) .
321 | wrapper_factory_class_name = get_unique_object_name(
322 | i_short_object_name = wrapper_factory_class_name
323 | i_object_type = 'CLAS'
324 | ).
325 |
326 | out->write( wrapper_class_name ).
327 | out->write( wrapper_interface_name ).
328 | out->write( wrapper_factory_class_name ).
329 |
330 | out->write( 'finished' ).
331 |
332 | ENDMETHOD.
333 |
334 | METHOD generate_aco_proxy_class.
335 |
336 | cl_aco_static_proxy=>create_static_proxy_by_rfc(
337 | EXPORTING
338 | function_names = i_function_modules
339 | proxy_name = i_proxy_class_name
340 | destination_name = 'NONE'
341 | devclass = i_package_name
342 | trkorr = i_transport_request
343 | classic_exceptions = abap_false
344 | bapi_exceptions = abap_false
345 | generate_inactive = abap_false
346 | destination_by_constructor = abap_false
347 | do_not_create_released_type = abap_true
348 | ).
349 | success = abap_true.
350 |
351 | ENDMETHOD.
352 |
353 | METHOD read_aco_proxy_cls_src_code.
354 |
355 | FIELD-SYMBOLS TYPE string.
356 |
357 | SELECT SINGLE * FROM i_abapobjectdirectoryentry INTO @DATA(obj_entry)
358 | WHERE abapobject = @wrapper_class_name
359 | .
360 |
361 | DATA(package) = obj_entry-abappackage.
362 |
363 | IF package IS INITIAL.
364 | EXIT.
365 | ENDIF.
366 |
367 | "read source code of generated proxy class
368 | DATA(ref_proxy_class_name) = cl_oo_factory=>create_instance( )->create_clif_source( to_upper( wrapper_class_name ) ).
369 | ref_proxy_class_name->get_source( IMPORTING source = aco_proxy_class_src_code ).
370 |
371 | ENDMETHOD.
372 |
373 | METHOD get_wrapper_factory_class_code.
374 |
375 |
376 | APPEND |CLASS { wrapper_factory_class_name } DEFINITION | TO r_wrapper__factory_class_code.
377 | APPEND |PUBLIC | TO r_wrapper__factory_class_code.
378 | APPEND |FINAL | TO r_wrapper__factory_class_code.
379 | APPEND |CREATE PRIVATE . | TO r_wrapper__factory_class_code.
380 |
381 | APPEND | PUBLIC SECTION. | TO r_wrapper__factory_class_code.
382 |
383 |
384 | APPEND | CLASS-METHODS create_instance | TO r_wrapper__factory_class_code.
385 | APPEND | RETURNING VALUE(result) TYPE REF TO { wrapper_interface_name }. | TO r_wrapper__factory_class_code.
386 | APPEND | PROTECTED SECTION. | TO r_wrapper__factory_class_code.
387 | APPEND | PRIVATE SECTION. | TO r_wrapper__factory_class_code.
388 | APPEND | METHODS constructor. | TO r_wrapper__factory_class_code.
389 | APPEND |ENDCLASS. | TO r_wrapper__factory_class_code.
390 |
391 | APPEND | CLASS { wrapper_factory_class_name } IMPLEMENTATION. | TO r_wrapper__factory_class_code.
392 |
393 | APPEND | METHOD create_instance. | TO r_wrapper__factory_class_code.
394 |
395 | APPEND | result = NEW { wrapper_class_name }( ). | TO r_wrapper__factory_class_code.
396 | APPEND | ENDMETHOD.| TO r_wrapper__factory_class_code.
397 |
398 | APPEND | METHOD constructor. | TO r_wrapper__factory_class_code.
399 | APPEND | ENDMETHOD. | TO r_wrapper__factory_class_code.
400 |
401 | APPEND | ENDCLASS. | TO r_wrapper__factory_class_code.
402 |
403 |
404 | ENDMETHOD.
405 |
406 | METHOD get_wrapper_interface_code.
407 |
408 | DATA add_code TYPE abap_bool.
409 | DATA source_code_line LIKE LINE OF i_aco_proxy_class_src_code.
410 |
411 | APPEND |INTERFACE { wrapper_interface_name }| TO r_wrapper_interface_code.
412 | APPEND | PUBLIC . | TO r_wrapper_interface_code.
413 |
414 | LOOP AT i_aco_proxy_class_src_code INTO source_code_line.
415 |
416 | DATA(result_last_statement) = find( val = source_code_line sub = |PROTECTED SECTION.| case = abap_false ).
417 | DATA(result_first_statement) = find( val = source_code_line sub = |INTERFACES if_aco_proxy| case = abap_false ).
418 | DATA(result_class_methods) = find( val = source_code_line sub = |CLASS-METHODS| case = abap_false ).
419 | DATA(result_if_aco_proxy) = find( val = source_code_line sub = |if_aco_proxy| case = abap_false ).
420 |
421 | IF result_class_methods <> -1.
422 | source_code_line = replace( val = source_code_line
423 | sub = |CLASS-METHODS|
424 | with = |METHODS| ).
425 | ENDIF.
426 |
427 |
428 | IF result_first_statement <> -1.
429 | add_code = abap_true.
430 | ENDIF.
431 |
432 | IF result_last_statement <> -1.
433 | APPEND |ENDINTERFACE.| TO r_wrapper_interface_code.
434 | EXIT.
435 | ENDIF.
436 |
437 | "skip if_aco_proxy statement
438 | IF add_code = abap_true AND result_if_aco_proxy = -1.
439 | APPEND source_code_line TO r_wrapper_interface_code.
440 | ENDIF.
441 |
442 | ENDLOOP.
443 | ENDMETHOD.
444 |
445 | METHOD get_wrapper_class_code.
446 |
447 | DATA add_code TYPE abap_bool.
448 | DATA source_code_line LIKE LINE OF i_aco_proxy_class_src_code.
449 |
450 | IF generate_intf_and_fact_class = abap_false.
451 |
452 | LOOP AT i_aco_proxy_class_src_code INTO source_code_line.
453 |
454 | " add a final statement before the CREATE PUBLIC statement.
455 | DATA(result_create_public_statement) = find( val = source_code_line sub = |CREATE PUBLIC| case = abap_false ).
456 | DATA(result_if_aco_proxy) = find( val = source_code_line sub = |if_aco_proxy| case = abap_false ).
457 |
458 | IF result_create_public_statement <> -1.
459 | APPEND 'FINAL' TO r_wrapper_class_code.
460 | source_code_line = replace( val = source_code_line
461 | sub = |CREATE PUBLIC|
462 | with = |CREATE PRIVATE| ).
463 | ENDIF.
464 |
465 | "remove DESTINATION _dest_ statements
466 | DATA(result_destination_statement) = find( val = source_code_line sub = |DESTINATION _dest_| case = abap_false ).
467 | * source_code_line = to_upper( source_code_line ).
468 | IF result_destination_statement <> -1.
469 | source_code_line = replace( val = source_code_line
470 | sub = |DESTINATION _dest_|
471 | with = |DESTINATION space| ).
472 | ENDIF.
473 | IF result_if_aco_proxy = -1.
474 | APPEND source_code_line TO r_wrapper_class_code.
475 | ENDIF.
476 | ENDLOOP.
477 |
478 | RETURN.
479 |
480 | ENDIF.
481 |
482 | CLEAR r_wrapper_class_code.
483 |
484 | APPEND |CLASS { wrapper_class_name } DEFINITION| TO r_wrapper_class_code.
485 | APPEND |PUBLIC | TO r_wrapper_class_code.
486 | APPEND |FINAL | TO r_wrapper_class_code.
487 | APPEND |CREATE PUBLIC . | TO r_wrapper_class_code.
488 | APPEND |PUBLIC SECTION. | TO r_wrapper_class_code.
489 | APPEND |INTERFACES { wrapper_interface_name }.| TO r_wrapper_class_code.
490 | APPEND |PROTECTED SECTION. | TO r_wrapper_class_code.
491 | APPEND |PRIVATE SECTION. | TO r_wrapper_class_code.
492 |
493 | "add private methods code
494 |
495 | LOOP AT methods_code_definition INTO DATA(method_code_line).
496 | APPEND method_code_line TO r_wrapper_class_code.
497 | ENDLOOP.
498 | APPEND |.| TO r_wrapper_class_code.
499 | APPEND |ENDCLASS.| TO r_wrapper_class_code.
500 | APPEND | | TO r_wrapper_class_code.
501 |
502 | LOOP AT i_aco_proxy_class_src_code INTO source_code_line.
503 |
504 | DATA(result_method_statement) = find( val = source_code_line sub = |METHOD| case = abap_false ).
505 | DATA(result_first_statement) = find( val = source_code_line sub = |CLASS { wrapper_class_name } IMPLEMENTATION.| case = abap_false ).
506 |
507 | "remove DESTINATION _dest_
508 | result_destination_statement = find( val = source_code_line sub = |DESTINATION _dest_| case = abap_false ).
509 |
510 | IF result_first_statement <> -1.
511 | add_code = abap_true.
512 | ENDIF.
513 |
514 | "add interface name to method name
515 | * IF result_method_statement <> -1 .
516 | * source_code_line = to_upper( source_code_line ).
517 | * source_code_line = replace( val = source_code_line
518 | * sub = |METHOD |
519 | * with = |METHOD { wrapper_interface_name }~| ).
520 | * ENDIF.
521 |
522 | IF result_destination_statement <> -1.
523 | source_code_line = replace( val = source_code_line
524 | sub = |DESTINATION _dest_|
525 | with = |DESTINATION space| ).
526 | ENDIF.
527 |
528 | IF add_code = abap_true.
529 | APPEND source_code_line TO r_wrapper_class_code.
530 | IF result_first_statement <> -1.
531 | LOOP AT methods_code_implementation INTO DATA(methods_code_impl_line).
532 | APPEND methods_code_impl_line TO r_wrapper_class_code.
533 | ENDLOOP.
534 | ENDIF.
535 | ENDIF.
536 | ENDLOOP.
537 |
538 |
539 | ENDMETHOD.
540 |
541 | METHOD update_wrapper_objects_code.
542 |
543 | DATA(ref) = cl_oo_factory=>create_instance( )->create_clif_source( to_upper( i_object_name ) ).
544 |
545 | TRY.
546 | ref->lock( ).
547 | ref->set_source( source = i_source_code ).
548 | ref->save( ).
549 | ref->unlock( ).
550 | CATCH cx_oo_access_permission cx_oo_class_scan_error INTO DATA(access_permission_exc).
551 | * WRITE : / |error occured: { access_permission_exc->get_text( ) }|.
552 | * EXIT.
553 | ENDTRY.
554 |
555 | * DATA objects TYPE STANDARD TABLE OF dwinactiv .
556 | *
557 | * objects = VALUE #( ( object = i_object_type obj_name = i_object_name uname = sy-uname ) ).
558 | *
559 | * CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
560 | * TABLES
561 | * objects = objects
562 | * EXCEPTIONS
563 | * excecution_error = 1
564 | * cancelled = 2
565 | * insert_into_corr_error = 3
566 | * OTHERS = 4.
567 |
568 | IF sy-subrc <> 0.
569 | * WRITE : / |error occured when activating class { cls_name }. SY-SUBRC = { sy-subrc } |.
570 | * EXIT.
571 | ENDIF.
572 | ENDMETHOD.
573 |
574 |
575 |
576 | METHOD generate_wrapper_interface.
577 |
578 | DATA lo_put_operation TYPE REF TO if_xco_gen_intf_o_put .
579 |
580 | IF transport_request IS INITIAL.
581 | lo_put_operation = xco_generation=>environment->local->for-intf->create_put_operation( ).
582 | ELSE.
583 | lo_put_operation = xco_generation=>environment->transported( transport_request )->for-intf->create_put_operation( ).
584 | ENDIF.
585 |
586 | DATA(lo_form_specification) = lo_put_operation->add_object( wrapper_interface_name
587 | )->set_package( package_name
588 | )->create_form_specification( ).
589 |
590 | lo_form_specification->set_short_description( 'Sample interface' ) ##NO_TEXT.
591 |
592 |
593 | lo_put_operation->execute( ).
594 |
595 | ENDMETHOD.
596 |
597 | METHOD generate_factory_class.
598 |
599 | DATA lo_put_operation TYPE REF TO if_xco_gen_clas_o_put .
600 |
601 | IF transport_request IS INITIAL.
602 | lo_put_operation = xco_generation=>environment->local->for-clas->create_put_operation( ).
603 | ELSE.
604 | lo_put_operation = xco_generation=>environment->transported( transport_request )->for-clas->create_put_operation( ).
605 | ENDIF.
606 |
607 | DATA(lo_form_specification) = lo_put_operation->add_object( wrapper_factory_class_name
608 | )->set_package( package_name
609 | )->create_form_specification( ).
610 |
611 | lo_form_specification->set_short_description( 'Factory class' ) ##NO_TEXT.
612 |
613 |
614 | lo_put_operation->execute( ).
615 | ENDMETHOD.
616 |
617 | METHOD get_namespace.
618 |
619 | IF i_package_name = '$TMP'.
620 | r_namespace = 'Z'.
621 | EXIT.
622 | ENDIF.
623 |
624 | FIND ALL OCCURRENCES OF '/'
625 | IN i_package_name
626 | IGNORING CASE " case insensitive
627 | RESULTS DATA(result). " TYPE match_result_tab
628 |
629 | IF lines( result ) = 2.
630 | CHECK result[ 1 ]-offset = 0.
631 | r_namespace = substring( val = i_package_name len = result[ 2 ]-offset + 1 ).
632 | EXIT.
633 | ENDIF.
634 |
635 | DATA(first_character_package) = substring( val = i_package_name off = 0 len = 1 ).
636 | DATA(package_name_length) = strlen( i_package_name ).
637 |
638 | IF first_character_package = 'Y'.
639 | r_namespace = 'Y'.
640 | EXIT.
641 | ENDIF.
642 |
643 | IF first_character_package = 'Z'.
644 | r_namespace = 'Z'.
645 | EXIT.
646 | ENDIF.
647 |
648 | IF package_name_length > strlen( 'TEST_' ).
649 | IF substring( val = i_package_name len = strlen( 'TEST_' ) ) = 'TEST_' .
650 | r_namespace = 'Z'.
651 | EXIT.
652 | ENDIF.
653 | ENDIF.
654 |
655 | r_namespace = ''.
656 |
657 |
658 | ENDMETHOD.
659 |
660 | METHOD get_unique_object_name.
661 |
662 | DATA is_valid_repo_object_name TYPE abap_bool VALUE abap_false.
663 | DATA unique_number TYPE i VALUE 0.
664 | DATA unique_hex_number TYPE xstring .
665 | DATA unique_hex_number_string TYPE c LENGTH 2.
666 |
667 | "Generate a short class name that provides us the option to add two characters to suggest a unique name
668 | * DATA short_class_name TYPE c LENGTH 28.
669 |
670 | * short_class_name = i_namespace && 'CL_WRAP_' && i_fugr_name.
671 |
672 | WHILE is_valid_repo_object_name = abap_false AND unique_number < 255 .
673 |
674 | unique_hex_number = CONV xstring( unique_number ).
675 |
676 | IF unique_hex_number = 00.
677 | unique_hex_number_string = ''.
678 | ELSE.
679 | unique_hex_number_string = unique_hex_number.
680 | ENDIF.
681 |
682 | r_object_name = i_short_object_name && unique_hex_number_string.
683 |
684 | IF i_object_type = 'CLAS'.
685 | IF NOT xco_abap_repository=>object->clas->for( r_object_name )->exists( ).
686 | is_valid_repo_object_name = abap_true.
687 | ELSE.
688 | unique_number += 1.
689 | ENDIF.
690 | ELSEIF i_object_type = 'INTF'.
691 | IF NOT xco_abap_repository=>object->intf->for( r_object_name )->exists( ).
692 | is_valid_repo_object_name = abap_true.
693 | ELSE.
694 | unique_number += 1.
695 | ENDIF.
696 | ELSE.
697 | ASSERT 1 = 0.
698 | ENDIF.
699 |
700 | ENDWHILE.
701 |
702 | ENDMETHOD.
703 |
704 |
705 |
706 |
707 | METHOD release_class_and_interface.
708 |
709 | IF generate_intf_and_fact_class = abap_true.
710 |
711 | DATA(api_state_wrapper_fact_class) = cl_abap_api_state=>create_instance(
712 | api_key = VALUE #(
713 | object_type = 'CLAS'
714 | object_name = to_upper( wrapper_factory_class_name )
715 | ) ).
716 |
717 | api_state_wrapper_fact_class->release(
718 | EXPORTING
719 | release_contract = 'C1'
720 | use_in_cloud_development = abap_true
721 | use_in_key_user_apps = abap_false
722 | request = transport_request
723 | ).
724 |
725 |
726 | DATA(api_state_wrapper_interface) = cl_abap_api_state=>create_instance(
727 | api_key = VALUE #(
728 | object_type = 'INTF'
729 | object_name = to_upper( wrapper_interface_name )
730 | ) ).
731 |
732 | api_state_wrapper_interface->release(
733 | EXPORTING
734 | release_contract = 'C1'
735 | use_in_cloud_development = abap_true
736 | use_in_key_user_apps = abap_false
737 | request = transport_request
738 | ).
739 |
740 | ELSE.
741 | DATA(api_state_wrapper_class) = cl_abap_api_state=>create_instance(
742 | api_key = VALUE #(
743 | object_type = 'CLAS'
744 | object_name = to_upper( wrapper_class_name )
745 | ) ).
746 |
747 | api_state_wrapper_class->release(
748 | EXPORTING
749 | release_contract = 'C1'
750 | use_in_cloud_development = abap_true
751 | use_in_key_user_apps = abap_false
752 | request = transport_request
753 | ).
754 | ENDIF.
755 |
756 | ENDMETHOD.
757 |
758 | METHOD create_transport.
759 | DATA(xco_package) = xco_abap_repository=>object->devc->for( package_name ).
760 | DATA(record_object_changes) = xco_package->read( )-property-record_object_changes.
761 | IF record_object_changes = abap_true.
762 | DATA(lo_transport_target) = xco_package->read( )-property-transport_layer->get_transport_target( ).
763 | DATA(new_transport_object) = xco_cp_cts=>transports->workbench( lo_transport_target->value )->create_request( |Wrapper class: { wrapper_class_name } | ).
764 | r_transport = new_transport_object->value.
765 | ELSE.
766 | r_transport = ''.
767 | ENDIF.
768 | ENDMETHOD.
769 |
770 | METHOD get_private_methods_code.
771 | DATA add_code TYPE abap_bool.
772 | DATA result_in_interface TYPE abap_bool.
773 |
774 | DATA source_code_line LIKE LINE OF i_aco_proxy_class_src_code.
775 |
776 | * APPEND |INTERFACE { wrapper_interface_name }| TO r_methods_definition_code.
777 | * APPEND | PUBLIC . | TO r_wrapper_interface_code.
778 |
779 | LOOP AT i_aco_proxy_class_src_code INTO source_code_line.
780 |
781 | DATA(result_last_statement) = find( val = source_code_line sub = |.| case = abap_false ).
782 | DATA(result_first_statement) = find( val = source_code_line sub = |CLASS-METHODS| case = abap_false ).
783 | DATA(result_type_statement) = find( val = source_code_line sub = |TYPE | case = abap_false ).
784 | DATA(result_endclass_statement) = find( val = source_code_line sub = |ENDCLASS.| case = abap_false ).
785 |
786 | DATA(result_class_methods) = find( val = source_code_line sub = |CLASS-METHODS| case = abap_false ).
787 |
788 | DATA(result_destination_statement) = find( val = source_code_line sub = |_dest_| case = abap_false ).
789 |
790 | DATA(result_none_statement) = find( val = source_code_line sub = |'NONE'| case = abap_false ).
791 |
792 | " !prheader TYPE ZIF_WRAP_TEST_4714~bapimereqheader OPTIONAL
793 |
794 | DATA(result_exclamation_mark) = find( val = source_code_line sub = |!| case = abap_false ).
795 |
796 |
797 | IF result_class_methods <> -1.
798 | source_code_line = replace( val = source_code_line
799 | sub = |CLASS-METHODS|
800 | with = |METHODS| ).
801 | DATA(source_code_line_impl) = replace( val = source_code_line
802 | sub = |METHODS |
803 | with = |METHOD { wrapper_interface_name }~| ).
804 | DATA(method_name) = replace( val = source_code_line
805 | sub = |METHODS |
806 | with = || ).
807 | CONDENSE method_name NO-GAPS.
808 | source_code_line_impl = source_code_line_impl && '.'.
809 | * APPEND |.| TO r_methods_implementation_code.
810 | APPEND source_code_line_impl TO r_methods_implementation_code.
811 | APPEND | "add call to private method { method_name }| TO r_methods_implementation_code.
812 | APPEND | "e.g. me->{ method_name }( ... ) | TO r_methods_implementation_code.
813 | APPEND |RAISE EXCEPTION TYPE cx_method_not_implemented.| TO r_methods_implementation_code.
814 | APPEND |ENDMETHOD.| TO r_methods_implementation_code.
815 | ENDIF.
816 |
817 | IF result_endclass_statement <> -1.
818 | EXIT.
819 | ENDIF.
820 | DATA string1 TYPE string.
821 | DATA string2 TYPE string.
822 | DATA pos TYPE i.
823 | CLEAR pos.
824 | IF result_exclamation_mark <> -1.
825 |
826 | SPLIT source_code_line AT '!' INTO string1 string2.
827 | SPLIT string2 AT space INTO TABLE DATA(source_code_line_tab).
828 |
829 | LOOP AT source_code_line_tab INTO DATA(single_statement).
830 | pos += 1.
831 | IF single_statement = 'TYPE'.
832 | DATA(pos_type) = pos.
833 | ENDIF.
834 | ENDLOOP.
835 |
836 | DATA(type_of) = source_code_line_tab[ pos_type + 1 ].
837 |
838 | "REPLACE '!' IN type_of WITH ''.
839 |
840 | LOOP AT wrapper_interface_code INTO DATA(interface_code_line).
841 | CLEAR result_in_interface.
842 | DATA(result_is_in_interface) = find( val = interface_code_line sub = type_of case = abap_false ).
843 | DATA(first_methods_statement) = find( val = interface_code_line sub = 'METHODS' case = abap_false ).
844 | "only search in types statements
845 | IF first_methods_statement <> -1.
846 | EXIT.
847 | ENDIF.
848 | IF result_is_in_interface <> -1.
849 | result_in_interface = abap_true.
850 | EXIT.
851 | ENDIF.
852 | ENDLOOP.
853 | ENDIF.
854 |
855 | IF result_first_statement <> -1.
856 | add_code = abap_true.
857 | ENDIF.
858 |
859 | IF add_code = abap_true AND result_last_statement <> -1.
860 | add_code = abap_false.
861 | ENDIF.
862 |
863 | IF result_type_statement <> -1 AND
864 | result_in_interface = abap_true AND
865 | result_destination_statement = -1
866 | .
867 |
868 | "certain function modules such as SATC_CI_GET_RESULT use
869 | "built in types such as 'I'
870 | "searching for 'I' by name is not reliable
871 |
872 | CASE to_upper( type_of ).
873 | "built in numeric types
874 | WHEN 'I' OR 'B' OR 'S' OR 'INT8' OR 'P' OR 'F'.
875 | "built in character type
876 | WHEN 'C' OR 'N' OR 'STRING'.
877 | "built in date type
878 | WHEN 'D' OR 'T'.
879 | "not a built in type
880 | WHEN OTHERS.
881 | source_code_line = replace( val = source_code_line
882 | sub = |TYPE |
883 | with = |TYPE { wrapper_interface_name }~| ).
884 | ENDCASE.
885 | ENDIF.
886 |
887 | IF result_destination_statement <> -1.
888 | source_code_line = replace( val = source_code_line
889 | sub = |DESTINATION _dest_|
890 | with = |DESTINATION space| ).
891 | ENDIF.
892 |
893 | IF result_none_statement <> -1.
894 | source_code_line = replace( val = source_code_line
895 | sub = |DESTINATION 'NONE'|
896 | with = |DESTINATION space| ).
897 | ENDIF.
898 |
899 | IF add_code = abap_true.
900 |
901 | IF result_class_methods <> -1.
902 | APPEND '.' TO r_methods_definition_code.
903 | ENDIF.
904 | APPEND source_code_line TO r_methods_definition_code.
905 | ENDIF.
906 |
907 |
908 |
909 | ENDLOOP.
910 | APPEND '.' TO r_methods_definition_code.
911 | ENDMETHOD.
912 |
913 | ENDCLASS.
914 |
--------------------------------------------------------------------------------
/src/zcl_gen_rfc_tier2_proxy.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_GEN_RFC_TIER2_PROXY
7 | E
8 | zcl_gen_rfc_tier2_proxy
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/zr_gen_rfc_tier2_proxy.prog.abap:
--------------------------------------------------------------------------------
1 | REPORT zr_gen_rfc_tier2_proxy.
2 |
3 | TYPES: BEGIN OF ty_fugr,
4 | area TYPE tlibg-area,
5 | END OF ty_fugr.
6 | TABLES sscrfields.
7 | DATA function_type TYPE tftit.
8 | DATA function_modules TYPE cl_aco_metadata_provider=>t_functions .
9 |
10 | DATA source_code_line TYPE string.
11 |
12 | SELECT-OPTIONS s_func FOR function_type-funcname NO INTERVALS .
13 |
14 | PARAMETERS package TYPE tadir-devclass.
15 |
16 | PARAMETERS : yes_intf RADIOBUTTON GROUP rad1 DEFAULT 'X',
17 | no_intf RADIOBUTTON GROUP rad1.
18 |
19 | PARAMETERS : wrapclas TYPE sxco_class_name DEFAULT 'ZCL_WRAP_TEST'.
20 | PARAMETERS : wrapfact TYPE sxco_class_name DEFAULT 'ZCL_FACT_TEST'.
21 | PARAMETERS : wrapintf TYPE sxco_class_name DEFAULT 'ZIF_WRAP_TEST'.
22 |
23 | *PARAMETERS : demomode TYPE abap_bool DEFAULT abap_true.
24 | DATA demomode TYPE abap_bool VALUE abap_false.
25 |
26 | "overwrite existing objects
27 | PARAMETERS : patchobj TYPE abap_bool DEFAULT abap_true.
28 |
29 | LOOP AT s_func INTO DATA(function_module_sel_option).
30 | "transaction aco_proxy only supports remote enabled function modules
31 | SELECT SINGLE * FROM tfdir INTO @DATA(function_module_info) WHERE funcname = @function_module_sel_option-low.
32 | IF function_module_info-fmode IS NOT INITIAL.
33 | APPEND to_upper( function_module_sel_option-low ) TO function_modules.
34 | ELSE.
35 | WRITE : / |function module { function_module_sel_option-low } has been skipped, because it is not remote-enabled. |.
36 | ENDIF.
37 | ENDLOOP.
38 |
39 | TRY.
40 | DATA(tier2_rfc_proxy_generator) = NEW zcl_gen_rfc_tier2_proxy(
41 | i_package_name = package
42 | i_transport_request = ''
43 | i_generate_intf_and_fact_class = yes_intf
44 | i_wrapper_class_name = wrapclas
45 | i_wrapper_interface_name = wrapintf
46 | i_wrapper_factory_class_name = wrapfact
47 | i_function_modules = function_modules
48 | i_overwrite_objects = patchobj
49 | ).
50 |
51 | CATCH cx_abap_invalid_value INTO DATA(invalid_parameter).
52 | WRITE : / 'Exception occured:'.
53 | WRITE : / invalid_parameter->get_text( ).
54 | EXIT.
55 | ENDTRY.
56 |
57 | DATA(exception_text) = tier2_rfc_proxy_generator->generate_wrapper_objects( demomode ).
58 |
59 | IF exception_text IS NOT INITIAL.
60 | WRITE : 'Exception occured generating objects:'.
61 | WRITE : exception_text.
62 | EXIT.
63 | ENDIF.
64 |
65 | DATA objects TYPE STANDARD TABLE OF dwinactiv .
66 |
67 | IF yes_intf = abap_true.
68 | objects = VALUE #(
69 | ( object = 'INTF' obj_name = wrapintf uname = sy-uname )
70 | ( object = 'CLAS' obj_name = wrapclas uname = sy-uname )
71 | ( object = 'CLAS' obj_name = wrapfact uname = sy-uname )
72 | ).
73 | ELSE.
74 | objects = VALUE #(
75 | ( object = 'CLAS' obj_name = wrapclas uname = sy-uname )
76 | ).
77 | ENDIF.
78 |
79 | IF demomode = abap_False.
80 |
81 | CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
82 | TABLES
83 | objects = objects
84 | EXCEPTIONS
85 | excecution_error = 1
86 | cancelled = 2
87 | insert_into_corr_error = 3
88 | OTHERS = 4.
89 |
90 | IF sy-subrc <> 0.
91 | WRITE : / |error occured when activating classes. SY-SUBRC = { sy-subrc } |.
92 | EXIT.
93 | ELSE.
94 | WRITE : / |Generation finished:|.
95 | IF yes_intf = abap_true.
96 | WRITE : / |{ wrapclas }, { wrapfact } and { wrapintf }|.
97 | ELSE.
98 | WRITE : / |{ wrapclas }|.
99 | ENDIF.
100 | ENDIF.
101 |
102 | ELSE.
103 |
104 | WRITE : / '***************************'.
105 | WRITE : / 'methods_code_definition'.
106 | WRITE : / '***************************'.
107 |
108 | LOOP AT tier2_rfc_proxy_generator->methods_code_definition INTO source_code_line.
109 | WRITE : / source_code_line.
110 | ENDLOOP.
111 |
112 | WRITE : / '***************************'.
113 | WRITE : / 'methods_code_implementation'.
114 | WRITE : / '***************************'.
115 |
116 | LOOP AT tier2_rfc_proxy_generator->methods_code_implementation INTO source_code_line.
117 | WRITE : / source_code_line.
118 | ENDLOOP.
119 |
120 | WRITE : / '***************************'.
121 | WRITE : / 'wrapper_factory_class_code'.
122 | WRITE : / '***************************'.
123 |
124 | LOOP AT tier2_rfc_proxy_generator->wrapper_factory_class_code INTO source_code_line.
125 | WRITE : / source_code_line.
126 | ENDLOOP.
127 |
128 | WRITE : / '***************************'.
129 | WRITE : / 'wrapper_class_code'.
130 | WRITE : / '***************************'.
131 |
132 | LOOP AT tier2_rfc_proxy_generator->wrapper_class_code INTO source_code_line.
133 | WRITE : / source_code_line.
134 | ENDLOOP.
135 |
136 | WRITE : / '***************************'.
137 | WRITE : / 'wrapper_interface_code'.
138 | WRITE : / '***************************'.
139 |
140 |
141 | LOOP AT tier2_rfc_proxy_generator->wrapper_interface_code INTO source_code_line.
142 | WRITE : / source_code_line.
143 | ENDLOOP.
144 |
145 | ENDIF.
146 |
--------------------------------------------------------------------------------
/src/zr_gen_rfc_tier2_proxy.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZR_GEN_RFC_TIER2_PROXY
7 | S
8 | 1
9 | X
10 | D$S
11 | X
12 |
13 |
14 | -
15 | R
16 | zr_gen_rfc_tier2_proxy
17 | 22
18 |
19 | -
20 | S
21 | DEMOMODE
22 | Demomode
23 | 16
24 |
25 | -
26 | S
27 | NO_INTF
28 | Only wrapper class
29 | 26
30 |
31 | -
32 | S
33 | PACKAGE
34 | Target Package
35 | 22
36 |
37 | -
38 | S
39 | PATCHOBJ
40 | Overwrite objects
41 | 25
42 |
43 | -
44 | S
45 | S_FUNC
46 | Function Modules
47 | 24
48 |
49 | -
50 | S
51 | WRAPCLAS
52 | Wrapper class
53 | 21
54 |
55 | -
56 | S
57 | WRAPFACT
58 | Wrapper factory class
59 | 29
60 |
61 | -
62 | S
63 | WRAPINTF
64 | Wrapper interface
65 | 25
66 |
67 | -
68 | S
69 | YES_INTF
70 | Intf., class and fact. class
71 | 36
72 |
73 |
74 |
75 | -
76 | D
77 |
78 |
-
79 | S
80 | DEMOMODE
81 | Demomode
82 | 38
83 |
84 | -
85 | S
86 | NO_INTF
87 | Nur Wrapper Klasse
88 | 38
89 |
90 | -
91 | S
92 | PACKAGE
93 | Zielpaket
94 | 38
95 |
96 | -
97 | S
98 | PATCHOBJ
99 | Objekte überschreiben
100 | 38
101 |
102 | -
103 | S
104 | S_FUNC
105 | Funktionsbausteine
106 | 38
107 |
108 | -
109 | S
110 | WRAPCLAS
111 | Wrapper Klasse
112 | 38
113 |
114 | -
115 | S
116 | WRAPFACT
117 | Wrapper Factory Klasse
118 | 38
119 |
120 | -
121 | S
122 | WRAPINTF
123 | Wrapper Interface
124 | 38
125 |
126 | -
127 | S
128 | YES_INTF
129 | Intf., Klasse u. Fact. Klasse
130 | 38
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------