View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.cxf.support;
8   
9   import javax.xml.stream.XMLStreamWriter;
10  
11  import org.apache.commons.logging.Log;
12  import org.apache.commons.logging.LogFactory;
13  import org.apache.cxf.databinding.DataBinding;
14  import org.apache.cxf.databinding.DataWriter;
15  import org.apache.cxf.interceptor.Fault;
16  import org.apache.cxf.interceptor.FaultOutInterceptor;
17  import org.apache.cxf.message.Message;
18  import org.apache.cxf.service.Service;
19  import org.apache.cxf.service.model.BindingFaultInfo;
20  import org.apache.cxf.service.model.BindingOperationInfo;
21  import org.apache.cxf.service.model.FaultInfo;
22  import org.apache.cxf.service.model.MessagePartInfo;
23  import org.apache.cxf.staxutils.W3CDOMStreamWriter;
24  
25  /**
26   * Fault out interceptor for Proxy configuration considering that FaultInfo might not have an associated class
27   * and that it uses StaxDatabinding.
28   */
29  public class ProxyFaultOutInterceptor extends FaultOutInterceptor
30  {
31      protected transient Log logger = LogFactory.getLog(getClass());
32  
33      @Override
34      public void handleMessage(Message message) throws Fault {
35          Fault f = (Fault)message.getContent(Exception.class);
36  
37          Throwable cause = f.getCause();
38          if (cause == null) {
39              return;
40          }
41  
42          BindingOperationInfo bop = message.getExchange().get(BindingOperationInfo.class);
43          if (bop == null) {
44              return;
45          }
46          FaultInfo fi = getFaultForClass(bop, cause.getClass());
47  
48          if (cause instanceof Exception && fi != null) {
49              Exception ex = (Exception)cause;
50              Object bean = getFaultBean(cause, fi, message);
51              Service service = message.getExchange().get(Service.class);
52  
53              MessagePartInfo part = fi.getMessageParts().iterator().next();
54              DataBinding db = service.getDataBinding();
55  
56              try
57              {
58                  if (f.hasDetails())
59                  {
60                      XMLStreamWriter xsw = new W3CDOMStreamWriter(f.getDetail());
61                      DataWriter<XMLStreamWriter> writer = db.createWriter(XMLStreamWriter.class);
62                      writer.write(bean, part, xsw);
63                  } else
64                  {
65                      XMLStreamWriter xsw = new W3CDOMStreamWriter(f.getOrCreateDetail());
66                      DataWriter<XMLStreamWriter> writer = db.createWriter(XMLStreamWriter.class);
67                      writer.write(bean, part, xsw);
68                      if (!f.getDetail().hasChildNodes())
69                      {
70                          f.setDetail(null);
71                      }
72                  }
73  
74                  f.setMessage(ex.getMessage());
75              }
76              catch (Exception fex) {
77                  //ignore - if any exceptions occur here, we'll ignore them
78                  //and let the default fault handling of the binding convert
79                  //the fault like it was an unchecked exception.
80                  logger.warn("Exception while writing fault", fex);
81              }
82  
83          }
84      }
85  
86      @Override
87      public FaultInfo getFaultForClass(BindingOperationInfo op, Class class1) {
88          for (BindingFaultInfo bfi : op.getFaults()) {
89  
90              FaultInfo faultInfo = bfi.getFaultInfo();
91              Class<?> c = (Class)faultInfo.getProperty(Class.class.getName());
92              if (c != null && c.isAssignableFrom(class1)) {
93                  return faultInfo;
94              }
95          }
96  
97          return null;
98      }
99  
100 }