Skip to Content
Author's profile photo Dilip Kumar Krishnadev Pandey

SAP PI Java Mapping to append File Contents

Overview

Here, we will see an example of SAP-PI Java Mapping, in which we come to know

  • How to use Dyanmic Configuration variables in Java Map
  • How to Print Trace log
  • How to refer ResourceFile data included in JavaMap.Jar files

This SAP-PI Java map was required in below business scenario:

  • One SAP-PI Soap Synchronous web-service has been hosted, where:
    • In Soap-Request, client will send FileName starting key words
    • and in Soap-Response message, SAP-PI has to return FileContents of one File found in SAP directory with same FileNameKey
    • To achieve above, we use this example of JavaMap to populate Soap Response message.
  • This Java map is been applied in Response-Tab of Operation Mapping

Functionality of given SAP-PI Java map:

  1. Get File-Name-Key from SoapRequest payload using Dynamic Configuration
    • In Request Mapping, below UDF is been used to get FileNameKey from Soap Request Dynamic Configuration variable
    • String  RequestDataStr = "";
      RequestDataStr = ReqStr_FileName ;
      try
      {
      	// set to dynamic config:
      	DynamicConfiguration conf = (DynamicConfiguration) container .getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
      	DynamicConfigurationKey key = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/SOAP", "FileName_StartKey" );
      	 if ( conf != null){
      	  conf.put(key, RequestDataStr);
      	}
      }
      catch (Exception ex)
      {
           ;
      }
      
      return RequestDataStr;
  2. Get FolderPath details from Resource file ‘FolderPath_details.xml‘ which is included with Jar File itself
  3. Search directory for files having starting name as of ‘FileNameKey’ and having extension ‘.CSV’ or ‘.csv’
  4. ‘If file found as per above criteria, extract its content and append it to Target Message format
  5. And Archive read file to other directory

 

 

Pre-requisites:

  • SAP-PI 7.1
  • Java Map Library (aii_map_api.jar)
  • Java Eclipse (to create Java Mapping program)
  • Jre 1.6

 

