CL_ABAP_CORRESPONDING, CL_JAVA_CORRESPONDING and CL_JS_CORRESPONDING
In Horst’s blog ABAP News for Release 7.50 – CORRESPONDING, again the usage of CL_ABAP_CORRESPONDING is introduced.
There is already a demo program in SAP help.
I write another simple one and I will keep using that scenario in Java and JavaScript as well.
CL_ABAP_CORRESPONDING
Suppose there are two developers Jerry and Tom who mainly focus on ABAP and Java. Their salary are stored in the internal table developer_list. Later they would like to work as presale for new challenge and the corresponding information should be moved to another internal table presale_list. The content of these two internal table should be equal, unfortunately the field name are slightly different. In this case it is show time for CL_ABAP_CORRESPONDING:
Report z.
TYPES: BEGIN OF developer,
focus_language TYPE string,
salary TYPE i,
name TYPE string,
END OF developer,
BEGIN OF presale,
focus_area TYPE string,
salary_plus_bonus TYPE i,
name TYPE string,
END OF presale.
DATA: developer_list TYPE TABLE OF developer WITH EMPTY KEY,
presale_list TYPE TABLE OF presale WITH EMPTY KEY.
developer_list = VALUE #(
( name = 'Jerry' focus_language = 'ABAP' salary = 2000 )
( name = 'Tom' focus_language = 'Java' salary = 2050 ) ).
presale_list = VALUE #( ( name = 'Jerry' ) ( name = 'Tom' ) ).
DATA(lo_mapping_executor) = cl_abap_corresponding=>create(
source = developer_list
destination = presale_list
mapping = VALUE cl_abap_corresponding=>mapping_table(
( level = 0 kind = 1 srcname = 'focus_language' dstname = 'focus_area' )
( level = 0 kind = 1 srcname = 'salary' dstname = 'salary_plus_bonus' ) ) ).
lo_mapping_executor->execute( EXPORTING source = developer_list
CHANGING destination = presale_list ).
The data transfer from developer internal table to presales internal table consists of two steps:
1. configure mapping information using CL_ABAP_CORRESPONDING=>CREATE, a mapping executor instance is returned.
2. call mapping executor’s method execute to get mapped internal table.
The mapped result in this example looks as below:

CL_JAVA_CORRESPONDING
Still use the same scenario, here is my definition of Developer and Presale:
public class Developer {
private String focusLanguage;
private int salary;
private String name;
public Developer(String name, String language, int salary){
this.name = name;
this.focusLanguage = language;
this.salary = salary;
}
}
public class PreSales {
private String name;
private String focusArea;
private int salaryPlusBonus;
public PreSales(String name){
this.name = name;
}
public String toString(){
return "Presales: " + this.name + " focusArea: " + this.focusArea + " salaryPlusBonus: " +
this.salaryPlusBonus;
}
}
And let’s do some enhancement on top of the scenario. Suppose after Jerry and Tom work as a Presale, they get their salary doubled ( this is just an example, not the real case in SAP of course ! ) It is expected such salary double could also be automatically performed during mapping execution.
This is my test code in Java:
List<Developer> developers = new ArrayList<Developer>();
developers.add(new Developer("Jerry", "ABAP", 2000));
developers.add(new Developer("Tom", "Java", 2050));
List<PreSales> preSales = new ArrayList<PreSales>();
preSales.add(new PreSales("Jerry"));
preSales.add(new PreSales("Tom"));
Above code just constructs a list for developer and a list for presales.
CL_MAPPING[] mapping = new CL_MAPPING[2];
mapping[0] = new CL_MAPPING("focusLanguage", "focusArea", null);
And above line defines the first mapping rule, to map field focusLanguage of developer to field focusArea of Presale.
Function<Integer, Integer> salaryDouble = e -> e * 2;
mapping[1] = new CL_MAPPING("salary", "salaryPlusBonus", salaryDouble);
Above line also defines a mapping rule using a Function instance salaryDouble. The implementation of this function is easy to understand: double the salary!
For comparison purpose I still stick to ABAP naming convention in this Java code, you see the consumption pattern for CL_JAVA_CORRESPONDING is exactly as what we have done in previous ABAP example: first configure mapping rule and get a mapping executor, and then call its execute method to perform the mapping.
CL_JAVA_CORRESPONDING mappingExecutor = CL_JAVA_CORRESPONDING.CREATE(developers, preSales, mapping);
List<PreSales> mappedPresales = (List<PreSales>) mappingExecutor.execute();
mappedPresales.forEach(System.out::println);
Mapping result, the salary for both guy are doubled 🙂

Below is the core method for mapping logic done in Java.
The idea is simple, get the value of source field via Java reflection, and set to the corresponding field of target object as well.
The complete implementation and test code of CL_JAVA_CORRESPONDING could be found from my github.

