Skip to Content

Update 19 May 2014: JAR file also available for download at GitHub repository

Background

Whenever we need to develop Java mappings in PI, often it involves a lot of copy-paste of codes and doing the same tasks again and again. Most of this effort is to comply with the Java Mapping API provided in PI. In this article, I will introduce an approach that can simplify developments of Java Mapping in PI. A similar approach was previously introduced in the following article XI Java Mapping Helper (DOM) by Alessandro Guarneri. In this article, the design is based on the new API utilizing AbstractTransformation class from PI7.1 onwards. Hopefully this might also lower the entry barrier for those who are contemplating developing Java mappings but are new to it.

Concept & Design

The idea is to “package” commonly reused codes together, which then enables the developer to focus on the specific logic for a particular requirement. This approach is based on the Strategy Pattern using Abstract Classes.

In general, following are the sequence of steps required for a Java Mapping.

  1. Parsing of Input
  2. Generating the output content
  3. Convert output content to output stream

As mentioned above, steps 1 and 3 are always the same most of the time. The difference between mappings are often for step 2 to generate the output content. As such we can encapsulate the logic in steps 1 and 3 into an abstract base class.

Also, there is possibility of different type of input/output content (plain, XML, binary, etc), and each of these require specific logic for parsing and stream generation. Therefore there will be a second tier of abstract classes which controls the correct sequence of logic for each conversion type.

The following table lists the classes in this design.

Class Description
AbstractMappingBase Base super class
AbstractDOM2DOM Extends AbstractMappingBase – Controls logic for DOM to DOM processing
AbstractDOM2Plain Extends AbstractMappingBase – Controls logic for DOM to Plain processing
AbstractPlain2Plain Extends AbstractMappingBase – Controls logic for Plain to Plain processing
AbstractPlain2DOM Extends AbstractMappingBase – Controls logic for Plain to DOM processing

Below is an example of the logic in AbstractPlain2DOM class. Firstly, the input data is parsed and stored in the array of String (representing each line of input payload). Then the output contents are generated in DOM format. Lastly, the DOM output is transformed to the output stream.


ArrayList<String> inputContents = parsePlainInput(input.getInputPayload().getInputStream());
Document outputDoc = getDocumentBuilder().newDocument();
generateOutput(inputContents, outputDoc);
transformDocumentToStream(outputDoc, output.getOutputPayload().getOutputStream(), indentOutputXML);





Each of the subclasses has an abstract generateOutput method. It is this method that needs to be implemented in a custom mapping class that extends the corresponding abstract class. Below is a table listing the input/output parameters of the abstract method for each of the classes.

Class Modifier & Type Method & Description
AbstractDOM2DOM abstract void

generateOutput (Document inDoc, Document outDoc)

Construct DOM output based on DOM input

AbstractDOM2Plain abstract StringBuilder

generateOutput (Document inDoc)

Generate String output based on DOM input

AbstractPlain2Plain abstract StringBuilder

generateOutput (ArrayList<String> inContents)

Generate String output based on input of String array

AbstractPlain2DOM abstract void

generateOutput (ArrayList<String> inContents, Document outDoc)

Generate DOM output based on input of String array

Example of Mapping Implementation

Now we go to the actual work to be done. In this example, I will develop the Java Mapping directly in ESR based on the technique shared by Sunil Chandra. Alternatively, this can be done in the normal way in Eclipse/NWDS – just need to remember to include the JAR file below in the build path.

Step 1

Import the JAR file into ESR as an Imported Archive (this can be skipped for further developments.)

/wp-content/uploads/2014/05/archive_449306.png

Step 2

Create Message Mapping with dummy source and target.

/wp-content/uploads/2014/05/mm_449308.png

Step 3

In the Functions tab, include the archive, and add the import for com.equalize.xpi.esr.mapping. If you are using DOM related functions, import org.w3c.dom as well.

/wp-content/uploads/2014/05/arc_449316.png  /wp-content/uploads/2014/05/import_449317.png

Step 4

Write code in “Attributes and Methods” section.

/wp-content/uploads/2014/05/code_449321.png

Essentially, there are only 2 things to do here. First of all, implement transform method of AbstractTransformation. The following code can be copied as-is.


@Override
public void transform(TransformationInput input, TransformationOutput output)
  throws StreamTransformationException {
  AbstractMappingBase map = new CustomMap();
  map.process(input, output, this.getTrace());
}




Secondly, and more importantly is to code the logic for the output content. To do this, create a local CustomMap class that extends from one of the above abstract classes (AbstractPlain2Plain in this example). Then implement the generateOutput method. The following code just adds a prefix for each of the input lines – HD for first line, FT for last line and IT for everything in between.


// Local class with logic for output generation
class CustomMap extends AbstractPlain2Plain {
  @Override
  protected StringBuilder generateOutput(ArrayList<String> inContents) {
    StringBuilder sb = new StringBuilder();
    int count = 0;
    for (String line : inContents) {
      if (count == 0) {
        sb.append("HD");
      } else if (count == inContents.size()-1) {
        sb.append("FT");
      } else {
        sb.append("IT");
      }
      sb.append(line);
      sb.append("\n");
      count++;
    }
    setPlainOutputEncoding("UTF-8");
    return new StringBuilder(sb.toString());
  }
}




Step 5

Test the mapping.

/wp-content/uploads/2014/05/result_449414.png

Conclusion

As you can see, the development of the Java mapping for any requirement has been significantly simplified. The developer no longer needs to handle the parsing and the stream conversion, and therefore can fully focus on the specific content generation.

Also, currently there are only 4 different mapping subclasses, handling DOM and plain text processing. This can be easily extensible in the future to include other types, i.e. SAX.

Source code and JAR

The Java source codes and JAR file are available in the following GitHub repository. Also included are sample implementation source codes for each of the abstract class above.

equalize-xpi-mapping at engswee’s GitHub

Reference

The following article Easy way to learn – Java Mapping using DOM – SAP PI 7.1+ by Ricardo Viana is a useful resource to learn DOM based processing.

To report this post you need to login first.

2 Comments

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

Leave a Reply