FileDocCategorySizeDatePackage
MessageNormalizerImpl.javaAPI DocGlassfish v2 API20424Fri May 04 22:30:28 BST 2007com.sun.enterprise.jbi.serviceengine.util.soap

MessageNormalizerImpl

public class MessageNormalizerImpl extends Object implements MessageNormalizer
This implementation converts a SOAP request message to a JBI specific format which can be understood by other JBI components.
author
Sun Microsystems, Inc.

Fields Summary
private Logger
mLogger
Internal handle to the logger instance
private StringTranslator
mStringTranslator
Internal handle to String Translator instance.
Constructors Summary
public MessageNormalizerImpl()
Creates a new instance of MessageNormalizerImpl.

        mLogger = Logger.getLogger(this.getClass().getPackage().getName());
        mStringTranslator = new StringTranslator(this.getClass().getPackage().getName(), this.getClass().getClassLoader());
    
Methods Summary
private voidappendSOAPNodeToDOMNode(org.w3c.dom.Document document, org.w3c.dom.Node domNode, javax.xml.soap.Node soapNode)
Appends a SOAP Node to a DOM Node, by creating DOM Node objects to represent the same information in the SOAP Node. The Document object is needed as a factory to create DOM Node objects.

    org.w3c.dom.Node newDOMNode = createDOMNodeFromSOAPNode(soapNode, document);

    // Now that the new element is completely constructed (including its
    // children), add it to the parent element.

    domNode.appendChild(newDOMNode);
    
private org.w3c.dom.NodecreateDOMNodeFromSOAPNode(javax.xml.soap.Node soapNode, org.w3c.dom.Document document)
Creates a DOM Node from a SOAP Node, using the given DOM Document object to own the DOM Node.

    org.w3c.dom.Node result = null;

    // First figure out what type the soapNode is. Unlike DOM nodes, there
    // is no "nodeType" property, so we have to use reflection.
    if (soapNode instanceof SOAPElement)
    {
        SOAPElement soapElement = (SOAPElement) soapNode;
        Name name = soapElement.getElementName();

        // Create the DOM Element.
        if( (name.getURI().length() != 0) && (name.getQualifiedName().length() != 0) )
            result = document.createElementNS(name.getURI(), name.getQualifiedName());
        else if(name.getLocalName() != null)
            result = document.createElement(name.getLocalName());
        else
        {
            //What to do??
        }

        // Iterate through the attributes of the SOAP node and add each one
        // to the DOM Node.
        for (Iterator iter = soapElement.getAllAttributes();iter.hasNext(); )
        {
            Name attrName = (Name) iter.next();
            String attrValue = soapElement.getAttributeValue(attrName);

            // The createAttributeNS method fails if you give it a null URI.
            Attr attribute = null;
            if (attrName.getURI() == null)
                attribute = document.createAttribute(attrName.getQualifiedName());
            else
                attribute = document.createAttributeNS(attrName.getURI(),attrName.getQualifiedName());

            attribute.setValue(attrValue);

            ((Element) result).setAttributeNodeNS(attribute);
        }

        // Iterate through the child elements of the SOAP node, recursing
        // on this method to add the child SOAP node to the newly created
        // DOM node.
        for (Iterator iter = soapElement.getChildElements(); iter.hasNext(); )
        {
            javax.xml.soap.Node childSOAPNode = (javax.xml.soap.Node) iter.next();
            appendSOAPNodeToDOMNode(document, result, childSOAPNode);
        }
    }
    else if (soapNode instanceof javax.xml.soap.Text)
    {
        javax.xml.soap.Text textNode = (javax.xml.soap.Text) soapNode;
        String textValue = textNode.getValue();

        // A text node can either be a comment or a real text node.
        if (textNode.isComment())
            result = document.createComment(textValue);
        else
            result = document.createTextNode(textValue);
    }
    else
    {
    // Not sure what to do here.
    }

    return (result);
    
private static voiddump(javax.xml.transform.Source source)

         TransformerFactory  tf      = TransformerFactory.newInstance();
         Transformer         t       = tf.newTransformer();
         StreamResult        stdOut  = new StreamResult(System.out);

         System.out.println("[BEGIN_MESSAGE_DUMP]");
         t.transform(source, stdOut);
         System.out.println("[END_MESSAGE_DUMP]");
    
private java.lang.StringextractFaultCode(java.lang.String completeFaultCode)
Extracts the fault code from the String.

