Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

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!!! :razz:

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.optionalNO


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

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 blog N:1 & N:M mappings not possible without BPM

9 Comments
Labels in this area