cancel
Showing results for 
Search instead for 
Did you mean: 

help with java mapping

sahana_ps
Participant
0 Kudos

PI File adapter has a processing option u2018Empty-Message Handlingu2019 to ignore or Write Empty Files. In case there is no data created after mapping on target side then this option determines whether to write an empty file or not. But there is a catch to this option when it comes to using it with File Content Conversion which is described in SAP Note u2018821267u2019. It states following:

I configure the receiver channel with File content conversion mode and I set the 'Empty Message Handling' option to ignore. Input payload to the receiver channel is generated out of mapping and it does not have any record sets. However, this payload has a root element. Why does file receiver create empty output file with zero byte size in the target directory? Example of such a payload generated from mapping is as follows:

<?xml version="1.0" encoding="UTF-8"?>

<ns1:test xmlns:ns1="http://abcd.com/ab"></ns1:test>

solution :

If the message payload is empty (i.e., zero bytes in size), then File adapter's empty message handling feature does NOT write files into the target directory. On the other hand, if the payload is a valid XML document (as shown in example) that is generated from mapping with just a root element in it, the File Adapter does not treat it as an empty message and accordingly it writes to the target directory. To achieve your objective of not writing files (that have just a single root element) into the target directory, following could be done:

Using a Java or ABAP Mapping in order to restrict the creation of node itself during mapping. (This cannot be achieved via Message Mapping)

Using standard adapter modules to do content conversion first and then write file.

can someone help with java mapping that can be used in this case?

Accepted Solutions (1)

Accepted Solutions (1)

PriyankaAnagani
Active Contributor
0 Kudos

Hi,

>>>> if the payload is a valid XML document (as shown in example) that is generated from mapping with just a root element in it, the File Adapter does not treat it as an empty message and accordingly it writes to the target directory

In your message mapping itself check if there is no source payload then do not create the root element i.e. <ns1:test>. If the payload exists then only create root.

>> to restrict the creation of node itself during mapping. (This cannot be achieved via Message Mapping) 

If you're trying to restrict the creation of root node (If I'm not wrong) , you can restrict the creation of target messagetype in the messagemeppiang only by changing its minimum occurrence to zero.

Regards,

Priyanka

Answers (2)

Answers (2)

anupam_ghosh2
Active Contributor
0 Kudos

Hi,

You have not mentioned the version of PI you are working in. In case you are working with PI 7.1 or above then here is the java mapping code you need to add after message mapping in the same interface mapping


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 com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;


public class RemoveRootNode extends AbstractTransformation{
	
	public void execute(InputStream in, OutputStream out)
	throws StreamTransformationException {
// TODO Auto-generated method stub
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();
	if(docIn.getDocumentElement().hasChildNodes())
	{
		docOut.appendChild(docOut.importNode(docIn.getDocumentElement(),true));
		transform.transform(new DOMSource(docOut), new StreamResult(out));
	}
	else
	{
		
		out.write(null);
	}
}
catch(Exception e)
{
}	

}

public void setParameter(Map arg0) {
// TODO Auto-generated method stub

}
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
	RemoveRootNode genFormat=new RemoveRootNode();
	FileInputStream in=new FileInputStream("C:\\apps\\sdn\\rootNode.xml");
	FileOutputStream out=new FileOutputStream("C:\\apps\\sdn\\rootNode1.xml");
	genFormat.execute(in,out);
	}
	catch(Exception e)
	{
	e.printStackTrace();
	}
}

public void transform(TransformationInput arg0, TransformationOutput arg1)
		throws StreamTransformationException {
	// TODO Auto-generated method stub
	this.execute(arg0.getInputPayload().getInputStream(), arg1.getOutputPayload().getOutputStream());
	
}

}

In case you are working in PI 7.0 you can use this code


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 com.sap.aii.mapping.api.StreamTransformation;
import com.sap.aii.mapping.api.StreamTransformationException;


public class RemoveRootNode implements StreamTransformation{
	
	public void execute(InputStream in, OutputStream out)
	throws StreamTransformationException {
// TODO Auto-generated method stub
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();
	if(docIn.getDocumentElement().hasChildNodes())
	{
		docOut.appendChild(docOut.importNode(docIn.getDocumentElement(),true));
		transform.transform(new DOMSource(docOut), new StreamResult(out));
	}
	else
	{
		out.write(null);
	}
}
catch(Exception e)
{
}	

}

public void setParameter(Map arg0) {
// TODO Auto-generated method stub

}
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
	RemoveRootNode genFormat=new RemoveRootNode();
	FileInputStream in=new FileInputStream("C:\\apps\\sdn\\rootNode.xml");
	FileOutputStream out=new FileOutputStream("C:\\apps\\sdn\\rootNode1.xml");
	genFormat.execute(in,out);
	}
	catch(Exception e)
	{
	e.printStackTrace();
	}
}

}

The code for PI 7.0 should also work for PI 7.1 provided you use the right jar files for compilation, but vice-versa is not true.

Could you please let us know if this code was useful to you or not?

Regards

Anupam

Edited by: anupamsap on Dec 15, 2011 9:43 AM

Former Member
0 Kudos

Hi,

What is root element of your source message?

Regards

Ramesh

Former Member
0 Kudos

Hi,

The note already says it is not possible to achieve via Message Mapping

My suggestion:

1. Create a Java Mapping

Logic for your java mapping would be, search for root element,
if found generate XML as source message only
if root element is not found then return empty output 

2. Then create your normal mapping (message mapping)

In this case, you will have to maintain multi level mapping for the same source and target message types

Regards

Ramesh