Skip to Content
Author's profile photo Arpil Gupta

Merge multiple files without BPM

BpmPatternCollectMultiIf is classical BPM pattern used for n:1 scenario. A classic scenario is to pick multiple files(different format): merge and send single output to receiver. Obviously given its issues one will go for BPM only when no better option seems feasible. I am sure many would have come across same requirement and BPM seems to be the only Option.

In this blog I am discussing an approach with which BPM can be avoided.

btw I myself am guilty of creating BPM for similar requirement… picking 2 files(same folder), merging and posting IDOC to receiver. I now ask myself Why didn’t I consider this approach back then!!! 😛

Requirement:

  • Read 2 files(XML/Text) from folder and merge and post data receiver.

Note: No message based correlation here. Just pick existing files and process.

Approach:

1) Read 2 Files using File sender adapter. One as MainPayload another as ApplicationAttachment

– Check Additional Files(s) and provide file name pattern

– Read 2nd file as mandatory(unless both files are available files will not be picked)

AttachmentFile1.optional NO

FileAdapter_AdditionalFiles.png


Note: FCC cannot be used for both files. In such case one can use MessageTransformBean and PayloadSwapBean in Sender channel.


2) Create mapping to merge Main payload and Attachment(s)

– Do Check Read Attachments in Operation mapping

OperationMapping_ReadAttachments.png

This is how we can merge the two:- MainDocument and ApplicationAttachment.

File1(Main Document) File2(Attachment)

Result Structure

(After Java mapping)

<?xml version=”1.0″ encoding=”UTF-8″?>

<ns0:MT_Sender xmlns:ns0=”http://AttachmentTest“>

   <MainDoc>

      <Row>

         <StudentID>190</StudentID>

         <StudentName>Lorum</StudentName>

         <StudentStream>MS</StudentStream>

      </Row>

      <Row>

         <StudentID>191</StudentID>

         <StudentName>Ipsum</StudentName>

         <StudentStream>B.Tech</StudentStream>

      </Row>

   </MainDoc>

</ns0:MT_Sender>

<?xml version=”1.0″ encoding=”UTF-8″?>

<ns0:MT_Attachment xmlns:ns0=”http://AttachmentTest“>

   <Attachment1>

      <Row>

         <StudentID>190</StudentID>

         <CourseData>

</CourseData>

      </Row>

      <Row>

         <StudentID>192</StudentID>

         <CourseData>

</CourseData>

      </Row>

   </Attachment1>

</ns0:MT_Attachment>

<?xml version=”1.0″ encoding=”UTF-8″?>

<ns0:MT_Intermediate xmlns:ns0=”http://AttachmentTest/“>

   <MainDoc>

      <Row>

         <StudentID>190</StudentID>

         <StudentName>Lorum</StudentName>

         <StudentStream>MS</StudentStream>

      </Row>

      <Row>

         <StudentID>191</StudentID>

         <StudentName>Ipsum</StudentName>

         <StudentStream>B.Tech</StudentStream>

      </Row>

   </MainDoc>

   <Attachment1>

      <Row>

         <StudentID>190</StudentID>

         <CourseData>

</CourseData>

      </Row>

      <Row>

         <StudentID>192</StudentID>

         <CourseData>

</CourseData>

      </Row>

   </Attachment1>

</ns0:MT_Sender>

Sample Java Mapping Code


