Function Description
getASMA(String attribute, String namespace) get PI adapter specific message attribute
XPath(String xpath) get value based on evaluated xpath on main payload
getCorrelationId() get Correlation Id from PI message
getMessageId() get Message Id from PI message
getProtocol() get Protocol from PI message
getRefToMessageId() get Reference Message Id from PI message
getDeliverySemantics() get Delivery Semantics from PI message
getFromParty() get From Party from PI message
getSequenceId() get Sequence Id from PI message
getFromService() get From Service from PI message
getMessageClass() get Message Class from PI message
getMessageDirection() get Message Direction from PI message
getToParty() get To Party from PI message
getToService() get To Service from PI message
appendIfMissing(String suffix) Appends the suffix to the end of the string if the string does not already end with any the suffixes.
appendIfMissingIgnoreCase(String suffix) Appends the suffix to the end of the string if the string does not already end, case insensitive, with any of the suffixes.
capitalize Capitalizes a String changing the first letter to title case
center(int size) Centers a String in a larger String of size size using the space character (' ').
center(int size, String padStr) Centers a String in a larger String of size size.
chop() Remove the last character from a String.
concat(String value) concatenate value
left(int len) Gets the leftmost len characters of a String.
leftPad(int size, String padStr) Left pad a String with a specified String.
normalizeSpace() The function returns the argument string with whitespace normalized by using trim(String) to remove leading and trailing whitespace and then replacing sequences of whitespace characters by a single space.
prependIfMissing(String prefix) Prepends the prefix to the start of the string if the string does not already start with any of the prefixes.
prependIfMissingIgnoreCase(String prefix) Prepends the prefix to the start of the string if the string does not already start, case insensitive, with any of the prefixes.
remove(String remove) Removes all occurrences of a substring from within the source string.
removeEnd(String remove) Removes a substring only if it is at the end of a source string, otherwise returns the source string.
removeEndIgnoreCase(String remove) Case insensitive removal of a substring if it is at the end of a source string, otherwise returns the source string.
removePattern(String regex) Removes each substring of the source String that matches the given regular expression using the DOTALL option.
removeStart(String remove) Removes a substring only if it is at the beginning of a source string, otherwise returns the source string.
removeStartIgnoreCase(String remove) Case insensitive removal of a substring if it is at the beginning of a source string, otherwise returns the source string.
repeat(int repeat) Repeat a String repeat times to form a new String.
repeat(String separator, int repeat) Repeat a String repeat times to form a new String, with a String separator injected each time.
replace(String searchString, String replacement) Replaces all occurrences of a String within another String.
replace(String searchString, String replacement, int max) Replaces a String with another String inside a larger String, for the first max values of the search String.
replaceOnce(String searchString, String replacement) Replaces a String with another String inside a larger String, once.
replacePattern(String regex, String replacement) Replaces each substring of the source String that matches the given regular expression with the given replacement using the Pattern.DOTALL option.
reverse() Reverses a String
reverseDelimited(char separatorChar) Reverses a String that is delimited by a specific character.
right(int len) Gets the rightmost len characters of a String.
rightPad(int size) Right pad a String with spaces (' ').
rightPad(int size, String padStr) Right pad a String with a specified String.
splitRegEx(String regex) Split a String with regex using regular expression, then take first string found.
splitRegEx(String regex, int position) Split a String with regex using regular expression, then take string based on index position.
substring(String str, int start) Gets a substring from the specified String avoiding exceptions.
substringAfter(String separator) Gets the substring after the first occurrence of a separator.
substringAfterLast(String separator) Gets the substring after the last occurrence of a separator.
substringBefore(String separator) Gets the substring before the first occurrence of a separator.
substringBeforeLast(String separator) Gets the substring before the last occurrence of a separator.
substringBetween(String tag) Gets the String that is nested in between two instances of the same String.
substringBetween(String open, String close) Gets the String that is nested in between two Strings.
substringRegEx(String regex) Gets the String that is matched regex regular expression. Take string in first position found."
substringRegEx(String regex, int position) Gets the String that is matched regex regular expression. Take string in based on position.
toLowerCase() Converts a String to lower case
toUpperCase() Converts a String to upper case
trim() Trim white space from a String
uncapitalize() Uncapitalizes a String, changing the first letter to lower case
wrap(String wrapWith) Wraps a String with another String
getTimestamp(String format) Get current timestamp using Java simpleDateFormat
package com.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.text.SimpleDateFormat;
import javax.ejb.Stateless;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DynamicFileNameBean implements DynamicFileNameBeanRemote, DynamicFileNameBeanLocal {
 private AuditAccess audit;
 private MessageKey msgkey;
 private Map<String, String> prefixNSmap;
 private Document document;
 public DynamicFileNameBean() {
  try {
   this.audit = PublicAPIAccessFactory.getPublicAPIAccess().getAuditAccess();
  } catch (MessagingException e) {
   this.audit = null;
 public ModuleData process(ModuleContext moduleContext, ModuleData inputModuleData)throws ModuleException{
   Message msg = (Message)inputModuleData.getPrincipalData();
   this.prefixNSmap = new HashMap<String, String>();
   this.msgkey = new MessageKey(msg.getMessageId(), msg.getMessageDirection());
   addLog(AuditLogStatus.SUCCESS, "Begin DynamicFileNameBean processing...");
   Enumeration oContextDataKeys;
   //Process setASMA & setVariable
   oContextDataKeys = moduleContext.getContextDataKeys();
    String cdk = (String)oContextDataKeys.nextElement();
    if(StringUtils.startsWithIgnoreCase(cdk, "setASMA")){
     addLog(AuditLogStatus.SUCCESS, "Process " + cdk);
     String sAttribute = StringUtils.split(cdk, "@")[1];
     String sNamespace = StringUtils.split(cdk, "@")[2];
     String sPattern = moduleContext.getContextData(cdk);
     addLog(AuditLogStatus.SUCCESS, "INPUT: Namespace=" + sNamespace + "; " + "Attribute=" + sAttribute + "; Pattern=" + sPattern);
     String sPatternOutput = processPattern(sPattern, msg, msgkey, inputModuleData);
     MessagePropertyKey mpk = new MessagePropertyKey(sAttribute, sNamespace);
     msg.setMessageProperty(mpk, sPatternOutput);
     addLog(AuditLogStatus.SUCCESS, "OUTPUT: Namespace=" + sNamespace + "; " + "Attribute=" + sAttribute + "; Value=" + sPatternOutput);
   addLog(AuditLogStatus.SUCCESS, "End DynamicFileNameBean processing...");
   return inputModuleData;
  catch (Exception e){
    ModuleException me = new ModuleException( e.toString());
    throw me;
 public String processPattern(String sPattern, Message msg, MessageKey msgkey, ModuleData inputModuleData)
  String sOutput = "";
   ArrayList<String> sTokenList = new ArrayList<String>(Arrays.asList(sPattern.split(" *& *")));
   for(int i=0; i<sTokenList.size(); i++){
    String sToken = sTokenList.get(i);
    String sExpResult = "";
    ArrayList<String> sExpression = new ArrayList<String>(Arrays.asList(sToken.split(" *\\Q|\\E *")));
    for(int j=0; j<sExpression.size(); j++){
     String sExp = sExpression.get(j);
     String sExpResultBefore = sExpResult;
     if(StringUtils.startsWithAny(sExp, new String[]{"\"", "\'"}) && StringUtils.endsWithAny(sExp, new String[]{"\"", "\'"})){
      sExpResult = StringUtils.strip(sExp, "\"\'");
     }else if(!sExp.contains("(")){
      sExpResult = sExp;
      String sFunction = StringUtils.substringBefore(sExp, "(");
      String sArgument = StringUtils.chop(StringUtils.substringAfter(sExp, "("));
      String sArg[] = sArgument.split("(?x) " +
    ", " + // Split on comma
    "(?= " + // Followed by
    " (?: " + // Start a non-capture group
    " [^\"]* " + // 0 or more non-quote characters
    " \" " + // 1 quote
    " [^\"]* " + // 0 or more non-quote characters
    " \" " + // 1 quote
    " )* " + // 0 or more repetition of non-capture group (multiple of 2 quotes will be even)
    " [^\"]* " + // Finally 0 or more non-quotes
    " $ " + // Till the end (This is necessary, else every comma will satisfy the condition)
    ") " // End look-ahead
      for(int k=0; k<sArg.length; k++){
       sArg[k] = StringUtils.strip(sArg[k], "\"\'");
      sExpResult = executeFunction(sExpResult, inputModuleData, msg, sFunction, sArg);
      sExpResultBefore = sExpResultBefore + "|";
     addLog(AuditLogStatus.SUCCESS, "Input=" + sExpResultBefore + sExp + "; Output=" + sExpResult);
    sOutput = sOutput + sExpResult;
  }catch(Exception ex)
   addLog(AuditLogStatus.ERROR, "Failed at processPattern=" + sPattern);
  return sOutput;
 public void addLog(AuditLogStatus status, String message) {
  if (this.audit != null) {
   this.audit.addAuditLogEntry(this.msgkey, status, message);
  }else {
   System.out.println( "Audit Log: " + message);
 public Document getDocument(Message msg){
  if(this.document == null){
    XMLPayload xmlpayload = msg.getDocument();
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder;
    try {
     builder = factory.newDocumentBuilder();
     this.document = builder.parse(xmlpayload.getInputStream());
    } catch (Exception ex) {
     addLog(AuditLogStatus.SUCCESS, "Failed at getDocument parse xmlpayload.");
   return this.document;
   return this.document;
 public void addPrefixNamespaceMap(Node root){
 NamedNodeMap attributes = root.getAttributes();
 if (attributes != null){
 for (int i = 0; i < attributes.getLength(); i++){
 Node node = attributes.item(i);
 if (node.getNodeType() == Node.ATTRIBUTE_NODE){
 String name = node.getNodeName();
 if(StringUtils.startsWithIgnoreCase(name, "xmlns")){
  String sPrefix = StringUtils.substringAfter(name, ":");
      String sNamespace = node.getNodeValue();
      this.prefixNSmap.put(sPrefix, sNamespace);
      addLog(AuditLogStatus.SUCCESS, "Added prefix namespace map; Prefix=" + sPrefix + "; " + "Namespace=" + sNamespace);
 public void addPrefixNamespaceMapRecursive(Node root) {
  NodeList childNodes = root.getChildNodes();
 for (int i = 0; i < childNodes.getLength(); i++){
 public String executeFunction(String sIn, ModuleData inputModuleData, Message msg, String sFunction, String[] sArg){
  String sOut = sIn;
   MessagePropertyKey mpk = new MessagePropertyKey(sArg[0],sArg[1]);
   sOut = msg.getMessageProperty(mpk);
  else if(sFunction.equalsIgnoreCase("XPath")){
   Element root = getDocument(msg).getDocumentElement();
   if(prefixNSmap.size() == 0){
    addPrefixNamespaceMapRecursive((Node) root);
   try {
    XPath xpath = XPathFactory.newInstance().newXPath();
    xpath.setNamespaceContext(new NamespaceContext() {
     public String getNamespaceURI(String prefix) {
     return prefixNSmap.get(prefix);
     public Iterator<String> getPrefixes(String val) {
     return null;
     public String getPrefix(String uri) {
     return null;
    XPathExpression expr;
    expr = xpath.compile(sArg[0]);
    Object result = expr.evaluate(root, XPathConstants.NODESET);
    NodeList nodes = (NodeList)result;
    if ((nodes != null) && (nodes.getLength() > 0)){
     sOut = nodes.item(0).getChildNodes().item(0).getNodeValue();
   } catch (XPathExpressionException e) {
    addLog(AuditLogStatus.SUCCESS, "Failed at XPath function.");
  else if(sFunction.equalsIgnoreCase("getSAPSYSTEMNAME")){
   sOut = System.getProperty("SAPSYSTEMNAME", "");
  else if(sFunction.equalsIgnoreCase("getSAPSYSTEM")){
   sOut = System.getProperty("SAPSYSTEM", "");
  else if(sFunction.equalsIgnoreCase("getCorrelationId")){
   sOut = msg.getCorrelationId();
  else if(sFunction.equalsIgnoreCase("getMessageId")){
   sOut = msg.getMessageId();
  else if(sFunction.equalsIgnoreCase("getProtocol")){
   sOut = msg.getProtocol();
  else if(sFunction.equalsIgnoreCase("getRefToMessageId")){
   sOut = msg.getRefToMessageId();
  else if(sFunction.equalsIgnoreCase("getDeliverySemantics")){
   sOut = msg.getDeliverySemantics().toString();
  else if(sFunction.equalsIgnoreCase("getFromParty")){
   sOut = msg.getFromParty().getName();
  else if(sFunction.equalsIgnoreCase("getSequenceId")){
   sOut = msg.getSequenceId();
  else if(sFunction.equalsIgnoreCase("getFromService")){
   sOut = msg.getFromService().getName();
  else if(sFunction.equalsIgnoreCase("getMessageClass")){
   sOut = msg.getMessageClass().toString();
  else if(sFunction.equalsIgnoreCase("getMessageDirection")){
   sOut = msg.getMessageDirection().toString();
  else if(sFunction.equalsIgnoreCase("getToParty")){
   sOut = msg.getToParty().getName();
  else if(sFunction.equalsIgnoreCase("getToService")){
   sOut = msg.getToService().getName();
  else if(sFunction.equalsIgnoreCase("appendIfMissing")){
   sOut = StringUtils.appendIfMissing(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("appendIfMissingIgnoreCase")){
   sOut = StringUtils.appendIfMissingIgnoreCase(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("capitalize")){
   sOut = StringUtils.capitalize(sIn);
  else if(sFunction.equalsIgnoreCase("center")){
   if(sArg.length == 1){
    sOut =, Integer.parseInt(sArg[0]));
   else if(sArg.length == 2){
    sOut =, Integer.parseInt(sArg[0]), sArg[1]);
  else if(sFunction.equalsIgnoreCase("chop")){
   sOut = StringUtils.chop(sIn);
  else if(sFunction.equalsIgnoreCase("concat")){
   sOut = sIn.concat(sArg[0]);
  else if(sFunction.equalsIgnoreCase("left")){
   sOut = StringUtils.left(sIn, Integer.parseInt(sArg[0]));
  else if(sFunction.equalsIgnoreCase("leftPad")){
   sOut = StringUtils.leftPad(sIn, Integer.parseInt(sArg[0]), sArg[1]);
  else if(sFunction.equalsIgnoreCase("normalizeSpace")){
   sOut = StringUtils.normalizeSpace(sIn);
  else if(sFunction.equalsIgnoreCase("prependIfMissing")){
   sOut = StringUtils.prependIfMissing(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("prependIfMissingIgnoreCase")){
   sOut = StringUtils.prependIfMissingIgnoreCase(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("remove")){
   sOut = StringUtils.remove(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("removeEnd")){
   sOut = StringUtils.removeEnd(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("removeEndIgnoreCase")){
   sOut = StringUtils.removeEndIgnoreCase(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("removePattern")){
   sOut = StringUtils.removePattern(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("removeStart")){
   sOut = StringUtils.removeStart(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("removeStartIgnoreCase")){
   sOut = StringUtils.removeStartIgnoreCase(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("repeat")){
   if(sArg.length == 1){
    sOut = sOut + StringUtils.repeat(sIn, Integer.parseInt(sArg[0]));
   }if(sArg.length == 2){
    sOut = sOut + StringUtils.repeat(sIn, sArg[0], Integer.parseInt(sArg[1]));
  else if(sFunction.equalsIgnoreCase("replace")){
   if(sArg.length == 2){
    sOut = StringUtils.replace(sIn, sArg[0], sArg[1]);
   }else if(sArg.length == 3){
    sOut = StringUtils.replace(sIn, sArg[0], sArg[1], Integer.parseInt(sArg[2]));
  else if(sFunction.equalsIgnoreCase("replaceOnce")){
   sOut = StringUtils.replace(sIn, sArg[0], sArg[1]);
  else if(sFunction.equalsIgnoreCase("replacePattern")){
   sOut = StringUtils.replacePattern(sIn, sArg[0], sArg[1]);
  else if(sFunction.equalsIgnoreCase("reverse")){
   sOut = StringUtils.reverse(sIn);
  else if(sFunction.equalsIgnoreCase("reverseDelimited")){
   sOut = StringUtils.reverseDelimited(sIn, sArg[0].toCharArray()[0]);
  else if(sFunction.equalsIgnoreCase("right")){
   sOut = StringUtils.right(sIn, Integer.parseInt(sArg[0]));
  else if(sFunction.equalsIgnoreCase("rightPad")){
   if(sArg.length == 2){
    sOut = StringUtils.rightPad(sIn, Integer.parseInt(sArg[0]));
   }else if(sArg.length == 3){
    sOut = StringUtils.rightPad(sIn, Integer.parseInt(sArg[0]), sArg[1]);
  else if(sFunction.equalsIgnoreCase("splitRegEx")){
    ArrayList<String> foundList = new ArrayList<String>(Arrays.asList(sIn.split(sArg[0])));
    sOut = foundList.get(Integer.parseInt(sArg[1]));
   }catch(Exception ex){
    sOut = "";
  else if(sFunction.equalsIgnoreCase("substring")){
   if(sArg.length == 1){
    sOut = sOut + StringUtils.substring(sIn, Integer.parseInt(sArg[0]));
   }else if(sArg.length == 2){
    sOut = sOut + StringUtils.substring(sIn, Integer.parseInt(sArg[0]), Integer.parseInt(sArg[1]));
  else if(sFunction.equalsIgnoreCase("substringAfter")){
   sOut = sOut + StringUtils.substringAfter(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("substringAfterLast")){
   sOut = sOut + StringUtils.substringAfterLast(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("substringBefore")){
   sOut = sOut + StringUtils.substringBefore(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("substringBeforeLast")){
   sOut = sOut + StringUtils.substringBeforeLast(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("substringBetween")){
   if(sArg.length == 1){
    sOut = sOut + StringUtils.substringBetween(sIn, sArg[0]);
   }else if(sArg.length == 2){
    sOut = sOut + StringUtils.substringBetween(sIn, sArg[0], sArg[1]);
  else if(sFunction.equalsIgnoreCase("substringRegEx")){
    Pattern p = Pattern.compile(sArg[0]);
   Matcher m = p.matcher(sIn);
   ArrayList<String> foundList = new ArrayList<String>();
   if(sArg.length == 1){
    sOut = foundList.get(0);
    }else if(sArg.length == 2){
     sOut = foundList.get(Integer.parseInt(sArg[1])-1);
   }catch(Exception ex){
    sOut = "";
  else if(sFunction.equalsIgnoreCase("toLowerCase")){
   sOut = sIn.toLowerCase();
  else if(sFunction.equalsIgnoreCase("toUpperCase")){
   sOut = sIn.toUpperCase();
  else if(sFunction.equalsIgnoreCase("trim")){
   sOut = sIn.trim();
  else if(sFunction.equalsIgnoreCase("uncapitalize")){
   sOut = StringUtils.uncapitalize(sIn);
  else if(sFunction.equalsIgnoreCase("wrap")){
   sOut = StringUtils.wrap(sIn, sArg[0]);
  else if(sFunction.equalsIgnoreCase("getTimestamp")){
    sArg[0] = "yyyyMMDD_HHmmss_SSS";
   Date date = new Date();
   SimpleDateFormat sdf = new SimpleDateFormat(sArg[0]);
   sOut = sdf.format(date);
  return sOut;
SAP PI Custom Module DynamicFileNameBean Development
Tagged on:         

One thought on “SAP PI Custom Module DynamicFileNameBean Development

  • December 2, 2021 at 1:17 pm

    Hi Khoo,

    Could you please add some examples of each function of this module? Its difficult to figure out how to use it in channel.



Leave a Reply

Your email address will not be published. Required fields are marked *