You are on page 1of 17

Step by step guide to develop a

module for reading file name in a


sender file adapter

SDN Community Contribution


(This is not an official SAP document.)

Disclaimer & Liability Notice

This document may discuss sample coding or other information that does not include SAP
official interfaces and therefore is not supported by SAP. Changes made based on this
information are not supported and can be overwritten during an upgrade.
SAP will not be held liable for any damages caused by using or misusing the information,
code or methods suggested in this document, and anyone using these methods does so at
his/her own risk.
SAP offers no guarantees and assumes no responsibility or liability of any type with respect
to the content of this technical article or code sample, including any liability resulting from
incompatibility between the content within this document and the materials and services
offered by SAP. You agree that you will not hold, or seek to hold, SAP responsible or liable
with respect to the content of this document.
Step by step guide to develop a module
for reading file name in a sender file
adapter

Applies To:

SAP NW 04 XI 3.0

Article Summary
This is a step by step guide for developing, deploying and configuring a module exit to read
the file name in a sender file adapter. This module will get the file name and add it as an
element to the XML Payload

By: Krishnakumar Ramamoorthy (KK) Deloitte Consulting


Title: Product Management
Date: 05 May 2005

Table of Content

Step by step guide to develop a module for reading file name in a sender file adapter ........... 2
Applies To: ................................................................................................................................ 2
Article Summary........................................................................................................................ 2
Table of Content........................................................................................................................ 2
Introduction ............................................................................................................................... 3
Prerequisites ............................................................................................................................. 3
Step by Step procedure ............................................................................................................ 3
Copy the required JAR files from XI Server .............................................................................. 3
Set up class path variables in NW Developer Studio ............................................................... 4
Create an EJB module project .................................................................................................. 4
Create an EJB module bean..................................................................................................... 5
Implement the bean .................................................................................................................. 7
Edit the bean deployment descriptors ejb-jar.xml.................................................................. 9
Create bean archive................................................................................................................ 10
Create Enterprise application project...................................................................................... 10
Create references in the Enterprise Application Project ......................................................... 11
Build Application archive and deploy ...................................................................................... 12
Appendix ................................................................................................................................. 13
Disclaimer & Liability Notice.................................................................................................... 17
Introduction

An integration scenario involving a sender file adapter, it may be necessary to know the
name of the file which was processed. This is particularly true when the files are picked up
using * and the file name is to be used in the condition editor for receiver determination.

This can be accomplished by developing a module processor exit bean. Please read SAP
Help documentation for more information on Module Processor and extending the module
chain.

Prerequisites

SAP XI 3.0 SP 9 or above


SAP Netweaver Developer Studio
JDK 1.4
Step by Step procedure
Copy the required JAR files from XI Server

The following JAR files are required to develop the module. The jar files need to be externally
referenced in the application. Copy these jars files from the provided location in the XI server,
to you local system.

Jar Name Location


aii_af_ms_spi.jar <serverDir>*\bin\ext\com.sap.aii.af.lib\
aii_af_cci.jar
aii_af_ms_api.jar
aii_af_trace.jar
aii_af_mp.jar
aii_utilxi_misc.jar <serverDir>*\bin\ext\com.sap.xi.util.misc\
aii_adapter_xi_svc.jar <serverDir>*\bin\services\ com.sap.aii.adapter.xi.svc\
aii_af_cpa.jar <serverDir>*\bin\services\ com.sap.aii.af.cpa.svc\
aii_af_svc.jar <serverDir>*\bin\services\ com.sap.aii.af.svc\
aii_util_xml.jar <serverDir>*\bin\ext\com.sap.xi.util.xml\
ejb20.jar \usr\sap\J2E\JC00\j2ee\j2eeclient
exception.jar

<serverDir> -> If XI has been installed on Windows under drive D, then server directory will
look like : d:\usr\sap\<SID>\<INSTANCE>\j2ee\cluster\server0\.
<SID> -> System ID, <INSTANCE> -> J2EE Instance.
Example: d:\usr\sap\XI3\DVEBMGS00\j2ee\cluster\server0\

While saving the jar files in the local system (for e.g. c:\jarfiles), suggestion is to follow the
below pattern

