KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > jbi > serviceengine > util > soap > MessageNormalizerImpl


1 // Copyright (c) 2004-2005 Sun Microsystems Inc., All Rights Reserved.
2

3 /*
4  * MessageNormalizerImpl.java
5  *
6  * SUN PROPRIETARY/CONFIDENTIAL.
7  * This software is the proprietary information of Sun Microsystems, Inc.
8  * Use is subject to license terms.
9  *
10  */

11 package com.sun.enterprise.jbi.serviceengine.util.soap;
12
13 import org.w3c.dom.Node JavaDoc;
14 import org.w3c.dom.NodeList JavaDoc;
15
16 import java.util.Iterator JavaDoc;
17 import java.util.logging.Level JavaDoc;
18 import java.util.logging.Logger JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 import java.net.HttpURLConnection JavaDoc;
22
23 import javax.jbi.JBIException;
24 import javax.jbi.messaging.NormalizedMessage;
25 import javax.jbi.messaging.MessagingException;
26
27 import javax.xml.soap.Detail JavaDoc;
28 import javax.xml.soap.SOAPBody JavaDoc;
29 import javax.xml.soap.SOAPEnvelope JavaDoc;
30 import javax.xml.soap.SOAPException JavaDoc;
31 import javax.xml.soap.SOAPHeader JavaDoc;
32 import javax.xml.soap.SOAPMessage JavaDoc;
33 import javax.xml.soap.SOAPPart JavaDoc;
34 import javax.xml.soap.SOAPFault JavaDoc;
35 import javax.xml.soap.AttachmentPart JavaDoc;
36 import javax.xml.soap.SOAPElement JavaDoc;
37 import javax.xml.soap.Name JavaDoc;
38
39 import javax.activation.DataHandler JavaDoc;
40
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.DOMException JavaDoc;
43 import org.w3c.dom.NodeList JavaDoc;
44 import org.w3c.dom.Attr JavaDoc;
45 import org.w3c.dom.Element JavaDoc;
46 import javax.xml.transform.dom.DOMSource JavaDoc;
47 import javax.xml.transform.stream.StreamSource JavaDoc;
48 import javax.xml.transform.TransformerFactory JavaDoc;
49 import javax.xml.transform.Transformer JavaDoc;
50 import javax.xml.transform.stream.StreamResult JavaDoc;
51 import javax.xml.transform.Source JavaDoc;
52
53 import javax.xml.parsers.DocumentBuilder JavaDoc;
54 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
55 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
56 import javax.xml.parsers.ParserConfigurationException JavaDoc;
57 /**
58  * This implementation converts a SOAP request message to a JBI specific format which can
59  * be understood by other JBI components.
60  *
61  * @author Sun Microsystems, Inc.
62  */

