View Javadoc

1   /*******************************************************************************
2    *  Copyright (c) 2005, 2006, 2007 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   
10  package it.imolinfo.jbi4ejb.processor;
11  
12  import it.imolinfo.jbi4ejb.Logger;
13  import it.imolinfo.jbi4ejb.LoggerFactory;
14  import it.imolinfo.jbi4ejb.exception.Jbi4EjbException;
15  import it.imolinfo.jbi4ejb.jbi.Messages;
16  import it.imolinfo.jbi4ejb.jbi.endpoint.Jbi4EjbEndpoint;
17  
18  import java.util.Iterator;
19  import java.util.Map;
20  
21  import javax.jbi.messaging.Fault;
22  import javax.jbi.messaging.MessagingException;
23  import javax.jbi.messaging.NormalizedMessage;
24  import javax.wsdl.Operation;
25  import javax.wsdl.Part;
26  import javax.wsdl.Port;
27  import javax.wsdl.PortType;
28  import javax.wsdl.Service;
29  import javax.xml.namespace.QName;
30  import javax.xml.transform.Source;
31  import javax.xml.transform.Transformer;
32  import javax.xml.transform.TransformerConfigurationException;
33  import javax.xml.transform.TransformerException;
34  import javax.xml.transform.TransformerFactory;
35  import javax.xml.transform.TransformerFactoryConfigurationError;
36  import javax.xml.transform.dom.DOMResult;
37  import javax.xml.transform.dom.DOMSource;
38  
39  import org.w3c.dom.Document;
40  import org.w3c.dom.Element;
41  import org.w3c.dom.Node;
42  
43  import com.sun.jbi.nms.wsdl11wrapper.HelperFactory;
44  import com.sun.jbi.nms.wsdl11wrapper.WrapperBuilder;
45  import com.sun.jbi.nms.wsdl11wrapper.WrapperProcessingException;
46  
47  
48  /**
49   * Jbi4Ejb normalizer class (convert Source to nmr message).
50   * 
51   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>
52   */
53  public class Jbi4EjbNormalizer {
54      
55      /** The Constant LOG. */
56      private static final Logger LOG
57          = LoggerFactory.getLogger(Jbi4EjbNormalizer.class);
58      private static final Messages MESSAGES 
59      = Messages.getMessages(Jbi4EjbNormalizer.class);
60  
61      /** The m trans. */
62      private Transformer mTrans = null;
63      
64      /** The wrapper builder. */
65      private WrapperBuilder wrapperBuilder = null;
66      
67      
68      /**
69       * Instantiates a new jbi4 ejb normalizer.
70       * 
71       * @throws Jbi4EjbException if some error occurs in the normalizer creation
72       */
73      public Jbi4EjbNormalizer() throws Jbi4EjbException {
74                  
75          try {
76              wrapperBuilder = HelperFactory.createBuilder();        
77          } catch (WrapperProcessingException ex) {
78          	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
79              LOG.error(msg,ex);
80              throw new Jbi4EjbException(msg,ex);
81          }
82          
83          try {
84              TransformerFactory factory = TransformerFactory.newInstance();
85              mTrans = factory.newTransformer();
86          } catch (TransformerFactoryConfigurationError ex) {
87          	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
88              LOG.error(msg,ex);
89              throw new Jbi4EjbException(msg,ex);
90          } catch (TransformerConfigurationException e) {
91          	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{e.getMessage()});
92              LOG.error(msg,e);
93              throw new Jbi4EjbException(msg,e);
94          }               
95      }
96          
97      /**
98       * Normalize the message.
99       * 
100      * @param xmlSource
101      *            the xmlSource to normalize
102      * @param normalizedMsg
103      *            the normlized message
104      * @param endpoint
105      *            the invoked endpoint
106      * @param operation
107      *            the invoked operation
108      * @param toWrap
109      *              if the message must be wrapped
110      * @throws Jbi4EjbException
111      *             if some problem occurs in normalization
112      */
113     public void normalize(Source xmlSource,
114             NormalizedMessage normalizedMsg,
115             Jbi4EjbEndpoint endpoint,
116             QName operation, boolean toWrap) throws Jbi4EjbException {
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                     wsdlMessage = op.getOutput().getMessage();
136                 }
137             }
138             
139             wrapperBuilder.initialize(null,
140                     wsdlMessage,
141                     null);
142 
143             if (LOG.isDebugEnabled()) {                           
144                 LOG.debug("WSDL Message: " + wsdlMessage);
145                 LOG.debug("WSDL Message Parts: " + wsdlMessage.getParts());
146             }
147 
148             // Take ALWAYS the first (should be the only) part
149             if (wsdlMessage.getParts().values().size() == 0) {
150             	String msg=MESSAGES.getString("EJB000603_No_message_parts_found");
151                 LOG.error(msg);
152                 throw new Jbi4EjbException(msg);
153             } else if (wsdlMessage.getParts().values().size() > 1) {
154             	LOG.warn("EJB000604_More_than_one message_part_found_using_the_first");
155             }
156             
157             Part part = (Part)wsdlMessage.getParts().values().iterator().next();        
158 
159             // String[] partNames = wsdlMessage.getParts().values().iterator().next(); 
160             String partName = part.getName();
161 
162             Node node = null;
163             if (xmlSource instanceof DOMSource) {
164                 // saves a transformation
165                 node = ((DOMSource) xmlSource).getNode();
166             } else {
167                 DOMResult domResult = new DOMResult();
168                 mTrans.transform(xmlSource, domResult);
169                 node = domResult.getNode();                
170             }
171             
172             DOMSource domSource = null;
173             // If do not need wrapping, return the document
174             if (!toWrap) {
175                 domSource =  new DOMSource(node);
176             } else {
177                 // needs wrapping
178                 if (node instanceof Document) {
179                     wrapperBuilder.addPart(partName, ((Document) node).getDocumentElement());
180                 } else if (node instanceof Element) {
181                     wrapperBuilder.addPart(partName, (Element) node);
182                 } else {
183                 	String msg=MESSAGES.getString("EJB000605_Invalid_result_from_XML_transformation", new Object[]{node.getClass()});
184                     LOG.error(msg);
185                     throw new Jbi4EjbException(msg);
186                 }
187                 Document doc = wrapperBuilder.getResult();            
188                 domSource = new DOMSource(doc);
189             }
190 
191             normalizedMsg.setContent(domSource);
192         } catch (WrapperProcessingException ex) {
193         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
194             LOG.error(msg,ex);
195             throw new Jbi4EjbException(msg,ex);
196         } catch (TransformerException ex) {
197         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
198             LOG.error(msg,ex);
199             throw new Jbi4EjbException(msg,ex);           
200         } catch (MessagingException ex) {
201         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
202             LOG.error(msg,ex);
203             throw new Jbi4EjbException(msg,ex);                         
204         }
205     }
206     
207 
208     /**
209      * Normalize a fault message.
210      * 
211      * @param xmlSource
212      *            The xml fault source
213      * @param fault
214      *            The Fault
215      * @param endpoint
216      *            The jbi4ejb endpoint
217      * @param operation
218      *            The operation
219      * @param faultName
220      *            The fault name
221      * @param toWrap
222      *            If the fault must be wrapped
223      * @throws Jbi4EjbException
224      *             If some problem occurs
225      */
226     public void normalizeFault(Source xmlSource,
227             Fault fault,
228             Jbi4EjbEndpoint endpoint,
229             QName operation, String faultName, boolean toWrap) throws Jbi4EjbException {
230         try {
231 
232             Service service  = endpoint.getDefinition().getService(endpoint.getServiceName());
233             Port port = service.getPort(QName.valueOf(endpoint.getEndpointName()).getLocalPart());
234             PortType portType = port.getBinding().getPortType();
235 
236             // Grab the operation that matches the operationName.  There actually may
237             // be more than one operation with the same name (but different input/output)
238             // names.  We need to fix this so that we uniquely identify which operation we're
239             // going after
240             Iterator it = portType.getOperations().iterator();
241             javax.wsdl.Message wsdlFault = null;
242 
243             while (it.hasNext()) {
244                 Operation op = (Operation)it.next();
245                 LOG.debug("Looking for operation: " + op.getName());
246                 if (op.getName().equals(operation.toString()) ||
247                         op.getName().equals(operation.getLocalPart())) {                    
248                     // Its' always an output
249                     Map faults = op.getFaults();
250                     Iterator faultIt = faults.values().iterator();                 
251                     while (faultIt.hasNext()) {                        
252                         javax.wsdl.Fault wsdlFaultTmp = (javax.wsdl.Fault) faultIt.next();
253                         LOG.debug("Looking for fault: " + faultName + ", found fault: " + wsdlFaultTmp.getName());
254                         if (wsdlFaultTmp.getName().equals(faultName)) {
255                             wsdlFault = wsdlFaultTmp.getMessage();
256                         }
257                         
258                     }
259                 }
260             }
261 
262             wrapperBuilder.initialize(null,
263                     wsdlFault,
264                     null);
265 
266             if (LOG.isDebugEnabled()) {                           
267                 LOG.debug("WSDL Fault: " + wsdlFault);
268                 LOG.debug("WSDL Fault Parts: " + wsdlFault.getParts());
269             }
270 
271             // Take ALWAYS the first (should be the only) part
272             if (wsdlFault.getParts().values().size() == 0) {
273             	String msg=MESSAGES.getString("EJB000603_No_message_parts_found");
274                 LOG.error(msg);
275                 throw new Jbi4EjbException(msg);
276             } else if (wsdlFault.getParts().values().size() > 1) {
277             	LOG.warn("EJB000604_More_than_one message_part_found_using_the_first");
278             }
279             
280             Part part = (Part)wsdlFault.getParts().values().iterator().next();        
281 
282             // String[] partNames = wsdlMessage.getParts().values().iterator().next(); 
283             String partName = part.getName();
284 
285             Node node = null;
286             if (xmlSource instanceof DOMSource) {
287                 // saves a transformation
288                 node = ((DOMSource) xmlSource).getNode();
289             } else {
290                 DOMResult domResult = new DOMResult();
291                 mTrans.transform(xmlSource, domResult);
292                 node = domResult.getNode();
293             }
294 
295             DOMSource domSource = null;
296             
297             if (!toWrap) {
298                 // If do not need wrapping, return the document
299                 domSource =  new DOMSource(node);
300             } else {
301                 // needs wrapping
302                 if (node instanceof Document) {
303                     wrapperBuilder.addPart(partName, ((Document) node).getDocumentElement());
304                 } else if (node instanceof Element) {
305                     wrapperBuilder.addPart(partName, (Element) node);
306                 } else {
307                 	String msg=MESSAGES.getString("EJB000605_Invalid_result_from_XML_transformation", new Object[]{node.getClass()});
308                     LOG.error(msg);
309                     throw new Jbi4EjbException(msg);
310                 }
311 
312                 Document doc = wrapperBuilder.getResult();
313                 domSource = new DOMSource(doc);
314             }
315             
316             fault.setContent(domSource);
317         } catch (WrapperProcessingException ex) {
318         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
319             LOG.error(msg,ex);
320             throw new Jbi4EjbException(msg,ex);
321         } catch (TransformerException ex) {
322         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
323             LOG.error(msg,ex);
324             throw new Jbi4EjbException(msg,ex);          
325         } catch (MessagingException ex) {
326         	String msg=MESSAGES.getString("EJB000602_Jbi4Ejb_processor", new Object[]{ex.getMessage()});
327             LOG.error(msg,ex);
328             throw new Jbi4EjbException(msg,ex);                        
329         }
330     }
331     
332            
333 }
334