C:\jarfiles\com.sap.aii.af.lib\aii_af_ms_spi.jar
C:\jarfiles\com.sap.xi.util.misc\aii_utilxi_misc.jar
Set up class path variables in NW Developer Studio

We need to set up a class path variable for referencing these .jar files in our application.
Open up NW Dev Studio and follow the below steps

Choose menu Window->Preferences.


In the popup window, choose Java->Classpath Variables.

Add a new variable by clicking


Provide an arbitrary name in the Name field. For e.g. SAP_USER_ADD_LIBS. (If the
variable is already available, edit the same)
In the Path field, choose the folder where you have stored all the jar files from step 1. Use
the button to choose the folder.
Confirm your entries by clicking OK.
Create an EJB module project

The module we are going to develop is an EJB. Hence, in the NW Dev Studio, we need to
create an EJB module project first.

Choose File->New->Project. In the popup screen, choose J2EE. From the right frame,
choose, EJB Module Project.

Click .
Provide a project name. In our example, we will say SampleFileAdatperModule. Leave the
Check box Use Default checked. This will place all your developments in the default
workspace.
Click to confirm your entries.
This will create the project as shown below

Now we have to set up reference to the jar files in our project. To do this, choose the J2EE
Explorer view in your left frame if not already chosen and then select the project, right click
and choose Properties

In the popup window, choose Java build path. On the right frame, choose tab libraries.

Click on button

In the next window, choose SAP_USER_ADD_LIBS and click . Please note that
this is the variable we created in the previous steps.
Select the required jar files and click confirm all by clicking OK. This will create the build
paths. Make sure that all the jar files are included this way.

Create an EJB module bean

We now create the module bean under the EJB module project created above. Follow the
below steps for the same

Choose the folder ejbModule in the J2EE Explorer view and from the context menu (right
click), choose New->EJB.
In the next screen, provide the following information
EJB Name -> A name for your bean. For example: GetFileName
EJB Project -> SampleFileAdatperModule
Bean Type -> Stateless Session Bean
Default EJB Package -> Some arbitrary package name. For e.g. com.kk.FileModule.
Remove the check box generate default interfaces. We do this, because we are going to
have only a local interface for this bean.
Click Next

In the next screen, remove the check box on Remote Interfaces and click Next.

Click to confirm your entries.


Now, in the J2EE explorer, expand the folder ejb Module ->com->KK->FileModule. You will
find a file named GetFileNameBean.java. This is where we are going to code our main
module.
Please refer SAP Help documentation and API documentation from the samples
provided under Adapter development.

Implement the bean

Below is provided, the code snippet for implementing the bean. The full code is provided in
the appendix.

First, we need to import the referenced classes.

// Classes for EJB


import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

// Classes for Module development & Trace


import com.sap.aii.af.mp.module.Module;
import com.sap.aii.af.mp.module.ModuleContext;
import com.sap.aii.af.mp.module.ModuleData;
import com.sap.aii.af.mp.module.ModuleException;
import com.sap.aii.af.ra.ms.api.Message;
import com.sap.aii.af.service.trace.Trace;
import java.util.Hashtable;
// XML parsing and transformation classes
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import com.sap.aii.af.ra.ms.api.XMLPayload;
import javax.xml.transform.*;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

The bean class MUST implement SessionBean and Module interface.