Steps to create Java Map:

  1. Create a Java Project in Eclipse
  2. Import External jar lib file ‘aii_map_api.jar
    • Go to -> right Click on Project fodler ‘JavaMap_Example-01’ -> Bulid Path -> Configure Build Path -> Tab ‘Libraries’ -> click button ‘Add External Jars’ to import file from local desktop
  3. Insert Resource File ‘FolderPath_details.xml’
    • Insert xml file having path information
  4. Create one Java Class
    • ight Click on Project fodler ‘JavaMap_Example-01’ -> src -> New -> Class -> create a new Java class
    • and write JavaMap Source code as given below
    • import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.util.HashMap;
      import java.util.Map;
      
      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.CDATASection;
      import org.w3c.dom.Document;
      import org.w3c.dom.Element;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      import org.xml.sax.SAXException;
      
      import com.sap.aii.mapping.api.AbstractTrace;
      import com.sap.aii.mapping.api.DynamicConfiguration;
      import com.sap.aii.mapping.api.DynamicConfigurationKey;
      import com.sap.aii.mapping.api.StreamTransformation;
      import com.sap.aii.mapping.api.StreamTransformationConstants;
      import com.sap.aii.mapping.api.StreamTransformationException;
      
      
      public class Example_01 implements StreamTransformation {
      	
      	private String ArchivalPath = "";
      	private String SourcePath = "";
      	private AbstractTrace trace = null;	
      	private Map param;
      	
      	public void setParameter(Map map){
      		param = map;
      		if (param == null)
      		{
      			param = new HashMap();
      		}
      	}
      	
      	public void execute(InputStream in, OutputStream out) throws StreamTransformationException{
      		try{	
      			
      			trace = (AbstractTrace) param.get(StreamTransformationConstants.MAPPING_TRACE);
      			trace.addInfo("Starting JavaMap 'Example_01'");	
      			
       			//Get FileNameKey using DynamicConfig
      			String FileNameKey = "";
       			FileNameKey = getFileNameKey();
       			trace.addInfo("FileName starting key found as: " + FileNameKey);		
       			
       			//Get FolderPath from ResourceFile 'FolderPath_details.xml'
       			getFolderPath();
       			trace.addInfo("SourcePath: " + SourcePath);
       			trace.addInfo("ArchivalPath: " + ArchivalPath);
       			
       			//----Start:Read File from SAPDirectory & Append it to OutputXml -------	
       			String FileName = "";
       	 		String FileContent = "";
       	 		String ErrorStr = ""; 	 		
       	 		File theDir = new File(SourcePath);				  
       	 		if (!theDir.exists()){
       	 			//Error message 'SourcePath not found'
       	 			ErrorStr = "SourcePath '" + SourcePath + "' not found";
       	 		}else{
       	 			//If directory found, then check if it is empty 	 			
       	 			File[] dirFileList = new File(SourcePath).listFiles();
       	 			if (dirFileList.length < 1){ 	 	 			
       	 				//Error message 'No file found in SourcePath'
       	 				ErrorStr = "No file found in SourcePath '" + SourcePath + "'"; 	 	 		
       	 			}else{
       	 				//If folder is not empty, the search for files
       	 				for (int i=0; i<dirFileList.length; i++){ 	 					
       	 					FileName = dirFileList[i].getName(); 	//Get file name		
       	 					//check if file is having CSV extensions
       	 					if ((FileName.indexOf(".CSV") != -1) || (FileName.indexOf(".csv") != -1)){
       	 						//Now check if FileName is having starting key word
       	 						if(FileName.startsWith(FileNameKey)){ 	 							
       	 							FileContent = getFileContent(SourcePath + FileName ); //Read file content  	 							
       	 							
       	 							//Archive file to other directory 	 							
       	 							File file = new File(FileName);
       	 							String arcFNm = ArchivalPath + "ARC_" +  file.getName();
       	 		            		file.renameTo(new File(arcFNm));
       	 		            		 		
       	 		            		ErrorStr = "File found and its content has been read";
       	 							break;	//break the loop if file found | To return one fileContent at a time
       	 						}
       	 					}else{
       	 						ErrorStr = "No .CSV/.csv file found";
       	 					}
       	 	 			}
       	 			} 	 			
       	 		}
       			//----End  :Read File from SAPDirectory & Append it to OutputXml -------
       			 			
       			
      	     	//----Start: Create output XML Document -------------------	     
      	    	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
      	 		DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
      	 		Document docOut = dbBuilder.newDocument();	 		
      	 		
      	 		//Create XML RootElement
      	 		Element rootElmnt = docOut.createElement("ns0:MT_TargetMsg"); 				
       	 		docOut.appendChild(rootElmnt);	//Append rootElement to Output document 	 
       	 		
      	 		//Set Attribute info to RootElement
      	 		Attr attr = docOut.createAttribute("xmlns:ns0");
      	 		attr.setValue("http://Test-01");
      	 		rootElmnt.setAttributeNode(attr);
      	 		
      	 		//Create child Node
       			Element Chld1 = docOut.createElement("Item"); 		   
       			rootElmnt.appendChild(Chld1);	
       			
       			//Create sub child node
       			Element subChld1 = docOut.createElement("FileName"); 		   
       			Chld1.appendChild(subChld1);
       		    Node nd1 = docOut.createTextNode(FileName);
       		    subChld1.appendChild(nd1);
       			
       			Element subChld2 = docOut.createElement("FileContent"); 		   
       			Chld1.appendChild(subChld2);  			
       			CDATASection cdataFCS = docOut.createCDATASection(FileContent); 			
       			subChld2.appendChild(cdataFCS); 
       			
       			Element subChld3 = docOut.createElement("Error"); 		   
       			Chld1.appendChild(subChld3);
       		    Node nd3 = docOut.createTextNode(ErrorStr);
       		    subChld3.appendChild(nd3); 	
       			//----End  : Create output XML Document -------------------
       			
       		    trace.addInfo("Message: " + ErrorStr);
       			
      			//Transform Output Document
       			trace.addInfo("Transforming results to output xml payload");
      			TransformerFactory tf = TransformerFactory.newInstance();
      			Transformer transform = tf.newTransformer();
      			transform.transform(new DOMSource(docOut), new StreamResult(out));
      
      		} catch (Exception e) {			
      			trace.addInfo(e.getMessage());
      		}		
      	}	
      	
      	private void getFolderPath() throws IOException, ParserConfigurationException, SAXException {
      		/*
      		This function helps to get folder path details from resource 'FolderPath_details.xml'
      		Jar file of this map will include resource file 'FolderPath_details.xml'	
      		*/
      				
      		//Get reference of ResourceFile 'FolderPath_details.xml'
      		InputStream is_ShpCrd = getClass().getResourceAsStream("FolderPath_details.xml");	
      		
      		//Parse input to create document tree
      		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
       		DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder(); 		   
      		Document xmlDoc_ShpCrd = dbBuilder.parse(is_ShpCrd);	
      	        
      		//Read XmlElement tag to fetch SharePoint_Credentials		
      		NodeList ndList_1 = xmlDoc_ShpCrd.getElementsByTagName("Path");
      		for(int i1 = 0; i1 < ndList_1.getLength(); i1++){
      			Node nd_1 = ndList_1.item(i1);
      			for(Node nd_2 = nd_1.getFirstChild(); nd_2 != null; nd_2 = nd_2.getNextSibling()){
      				if(nd_2.getNodeName().equals("SourcePath")){
      					SourcePath  = nd_2.getFirstChild().getNodeValue();					
      				}
      				if(nd_2.getNodeName().equals("ArchivalPath")){
      					ArchivalPath  = nd_2.getFirstChild().getNodeValue();
      				}
      			}						
      		}			
      	}
      	
      	private String getFileNameKey() throws IOException {
      		/*
      		This function helps to get FileName starting Key word
      		using DynamicConfiguration variable which is set from SoapRequestPayload 
      		*/
      	
      		String FileNameKey = "";
      		try{ 		
      			DynamicConfiguration conf = (DynamicConfiguration)param.get("DynamicConfiguration");
      			DynamicConfigurationKey key = DynamicConfigurationKey.create("http://sap.com/xi/XI/System/SOAP", "FileName_StartKey");
      			if(conf != null){
      				FileNameKey = conf.get(key);
      	 		}
      	 	}catch(Exception e) {
      	 		trace.addInfo(e.getMessage());
      	 	} 		
      		return FileNameKey;
      	}
      
      	
      	private String getFileContent(String filePath) throws IOException {
      		/* 
      		 * This Function read file content into String
      		 * 		
      		*/
      		FileInputStream fin = new FileInputStream(new File(filePath));
      		java.util.Scanner scanner = new java.util.Scanner(fin,"UTF-8").useDelimiter("\\A");
      		String theString = scanner.hasNext() ? scanner.next() : "";
      		scanner.close();
      		return theString; 	
      	
          }
      	
      	/*
      	public static void main(String[] args) {
      		try{
      			Example_01 myClass = new Example_01();
      			FileInputStream in = new FileInputStream("C:/Request_Input_2.xml");
      			FileOutputStream out = new FileOutputStream("C:/Output.xml");
      			myClass.execute(in, out);
      		}catch (Exception e){
      			e.printStackTrace();
      		}		
      	}
      	*/
      	
      	
      }
      
  5. Create Jar File of Java Map
    • right Click on Project fodler ‘JavaMap_Example-01’ -> Export -> Java -> JAR File -> Click Next -> give Jar name -> select resource -> Finish
  6. Import JavaMap Jar file to SAP -PI as a ‘Imported Archive’