63 public class MessageNormalizerImpl implements MessageNormalizer
64 {
65     /**
66      * Internal handle to the logger instance
67      */

68     private Logger JavaDoc mLogger;
69
70     /**
71      * Internal handle to String Translator instance.
72      */

73     private StringTranslator mStringTranslator;
74
75     /**
76      * Creates a new instance of MessageNormalizerImpl.
77      *
78      */

79     public MessageNormalizerImpl()
80     {
81         mLogger = Logger.getLogger(this.getClass().getPackage().getName());
82         mStringTranslator = new StringTranslator(this.getClass().getPackage().getName(), this.getClass().getClassLoader());
83     }
84
85     /**
86      * Converts a SOAP Message to a NormalizedMessage format.
87      *
88      * @param soapWrapper request message.
89      * @param normalizedMessage jbi specific format.
90      * @param operation operation requested.
91      *
92      * @throws JBIException if the message cannot be normalized.
93      */

94     public void normalizeMessage(
95         SOAPWrapper soapWrapper, NormalizedMessage normalizedMessage,
96         Operation operation)
97         throws JBIException
98     {
99         if ( soapWrapper.getStatus() == HttpURLConnection.HTTP_INTERNAL_ERROR )
100         {
101             normalizeFaultMessage( soapWrapper, normalizedMessage);
102         }
103         else
104         {
105             normalizeResponseMessage( soapWrapper, normalizedMessage, operation);
106         }
107     }
108
109     /**
110      * Converts a SOAP Fault Message to a NormalizedMessage format.
111      *
112      * @param soapWrapper request message.
113      * @param normalizedMessage jbi specific format.
114      *
115      * @throws JBIException if the message cannot be normalized.
116      */

117     public void normalizeFaultMessage(
118         SOAPWrapper soapWrapper, NormalizedMessage normalizedMessage)
119         throws JBIException
120     {
121
122         try
123         {
124             SOAPMessage JavaDoc soapMessage = soapWrapper.getMessage();
125
126             if (soapMessage != null)
127             {
128                 SOAPPart JavaDoc soapPart = soapMessage.getSOAPPart();
129                 SOAPEnvelope JavaDoc soapEnvelope = soapPart.getEnvelope();
130                 SOAPBody JavaDoc soapBody = soapEnvelope.getBody();
131                 if ( soapBody.hasFault() )
132                 {
133                     // The Message contains a fault detail element.
134
// Propogate the details in the message content.
135
// ,fault string and fault actor in the message properties.
136

137             mLogger.fine(mStringTranslator.getString("SBC_FAULT_ELEMENT_FOUND"));
138
139                     SOAPFault JavaDoc soapFault = soapBody.getFault();
140                     Detail JavaDoc soapDetail = soapFault.getDetail();
141                     if ( soapDetail != null )
142                     {
143                         normalizedMessage.setContent(
144                                             new DOMSource JavaDoc(
145                                                 getChildElement(soapDetail)));
146                         // Populate the SOAP Header into the message context
147
SOAPHeader JavaDoc soapHeader = soapEnvelope.getHeader();
148
149                         if (soapHeader != null)
150                         {
151                             normalizedMessage.setProperty(
152                                 SOAPConstants.HEADER_PROPERTY_NAME,
153                                 soapHeader);
154                         }
155                         normalizedMessage.setProperty(
156                                         SOAPConstants.FAULT_STRING_PROPERTY_NAME,
157                                         soapFault.getFaultString());
158                         normalizedMessage.setProperty(
159                                         SOAPConstants.FAULT_CODE_PROPERTY_NAME,
160                                         extractFaultCode( soapFault.getFaultCode()) );
161                     }
162                     else
163                     {
164                         // The Message does not contain fault detail. Propogate details
165
// as a JBIException.
166
throw new JBIException( soapFault.getFaultString() );
167                     }
168
169
170                 }
171                 else
172                 {
173                     // this should not happen.
174
mLogger.severe(mStringTranslator.getString("SBC_ALGORITHM_ERROR"));
175                 }
176             }
177         }
178         catch (SOAPException JavaDoc soapException)
179         {
180         mLogger.severe ( mStringTranslator.getString("SBC_NORMALIZE_FAULT_MESSAGE_FAILURE") );
181
182         mLogger.severe( mStringTranslator.getString("SBC_ERROR_DETAILS") );
183             JBIException jbiException =
184                     new JBIException(
185                        mStringTranslator.getString(
186                                      "SBC_NORMALIZE_FAULT_MESSAGE_FAILURE") );
187             jbiException.initCause(soapException);
188             throw jbiException;
189         }
190     }
191
192
193     /**
194      * Converts a SOAP Response Message to a JBI NormalizedMessage.
195      *
196      * @param soapWrapper request message.
197      * @param normalizedMessage jbi normalized message.
198      * @param operation operation details.
199      *
200      * @throws JBIException if the message cannot be normalized.
201      */

202     public void normalizeResponseMessage(
203         SOAPWrapper soapWrapper, NormalizedMessage normalizedMessage,
204         Operation operation)
205         throws JBIException
206     {
207     mLogger.fine( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE") );
208         try
209         {
210             SOAPMessage JavaDoc soapMessage = soapWrapper.getMessage();
211
212             if (soapMessage != null)
213             {
214                 SOAPPart JavaDoc soapPart = soapMessage.getSOAPPart();
215                 SOAPEnvelope JavaDoc soapEnvelope = soapPart.getEnvelope();
216                 SOAPBody JavaDoc soapBody = soapEnvelope.getBody();
217
218                 // Check whether the soap body has all namespace prefixes resolved.
219
// If not resolve them
220
// Populate the SOAP body into the message content.
221
org.w3c.dom.Node JavaDoc bodyContents = getBodyContentsAsNode(soapBody);
222                 DOMSource JavaDoc ds = new DOMSource JavaDoc(bodyContents);
223                 //dump(ds);
224
normalizedMessage.setContent(ds);
225                        /* extractPayload(soapBody, operation,
226                         isFault(soapWrapper.getStatus()))));*/

227
228                 // Attach attachments to the normalizedMessage
229
normalizeAttachments(soapMessage, normalizedMessage);
230
231                 // Populate the SOAP Header into the message context
232
SOAPHeader JavaDoc soapHeader = soapEnvelope.getHeader();
233
234                 if (soapHeader != null)
235                 {
236                     //normalizedMessage.setProperty(
237
// SOAPConstants.HEADER_PROPERTY_NAME, soapHeader);
238
}
239             }
240
241             Iterator JavaDoc messageProperties = soapWrapper.getProperties();
242
243             for (; messageProperties.hasNext();)
244             {
245                 String JavaDoc propertyName = (String JavaDoc) messageProperties.next();
246                 normalizedMessage.setProperty(
247                     propertyName, soapWrapper.getValue(propertyName));
248             }
249         }
250         catch (RuntimeException JavaDoc runtimeException)
251         {
252             // This should not happen.
253
mLogger.severe ( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE_FAILURE_RT_EXP") );
254
255             JBIException jbiException = new JBIException(
256                                             mStringTranslator.getString(
257                                             "SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
258             jbiException.initCause(runtimeException);
259             throw jbiException;
260         }
261         catch (SOAPException JavaDoc soapException)
262         {
263         mLogger.severe( mStringTranslator.getString("SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
264         mLogger.severe( mStringTranslator.getString("SBC_ERROR_DETAILS", soapException.toString()) );
265
266             JBIException jbiException = new JBIException(
267                                     mStringTranslator.getString(
268                                      "SBC_NORMALIZE_SOAP_MESSAGE_FAILURE") );
269             jbiException.initCause(soapException);
270             throw jbiException;
271         }
272         catch(Exception JavaDoc ex)
273         {
274             mLogger.severe("Some Exception while dumping Source.");
275             ex.printStackTrace();
276         }
277
278     mLogger.fine( mStringTranslator.getString("SBC_SUCCESS_NORMALISE_SUCCESS") );
279     }
280
281     private org.w3c.dom.Node JavaDoc getBodyContentsAsNode(SOAPBody JavaDoc body)
282     {
283         org.w3c.dom.Node JavaDoc dNode = null;
284         try
285         {
286             DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
287             DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
288             Document JavaDoc mDoc = builder.newDocument();
289
290             Iterator JavaDoc iter2 = body.getChildElements();
291             //This code will not work if there are multiple child elements under
292
// soap:Body
293
while (iter2.hasNext()) {
294                 javax.xml.soap.Node JavaDoc n = (javax.xml.soap.Node JavaDoc)iter2.next();
295                 if(n instanceof SOAPElement JavaDoc)
296                 {
297                     dNode = createDOMNodeFromSOAPNode(n, mDoc);
298                     //dump(new DOMSource(dNode));
299
break;
300                 }
301             }
302         }
303         catch(ParserConfigurationException JavaDoc pce)
304         {
305             pce.printStackTrace();
306             return null;
307         }
308         catch(Exception JavaDoc e)
309         {
310             e.printStackTrace();
311             return null;
312         }
313         
314         return dNode;
315         
316     }
317
318    /**
319     * Creates a DOM Node from a SOAP Node, using the given DOM Document object
320     * to own the DOM Node.
321     */

322     private org.w3c.dom.Node JavaDoc createDOMNodeFromSOAPNode(javax.xml.soap.Node JavaDoc soapNode, Document JavaDoc document)
323     throws ParserConfigurationException JavaDoc
324     {
325     org.w3c.dom.Node JavaDoc result = null;
326
327     // First figure out what type the soapNode is. Unlike DOM nodes, there
328
// is no "nodeType" property, so we have to use reflection.
329
if (soapNode instanceof SOAPElement JavaDoc)
330     {
331         SOAPElement JavaDoc soapElement = (SOAPElement JavaDoc) soapNode;
332         Name JavaDoc name = soapElement.getElementName();
333
334         // Create the DOM Element.
335
if( (name.getURI().length() != 0) && (name.getQualifiedName().length() != 0) )
336             result = document.createElementNS(name.getURI(), name.getQualifiedName());
337         else if(name.getLocalName() != null)
338             result = document.createElement(name.getLocalName());
339         else
340         {
341             //What to do??
342
}
343
344         // Iterate through the attributes of the SOAP node and add each one
345
// to the DOM Node.
346
for (Iterator JavaDoc iter = soapElement.getAllAttributes();iter.hasNext(); )
347         {
348             Name JavaDoc attrName = (Name JavaDoc) iter.next();
349             String JavaDoc attrValue = soapElement.getAttributeValue(attrName);
350
351             // The createAttributeNS method fails if you give it a null URI.
352
Attr JavaDoc attribute = null;
353             if (attrName.getURI() == null)
354                 attribute = document.createAttribute(attrName.getQualifiedName());
355             else
356                 attribute = document.createAttributeNS(attrName.getURI(),attrName.getQualifiedName());
357
358             attribute.setValue(attrValue);
359
360             ((Element JavaDoc) result).setAttributeNodeNS(attribute);
361         }
362
363         // Iterate through the child elements of the SOAP node, recursing
364
// on this method to add the child SOAP node to the newly created
365
// DOM node.
366
for (Iterator JavaDoc iter = soapElement.getChildElements(); iter.hasNext(); )
367         {
368             javax.xml.soap.Node JavaDoc childSOAPNode = (javax.xml.soap.Node JavaDoc) iter.next();
369             appendSOAPNodeToDOMNode(document, result, childSOAPNode);
370         }
371     }
372     else if (soapNode instanceof javax.xml.soap.Text JavaDoc)
373     {
374         javax.xml.soap.Text JavaDoc textNode = (javax.xml.soap.Text JavaDoc) soapNode;
375         String JavaDoc textValue = textNode.getValue();
376
377         // A text node can either be a comment or a real text node.
378
if (textNode.isComment())
379             result = document.createComment(textValue);
380         else
381             result = document.createTextNode(textValue);
382     }
383     else
384     {
385     // Not sure what to do here.
386
}
387
388     return (result);
389     }
390
391     /**
392     * Appends a SOAP Node to a DOM Node, by creating DOM Node objects to
393     * represent the same information in the SOAP Node. The Document object is
394     * needed as a factory to create DOM Node objects.
395     */

396     private void appendSOAPNodeToDOMNode(Document JavaDoc document, org.w3c.dom.Node JavaDoc domNode,javax.xml.soap.Node JavaDoc soapNode)
397     throws ParserConfigurationException JavaDoc
398     {
399     org.w3c.dom.Node JavaDoc newDOMNode = createDOMNodeFromSOAPNode(soapNode, document);
400
401     // Now that the new element is completely constructed (including its
402
// children), add it to the parent element.
403

404     domNode.appendChild(newDOMNode);
405     }
406     
407     
408     private static void dump(Source JavaDoc source) throws Exception JavaDoc
409     {
410          TransformerFactory JavaDoc tf = TransformerFactory.newInstance();
411          Transformer JavaDoc t = tf.newTransformer();
412          StreamResult JavaDoc stdOut = new StreamResult JavaDoc(System.out);
413
414          System.out.println("[BEGIN_MESSAGE_DUMP]");
415          t.transform(source, stdOut);
416          System.out.println("[END_MESSAGE_DUMP]");
417     }
418     
419     
420     /**
421      * Extracts request/response payload from the soap body.
422      *
423      * @param soapBody soap body message.
424      * @param operation operation requested.
425      * @param isFault boolean indicating if it is a fault.
426      *
427      * @return request payload
428      *
429      * @throws JBIException - if request could not be extracted.
430      */

431     protected Node JavaDoc extractPayload(SOAPBody JavaDoc soapBody, Operation operation, boolean isFault)
432         throws JBIException
433     {
434     mLogger.fine( mStringTranslator.getString("SBC_EXTRACT_REQUEST_PAYLOAD") );
435
436         return getChildElement(soapBody);
437     }
438
439     /**
440      * Used to check if the response code corresponds to a fault.
441      *
442      * @param responseCode response code
443      *
444      * @return true if it is a fault; false otherwise.
445      */

446     public boolean isFault(int responseCode)
447     {
448         return false;
449     }
450
451     /**
452      * Extracts the first Element node from the parent node.
453      *
454      * @param parentNode parent node
455      *
456      * @return first child element node.
457      */

458     private Node JavaDoc getChildElement(Node JavaDoc parentNode)
459     {
460         NodeList JavaDoc childNodes = parentNode.getChildNodes();
461         Node JavaDoc currentNode = null;
462         Node JavaDoc elementNode = null;
463
464         for (int i = 0; i < childNodes.getLength(); i++)
465         {
466             currentNode = childNodes.item(i);
467
468             if (currentNode.getNodeType() == Node.ELEMENT_NODE)
469             {
470                 elementNode = currentNode;
471
472                 break;
473             }
474         }
475
476         return elementNode;
477     }
478
479     /**
480      * Extracts the fault code from the String.
481      *
482      * @param completeFaultCode fault code containing the namespace prefix and the code.
483      *
484      * @return the fault code without the namespace prefix
485      */

486     private String JavaDoc extractFaultCode(String JavaDoc completeFaultCode)
487     {
488         String JavaDoc faultCode;
489         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(completeFaultCode,
490                                                         ":");
491         if ( tokenizer.countTokens() == 1)
492         {
493             faultCode = completeFaultCode;
494         }
495         else
496         {
497             // Discard the first token which is hte namespace prefix.
498
tokenizer.nextToken();
499             faultCode = tokenizer.nextToken();
500         }
501         return faultCode;
502     }
503
504     /**
505      * Normalizes the attachments sent as part of the SoapMessage.
506      *
507      * @param soapMessage soap Message
508      * @param normalizedMessage normalized Message
509      *
510      * @throws SOAPException if soap message cannot be read
511      * @throws MessagingException if attachments cannot be added to normalized message.
512      */

513     private void normalizeAttachments(SOAPMessage JavaDoc soapMessage,
514                                       NormalizedMessage normalizedMessage)
515         throws SOAPException JavaDoc, MessagingException
516     {
517         if ( soapMessage != null)
518         {
519             if ( soapMessage.countAttachments() > 0 )
520             {
521                 Iterator JavaDoc attachmentIter = soapMessage.getAttachments();
522                 for (; attachmentIter.hasNext();)
523                 {
524                     AttachmentPart JavaDoc attachment = (AttachmentPart JavaDoc) attachmentIter.next();
525                     DataHandler JavaDoc dataHandler = attachment.getDataHandler();
526                     String JavaDoc contentId = attachment.getContentId();
527                     normalizedMessage.addAttachment( contentId, dataHandler);
528                 }
529             }
530         }
531     }
532 }
533
Popular Tags