public class GetFileNameBean implements SessionBean, Module {

Add a business method process(). This method will be called by the Module Processor.
public ModuleData process(ModuleContext moduleContext, ModuleData
inputModuleData) throws ModuleException {

Read the XML payload and message for getting the needed data.

Object obj = null; // Handler to get Principle data


Message msg = null; // Handler to get Message object
String fileName = null; // File Name which is being processed
try {
obj = inputModuleData.getPrincipalData();
msg = (Message) obj;
// Get the Supplemental data which is available as hash table
Hashtable mp = (Hashtable)
inputModuleData.getSupplementalData
("module.parameters");
// Get the file name which is being processed
if (mp != null) fileName = (String) mp.get("FileName");
} catch (Exception e) {

// Throw any exceptions


ModuleException me = new ModuleException(e);
throw me;
}

Now, we have read the file name, we now have to get the XML payload and add this file
name at the appropriate place in the XML. For parsing and adding new element, we use
DOM.

try{
// Get the XML Payload
XMLPayload xmlpayload = msg.getDocument();

DocumentBuilderFactory factory;
factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

// Parse the XML Payload


Document document = builder.parse((InputStream)
xmlpayload.getInputStream());
// Get the XML payload root element
Element rootNode = document.getDocumentElement();
if(rootNode != null){

// Create an element node for with name FileName


Element childElement =
document.createElement("FileName");

// populate the Filename element with the value of the filename obtained from supplement
data
childElement.appendChild
(document.createTextNode(fileName));

// Append the newly created element to the root


rootNode.appendChild(childElement);
}

Now, we have to transform our XML document in DOM stream to Byte stream so that it can
be assigned back to the XML payload.

TransformerFactory tfactory = TransformerFactory.newInstance();


Transformer transformer = tfactory.newTransformer();
Source src = new DOMSource(document); // DOM source is our DOM doc
// Create a new instance of ByteArrayOutputStream
ByteArrayOutputStream myBytes = new ByteArrayOutputStream();
Result dest = new StreamResult(myBytes);

// Transform the DOM source to Stream Result (ByteArrayOutputStream)


transformer.transform(src,dest);

// Get the byte array for the payload


byte[] docContent = myBytes.toByteArray();
if(docContent != null){

// Set the content for xmlpayload and the principal data of ModuleData to be returned.
xmlpayload.setContent(docContent);
inputModuleData.setPrincipalData(msg);
}

You can add additional tracing information for error handling, which out of scope of this
document.

Edit the bean deployment descriptors ejb-jar.xml

From the J2EE Explorer tab, double click on node ejb-jar.xml. On the right side pane, choose
tab source and replace the home, remote, local-home and local nodes as below

<enterprise-beans>
<session>
<ejb-name>GetFileNameBean</ejb-name>
<home>com.sap.aii.af.mp.module.ModuleHome</home>
<remote>com.sap.aii.af.mp.module.ModuleRemote</remote>
<local-home>com.sap.aii.af.mp.module.ModuleLocalHome</local-home>
<local>com.sap.aii.af.mp.module.ModuleLocal</local>
<ejb-class>com.kk.FileModule.GetFileNameBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>

Create bean archive

Now, we have to create an archive (.jar) for our bean. In the J2EE explorer, right click on the
EJB project (KKSampleAdapterModule) and choose option Build Archive

This will add a .jar file to the EJB module project.

Create Enterprise application project

To deploy our bean, we need to create an enterprise application project. Follow the below
steps

Menu File -> New -> Project -> J2EE -> Enterprise Application Project

In the next screen, provide an arbitrary project name. In our example, we will give it a name
com.kk.FileModule.

Click Next and choose EJB Module project as Referenced Projects.


Confirm your entries by clicking Finish

Create references in the Enterprise Application Project

The deployed application need to reference the libraries and services in the deployed J2EE
engine.

In the created enterprise application project, double click on the node application-j2ee-
engine.xml.

On the right hand pane, choose the tab General

Click on the References folder and click Add

In the next popup screen, click on button Create New

Provide the following information

Reference Target :- com.sap.aii.af.lib


Reference Type :- weak
Reference target type :- Library
Provider Name :- sap.com

Repeat the above steps with the below values for other references

Reference Target Reference Reference Provider Name


Type Target type
com.sap.xi.util.misc Weak Library sap,com
com.sap.aii.adapter.xi.svc Weak Service sap.com
com.sap.aii.af.svc Weak Service sap.com
com.sap.aii.af.cpa.svc Weak Service sap.com
com.sap.xi.util.xml Weak Library sap.com

Now you should have six references created as shown


Once done, save the changes

Build Application archive and deploy

Now we have to build an .ear file and deploy the same to the J2EE engine.

Right click on the Enterprise application project. In our example, it is com.kk.FileModule.


Click on Build Application Archive

Once the .ear file has been generated, right click on it and choose Deploy to J2EE Engine.
You may need the SDM password for deploying.

Please note that the application will be deployed to the engine provided under preferences in
your NW Developer Studio. To verify the same, follow the menu path Window -> Preferences
-> SAP J2EE Engine. On the right hand pane, check the entries. You can either provide a
local J2EE engine or a remote host.
Once successfully deployed, you should be able to use this bean in your communication
channel. In the communication channel, the module is referred as localejbs/JNDI Name. In
our case, it will be /sap.com/com.kk.FileModule/GetFileNameBean.

This module should be placed before the module localeejbs/CallSAPAdapter in the sender
file communication channel.

Appendix
package com.kk.FileModule;
// Classes for EJB
import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

// Classes for Module development & Trace


import com.sap.aii.af.mp.module.Module;
import com.sap.aii.af.mp.module.ModuleContext;
import com.sap.aii.af.mp.module.ModuleData;
import com.sap.aii.af.mp.module.ModuleException;
import com.sap.aii.af.ra.ms.api.Message;
import com.sap.aii.af.service.trace.Trace;
import java.util.Hashtable;

// XML parsing and transformation classes


import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import com.sap.aii.af.ra.ms.api.XMLPayload;
import javax.xml.transform.*;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
* @ejbLocal <{com.kk.FileModule.GetFileNameLocal}>
* @ejbLocalHome <{com.kk.FileModule.GetFileNameLocalHome}>
* @stateless
* @transactionType Container
*/
public class GetFileNameBean implements SessionBean, Module {

public static final String VERSION_ID = "$Id:


//tc/aii/30_REL/src/_adapters/_sample/java/com/sap/aii/af/sample/mod
ule/GetFileNameBean.java#1 $";
private static final Trace TRACE = new Trace(VERSION_ID);
private SessionContext myContext;

public void ejbRemove() {


}

public void ejbActivate() {


}

public void ejbPassivate() {


}
public void setSessionContext(SessionContext context) {
myContext = context;
}

public void ejbCreate() throws CreateException {


}

public ModuleData process(ModuleContext moduleContext, ModuleData


inputModuleData) throws ModuleException {
Object obj = null;
Message msg = null;
String fileName = null;
try {
obj = inputModuleData.getPrincipalData();
msg = (Message) obj;
Hashtable mp = (Hashtable)
inputModuleData.getSupplementalData("module.parameters");
if (mp != null) fileName = (String)
mp.get("FileName");

} catch (Exception e) {
ModuleException me = new ModuleException(e);
throw me;
}

try{
XMLPayload xmlpayload = msg.getDocument();
DocumentBuilderFactory factory;
factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder =
factory.newDocumentBuilder();
Document document = builder.parse((InputStream)
xmlpayload.getInputStream());
Element rootNode =
document.getDocumentElement();
if(rootNode != null){
Element childElement =
document.createElement("FileName");
childElement.appendChild(document.createTextNode(fileName));
rootNode.appendChild(childElement);

// Transforming the DOM object to Stream object.


TransformerFactory tfactory =
TransformerFactory.newInstance();
Transformer transformer =
tfactory.newTransformer();

Source src = new DOMSource(document);


ByteArrayOutputStream myBytes = new
ByteArrayOutputStream();
Result dest = new StreamResult(myBytes);
transformer.transform(src,dest);

byte[] docContent = myBytes.toByteArray();

if(docContent != null){
xmlpayload.setContent(docContent);
inputModuleData.setPrincipalData(msg);

} catch (Exception e) {
ModuleException me = new ModuleException(e);
throw me;
}

return inputModuleData;
}
}
Disclaimer & Liability Notice

This document may discuss sample coding, which does not include official interfaces and
therefore is not supported. Changes made based on this information are not supported and
can be overwritten during an upgrade.

SAP will not be held liable for any damages caused by using or misusing of the code and
methods suggested here, and anyone using these methods, is doing it under his/her own
responsibility.

SAP offers no guarantees and assumes no responsibility or liability of any type with respect
to the content of the technical article, including any liability resulting from incompatibility
between the content of the technical article and the materials and services offered by SAP.
You agree that you will not hold SAP responsible or liable with respect to the content of the
Technical Article or seek to do so.

Copyright 2004 SAP AG, Inc. All Rights Reserved. SAP, mySAP, mySAP.com, xApps,
xApp, and other SAP products and services mentioned herein as well as their
respective logos are trademarks or registered trademarks of SAP AG in Germany and
in several other countries all over the world. All other product, service names,
trademarks and registered trademarks mentioned are the trademarks of their
respective owners.

You might also like