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_member181985
Active Contributor

In this doucment, I will show how we can zip the incoming attachments and create a new zip attachment during mapping step. We can also remove the original incoming attachments if they are not required. The concept is applicable from PI7.1 version onwards.

Create a java mapping with below code and use it as first mapping in your operation mapping step.


Java Mapping Code


  import java.io.*;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
import java.util.zip.*;
import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.*;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
// import com.sap.aii.mapping.api.StreamTransformation;
// import com.sap.aii.mapping.api.StreamTransformationConstants;
import com.sap.aii.mapping.api.StreamTransformationException;
public class AttachmentsZipJM extends AbstractTransformation {
              private static final DynamicConfigurationKey contentIDSKey = DynamicConfigurationKey.create("http://test.com", "contentIDS");
        public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException
                        {
                                    try
                                    {
                                                DynamicConfiguration conf = (DynamicConfiguration) in.getDynamicConfiguration();
                                                // get message ID
                                                String msgID = (String) in.getInputHeader().getMessageId();
                                                String s = null;
                                                int len = 0;
                                                Object[] arrayObj = null;
                                                byte[] buffer = new byte[1024];
                                                byte[] attachmentBuffer = new byte[1024];
                                                String attachmentID = null;
                                                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                                ZipOutputStream zos = new ZipOutputStream(baos);
                                                ZipEntry anEntry = null;
                                                InputStream is = (InputStream) in.getInputPayload().getInputStream();
                                                while ((len = is.read(buffer)) > 0)
                                                {
                                                            out.getOutputPayload().getOutputStream().write(buffer, 0, len);                                                  
                                                }
                                                InputAttachments inputAttachments = in.getInputAttachments();
                                                if(inputAttachments.areAttachmentsAvailable())
                                                {                                                          
                                                            //gets the attachmentIds and store it in an Object array
                                                            Collection<String> collectionIDs = inputAttachments.getAllContentIds(true);
                                                            arrayObj = collectionIDs.toArray();
                                                            //Object[] arrayObj = collectionIDs.toArray();
                                                            String contentIDS = "";
                                                            //Loops at the input attachments to get the content of the attachment and then write it to zip output stream wrapper.
                                                            for(int i =0;i<arrayObj.length;i++)
                                                            {
                                                                        attachmentID =(String)arrayObj[i];
                                                                        contentIDS = contentIDS + (i+1) + ") " + attachmentID + "; ";
                                                                        Attachment attachment = inputAttachments.getAttachment(attachmentID);            
                                                                        byte[] attachmentBytes = attachment.getContent();
                                                                        zos.putNextEntry(new ZipEntry(attachmentID));
                                                                        zos.write(attachmentBytes);
                                                                        zos.closeEntry();           //Close each zipentry after writing it to stream
                                                                        //remove each attachment if required. Uncommonent below line
                                                                        //out.getOutputAttachments().removeAttachment(attachmentID);                                                 
                                                            }
                                                            zos.close();       //Close Zip Stream
                                                            conf.put(contentIDSKey, contentIDS);
                                                }
                                                Attachment newopAttachment = out.getOutputAttachments().create(msgID + ".zip", baos.toByteArray());
                                                out.getOutputAttachments().setAttachment(newopAttachment);
                                    }
                                    catch(Exception e)
                                    {
                                                e.printStackTrace();
                                    }
        }
}

The same can be achieved in graphical mapping using below code. Use the UDF in between source and target root nodes. Ensure to explicitly mention java.util.zip.* package under import statements of UDF function.



Graphical Mapping UDF Code


String attachmentID = null;
String msgID = null;
String contentIDS = "";
java.util.Map map;
AbstractTrace trace;
//gets the input attachment from the source message
GlobalContainer globalContainer = container.getGlobalContainer();
InputAttachments inputAttachments = globalContainer.getInputAttachments();
OutputAttachments outputAttachments = globalContainer.getOutputAttachments();
trace = container.getTrace();
map = globalContainer.getParameters();
msgID = (String) map.get(StreamTransformationConstants.MESSAGE_ID);
trace.addInfo("Message ID:" + msgID);
DynamicConfiguration conf = (DynamicConfiguration) map.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
DynamicConfigurationKey contentIDSKey = DynamicConfigurationKey.create("http://test.com", "contentIDS");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
try
{
            //checks for the availability of attachments in the input message
            if(inputAttachments.areAttachmentsAvailable())
            {
                        trace.addInfo("Attachments Available");
                        //gets the attachmentIds and store it in an Object array
                        Collection<String> CollectionIDs = inputAttachments.getAllContentIds(true);
                        Object[] arrayObj = CollectionIDs.toArray();
                        //Loops at the input attachments to get the content of the attachment
                        for(int i =0;i<arrayObj.length;i++)
                        {
                                    attachmentID =(String)arrayObj[i];
                                    contentIDS = contentIDS + (i+1) + ") " + attachmentID + "; ";
                                    trace.addInfo("Attachment no: " + (i+1) + " & Name: " + attachmentID);
                                    Attachment attachment = inputAttachments.getAttachment(attachmentID);
                                    byte[] attachmentBytes = attachment.getContent();
                                    trace.addInfo("Creating Zip Entry for attachmet no: " + (i+1));
                                    zos.putNextEntry(new ZipEntry(attachmentID));
                                    zos.write(attachmentBytes);
                                    zos.closeEntry();           //Close each zipentry after writing it to stream
                                    //remove each attachment if required. Uncommonent below
                                    //trace.addInfo("Removing Attachment no: " + (i+1) + " & Name: " + attachmentID);
                                    //outputAttachments.removeAttachment(attachmentID);                                                              
                        }
                        zos.close();
                        conf.put(contentIDSKey, contentIDS);
                        trace.addInfo("Creating new Zip Attachment: " + msgID + ".zip");
                        Attachment newopAttachment = outputAttachments.create(msgID + ".zip", baos.toByteArray());
                        outputAttachments.setAttachment(newopAttachment);
            }          
}
catch (Exception e)
{
            e.printStackTrace();
}
return    var1; //return “1”;

I tested a sample SOAP to Mail scenario with above code and the results are as below.


In RWB for mail receiver adapter,


The zipping/unzipping of attachments can also be achieved at adapter level using PayloadZipBean module.

5 Comments
Labels in this area