package com.sap.JavaMapping;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import com.sap.aii.mapping.api.*;
public class MergeAttachment extends AbstractTransformation{
  public void transform(TransformationInput in, TransformationOutput out)  throws StreamTransformationException
  {
  InputAttachments inputAttachments = in.getInputAttachments();
  InputStream inputstream = in.getInputPayload().getInputStream();
  OutputStream outputstream = out.getOutputPayload().getOutputStream();
  try {
  DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
  DocumentBuilder dbuilder = dbfactory.newDocumentBuilder();
  Document mainDoc = dbuilder.parse(inputstream);
  if(inputAttachments!=null)
  {
  if(inputAttachments.areAttachmentsAvailable())
  {
  Collection<String> collectionIDs  = inputAttachments.getAllContentIds(true);
  Object[] arrayObj  =collectionIDs.toArray();
  for(int i=0;i<arrayObj.length;i++)
  {
  String attachmentID = (String) arrayObj[i];
  Attachment attachment =inputAttachments.getAttachment(attachmentID);
  InputStream attachmentInputStream = new ByteArrayInputStream(attachment.getContent());
  Document attachmentDoc = dbuilder.parse(attachmentInputStream);
  Element element = (Element) attachmentDoc.getElementsByTagName("Attachment1").item(0);
  Node copiedNode = mainDoc.importNode(element, true);
  mainDoc.getDocumentElement().appendChild(copiedNode);
  }
  }
  }
  TransformerFactory tf = TransformerFactory.newInstance();
  Transformer transformer  = tf.newTransformer();
  transformer.transform(new DOMSource(mainDoc), new StreamResult(outputstream));
  } catch (ParserConfigurationException e) {
  this.getTrace().addInfo("ParserConfigurationException caught");
  e.printStackTrace();
  } catch (SAXException e) {
  this.getTrace().addInfo("SAXException caught");
  e.printStackTrace();
  } catch (IOException e) {
  this.getTrace().addInfo("IOException caught");
  e.printStackTrace();
  } catch (TransformerException e) {
  this.getTrace().addInfo("TransformerException caught");
  e.printStackTrace();
  }
  }
}









This code reads 2 xml document and merge attachment recordset below.

Please note following things:

– Read additional files option is only available for NFS not for FTP.

– Also in case Business system/location are different for sender file cannot be read as attachment.

Though using separate interface files can be brought to a common location and then this approach can be followed.

Let me know if this blog helps you.

This approach is also discussed in Praveen Gujjeti’s blog N:1 & N:M mappings not possible without BPM

Assigned Tags

      9 Comments
      Comments are closed.
      Author's profile photo Praveen Gujjeti
      Praveen Gujjeti

      Hi Arpil,

      Well, theoretically I have covered this concept around 2 years back: N:1 & N:M mappings not possible without BPM... Any more !!!!!!!!!!

      Anyway, yours should help practically for the SCN community

      Good job 🙂

      Cheers,

      Praveen Gujjeti

      Author's profile photo Arpil Gupta
      Arpil Gupta
      Blog Post Author

      Thanks Praveen,

      I have also added your blog as reference.

      🙂

      -Arpil

      Author's profile photo Former Member
      Former Member

      NIce Blog Arpil...

         

      Ravi Raika 🙂

      Author's profile photo Former Member
      Former Member

      Hi Arpil,

      I have a similar scenario where i have to merge 2 txt files, can u help with the approach and java code for the same.

      Author's profile photo Arpil Gupta
      Arpil Gupta
      Blog Post Author

      Hi Viritha,

      Can you pl explain where exactly you are stuck. I think I have clearly covered the approach.

      Regards

      Arpil

      Author's profile photo Former Member
      Former Member

      Hi Arpil,

      1.The above approach is for merging 2 xml files.I want the code to merge 2 txt files without converting them to xml.

      2.And also can u provide the jar file for the above java code to merge 2 xml files, im getting below error if i use above code and created jar file for the same:

      "Mapping failed in runtimeLinkage Error when loading class"

      Author's profile photo Arpil Gupta
      Arpil Gupta
      Blog Post Author

      I have mentioned in blog:

      Note: FCC cannot be used for both files. In such case one can use MessageTransformBean and PayloadSwapBean in Sender channel.


      So you need to do content conversion in sender channel, then proceed with Java mapping to merge: mainPayload and Attachment(s).


      Also blog has sample code. It may/may not  work for your requirement and PI version.

      Author's profile photo kalyan golla
      kalyan golla

      Hi Arpil,

      Thanks for your blog. Regarding the FCC, should both the files use content conversion from Module config along with PayloadSwapBean or is it that only the attachment file should be configured in Moulde config and the main payload in the standard FCC?

      Regards

      Kalyan.

      Author's profile photo Former Member
      Former Member

      Hello Arpil,

      Can you please let me know if it is possible to pick up files from two different systems instead of two different directories without BPM?

      Regards,

      Ninu