Skip to Content

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

To report this post you need to login first.

9 Comments

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

      1. viritha vanama

        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”

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

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

            (0) 
  1. Ninu Sankar

    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

    (0) 

Comments are closed.