Removing additional namespace prefixes in the SOAP Fault using a Class Mediator
In the previous post I have described how to use an xslt mediator to remove unwanted namespace prefixes in the SOAP Fault. This blog post describes how to accomplish that task using a simple Class Mediator.
You can fine more information about how to implement a class mediator at [1].
Sample implementation of the Class Mediator is as follows
package org.wso2.sample.mediator;
import java.util.Iterator;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPFault;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
/**
*
* This class removes the additional axis2 namespace prefixes and creates a new
* OMElement
*
*/
public class Axis2NSPrefixRemoveMediator extends AbstractMediator {
private static final String AXIS2_NAMESPACE_PREFIX = "axis2ns";
private static final String CLONED_ROOT = "ClonedDetail";
public boolean mediate(MessageContext synCtx) {
SOAPBody soapBody = synCtx.getEnvelope().getBody();
//Check for a Fault
if(soapBody.hasFault()){
SOAPFault faultNode = soapBody.getFault();
// Retrieves the Detail Element
OMElement detailNode = faultNode.getDetail();
if (detailNode.getChildElements().hasNext()) {
Iterator<?> complexElement = detailNode.getChildElements();
OMFactory fac = OMAbstractFactory.getOMFactory();
// Creates a clone from detail element
OMElement clonedRoot = fac.createOMElement(new QName(CLONED_ROOT));
//For every child creates a cloned element without axis2ns prefix
getChildrenRecursively(fac, clonedRoot, complexElement);
if (clonedRoot.getChildElements().hasNext()) {
// Detach the fault body
Iterator<?> children = detailNode.getChildElements();
while (children.hasNext()) {
((OMNode) children.next()).detach();
}
// Attach the new fault body
Iterator<?> clonedChildren = clonedRoot.getChildElements();
while (clonedChildren.hasNext()) {
detailNode.addChild((OMElement) clonedChildren.next());
}
}
}
}
return true;
}
/**
*
* @param fac OMFactory
* @param root root element of the detail block
* @param complexElement children of the detail block
* @return final list of elements
*/
private OMElement getChildrenRecursively(OMFactory fac, OMElement root, Iterator<?> complexElement) {
while (complexElement.hasNext()) {
Object next = complexElement.next();
if (next instanceof OMElement) {
OMElement element = (OMElement) next;
// Creates the new OMElement excluding additional namespace prefixes
OMElement duplicateElement = createNewOMElement(fac, element);
if (element.getChildElements().hasNext()) {
getChildrenRecursively(fac, duplicateElement, element.getChildElements());
//Add to root at the end of populating the child
root.addChild(duplicateElement);
} else {
// If no more children add it to root
root.addChild(duplicateElement);
}
}
}
return root;
}
/**
*
* @param fac OMFactory
* @param element complex element
* @return duplicated new OMElement
*/
private OMElement createNewOMElement(OMFactory fac, OMElement element) {
OMElement duplicateElement = null;
String elementText = element.getText();
// Set Namespace
duplicateElement = setNameSpaces(fac, element);
// Set Attributes
setAttributes(element, duplicateElement);
// Set text
setTextValues(fac, duplicateElement, elementText);
return duplicateElement;
}
/**
*
* @param fac OMFactory
* @param rootElement newly created OMElement
* @param elementText Text of the element
*/
private void setTextValues(OMFactory fac, OMElement rootElement, String elementText) {
// Includes the text as a child
if (elementText != null && !elementText.isEmpty()) {
OMText omText = fac.createOMText(elementText);
rootElement.addChild(omText);
}
}
/**
*
* @param element complex element
* @param tempElement newly created OMElement
*/
private void setAttributes(OMElement element, OMElement tempElement) {
// Get the attributes
Iterator<?> allAttributes = element.getAllAttributes();
while (allAttributes.hasNext()) {
tempElement.addAttribute((OMAttribute) allAttributes.next());
}
}
/**
*
* @param fac OMFactory
* @param tempElement newly created OMElement
* @return OMElement without axis2 namespace prefix
*/
private OMElement setNameSpaces(OMFactory fac, OMElement tempElement) {
String name = tempElement.getLocalName();
OMNamespace namespace = tempElement.getNamespace();
if (name != null && namespace != null) {
String namespaceURI = namespace.getNamespaceURI();
String namespacePrefix = namespace.getPrefix();
if (namespacePrefix.startsWith(AXIS2_NAMESPACE_PREFIX)) {
// Removes additional namespaces
String emptyNamespacePrefix = namespace.getPrefix().replace(namespacePrefix, "");
OMNamespace modifiedNamespace = fac.createOMNamespace(namespaceURI, emptyNamespacePrefix);
// Creates the final OMElement with correct namesapce
tempElement = fac.createOMElement(name, modifiedNamespace);
}
}else{
tempElement = fac.createOMElement(name, namespace);
}
return tempElement;
}
}
Please refer [2] for more information about configuring the class mediator in synapse configuration
[2] https://docs.wso2.com/display/ESB481/Class+Mediator