Technical Articles
Java Mapping code and JAR creation for SAP PI Integration with Salesforce
Introduction
This document provides end to end details for how to create JAR file withing Eclips and how to export and upload the JAR file in the SAP PI ESR configuration.
The document covers the small thing which is very import for the java code, from where to download the external jar file from the PI path and how to add the external jar file into the java project.
Step by Step to Create a .jar file for Java Mapping.
For the creation of JAR file, you have download the Eclipse.
Below is the step by step screenshot to create JAR file.
Right-click on src package and create a java class.
Right-click on Java Project and go to Build Path and click on the Configuration Build path.
Add two External JAR files as mention below.
com.sap.xi.mapping.tool.lib_api.jar
com.sap.xpi.ib.mapping.lib.jar
http://<hostname>:<port>/rep/repository/com.sap.xpi.ib.mapping.lib.jar
http://<hostname>:<port>/rep/repository/com.sap.xpi.ib.mapping.lib.jar
Below is the complete java code for request mapping.
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Map;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import com.sap.aii.mappingtool.tf3.rt.Container;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import com.sap.aii.mapping.lookup.Channel;
import com.sap.aii.mapping.lookup.LookupService;
import com.sap.aii.mapping.lookup.Payload;
import com.sap.aii.mapping.lookup.SystemAccessor;
//import com.sun.xml.internal.ws.api.server.Container;
import com.sap.aii.mapping.api.*;
public class SFDC_JAVA extends AbstractTransformation {
String sessionId = “”;
String serverUrl = “”;
String prefix = “<?xml version=\”1.0\” encoding=\”UTF-8\”?>”
+ “<soapenv:Envelope xmlns:soapenv=\”http://schemas.xmlsoap.org/soap/envelope/\” ”
+ “xmlns:urn=\”urn:enterprise.soap.sforce.com\” ”
+ “xmlns:urn1=\”urn:sobject.enterprise.soap.sforce.com\” ”
+ “xmlns:urn2=\”urn:sobject.enterprise.soap.sforce.com\”>”
+ “<soapenv:Header> ” + “<urn:SessionHeader>” + “<urn:sessionId> “;
String suffix = ” </urn:sessionId> </urn:SessionHeader> </soapenv:Header> <soapenv:Body>”;
String envelope = “</soapenv:Body> </soapenv:Envelope>”;
private Map map;
/* method setParamters is required, but we do not anything with it */
public void setParameter(Map param) {
map = param;
if(map == null)
{
map = new HashMap();
}
}
public void execute(InputStream in, OutputStream out) {
try {
copyPayload(in, out);
} catch (Exception t) {
t.printStackTrace();
}
}
private static final DynamicConfigurationKey KEY_URL = DynamicConfigurationKey.create(“http://sap.com/xi/XI/System/SOAP”, “TServerLocation”);
/* method is to build the Soap envelope for the input message payload */
private void copyPayload(InputStream in, OutputStream out) throws StreamTransformationException
{
String c = “”;
String Newpayload = “”;
try {
InputStreamReader inr = new InputStreamReader(in);
/* InputStream inr = in.getInputPayload().getInputStream(); */
BufferedReader reader = new BufferedReader(inr);
/*
* The following is to remove the <?xml version=\”1.0\” encoding=\”UTF-8\”?>
* from the input message payload
*/
String temp = “”;
while ((temp = reader.readLine()) != null) {
c = c + temp;
}
int len = c.indexOf(“>”);
Newpayload = c.substring(len + 1);
Newpayload = Newpayload.replace(“<ns0:sObjects>”,
“<ns0:sObjects xsi:type=\”urn1:Product2\” xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\”>”);
out.write(prefix.getBytes());
out.write(sessionId.getBytes());
out.write(suffix.getBytes());
out.write(Newpayload.getBytes());
out.write(envelope.getBytes());
} catch (IOException e) {
throw new StreamTransformationException(e.getMessage());
}
}
/*
* method is to login to SFDC with the username and password to get the
* sessionId and serverurl from the response
*/
private void getSessionIdFromSFDC(String username, String password) {
try {
Channel channel = LookupService.getChannel(“BC_SALESFORCE”, “CC_SOAP_LOOKUP”);
SystemAccessor accessor = null;
accessor = LookupService.getSystemAccessor(channel);
String loginxml = “<login xmlns=\”urn:enterprise.soap.sforce.com\”> <username>” + username
+ “</username> <password>” + password + “</password> </login>”;
InputStream inputStream = new ByteArrayInputStream(loginxml.getBytes());
Payload payload = LookupService.getXmlPayload(inputStream);
Payload SOAPOutPayload = null;
SOAPOutPayload = accessor.call(payload);
InputStream inp = SOAPOutPayload.getContent();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inp);
NodeList sessionId1 = document.getElementsByTagName(“sessionId”);
NodeList serverUrl1 = document.getElementsByTagName(“serverUrl”);
Node node = sessionId1.item(0);
Node node1 = serverUrl1.item(0);
if (node != null) {
node = node.getFirstChild();
if (node != null) {
sessionId = node.getNodeValue();
}
}
if (node1 != null) {
node1 = node1.getFirstChild();
if (node1 != null) {
serverUrl = node1.getNodeValue();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
try {
SFDC_JAVA obj = new SFDC_JAVA();
FileInputStream in = new FileInputStream(“D:/input.xml”);
FileOutputStream out = new FileOutputStream(“D:/Output.xml”);
obj.execute(in, out);
} catch (Exception e) {
e.printStackTrace();
}
}
public String convertStreamToString(InputStream in) {
StringBuffer sb = new StringBuffer();
try {
InputStreamReader isr = new InputStreamReader(in);
Reader reader = new BufferedReader(isr);
int ch;
while ((ch = in.read()) > -1)
sb.append((char) ch);
reader.close();
} catch (Exception exception) {
}
return sb.toString();
}
public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException {
DynamicConfiguration conf = in.getDynamicConfiguration();
getSessionIdFromSFDC(“userid”, “password”);
conf.put(KEY_URL, serverUrl);
execute(in.getInputPayload().getInputStream(), out.getOutputPayload().getOutputStream());
}
}
Response Java Mapping:
The same step you have to perform for response java mapping as mention above ( to create java project and class etc…)
Below code is using to remove the envelope and the header from Response message and send the actual UPSERT Response message to the target system. ( Salesforce -à SAP )
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
public class RemoveSoapEnvelop implements StreamTransformation {
public void execute(InputStream in, OutputStream out) throws StreamTransformationException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builderel = factory.newDocumentBuilder();
/* input document in form of XML */
Document docIn = builderel.parse(in);
/* document after parsing */
Document docOut = builderel.newDocument();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transform = tf.newTransformer();
Element root;
Node p;
NodeList l;
int mm, n1;
Node a;
NodeList b;
int cc,n2;
// if you need to include namespace use next two lines
//root=docOut.createElement(“ns0:upsertResponse”);
//root.setAttribute(“xmlns:ns0″,”urn:enterprise.soap.sforce.com”);
root = docOut.createElement(“upsertResponse”);
root.setAttribute(“xmlns:xsi”,”http://www.w3.org/2001/XMLSchema-instance”);
root.setAttribute(“xmlns:”,”urn:enterprise.soap.sforce.com”);
//root = docOut.createElement(“errors”);
//root.setAttribute(“xmlns:”,”urn:enterprise.soap.sforce.com”);
p = docIn.getElementsByTagName(“upsertResponse”).item(0);
//a = docIn.getElementsByTagName(“errors”).item(0);
l = p.getChildNodes();
//b = a.getChildNodes();
n1 = l.getLength();
//n2 = b.getLength();
for (mm = 0; mm < n1; ++mm)
{
Node temp = docOut.importNode(l.item(mm), true);
root.appendChild(temp);
//for (cc = 0; cc < n2; ++cc)
//{
//Node temp1 = docOut.importNode(l.item(mm), true);
//temp.appendChild(temp1);
//}
}
docOut.appendChild(root);;
transform.transform(new DOMSource(docOut), new StreamResult(out));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setParameter(Map arg0) {
}
public static void main(String[] args) {
try {
RemoveSoapEnvelop genFormat = new RemoveSoapEnvelop();
FileInputStream in = new FileInputStream(“D:/sd2.xml”);
FileOutputStream out = new FileOutputStream(“D:/removedEnvelop.xml”);
genFormat.execute(in, out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Export the Jar file. right-click on java project and export.
Provide the path where you want to export the jar file.
Conclusion
This document includes the complete java code with Dynamic configuration within the java code.
Thanks,
Uday Vyas
I am searching this type of blog for a long time. This is very informative.
thanks for sharing this blog.
Thanks Uday,
Its a Great blog,
This blog very useful for Salesforce integration using PI/PO. I am also working on Salesforce interfaces using PO 7.5, I am struggle with Java code for Request and Response Java mapping. I have checked so many blogs for related salesforce integration using PO and not getting the clear information.
But as you provided Java Code in the blog, it is a suitable for my requirement.
Thanks Uday,
Its a very nice blog,
I have seen your blog, Its a clear information you provided in the blog, I hope this blog very useful for salesforce integration via PO.