View Javadoc

1    /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   
9   package it.imolinfo.jbi4corba.jbi.processor;
10  
11  import it.imolinfo.jbi4corba.Logger;
12  import it.imolinfo.jbi4corba.LoggerFactory;
13  import it.imolinfo.jbi4corba.exception.Jbi4CorbaException;
14  import it.imolinfo.jbi4corba.jbi.Messages;
15  import it.imolinfo.jbi4corba.jbi.endpoint.Jbi4CorbaEndpoint;
16  
17  import java.util.Iterator;
18  import java.util.Map;
19  
20  import javax.jbi.messaging.Fault;
21  import javax.jbi.messaging.MessagingException;
22  import javax.jbi.messaging.NormalizedMessage;
23  import javax.wsdl.Operation;
24  import javax.wsdl.Part;
25  import javax.wsdl.Port;
26  import javax.wsdl.PortType;
27  import javax.wsdl.Service;
28  import javax.xml.namespace.QName;
29  import javax.xml.transform.Source;
30  import javax.xml.transform.Transformer;
31  import javax.xml.transform.TransformerConfigurationException;
32  import javax.xml.transform.TransformerException;
33  import javax.xml.transform.TransformerFactory;
34  import javax.xml.transform.TransformerFactoryConfigurationError;
35  import javax.xml.transform.dom.DOMResult;
36  import javax.xml.transform.dom.DOMSource;
37  
38  import org.w3c.dom.Document;
39  import org.w3c.dom.Element;
40  import org.w3c.dom.Node;
41  
42  import com.sun.jbi.nms.wsdl11wrapper.HelperFactory;
43  import com.sun.jbi.nms.wsdl11wrapper.WrapperBuilder;
44  import com.sun.jbi.nms.wsdl11wrapper.WrapperProcessingException;
45  
46  
47  /**
48   * Message normalizer class (convert Source to nmr message).
49   * 
50   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>
51   */
52  @SuppressWarnings("unchecked")
53  public class MessageNormalizer {
54      
55      /** The Constant LOG. */
56      private static final Logger LOG
57          = LoggerFactory.getLogger(MessageDenormalizer.class);
58  
59      /** The m trans. */
60      private Transformer mTrans = null;
61      
62      /** The wrapper builder. */
63      private WrapperBuilder wrapperBuilder = null;
64      
65     
66  	/**
67  	 * The responsible to translate localized messages.
68  	 */
69  	private static final Messages MESSAGES = Messages
70  			.getMessages(MessageNormalizer.class);
71      
72      /**
73       * Instantiates a new message normalizer.
74       * 
75       * @throws Jbi4CorbaException if some error occurs in the normalizer creation
76       */
77      public MessageNormalizer() throws Jbi4CorbaException {
78                  
79          try {
80              wrapperBuilder = HelperFactory.createBuilder();        
81          } catch (WrapperProcessingException ex) {
82  			String msg = MESSAGES.getString("CRB000807_Unable_to_instantiate_normalizer");
83  			LOG.error(msg, ex.getMessage());
84              throw new Jbi4CorbaException(ex);
85          }
86          
87          try {
88              TransformerFactory factory = TransformerFactory.newInstance();
89              mTrans = factory.newTransformer();
90          } catch (TransformerFactoryConfigurationError ex) {
91  			String msg = MESSAGES.getString("CRB000807_Unable_to_instantiate_normalizer");
92  			LOG.error(msg, ex.getMessage());
93              throw new Jbi4CorbaException(ex);
94          } catch (TransformerConfigurationException e) {
95  			String msg = MESSAGES.getString("CRB000807_Unable_to_instantiate_normalizer");
96  			LOG.error(msg, e.getMessage());
97              throw new Jbi4CorbaException(e);
98          }               
99      }
100         
101     /**
102      * Normalize the message.
103      * 
104      * @param xmlSource the xmlSource to normalize
105      * @param normalizedMsg the normlized message
106      * @param endpoint the invoked endpoint
107      * @param operation the invoked operation
108      * @param toWrap if the message must be wrapped
109      * @param isOutput true if the output is an output message
110      * 
111      * @throws Jbi4CorbaException if some problem occurs in normalization
112      */
113     public void normalize(Source xmlSource,
114             NormalizedMessage normalizedMsg,
115             Jbi4CorbaEndpoint endpoint,
116             QName operation, boolean toWrap, boolean isOutput) throws Jbi4CorbaException {
117 
118         try {
119 
120             Service service  = endpoint.getDefinition().getService(endpoint.getServiceName());
121             Port port = service.getPort(QName.valueOf(endpoint.getEndpointName()).getLocalPart());
122             PortType portType = port.getBinding().getPortType();
123 
124             // Grab the operation that matches the operationName.  There actually may
125             // be more than one operation with the same name (but different input/output)
126             // names.  We need to fix this so that we uniquely identify which operation we're
127             // going after
128             Iterator it = portType.getOperations().iterator();
129             javax.wsdl.Message wsdlMessage = null;
130             while (it.hasNext()) {
131                 Operation op = (Operation)it.next();
132                 if (op.getName().equals(operation.toString()) ||
133                         op.getName().equals(operation.getLocalPart())) {                    
134                     // Its' always an outputisWrapped
135                     if (isOutput) {
136                         wsdlMessage = op.getOutput().getMessage();                        
137                     } else {
138                         wsdlMessage = op.getInput().getMessage();
139                     }
140                 }
141             }
142             
143             wrapperBuilder.initialize(null,
144                     wsdlMessage,
145                     null);
146 
147             if (LOG.isDebugEnabled()) {                           
148                 LOG.debug("WSDL Message: " + wsdlMessage);
149                 LOG.debug("WSDL Message Parts: " + wsdlMessage.getParts());
150             }
151 
152             // Take ALWAYS the first (should be the only) part
153             if (wsdlMessage.getParts().values().size() == 0) {
154 				String msg = MESSAGES.getString("CRB000804_No_message_parts_found");
155 				LOG.error(msg);
156                 throw new Jbi4CorbaException(msg);                
157             } else if (wsdlMessage.getParts().values().size() > 1) {
158                 String msg = "More than one message part found: using the first";
159                 LOG.warn(msg);
160             }
161             
162             Part part = (Part)wsdlMessage.getParts().values().iterator().next();        
163 
164             // String[] partNames = wsdlMessage.getParts().values().iterator().next(); 
165             String partName = part.getName();
166 
167             Node node = null;
168             if (xmlSource instanceof DOMSource) {
169                 // saves a transformation
170                 node = ((DOMSource) xmlSource).getNode();
171             } else {
172                 DOMResult domResult = new DOMResult();
173                 mTrans.transform(xmlSource, domResult);
174                 node = domResult.getNode();                
175             }
176             
177             DOMSource domSource = null;
178             // If do not need wrapping, return the document
179             if (!toWrap) {
180                 domSource =  new DOMSource(node);
181             } else {
182                 // needs wrapping
183                 if (node instanceof Document) {
184                     wrapperBuilder.addPart(partName, ((Document) node).getDocumentElement());
185                 } else if (node instanceof Element) {
186                     wrapperBuilder.addPart(partName, (Element) node);
187                 } else {
188         			String msg = MESSAGES
189 							.getString(
190 									"CRB000809_Error_in_normalizing_the_messsage_Invalid_result_from_XML_transformation",
191 									new java.lang.Object[] { node.getClass() });
192 					LOG.error(msg);
193 					throw new Jbi4CorbaException(msg);
194                 }
195                 Document doc = wrapperBuilder.getResult();            
196                 domSource = new DOMSource(doc);
197             }
198 
199             normalizedMsg.setContent(domSource);
200         } catch (WrapperProcessingException ex) {
201 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
202 			LOG.error(msg, ex.getMessage());
203             throw new Jbi4CorbaException(msg);
204         } catch (TransformerException ex) {
205 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
206 			LOG.error(msg, ex.getMessage());
207             throw new Jbi4CorbaException(msg);            
208         } catch (MessagingException ex) {
209 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
210 			LOG.error(msg, ex.getMessage());
211             throw new Jbi4CorbaException(msg);                        
212         }
213     }
214     
215     /**
216      * Normalize the message.
217      * 
218      * @param xmlSource the xmlSource to normalize
219      * @param endpoint the invoked endpoint
220      * @param operation the invoked operation
221      * @param toWrap if the message must be wrapped
222      * @param isOutput true if the message is an output message
223      * 
224      * @return
225      * 
226      * @throws Jbi4CorbaException if some problem occurs in normalization
227      */
228     public Source normalize(Source xmlSource,            
229             Jbi4CorbaEndpoint endpoint,
230             QName operation, boolean toWrap, boolean isOutput) throws Jbi4CorbaException {
231 
232         try {
233 
234             Service service  = endpoint.getDefinition().getService(endpoint.getServiceName());
235             Port port = service.getPort(QName.valueOf(endpoint.getEndpointName()).getLocalPart());
236             PortType portType = port.getBinding().getPortType();
237 
238             // Grab the operation that matches the operationName.  There actually may
239             // be more than one operation with the same name (but different input/output)
240             // names.  We need to fix this so that we uniquely identify which operation we're
241             // going after
242             Iterator it = portType.getOperations().iterator();
243             javax.wsdl.Message wsdlMessage = null;
244             while (it.hasNext()) {
245                 Operation op = (Operation)it.next();
246                 if (op.getName().equals(operation.toString()) ||
247                         op.getName().equals(operation.getLocalPart())) {                    
248                     if (isOutput) {
249                         wsdlMessage = op.getOutput().getMessage();                                                
250                     } else {
251                         wsdlMessage = op.getInput().getMessage();
252                     }
253                 }
254             }
255             
256             wrapperBuilder.initialize(null,
257                     wsdlMessage,
258                     null);
259 
260             if (LOG.isDebugEnabled()) {                           
261                 LOG.debug("WSDL Message: " + wsdlMessage);
262                 LOG.debug("WSDL Message Parts: " + wsdlMessage.getParts());
263             }
264 
265             // Take ALWAYS the first (should be the only) part
266             if (wsdlMessage.getParts().values().size() == 0) {
267 				String msg = MESSAGES.getString("CRB000804_No_message_parts_found");
268 				LOG.error(msg);
269                 throw new Jbi4CorbaException(msg);                
270             } else if (wsdlMessage.getParts().values().size() > 1) {
271                 String msg = "More than one message part found: using the first";
272                 LOG.warn(msg);
273             }
274             
275             Part part = (Part)wsdlMessage.getParts().values().iterator().next();        
276 
277             // String[] partNames = wsdlMessage.getParts().values().iterator().next(); 
278             String partName = part.getName();
279 
280             Node node = null;
281             if (xmlSource instanceof DOMSource) {
282                 // saves a transformation
283                 node = ((DOMSource) xmlSource).getNode();
284             } else {
285                 DOMResult domResult = new DOMResult();
286                 mTrans.transform(xmlSource, domResult);
287                 node = domResult.getNode();                
288             }
289             
290             DOMSource domSource = null;
291             // If do not need wrapping, return the document
292             if (!toWrap) {
293                 domSource =  new DOMSource(node);
294             } else {
295                 // needs wrapping
296                 if (node instanceof Document) {
297                     wrapperBuilder.addPart(partName, ((Document) node).getDocumentElement());
298                 } else if (node instanceof Element) {
299                     wrapperBuilder.addPart(partName, (Element) node);
300                 } else {
301 					String msg = MESSAGES
302 							.getString(
303 									"CRB000809_Error_in_normalizing_the_messsage_Invalid_result_from_XML_transformation",
304 									new java.lang.Object[] { node.getClass() });
305 					LOG.error(msg);
306 					throw new Jbi4CorbaException(msg);
307 				}
308                 Document doc = wrapperBuilder.getResult();            
309                 domSource = new DOMSource(doc);
310             }
311             
312             return domSource;
313             
314         } catch (WrapperProcessingException ex) {
315 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
316 			LOG.error(msg, ex.getMessage());
317             throw new Jbi4CorbaException(msg);
318         } catch (TransformerException ex) {
319 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
320 			LOG.error(msg, ex.getMessage());
321             throw new Jbi4CorbaException(msg);            
322         } 
323     }    
324     
325 
326     /**
327      * Normalize a fault message.
328      * 
329      * @param xmlSource
330      *            The xml fault source
331      * @param fault
332      *            The Fault
333      * @param endpoint
334      *            The jbi4ejb endpoint
335      * @param operation
336      *            The operation
337      * @param faultName
338      *            The fault name
339      * @param toWrap
340      *            If the fault must be wrapped
341      * @throws Jbi4CorbaException
342      *             If some problem occurs
343      */
344     public void normalizeFault(Source xmlSource,
345             Fault fault,
346             Jbi4CorbaEndpoint endpoint,
347             QName operation, String faultName, boolean toWrap) throws Jbi4CorbaException {
348         try {
349 
350             Service service  = endpoint.getDefinition().getService(endpoint.getServiceName());
351             Port port = service.getPort(QName.valueOf(endpoint.getEndpointName()).getLocalPart());
352             PortType portType = port.getBinding().getPortType();
353 
354             // Grab the operation that matches the operationName.  There actually may
355             // be more than one operation with the same name (but different input/output)
356             // names.  We need to fix this so that we uniquely identify which operation we're
357             // going after
358             Iterator it = portType.getOperations().iterator();
359             javax.wsdl.Message wsdlFault = null;
360 
361             while (it.hasNext()) {
362                 Operation op = (Operation)it.next();
363                 LOG.debug("Looking for operation: " + op.getName());
364                 if (op.getName().equals(operation.toString()) ||
365                         op.getName().equals(operation.getLocalPart())) {                    
366                     // Its' always an output
367                     Map faults = op.getFaults();
368                     Iterator faultIt = faults.values().iterator();                 
369                     while (faultIt.hasNext()) {                        
370                         javax.wsdl.Fault wsdlFaultTmp = (javax.wsdl.Fault) faultIt.next();
371                         LOG.debug("Looking for fault: " + faultName + ", found fault: " + wsdlFaultTmp.getName());
372                         if (wsdlFaultTmp.getName().equals(faultName)) {
373                             wsdlFault = wsdlFaultTmp.getMessage();
374                         }
375                         
376                     }
377                 }
378             }
379 
380             wrapperBuilder.initialize(null,
381                     wsdlFault,
382                     null);
383 
384             if (LOG.isDebugEnabled()) {                           
385                 LOG.debug("WSDL Fault: " + wsdlFault);
386                 LOG.debug("WSDL Fault Parts: " + wsdlFault.getParts());
387             }
388 
389             // Take ALWAYS the first (should be the only) part
390             if (wsdlFault.getParts().values().size() == 0) {
391 				String msg = MESSAGES.getString("CRB000804_No_message_parts_found");
392 				LOG.error(msg);
393                 throw new Jbi4CorbaException(msg);                
394             } else if (wsdlFault.getParts().values().size() > 1) {
395                 String msg = "More than one message part found: using the first";
396                 LOG.warn(msg);
397             }
398             
399             Part part = (Part)wsdlFault.getParts().values().iterator().next();        
400 
401             // String[] partNames = wsdlMessage.getParts().values().iterator().next(); 
402             String partName = part.getName();
403 
404             Node node = null;
405             if (xmlSource instanceof DOMSource) {
406                 // saves a transformation
407                 node = ((DOMSource) xmlSource).getNode();
408             } else {
409                 DOMResult domResult = new DOMResult();
410                 mTrans.transform(xmlSource, domResult);
411                 node = domResult.getNode();
412             }
413 
414             DOMSource domSource = null;
415             
416             if (!toWrap) {
417                 // If do not need wrapping, return the document
418                 domSource =  new DOMSource(node);
419             } else {
420                 // needs wrapping
421                 if (node instanceof Document) {
422                     wrapperBuilder.addPart(partName, ((Document) node).getDocumentElement());
423                 } else if (node instanceof Element) {
424                     wrapperBuilder.addPart(partName, (Element) node);
425                 } else {
426         			String msg = MESSAGES
427 							.getString(
428 									"CRB000809_Error_in_normalizing_the_messsage_Invalid_result_from_XML_transformation",
429 									new java.lang.Object[] { node.getClass() });
430 					LOG.error(msg);
431 					throw new Jbi4CorbaException(msg);
432                 }
433 
434                 Document doc = wrapperBuilder.getResult();
435                 domSource = new DOMSource(doc);
436             }
437             
438             fault.setContent(domSource);
439         } catch (WrapperProcessingException ex) {
440 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
441 			LOG.error(msg, ex.getMessage());
442             throw new Jbi4CorbaException(msg);
443         } catch (TransformerException ex) {
444 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
445 			LOG.error(msg, ex.getMessage());
446             throw new Jbi4CorbaException(msg);            
447         } catch (MessagingException ex) {
448 			String msg = MESSAGES.getString("CRB000808_Error_in_normalizing_the_messsage");
449 			LOG.error(msg, ex.getMessage());
450             throw new Jbi4CorbaException(msg);                        
451         }
452     }
453     
454            
455 }
456