Assigned Tags

      14 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Apu Das
      Apu Das

      Hi,

      Which adapter you have used in the receiver end?

      Thanks,

      Apu

       

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Apu,

      Sorry for delayed response...

      At receiver end we have used File-Adapter, that will create a File with fix name in to SAP-Directory, which will be overwritten for each processing. The purpose of this File-Receiver is to complete the scenario only.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Dilip!

      It sounds a bit unclear. As I could understand you use Synchronous sender interface with file mask in request message and in response message you get the file contents if the file with given mask exists at defined location. Am I right? If so, what is the receiver of your synchronous reguest? And where do you use receiver file adapter?

      Regards, Evgeniy.

      Author's profile photo Apu Das
      Apu Das

      Thanks for your reply.

      How you maintain the paths in the FolderPath_details.xml.

      What will be the path if my NFS directory is - /data/123/

      /data/123/archive/

       

      You can enhance this JAVA mapping further using FTPClient class to pull data content from FTP.

      Thanks,

      Apu

       

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear Apu,

      In FolderPath_details.xml, paths will be maintained as:

      • SorucePath     /folder-sap/folder-2/
      • ArchivalPath   /folder-sap/folder-2/Archive/

      And thanks for your suggestions about FTPClient, will try for sure in next requirement.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Apu Das
      Apu Das

      Hi Dilip,

      I am still not sure about the path is required to maintain. What is /folder-sap/?

      Can yoy please tell what will be exact path to maintain ?

       

      Thanks,

      Apu

       

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear Apu,

      Please do no get confused with '/folder-sap/' its only for example purpose. Let me explain in this manner:

      • Suppose SAP-ECC has one path location in t-code 'Al11' as '/folder1/sub-folder1/''
      • And from SAP-PI this path can be accessed, respective required accessibility settings of SAP-Ecc directories in SAP-PI can be done with help of basis team

      In this case, in Java Map scenario:

      • 1st source path where file resides, is like '/folder1/sub-folder1/', JavaMap reads files from here
      • For archival, JavaMap refers 2nd path as '/folder1/sub-folder1/Archive/'

      Please note:

      • Above are only examples of path names, it can be any location of SAP-Ecc directory from where file is to be read.
      • Its same as of path location in File-Adapter channels, but as a prefix and post-fix add '/'

       

      Thanks & Regards,

      Dilip

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Dilip!

      And when the path is changed by any case, we should make changes in resource file and import/transport that new jar between all PI systems involved?

      Regards, Evgeniy.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear  Evgeniy Kolmakov,

      • When the path is changed by any case, there is no need to re-import jar file again.
      • We can edit resource file in "Imported Archive" of PI itself and save it, this is advantage of having resource file in jar file.
      • And about transport to all PI system, yes, we have to make a new TPZ file which includes that "Imported Archive" having java map files.
      • Please refer below scree for more clarity

       

       

      Thanks & Regards,

      Dilip

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Dilip!

      Thanks for the answer. And why not to use Operation mapping parameters instead? It can be changed on the fly.

      Regards, Evgeniy.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear  Evgeniy Kolmakov,

      I have to check, how I can use Operation mapping parameters in this case.

      Thanks for the hint.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Dilip!

      This is very simple step: just define respective parameters in Operation mapping and assign it to your java mapping. In java mapping just read it.

      Regards, Evgeniy.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Sure, will try it. Thanks for new info.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear Evgeniy Kolmakov,

      Let me put this scenario in below manner for more clarity:

      • Its a SAP-PI web-service to File Inbound Synchronous Scenario
      • Receiver-Channel is File Adapter, its only job is to create a file with FixName with overWritten property.
      • Sender-Channel is SOAP Adapter.
      • Scenarios is synchronous web-service having SOAP-Request and SOAP-Response message structures.
      • In Soap-Request, we get FileName starting key word.
      • Using DynamicConfiguration, we capture 'FileName-Starting-Key', in Request-Message-Mapping'
      • In Java-Map, we get FileName-Starting-Key from DynamicConfig-Variable
      • In Java-Map, we read filePath details from resource xml file included with in jar
      • And In JavaMap itself, we perform below tasks:
        • Read folder files starting with FileNameKey and check .CSV extension
        • and if file found, the read its content and enclose it in Soap-Response-Message format
        • Post content-reading, archive original file to other directory

       

      Hope above helps...

       

      Thanks & Regards,

      Dilip