You are on page 1of 8

How To Implement Java Mapping

Document Information
XI Area:
Release:
Keywords:

Design
XI 2.0
Java Mapping

Problem Description
You want to use Java classes for mapping.

Procedure

1. Create the Java Program


You need the libraries aii_map_api.jar and inqmyxml.jar for testing and debugging purpose. You find these
files in the file system of the J2EE engine, where your XI is running (see note 636447). These libraries are
part of the mapping program, so you can use all classes and methods of them without binding the libraries
to your jar. In inqmyxml.jar you find a lot of methods for parsing the XML. You can use SAX (simple API
for XML) and DOM (document oriented model) for easily navigating through the source XML and creating
the target XML.
Create a Java class implementing the interface
com.sap.aii.mapping.api.StreamTransformation
The interface looks like follows:
package com.sap.aii.mapping.api;
import java.io.InputStream;
import java.io.OutputStream;
public interface StreamTransformation {
public void setParameter(java.util.Map param);
public void execute(InputStream in, OutputStream out) throws
StreamTransformationException;
}
In the following you find two examples for Java mapping with SAX parser and DOM parser.
The objective of the mapping is the transformation of this XML file:
Source XML

Target XML

<Person>
<Gender>1</Gender>
<Surname>Miller</Surname>
</Person>

<Passenger>
<Title>Mr.</Title>
<Name>Miller</Name>
</Passenger>

Example with SAX parser:


A SAX parser extends the abstract class DefaultHandler. Here you find an example code, in which the
output message is created while the input message is validated, so for every valid input tag we create an
output tag.
package sample;
import
import
import
import
import
import

com.sap.aii.mapping.api.StreamTransformation;
java.io.*;
java.util.Map;
javax.xml.parsers.*;
org.xml.sax.*;
org.xml.sax.helpers.*;

/**
* An easy example in which one XML file is scanned for entries in specified
tags.
*
* Input: Person - Gender
*
- Surname
*
* Output: Passenger - Title
*
- Name
*/
public class SampleWithSaxParser
extends DefaultHandler
implements StreamTransformation
{
private Map map;
private OutputStream out;
/* need some constants to know, which tag we have now */
private int tag = 0;
private final int GENDER_TAG = 1;
private final int SURNAME_TAG = 2;
private final int PERSON_TAG = 3;
private final int OTHER_TAG = 0;
/**
* method setParamters is required, but we do not anything with it
*/
public void setParameter (Map param) {
map = param;
}
/**
* method execute is called by the XI mapping program
*/
public void execute (InputStream in, OutputStream out)
throws com.sap.aii.mapping.api.StreamTransformationException {
DefaultHandler handler = this;
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
this.out = out;
saxParser.parse(in, handler);
} catch (Throwable t) {

t.printStackTrace();
}
}
//===========================================================
// SAX DocumentHandler methods
//===========================================================
/**
* startDocument is called at the beginning, so we write the xml header
*/
public void startDocument ()
throws SAXException {
write("<?xml version='1.0' encoding='UTF-8'?>");
}
/**
* endDocument is called at the end, so we clear the buffer
*/
public void endDocument ()
throws SAXException {
try {
out.flush();
} catch (IOException e) {
throw new SAXException("I/O error", e);
}
}
/**
* startElement is called when a new tag appears. We store the information,
which tag we have now.
* Each beginning tag in the input creates a different tag in the output
*/
public void startElement (String namespaceURI, String lName, String qName,
Attributes attrs)
throws SAXException {
String eName = lName; // element name
if ("".equals(eName)) {
eName = qName; // namespaceAware = false
}
if (eName.equals("Gender")) {
tag = GENDER_TAG;
write("<Title>");
} else if (eName.equals("Surname")) {
tag = SURNAME_TAG;
write("<Name>");
} else if (eName.equals("Person")) {
tag = PERSON_TAG;
write("<Passenger>");
} else {
tag = OTHER_TAG;
}
}
/**

* endElement is called, when an end tag appears.


* We choose the right end tag for the output
*/
public void endElement (String namespaceURI, String sName, String qName)
throws SAXException {
String eName = sName;
if ("".equals(eName)) {
eName = qName;
}
if (eName.equals("Gender")) {
write("</Title>");
} else if (eName.equals("Surname")) {
write("</Name>");
} else if (eName.equals("Person")) {
write("</Passenger>");
}
}
/**
* method characters is always called, when we are outside of tags.
* The output is depending from the tag we have.
* When we have <Gender>, the output value is mapped 0 -> Mr., 1 -> Mrs.
* When we have <Surname>, the output is the same as the input.
*/
public void characters (char buf[], int offset, int len)
throws SAXException {
String s = new String(buf, offset, len);
switch (tag) {
case GENDER_TAG:
if (s.equals("0")) {
write("Mr.");
}
if (s.equals("1")) {
write("Mrs.");
}
break;
case SURNAME_TAG:
write(s);
break;
}
}
/**
* Wrap I/O exceptions in SAX exceptions, to suit handler signature
requirements
*/
private void write (String s)
throws SAXException {
try {
out.write(s.getBytes());
out.flush();
} catch (IOException e) {
throw new SAXException("I/O error", e);
}
}
}

