A few days ago I answered this interesting question by Florian Kube in the Questions & Answers area. It struck me that the solution might be of more general interest, so in this blog I’m going to expand a bit on my answer.

Florian’s scenario is this: He picks up an email with a sender Mail channel. The email has an XML attachment, and it is the contents of this attachment, he wants to process. He therefore needs to replace the message body with the attached XML document, and then proceed with mapping and so forth.

I’m going to show you how to solve this problem using scripting. The code is written in Groovy, but if your prefer JavaScript, translating it is straightforward.

Methods of the Message class

Access to the body and attachments of a message is provided by the com.sap.gateway.ip.core.customdev.util.Message object, which the runtime passes to your Groovy function. There is no API documentation available for this class, but most of its methods are listed in the HCI Developer’s Guide.

The two methods, we are going to use, are getAttachments and setBody. The former returns a java.util.Map object containing the message’s attachments, and the latter sets a new message body.

Extracting the attachment contents

Let us deal with the attachment first, since that is the more complicated part. The keys of the Map returned by getAttachments are attachment names, and the values are javax.activation.DataHandler objects. The DataHandler objects contain the actual attachment data. Given the scenario, we assume that the Map contains exactly one attachment, but we do not know its key ahead of time.

In order to get the Map’s only value without knowing its associated key, I retrieve the Collection of all the Map’s values and iterate it once. The code looks like this (required import statements not shown):

Map<String, DataHandler> attachments = message.getAttachments()
Iterator<DataHandler> it = attachments.values().iterator()
DataHandler attachment = it.next()

(You could combine the three lines into a single line, if you are so inclined, but that would make the intention of the code less clear, IMHO.)

Setting the message body

The DataHandler class offers a couple of different ways to get at the wrapped data. We are going to use the getContent method, which returns a java.lang.Object object. Why? Because an Object instance is what the setBody method of the Message class expects. Here is the code that replaces the message body:

message.setBody(attachment.getContent())

Putting the pieces together

We are now ready to put it all together. Here is the complete script:

import com.sap.gateway.ip.core.customdev.util.Message
import java.util.Map
import java.util.Iterator
import javax.activation.DataHandler

def Message processData(Message message) {
   Map<String, DataHandler> attachments = message.getAttachments()
   Iterator<DataHandler> it = attachments.values().iterator()
   DataHandler attachment = it.next()
   message.setBody(attachment.getContent())
   return message
}

In order to use it, put the code in a Script step at the very beginning of your integration flow. After this step, proceed with whatever processing your scenario requires.

How to handle messages with no attachments

Keep in mind that the script assumes that the message has exactly one attachment. If it does not have any attachments, the code will fail. Determining why it fails, is left as an exercise for the reader 🙂

If this assumption is not always met in your particular scenario, you can test for the presence of attachments, by checking whether the Map returned by getAttachments is empty. You do this by calling its isEmpty method as follows:

import com.sap.gateway.ip.core.customdev.util.Message
import java.util.Map
import java.util.Iterator
import javax.activation.DataHandler

def Message processData(Message message) {
   Map<String, DataHandler> attachments = message.getAttachments()
   if (attachments.isEmpty()) {
      // Handling of missing attachment goes here
   } else {
      Iterator<DataHandler> it = attachments.values().iterator()
      DataHandler attachment = it.next()
      message.setBody(attachment.getContent())
   }
   return message
}
To report this post you need to login first.

Be the first to leave a comment

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

Leave a Reply