1 17 package org.apache.servicemix.components.http; 18 19 import java.io.IOException ; 20 import java.util.Iterator ; 21 import java.util.Map ; 22 import java.util.Map.Entry; 23 24 import javax.jbi.JBIException; 25 import javax.jbi.component.ComponentContext; 26 import javax.jbi.messaging.DeliveryChannel; 27 import javax.jbi.messaging.ExchangeStatus; 28 import javax.jbi.messaging.InOnly; 29 import javax.jbi.messaging.InOut; 30 import javax.jbi.messaging.MessageExchange; 31 import javax.jbi.messaging.MessageExchangeFactory; 32 import javax.jbi.messaging.NormalizedMessage; 33 import javax.servlet.ServletException ; 34 import javax.servlet.http.HttpServletRequest ; 35 import javax.servlet.http.HttpServletResponse ; 36 import javax.xml.XMLConstants ; 37 import javax.xml.transform.Source ; 38 import javax.xml.transform.dom.DOMSource ; 39 40 import org.apache.servicemix.components.util.ComponentSupport; 41 import org.apache.servicemix.jbi.jaxp.SourceTransformer; 42 import org.codehaus.xfire.DefaultXFire; 43 import org.codehaus.xfire.MessageContext; 44 import org.codehaus.xfire.XFire; 45 import org.codehaus.xfire.aegis.AegisBindingProvider; 46 import org.codehaus.xfire.attachments.Attachment; 47 import org.codehaus.xfire.attachments.Attachments; 48 import org.codehaus.xfire.fault.XFireFault; 49 import org.codehaus.xfire.service.Service; 50 import org.codehaus.xfire.service.invoker.BeanInvoker; 51 import org.codehaus.xfire.service.binding.ObjectServiceFactory; 52 import org.codehaus.xfire.soap.SoapConstants; 53 import org.codehaus.xfire.soap.handler.ReadHeadersHandler; 54 import org.codehaus.xfire.transport.http.XFireServletController; 55 import org.w3c.dom.Document ; 56 import org.w3c.dom.Element ; 57 import org.w3c.dom.Node ; 58 59 public class HttpSoapInOutBinding extends ComponentSupport implements 60 HttpBinding { 61 62 protected XFire xfire; 63 protected XFireServletController controller; 64 protected Service service; 65 protected boolean defaultInOut = true; 66 protected String soapAction = "\"\""; 67 protected SourceTransformer transformer; 68 69 public HttpSoapInOutBinding() { 70 } 71 72 public void init(ComponentContext context) throws JBIException { 73 super.init(context); 74 xfire = new DefaultXFire(); 75 ObjectServiceFactory factory = new ObjectServiceFactory(xfire.getTransportManager(), 76 new AegisBindingProvider()); 77 factory.setVoidOneWay(true); 78 factory.setStyle(SoapConstants.STYLE_DOCUMENT); 79 if (isDefaultInOut()) { 80 service = factory.create(InOutService.class); 81 service.setInvoker(new BeanInvoker(new InOutService(this))); 82 } else { 83 service = factory.create(InOnlyService.class); 84 service.setInvoker(new BeanInvoker(new InOnlyService(this))); 85 } 86 xfire.getServiceRegistry().register(service); 87 controller = new Controller(xfire); 88 transformer = new SourceTransformer(); 89 } 90 91 public void process(HttpServletRequest request, HttpServletResponse response) 92 throws ServletException , IOException { 93 controller.doService(request, response); 94 } 95 96 public void invokeInOnly(Source source, MessageContext context) throws XFireFault { 97 if (source == null) { 98 throw new XFireFault("Invalid source.", XFireFault.SENDER); 99 } 100 try { 101 if (soapAction != null) { 102 XFireServletController.getResponse().setHeader("SOAPAction", soapAction); 103 } 104 DeliveryChannel channel = getDeliveryChannel(); 105 MessageExchangeFactory factory = channel.createExchangeFactory(); 106 InOnly exchange = factory.createInOnlyExchange(); 107 populateExchange(exchange, source, context); 108 boolean result = channel.sendSync(exchange); 109 if (!result) { 110 throw new XFireFault("Error sending exchange", XFireFault.SENDER); 111 } 112 } catch (XFireFault e) { 113 throw e; 114 } catch (Exception e) { 115 throw new XFireFault(e); 116 } 117 } 118 119 public Source invokeInOut(Source source, MessageContext context) throws XFireFault { 120 if (source == null) { 121 throw new XFireFault("Invalid source.", XFireFault.SENDER); 122 } 123 try { 124 if (soapAction != null) { 125 XFireServletController.getResponse().setHeader("SOAPAction", soapAction); 126 } 127 DeliveryChannel channel = getDeliveryChannel(); 128 MessageExchangeFactory factory = channel.createExchangeFactory(); 129 InOut exchange = factory.createInOutExchange(); 130 populateExchange(exchange, source, context); 131 boolean result = channel.sendSync(exchange); 132 if (!result) { 133 throw new XFireFault("Error sending exchange", XFireFault.SENDER); 134 } 135 if (exchange.getStatus() == ExchangeStatus.ERROR) { 136 Exception e = exchange.getError(); 137 if (e == null) { 138 throw new XFireFault("Received error", XFireFault.SENDER); 139 } else { 140 throw new XFireFault(e, XFireFault.SENDER); 141 } 142 } 143 NormalizedMessage outMessage = exchange.getOutMessage(); 144 if (outMessage == null) { 145 exchange.setError(new Exception ("Expected an out message")); 146 channel.sendSync(exchange); 147 throw new XFireFault("No response", XFireFault.SENDER); 148 } 149 Source src = exchange.getOutMessage().getContent(); 150 exchange.setStatus(ExchangeStatus.DONE); 151 channel.send(exchange); 152 src = transformer.toDOMSource(src); 153 return src; 154 } catch (XFireFault e) { 155 throw e; 156 } catch (Exception e) { 157 throw new XFireFault(e); 158 } 159 } 160 161 protected void populateExchange(MessageExchange exchange, Source src, MessageContext ctx) throws Exception { 162 NormalizedMessage inMessage = exchange.createMessage(); 164 Map namespaces = (Map ) ctx.getProperty(ReadHeadersHandler.DECLARED_NAMESPACES); 166 Node node = transformer.toDOMNode(src); 167 Element element; 168 if (node instanceof Element ) { 169 element = (Element ) node; 170 } else if (node instanceof Document ) { 171 element = ((Document ) node).getDocumentElement(); 172 } else { 173 throw new UnsupportedOperationException ("Unable to handle nodes of type " + node.getNodeType()); 174 } 175 for (Iterator it = namespaces.entrySet().iterator(); it.hasNext();) { 177 Entry entry = (Entry) it.next(); 178 if (element.getAttributes().getNamedItemNS( 179 XMLConstants.XMLNS_ATTRIBUTE_NS_URI, 180 (String ) entry.getKey()) == null) { 181 element.setAttributeNS( 182 XMLConstants.XMLNS_ATTRIBUTE_NS_URI, 183 XMLConstants.XMLNS_ATTRIBUTE + ":" + (String ) entry.getKey(), 184 (String ) entry.getValue()); 185 } 186 } 187 inMessage.setContent(new DOMSource (element)); 189 Attachments attachments = (Attachments) ctx.getInMessage().getAttachments(); 191 if (attachments != null) { 192 for (Iterator it = attachments.getParts(); it.hasNext();) { 193 Attachment part = (Attachment) it.next(); 194 inMessage.addAttachment(part.getId(), part.getDataHandler()); 195 } 196 } 197 exchange.setMessage(inMessage, "in"); 198 } 199 200 public static class InOnlyService { 201 private HttpSoapInOutBinding component; 202 public InOnlyService() {} 203 public InOnlyService(HttpSoapInOutBinding component) { 204 this.component = component; 205 } 206 public void invokeInOnly(Source source, MessageContext context) throws XFireFault { 207 this.component.invokeInOnly(source, context); 208 } 209 } 210 211 public static class InOutService { 212 private HttpSoapInOutBinding component; 213 public InOutService() {} 214 public InOutService(HttpSoapInOutBinding component) { 215 this.component = component; 216 } 217 public Source invokeInOut(Source source, MessageContext context) throws XFireFault { 218 return this.component.invokeInOut(source, context); 219 } 220 } 221 222 223 public class Controller extends XFireServletController { 224 public Controller(XFire xfire) { 225 super(xfire); 226 } 227 protected String getService(HttpServletRequest request) { 228 return service.getSimpleName(); 229 } 230 } 231 232 public boolean isDefaultInOut() { 235 return defaultInOut; 236 } 237 238 241 public void setDefaultInOut(boolean defaultInOut) { 242 this.defaultInOut = defaultInOut; 243 } 244 245 public String getSoapAction() { 246 return soapAction; 247 } 248 249 public void setSoapAction(String soapAction) { 250 this.soapAction = soapAction; 251 } 252 253 } 254 | Popular Tags |