Example with DOM parser:


In this example we create a DOM tree for the input and the output message. The values for Gender and
Surname are searched in the tree.
package sample;
import
import
import
import
import
import
import
import
import

com.sap.aii.mapping.api.*;
java.io.*;
java.util.Map;
javax.xml.parsers.*;
javax.xml.transform.*;
javax.xml.transform.dom.DOMSource;
javax.xml.transform.stream.StreamResult;
org.w3c.dom.*;
org.xml.sax.*;

/**
* An easy example in which one XML file is scanned for entries in specified
tags.
*
* Input: Person - Gender
*
- Surname
*
* Output: Passenger - Title
*
- Name
*/
public class SampleWithDomParser
implements StreamTransformation
{
private Map map;
private Document document;
private String title = "";
private String name = "";
/**
* method setParamters is required, but we do not anything with it
*/
public void setParameter (Map param) {
map = param;
}
/**
* method execute is called by the XI mapping program
*/
public void execute (InputStream in, OutputStream out)
throws com.sap.aii.mapping.api.StreamTransformationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
// create DOM structure from input XML
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(in);
// look for the tag 'Gender'
NodeList list = document.getElementsByTagName("Gender");

Node node = list.item(0);


if (node != null) {
// if found, look for the value of gender
node = node.getFirstChild();
if (node != null) {
String gender = node.getNodeValue();
// Choose title depending from gender
if (gender.equals("0")) {
title = "Mr.";
} else if (gender.equals("1")) {
title = "Mrs.";
}
}
}
// look for the tag 'Surname'
list = document.getElementsByTagName("Surname");
node = list.item(0);
if (node != null) {
// if found, look for the value of surname
node = node.getFirstChild();
if (node != null) {
name = node.getNodeValue();
}
}
//Create the output DOM
Document docOut = builder.newDocument();
// create the root element <Passenger>
Element passengerNode = docOut.createElement("Passenger");
docOut.appendChild(passengerNode);
// create a child element <Title>
Element titleNode = docOut.createElement("Title");
passengerNode.appendChild(titleNode);
// create a text element for the value of the title
Text titleText = docOut.createTextNode(title);
titleNode.appendChild(titleText);
// create a child element <Name>
Element nameNode = docOut.createElement("Name");
passengerNode.appendChild(nameNode);
// create a text element for the value of the name
Text nameText = docOut.createTextNode(name);
nameNode.appendChild(nameText);
// print the output XML
TransformerFactory tf =
Transformer transform =
transform.transform(new

direct from the DOM


TransformerFactory.newInstance();
tf.newTransformer();
DOMSource(docOut), new StreamResult(out));

} catch (Throwable t) {
throw new StreamTransformationException("error", t);
}
}
}

2. Create a jar file


After compiling your program, you have to create a jar file. The content of the jar file have to be all classes
and libraries you need for the mapping program to run and which are not part of the J2EE installation.
You need not bind the libraries aii_map_api.jar and inqmyxml.jar, as they are part of the standard J2EE
installation.

3. Load the jar file to the Integration Repository


Go to the Integration Repository. Under your Software Component and Namespace you create a new
Mapping Object Imported Archive. Inside this object you upload the jar file.

3. Attach the Java Mapping to an Interface Mapping


Create a new Mapping Object Interface Mapping, chose the interfaces you want to map. To attach the
Mapping to the request or response, use value help and chose Java Class. Chose the Java Class with
the corresponding mapping.
After saving and activating the change list, you will be able to use the Mapping in the Integration Directory.

Further Information
A tutorial for the methods of SAX and DOM you find here:
http://java.sun.com/webservices/docs/1.1/tutorial/doc/

You might also like