In this post I will discuss the basics of developing, debugging and testing PI Function Libraries using Netweaver Developer Studio. This includes creating the function in PI, exporting the code, importing the code into NWDS, creating a test class and implementations of supporting classes, and executing\debugging the code locally.
Create the function
- Create new function library
- Create a function with Execution Type = All Values of a Context
- Create Signature Variables
- Export the source code
- Click the "Export Source Text" icon
|
Click to enlarge |
|
Click to enlarge |
- Add the code to the created package
- Drag the java file extracted from the Function Library into your package
Fix referencing errors
After dragging in the source file into your package, it will complain about missing libraries.
To add the needed libraries do the following: Right-click project root - Build Path - Libraries - XPI Libraries - XPI Mapping Libraries
|
Click to enlarge |
public void replaceBlankValue(String[] var1, String var2, ResultList result, Container container) throws StreamTransformationException{
//Function for replacing a blank value in var1 with another
//specified value in var2.
for (int i = 0; i < var1.length; i++) {
if (!var1[i].equals(ResultList.CC)) {
if(!var1[i].equals(ResultList.SUPPRESS)){
if(var1[i].equals("")){
result.addValue(var2);
}
else{
result.addValue(var1[i]);
}
}
else{
result.addSuppress();
}
}
else{
result.addContextChange();
}
}
}
Testing the function
- Create Test Class
- Package - New - Class
- Tick "public static void main"
|
Click to enlarge |
- Create Container and ResultList implementations
- Because the signature of the function references the ResultList and Container classes, we have to write our own implementations for these.
- ResultList implementation:
package sap.myfunctions.co.za.samples;
import com.sap.aii.mappingtool.tf7.rt.*;
import java.util.ArrayList;
public class ResultListImpl extends ArrayList implements ResultList{
public static final String SUPPRESS = "_sUpPresSeD_";
public static final String CC = "__cC_";
public static final String XSI_NIL = "_!xSi#NiL$_";
public static ArrayList al = new ArrayList();
public void addValue(Object obj){
al.add(obj);
}
public void addContextChange(){
al.add(CC);
}
public void addSuppress(){
al.add(SUPPRESS);
}
public String toString(){
return al.toString();
}
public void clear(){
al.clear();
}
}
- Container implementation:
package sap.myfunctions.co.za.samples;
import com.sap.aii.mappingtool.tf7.rt.*;
import com.sap.aii.mapping.api.*;
import java.util.Map;
public class ContainerImpl implements Container{
public Object getParameter(String s){
return new Object();
}
public void setParameter(String s, Object obj){
}
public AbstractTrace getTrace(){
return (AbstractTrace) new Object();
}
public GlobalContainer getGlobalContainer(){
return (GlobalContainer) new Object();
}
public InputHeader getInputHeader(){
return (InputHeader) new Object();
}
public InputParameters getInputParameters(){
return (InputParameters) new Object();
}
public OutputHeader getOutputHeader(){
return (OutputHeader) new Object();
}
public OutputParameters getOutputParameters(){
return (OutputParameters) new Object();
}
public Map getTransformationParameters(){
return (Map) new Object();
}
}
- Write code for test class
- You can now reference the ResultList and Container classes, and write the code to test your function.
package sap.myfunctions.co.za.samples;
import com.sap.aii.mappingtool.tf7.rt.Container;
import com.sap.aii.mappingtool.tf7.rt.ResultList;
public class Test_PI_Utils {
public static void main(String[] args) {
ResultList result = new ResultListImpl();
Container container = new ContainerImpl();
PI_Utils pi_utils = new PI_Utils();
String[] var1 = {"111",ResultList.CC,"222",ResultList.CC,"",ResultList.CC,"333"};
String var2 = "0";
try {
pi_utils.replaceBlankValue(var1, var2, result, container);
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println(result.toString());
}
}
- Test your function by executing the main method
- Run - run as... - Java Applicaiton
- We can see that the output of the method is correct, because it converted the space to a "0".
|
Click to enlarge |
Deploy code on PI
|
Click to enlarge |
Test Function in PI
- Now we can test the function in the mapping.
|
Click to enlarge |
Hi, when you create a package, NWDS does not allow us to use ':' as part of the package name. May I know how you resolve this? Our namespace naming convetion is urn:sap..com:
ReplyDeleteHi, when you create a package, NWDS does not allow us to use ':' as part of the package name. May I know how you resolve this? Our namespace naming convetion is urn:sap..com::
ReplyDeleteHi, I can't see the option to import XPI library. Do I need to import it externally?
ReplyDeleteHi Simon. It is important to differentiate between a java package and a repository namespace (SAP PI). A java package has the function of organizing java classes. A respository namespace as we use it in SAP PI also has the function of organizing, but organizes PI objects. Even though the package name and the respository namespace may be similar, it will be diffirent as it organizes different things and has different restrictions, as you pointed out. I would recomend using the following naming convention when creating a java packages for your function library in NWDS:
ReplyDeletesap.companyname.co.za.pi.businessfunction.
Hi Simon, regarding the importing of the XPI library, if you can't see the Build Path option from the context menu of the project root, you can also access it from the Project-Properties menu. You can then select Java Build Path, Libraries tab and Add Library. Also note that I am using the following version of NWSD:
ReplyDeleteSAP NetWeaver Developer Studio
SAP Enhancement Package 1 for SAP NetWeaver 7.1 SP00 PAT0000
Build id: 200809132152
nice post thank you
ReplyDeleteexcellent post thanks for sharing from Kajal
ReplyDeleteStep by Step procedure of SAP done in Open Source is explained briefly.
ReplyDeleteHi Sir, You provided info on sap mm online training is amazing. Thanks for providing info. Keep on publishing more info.
ReplyDeleteChange ResultList implementation as follows:
ReplyDeletepublic static ArrayList al = new ArrayList();
to
private ArrayList al = new ArrayList();
Removing static allows you to have multiple instances of ArrayList and make it private prevents direct access.