CL_JS_CORRESPONDING
Due to the dynamic programming trait of JavaScript, it is pretty easier to implement the same logic in JavaScript.
Again the definition of Developer and Presale:
function Developer(name, language, salary){
this.name = name;
this.focusLanguage = language;
this.salary = salary;
}
function Presales(name){
this.name = name;
}
And implementation of CL_JS_CORRESPONDING ( I use ABAP naming convention once again here )
var CL_JS_CORRESPONDING = function() {
function MappingExecutor(src, target, mapping){
this.src = src;
this.target = target;
this.mapping = mapping;
function _map(source, target, mapping){
for( var i = 0; i < source.length; i++){
_mapEach(source[i], target[i], mapping);
}
}
function _mapEach(source, target, mapping){
target[mapping.target] = source[mapping.source];
if( mapping.function){
target[mapping.target] = mapping.function.call(null, target[mapping.target]);
}
}
MappingExecutor.prototype.execute = function(){
for( var i = 0; i < this.mapping.length; i++){
_map(this.src, this.target, this.mapping[i]);
}
return this.target;
}
};
return {
CREATE:function(src,target,mapping){
if( !Array.isArray(src) || !Array.isArray(target)){
return target;
}
if( src.length != target.length){
return target;
}
if( src.length == 0){
return target;
}
return new MappingExecutor(src, target, mapping);
}
}}();
Consumer code below. Here I use the arrow function to define the salary double rule:
var developerList = [ new Developer("Jerry", "ABAP", 2000),
new Developer("Tom", "Java", 2050)];
var preSalesList = [ new Presales("Jerry"),
new Presales("Tom")];
var mapping = [
{
source:"focusLanguage",
target:"focusArea"
},
{
source:"salary",
target:"salaryPlusBonous",
function: x => { return x * 2 }
}
];
var mappingExecutor = CL_JS_CORRESPONDING.CREATE(developerList, preSalesList, mapping);
var mappedPreSales = mappingExecutor.execute();
Execution result: salary doubled, again!

All source code of JavaScript version could be found from my github here.
Rewrite Javascript implementation using functional programming style
According to David ‘s comment since in JavaScript the functional programming is possible, why not try it?
Then I rewrite the Javascript implementation using map provided for Array. Here below is the source code:
var CL_JS_CORRESPONDING = function() {
function MappingExecutor(src, target, mapping){
this.src = src;
this.target = target;
this.mapping = mapping;
MappingExecutor.prototype.execute = function(){
var mapCurrentTarget = function(currentTarget, currentSource, mapping){
mapping.map(function(currentMapping){
this.currentTarget[currentMapping.target] = this.currentSource[currentMapping.source];
if( currentMapping.function) {
this.currentTarget[currentMapping.target] = currentMapping.function.call(null, this.currentTarget[currentMapping.target]);
}
}, {
currentTarget: currentTarget,
currentSource: currentSource
});
return currentTarget;
}
var mappingFunctor = function (currentTarget, index){
return mapCurrentTarget(currentTarget, this.src[index], this.mapping);
};
return this.target.map(mappingFunctor, this);
}
};
return {
CREATE:function(src,target,mapping){
if( !Array.isArray(src) || !Array.isArray(target)){
return target;
}
if( src.length != target.length){
return target;
}
if( src.length == 0){
return target;
}
return new MappingExecutor(src, target, mapping);
}
}}();
This version has 40 lines of source code, you can compare it with the old style implementation using for loop, which has 37 lines of code.
Meanwhile in ABAP we can also simulate “Functional Programming” a little bit. See this blog Functional Programming – Try Reduce in JavaScript and in ABAP for detail.
Further reading
I have written a series of blogs which compare the language feature among ABAP, JavaScript and Java. You can find a list of them below:
- Lazy Loading, Singleton and Bridge design pattern in JavaScript and in ABAP
- Fibonacci Sequence in ES5, ES6 and ABAP
- Java byte code and ABAP Load
- How to write a correct program rejected by compiler: Exception handling in Java and in ABAP
- An small example to learn Garbage collection in Java and in ABAP
- String Template in ABAP, ES6, Angular and React
- Try to access static private attribute via ABAP RTTI and Java Reflection
- Local class in ABAP, Java and JavaScript
- Integer in ABAP, Java and JavaScript
- Covariance in Java and simulation in ABAP
- Various Proxy Design Pattern implementation variants in Java and ABAP
- Tag(Marker) Interface in ABAP and Java
- Bitwise operation ( OR, AND, XOR ) on ABAP Integer
- ABAP ICF handler and Java Servlet
- ADBC and JDBC
- CL_ABAP_CORRESPONDING, CL_JAVA_CORRESPONDING and CL_JS_CORRESPONDING
- Build an Cross Site Scripting example in Java and ABAP
- Play around with JSONP in nodeJS server and ABAP server
Hi!
I don't think it is a good idea to write JavaScript in an 'ABAP style'.
For example, I would avoid 'for (int i = 0, ....)' loops and use a combination of reduce, map and filter.
If you are interested in a more functional style, which comes in very handy in this context, take a look at the Ramda package and https://github.com/MostlyAdequate/mostly-adequate-guide .
Best regards
David
Hello David,
Yes you are right, I will try to re-implement the execute method of JavaScript version using more pure JavaScript style.
And really appreciate your link to the nice book 🙂
Best regards,
Jerry
Hello David,
I have reimplemented the JavaScript version using Array.map. Would you please kindly have a look again? 🙂
Best regards,
Jerry
Hi Jerry!
Using map is a start 🙂
One critical aspect of functional programming is to use pure functions (https://en.wikipedia.org/wiki/Pure_function) wherever possible. I think you try to force the abap functionality too much in your application (i.e. the consumer code).
There is a nice video which shows Ramda by example: https://www.youtube.com/watch?v=tN4wyJ9DdtM
I think you can benefit a lot from this!
Keep up the good work!
Best regards
David
Hello David,
Thanks a lot for your comment. Yes the aim of this blog is to simulate the corresponding functionality supported by ABAP with other programming language while keeping the same signature. Nevertheless I will study the video you provided to learn more.
Have a nice day 🙂
Best regards,
Jerry