Skip to Content

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’
To report this post you need to login first.

14 Comments

You must be Logged on to comment or reply to a post.

  1. Dilip Kumar KrishnaDev Pandey 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

    (0) 
    1. 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.

      (0) 
    2. 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

       

      (0) 
      1. Dilip Kumar KrishnaDev Pandey 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

        (0) 
        1. 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

           

          (0) 
          1. Dilip Kumar KrishnaDev Pandey 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

            (0) 
            1. 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.

              (0) 
              1. Dilip Kumar KrishnaDev Pandey 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

                (0) 
                    1. 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.

                      (0) 
  2. Dilip Kumar KrishnaDev Pandey 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

    (0) 

Leave a Reply