param
completeFaultCode fault code containing the namespace prefix and the code.
return
the fault code without the namespace prefix

        String faultCode;
        StringTokenizer tokenizer = new StringTokenizer(completeFaultCode,
                                                        ":");
        if ( tokenizer.countTokens() == 1)
        {
            faultCode = completeFaultCode;
        }
        else
        {
            // Discard the first token which is hte namespace prefix.
            tokenizer.nextToken();
            faultCode = tokenizer.nextToken();
        }
        return faultCode;
    
protected org.w3c.dom.NodeextractPayload(javax.xml.soap.SOAPBody soapBody, Operation operation, boolean isFault)
Extracts request/response payload from the soap body.

param
soapBody soap body message.
param
operation operation requested.
param
isFault boolean indicating if it is a fault.
return
request payload
throws
JBIException - if request could not be extracted.

	mLogger.fine( mStringTranslator.getString("SBC_EXTRACT_REQUEST_PAYLOAD") );

        return getChildElement(soapBody);
    
private org.w3c.dom.NodegetBodyContentsAsNode(javax.xml.soap.SOAPBody body)

        org.w3c.dom.Node dNode = null;
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document mDoc = builder.newDocument();

            Iterator iter2 = body.getChildElements();
            //This code will not work if there are multiple child elements under
            // soap:Body
            while (iter2.hasNext()) {
                javax.xml.soap.Node n = (javax.xml.soap.Node)iter2.next();
                if(n instanceof SOAPElement)
                {
                    dNode = createDOMNodeFromSOAPNode(n, mDoc);
                    //dump(new DOMSource(dNode));
                    break;
                }
            }
        }
        catch(ParserConfigurationException pce)
        {
            pce.printStackTrace();
            return null;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return dNode;
        
    
private org.w3c.dom.NodegetChildElement(org.w3c.dom.Node parentNode)
Extracts the first Element node from the parent node.

param
parentNode parent node
return
first child element node.

        NodeList childNodes = parentNode.getChildNodes();
        Node currentNode = null;
        Node elementNode = null;

        for (int i = 0; i < childNodes.getLength(); i++)
        {
            currentNode = childNodes.item(i);

            if (currentNode.getNodeType() == Node.ELEMENT_NODE)
            {
                elementNode = currentNode;

                break;
            }
        }

        return elementNode;
    
public booleanisFault(int responseCode)
Used to check if the response code corresponds to a fault.

param
responseCode response code
return
true if it is a fault; false otherwise.

        return false;
    
private voidnormalizeAttachments(javax.xml.soap.SOAPMessage soapMessage, javax.jbi.messaging.NormalizedMessage normalizedMessage)
Normalizes the attachments sent as part of the SoapMessage.

param
soapMessage soap Message
param
normalizedMessage normalized Message
throws
SOAPException if soap message cannot be read
throws
MessagingException if attachments cannot be added to normalized message.

        if ( soapMessage != null)
        {
            if ( soapMessage.countAttachments() > 0  )
            {
                Iterator attachmentIter = soapMessage.getAttachments();
                for (; attachmentIter.hasNext();)
                {
                    AttachmentPart attachment = (AttachmentPart) attachmentIter.next();
                    DataHandler dataHandler = attachment.getDataHandler();
                    String contentId = attachment.getContentId();
                    normalizedMessage.addAttachment( contentId, dataHandler);
                }
            }
        }
    
public voidnormalizeFaultMessage(SOAPWrapper soapWrapper, javax.jbi.messaging.NormalizedMessage normalizedMessage)
Converts a SOAP Fault Message to a NormalizedMessage format.

param
soapWrapper request message.
param
normalizedMessage jbi specific format.
throws
JBIException if the message cannot be normalized.


        try
        {
            SOAPMessage soapMessage = soapWrapper.getMessage();

            if (soapMessage != null)
            {
                SOAPPart soapPart = soapMessage.getSOAPPart();
                SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
                SOAPBody soapBody = soapEnvelope.getBody();
                if ( soapBody.hasFault() )
                {
                    // The Message contains a fault detail element.
                    // Propogate the details in the message content.
                    // ,fault string  and fault actor in the message properties.

		    mLogger.fine(mStringTranslator.getString("SBC_FAULT_ELEMENT_FOUND"));

                    SOAPFault soapFault = soapBody.getFault();
                    Detail soapDetail = soapFault.getDetail();
                    if ( soapDetail != null )
                    {
                        normalizedMessage.setContent(
                                            new DOMSource(
                                                getChildElement(soapDetail)));
                        // Populate the SOAP Header into the message context
                        SOAPHeader soapHeader = soapEnvelope.getHeader();

                        if (soapHeader != null)
                        {
                            normalizedMessage.setProperty(
                                SOAPConstants.HEADER_PROPERTY_NAME,
                                soapHeader);
                        }
                        normalizedMessage.setProperty(
                                        SOAPConstants.FAULT_STRING_PROPERTY_NAME,
                                        soapFault.getFaultString());
                        normalizedMessage.setProperty(
                                        SOAPConstants.FAULT_CODE_PROPERTY_NAME,
                                        extractFaultCode( soapFault.getFaultCode()) );
                    }
                    else
                    {
                        // The Message does not contain fault detail. Propogate details
                        // as a JBIException.
                        throw new JBIException( soapFault.getFaultString() );
                    }


                }
                else
                {
                    // this should not happen.
		    mLogger.severe(mStringTranslator.getString("SBC_ALGORITHM_ERROR"));
                }
            }
        }
        catch (SOAPException soapException)
        {
	    mLogger.severe ( mStringTranslator.getString("SBC_NORMALIZE_FAULT_MESSAGE_FAILURE") );

	    mLogger.severe( mStringTranslator.getString("SBC_ERROR_DETAILS") );
            JBIException jbiException =
                    new JBIException(
                       mStringTranslator.getString(
                                     "SBC_NORMALIZE_FAULT_MESSAGE_FAILURE") );
            jbiException.initCause(soapException);
            throw jbiException;
        }
    
public voidnormalizeMessage(SOAPWrapper soapWrapper, javax.jbi.messaging.NormalizedMessage normalizedMessage, Operation operation)
Converts a SOAP Message to a NormalizedMessage format.

param
soapWrapper request message.
param
normalizedMessage jbi specific format.
param
operation operation requested.
throws
JBIException if the message cannot be normalized.

        if ( soapWrapper.getStatus() == HttpURLConnection.HTTP_INTERNAL_ERROR )
        {
            normalizeFaultMessage( soapWrapper, normalizedMessage);
        }
        else
        {
            normalizeResponseMessage( soapWrapper, normalizedMessage, operation);
        }
    
public voidnormalizeResponseMessage(SOAPWrapper soapWrapper, javax.jbi.messaging.NormalizedMessage normalizedMessage, Operation operation)
Converts a SOAP Response Message to a JBI NormalizedMessage.

param
soapWrapper request message.
param
normalizedMessage jbi normalized message.
param
operation operation details.
throws
JBIException if the message cannot be normalized.

	mLogger.fine( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE") );
        try
        {
            SOAPMessage soapMessage = soapWrapper.getMessage();

            if (soapMessage != null)
            {
                SOAPPart soapPart = soapMessage.getSOAPPart();
                SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
                SOAPBody soapBody = soapEnvelope.getBody();

                // Check whether the soap body has all namespace prefixes resolved.
                // If not resolve them
                // Populate the SOAP body into the message content.
                org.w3c.dom.Node bodyContents = getBodyContentsAsNode(soapBody);
                DOMSource ds = new DOMSource(bodyContents);
                //dump(ds);
                normalizedMessage.setContent(ds);
                       /* extractPayload(soapBody, operation,
                        isFault(soapWrapper.getStatus()))));*/

                // Attach attachments to the normalizedMessage
                normalizeAttachments(soapMessage, normalizedMessage);

                // Populate the SOAP Header into the message context
                SOAPHeader soapHeader = soapEnvelope.getHeader();

                if (soapHeader != null)
                {
                    //normalizedMessage.setProperty(
                    //    SOAPConstants.HEADER_PROPERTY_NAME, soapHeader);
                }
            }

            Iterator messageProperties = soapWrapper.getProperties();

            for (; messageProperties.hasNext();)
            {
                String propertyName = (String) messageProperties.next();
                normalizedMessage.setProperty(
                    propertyName, soapWrapper.getValue(propertyName));
            }
        }
        catch (RuntimeException runtimeException)
        {
            // This should not happen.
	    mLogger.severe ( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE_FAILURE_RT_EXP") );

            JBIException jbiException = new JBIException(
                                            mStringTranslator.getString(
                                            "SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
            jbiException.initCause(runtimeException);
            throw jbiException;
        }
        catch (SOAPException soapException)
        {
	    mLogger.severe( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
	    mLogger.severe( mStringTranslator.getString("SBC_ERROR_DETAILS", soapException.toString()) );

            JBIException jbiException = new JBIException(
                                    mStringTranslator.getString(
                                     "SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
            jbiException.initCause(soapException);
            throw jbiException;
        }
        catch(Exception ex)
        {
            mLogger.severe("Some Exception while dumping Source.");
            ex.printStackTrace();
        }

	mLogger.fine( mStringTranslator.getString("SBC_SUCCESS_NORMALISE_SUCCESS") );