#set( $symbol_pound = '#' ) #set( $symbol_dollar = '$' ) #set( $symbol_escape = '\' ) /* * AbstractNormalizer.java */ package net.openesb.component.${componentName}.common.wsdl; import java.util.ArrayList; import java.util.List; import javax.jbi.messaging.MessagingException; import javax.jbi.messaging.NormalizedMessage; import javax.wsdl.Binding; import javax.wsdl.Definition; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Part; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * This is an abstract class that implements most of the functionality to normalize the binding protocol * specific concrete message to jbi wrapper and and denormalize jbi wrapper to the concrete binding * protocol specific message. *

* The extended classes specific to particular binding protocol will be used when a jbi binding * component is sending and receiving messages from the external service providers and consumers using * a particular binding protocol known to this class. Extended implementation of this class should make * use of the helper methods in this class in normalizing and denormalizing the messages. * @see JMXBindingNormalizer * @author chikkala */ public abstract class AbstractNormalizer { public static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/"; /** wsdl definition to use when normalizing and denormalizing */ private Definition mWSDL; /** Binding definition to use when normalizing and denormalizing */ private Binding mBinding; private AbstractNormalizer() {} /** Creates a new instance of JMXBCNormalizer */ public AbstractNormalizer(Definition wsdl, Binding binding) { this.mWSDL = wsdl; this.mBinding = binding; } /** * normalize the binding protocol specific concrete message to jbi wrapper. * @param operation wsdl operation for which a concrete message should be normalized. * @param normMsg NoramalizedMessage which will be configurate with normalized data from * the concrete message * @param msgSource concrete mssage of a particular binding protocol. */ public abstract void normalizeInput(Operation operation, NormalizedMessage normMsg, DOMSource msgSource) throws MessagingException; /** * normalize the binding protocol specific concrete message to jbi wrapper. * @param operation wsdl operation for which a concrete message should be normalized. * @param normMsg NoramalizedMessage which will be configurate with normalized data from * the concrete message * @param msgSource concrete message of a particular binding protocol. */ public abstract void normalizeOutput(Operation operation, NormalizedMessage normMsg, DOMSource msgSource) throws MessagingException; /** * normalize the binding protocol specific concrete message to jbi wrapper. * @param operation wsdl operation for which a concrete message should be normalized. * @param normMsg NoramalizedMessage which will be configurate with normalized data from * the concrete message * @param msgSource concrete message of a particular binding protocol. */ public abstract void normalizeFault(Operation operation, String faultName, NormalizedMessage normMsg, DOMSource msgSource) throws MessagingException; /** * denormalize the normalized message into a concrete message for a particular binding protocol * @param operation wsdl operation for which a concrete message should be de-normalized. * @param normMsg NormalizedMessage which should be used to create de-normalized message. */ public abstract DOMSource denormalizeInput(Operation operation, NormalizedMessage normMsg) throws MessagingException; /** * denormalize the normalized message into a concrete message for a particular binding protocol * @param operation wsdl operation for which a concrete message should be denormalized. * @param normMsg NormalizedMessage which should be used to create denormalized message. */ public abstract DOMSource denormalizeOutput(Operation operation, NormalizedMessage normMsg) throws MessagingException; /** * denormalized the normalized fault message into a concrete message for a particular binding protocol * @param operation wsdl operation for which a concrete message should be denormalized. * @param normMsg NormalizedMessage which should be used to create denormalized message. */ public abstract DOMSource denormalizeFault(Operation operation, String faultName, NormalizedMessage normMsg) throws MessagingException; /** * @return the wsdl definition to use in normalizing and denormalizing the message */ protected Definition getWSDL() { return this.mWSDL; } /** * @return the wsdl binding definition to use in normalizing and denormalizing the message */ protected Binding getBinding() { return this.mBinding; } /** * create and add message parts to the jbiWrapper according to the abstract message model. This * method assumes that the each element in the msgParts list passed to it is mapped to the part * of the abstract wsdl message and uses the type or element attribute of the abstract message to * determine whether the element is actual part element or a wrapped part type. * Use this method in normalizing the concrete protocol specific message to jbi wrapper message. * @param jbiWrapper object that holds the jbi wrapper information. * @param wsdlMsg abstract message from the wsdl definition * @param msgParts actual message parts from the concrete message */ protected void addMessagePartsToJBIWrapper(WSDL11JBIWrapper jbiWrapper, Message wsdlMsg, List msgParts) throws MessagingException { List wsdlParts = wsdlMsg.getOrderedParts(null); for ( int i=0; i < wsdlParts.size(); ++i ) { Part wsdlPart = (Part) wsdlParts.get(i); if ( i >= msgParts.size() ) { throw new MessagingException("missing message content for part " + wsdlPart.getName()); } Element msgPart = msgParts.get(i); if ( wsdlPart.getElementName() != null ) { jbiWrapper.appendPart(msgPart); } else { // it is type. // check the element name is same as part if ( !wsdlPart.getName().equals(msgPart.getLocalName()) ) { throw new MessagingException("mismatched message content for part " + wsdlPart.getName()); } if ( !wsdlMsg.getQName().getNamespaceURI().equals(msgPart.getNamespaceURI()) ) { throw new MessagingException("mismatched message content namespace for part " + wsdlPart.getName()); } // check the content is text or element. List partContent = getChildElements(msgPart); if ( partContent.size() > 0 ) { // add content as part elements jbiWrapper.appendPart(partContent); } else { // add the content as text jbiWrapper.appendPart(msgPart.getTextContent()); } } } } /** * extracts the message parts from the jbiWrapper according to the abstract wsdl message * definition passed to it. Use this method in denormalizing the jbi wrapper message into the * binding protocol specific concrete message. * @param jbiWrapper jbi wrapper object that contains message parts and the message type information. * @param wsdlMsg abstract wsdl message definition to use in constructing the part elements. */ protected List getMessagePartsFromJBIWrapper(WSDL11JBIWrapper jbiWrapper, Message wsdlMsg) throws MessagingException, ParserConfigurationException { List msgParts = new ArrayList(); int jbiPartCount = jbiWrapper.getPartCount(); List wsdlParts = wsdlMsg.getOrderedParts(null); QName msgType = jbiWrapper.getType(); if (!wsdlMsg.getQName().getNamespaceURI().equals(msgType.getNamespaceURI())) { throw new MessagingException("Namespace mismatch between jbi wrapper message type and wsdl message"); } Document newDoc = jbiWrapper.getDocumentBuilder().newDocument(); for ( int i=0; i < wsdlParts.size(); ++i ) { Part wsdlPart = (Part) wsdlParts.get(i); if ( i >= jbiPartCount ) { throw new MessagingException("missing message content for part " + wsdlPart.getName()); } if ( wsdlPart.getElementName() != null ) { msgParts.add(jbiWrapper.getPartAsElement(i)); } else { // it is type. create a new element for a typed part // check the element name is same as part String prefix = msgType.getPrefix(); String nsURI = msgType.getNamespaceURI(); String localName = wsdlPart.getName(); Element partEl = newDoc.createElementNS(nsURI, prefix + ":" + localName); partEl.setAttributeNS(XMLNS_NS, "xmlns:"+prefix, nsURI); NodeList partContent = jbiWrapper.getPart(i); appendChildren(partEl, partContent, newDoc, true); msgParts.add(partEl); } } return msgParts; } /** * utility method that can append the nodeList passed to it to the element children. * @param el element node to which the nodeList should be appended * @param doc the document object that should be used to import the nodeList * @param importNode true if the nodeList should be imported while appending the nodeList to the * element children. false if no import is necessary. */ protected void appendChildren(Element el, NodeList nodeList, Document doc, boolean importNode) { for ( int pIdx = 0; pIdx < nodeList.getLength(); ++pIdx) { Node node = nodeList.item(pIdx); if ( importNode ) { node = doc.importNode(node, true); } el.appendChild(node); } } /** * @param el element from which to extract the child elements * @return List list of child Element nodes. */ protected List getChildElements(Element el) { List list = new ArrayList(); NodeList nodeList = el.getChildNodes(); for ( int i=0; i < nodeList.getLength(); ++i) { Node node = nodeList.item(i); if (!(node instanceof Element) ){ continue; } list.add((Element)node); } return list; } }