1 package org.objectweb.celtix.bus.bindings.soap; 2 3 import java.io.ByteArrayOutputStream ; 4 import java.io.IOException ; 5 import java.util.ArrayList ; 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 import java.util.Map ; 10 import java.util.Set ; 11 import java.util.logging.Level ; 12 import java.util.logging.Logger ; 13 14 import javax.jws.WebParam; 15 import javax.jws.soap.SOAPBinding.ParameterStyle; 16 import javax.jws.soap.SOAPBinding.Style; 17 import javax.xml.namespace.QName ; 18 import javax.xml.soap.Detail ; 19 import javax.xml.soap.MessageFactory ; 20 import javax.xml.soap.MimeHeader ; 21 import javax.xml.soap.MimeHeaders ; 22 import javax.xml.soap.SOAPBody ; 23 import javax.xml.soap.SOAPConstants ; 24 import javax.xml.soap.SOAPElement ; 25 import javax.xml.soap.SOAPEnvelope ; 26 import javax.xml.soap.SOAPException ; 27 import javax.xml.soap.SOAPFactory ; 28 import javax.xml.soap.SOAPFault ; 29 import javax.xml.soap.SOAPHeader ; 30 import javax.xml.soap.SOAPMessage ; 31 import javax.xml.transform.dom.DOMSource ; 32 import javax.xml.transform.sax.SAXSource ; 33 import javax.xml.transform.stream.StreamSource ; 34 import javax.xml.ws.Holder; 35 import javax.xml.ws.ProtocolException; 36 import javax.xml.ws.WebFault; 37 import javax.xml.ws.WebServiceException; 38 import javax.xml.ws.handler.MessageContext; 39 import javax.xml.ws.handler.soap.SOAPMessageContext; 40 import javax.xml.ws.soap.SOAPBinding; 41 import javax.xml.ws.soap.SOAPFaultException; 42 43 import org.w3c.dom.Element ; 44 import org.w3c.dom.Node ; 45 import org.w3c.dom.NodeList ; 46 47 import org.objectweb.celtix.bindings.AbstractBindingImpl; 48 import org.objectweb.celtix.bindings.DataBindingCallback; 49 import org.objectweb.celtix.bindings.DataReader; 50 import org.objectweb.celtix.bindings.DataWriter; 51 import org.objectweb.celtix.bus.handlers.HandlerChainInvoker; 52 import org.objectweb.celtix.common.logging.LogUtils; 53 import org.objectweb.celtix.context.InputStreamMessageContext; 54 import org.objectweb.celtix.context.ObjectMessageContext; 55 import org.objectweb.celtix.context.OutputStreamMessageContext; 56 import org.objectweb.celtix.handlers.HandlerInvoker; 57 import org.objectweb.celtix.helpers.NSStack; 58 import org.objectweb.celtix.helpers.NodeUtils; 59 60 import static org.objectweb.celtix.bus.bindings.soap.SOAPConstants.FAULTCODE_CLIENT; 61 import static org.objectweb.celtix.bus.bindings.soap.SOAPConstants.FAULTCODE_SERVER; 62 import static org.objectweb.celtix.bus.bindings.soap.SOAPConstants.FAULTCODE_VERSIONMISMATCH; 63 import static org.objectweb.celtix.bus.bindings.soap.SOAPConstants.HEADER_MUSTUNDERSTAND; 64 65 public class SOAPBindingImpl extends AbstractBindingImpl implements SOAPBinding { 66 private static final Logger LOG = LogUtils.getL7dLogger(SOAPBindingImpl.class); 67 protected final MessageFactory msgFactory; 68 protected final SOAPFactory soapFactory; 69 protected final boolean isServer; 70 private NSStack nsStack; 71 private QName faultCode; 72 73 public SOAPBindingImpl(boolean server) { 74 try { 75 isServer = server; 76 msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); 77 soapFactory = SOAPFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); 78 faultCode = isServer ? FAULTCODE_SERVER 79 : FAULTCODE_CLIENT; 80 } catch (SOAPException se) { 81 LOG.log(Level.SEVERE, "SAAJ_FACTORY_CREATION_FAILURE_MSG", se); 82 throw new WebServiceException(se.getMessage()); 83 } 84 } 85 86 88 public MessageContext createBindingMessageContext(MessageContext srcCtx) { 89 return new SOAPMessageContextImpl(srcCtx); 90 } 91 92 public HandlerInvoker createHandlerInvoker() { 93 return new HandlerChainInvoker(getHandlerChain(true)); 94 } 95 96 public void marshal(ObjectMessageContext objContext, MessageContext mc, DataBindingCallback callback) { 97 98 try { 99 boolean isInputMsg = (Boolean )mc.get(ObjectMessageContext.MESSAGE_INPUT); 100 SOAPMessage msg = initSOAPMessage(); 101 102 if (null != callback) { 103 104 if (!"".equals(callback.getSOAPAction())) { 105 msg.getMimeHeaders().setHeader("SOAPAction", "\"" + callback.getSOAPAction() + "\""); 106 } 107 108 if (callback.getMode() == DataBindingCallback.Mode.PARTS) { 109 if (callback.getSOAPStyle() == Style.RPC) { 110 nsStack = new NSStack(); 111 nsStack.push(); 112 } 113 114 addHeaderParts(msg.getSOAPPart().getEnvelope(), objContext, isInputMsg, callback); 116 117 SOAPElement soapElement = addOperationNode(msg.getSOAPBody(), callback, isInputMsg); 118 addParts(soapElement, objContext, isInputMsg, callback); 120 } else if (callback.getMode() == DataBindingCallback.Mode.MESSAGE) { 121 122 Object src = isInputMsg ? objContext.getReturn() : objContext.getMessageObjects()[0]; 123 boolean found = false; 125 for (Class <?> cls : callback.getSupportedFormats()) { 126 if (cls == SOAPMessage .class) { 127 msg = (SOAPMessage )src; 128 found = true; 129 break; 130 } else if (cls == DOMSource .class || cls == SAXSource .class 131 || cls == StreamSource .class) { 132 DataWriter<SOAPMessage > writer = callback.createWriter(SOAPMessage .class); 133 writer.write(src, msg); 134 found = true; 135 break; 136 } 137 } 138 if (!found) { 139 throw new SOAPException ("Could not figure out how to marshal data"); 140 } 141 } else if (callback.getMode() == DataBindingCallback.Mode.PAYLOAD) { 142 boolean found = false; 144 Object src = isInputMsg ? objContext.getReturn() : objContext.getMessageObjects()[0]; 145 146 for (Class <?> cls : callback.getSupportedFormats()) { 147 if (cls == DOMSource .class || cls == SAXSource .class || cls == StreamSource .class 148 || cls == Object .class) { 149 DataWriter<SOAPBody > writer = callback.createWriter(SOAPBody .class); 150 writer.write(src, msg.getSOAPBody()); 151 found = true; 152 break; 153 } 154 } 155 if (!found) { 156 throw new SOAPException ("Could not figure out how to marshal data"); 157 } 158 } 159 } else { 160 LOG.fine("Leaving soap message empty - no data binding callback"); 161 } 162 ((SOAPMessageContext)mc).setMessage(msg); 163 164 165 } catch (SOAPException se) { 166 LOG.log(Level.SEVERE, "SOAP_MARSHALLING_FAILURE_MSG", se); 167 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se); 168 } 169 } 170 171 public void marshalFault(ObjectMessageContext objContext, MessageContext mc, 172 DataBindingCallback callback) { 173 174 SOAPMessage msg = null; 175 176 try { 177 msg = SOAPMessageContext.class.isInstance(mc) && ((SOAPMessageContext)mc).getMessage() != null 178 ? ((SOAPMessageContext)mc).getMessage() : initSOAPMessage(); 179 180 if (msg.getSOAPBody().hasChildNodes()) { 181 msg.getSOAPBody().removeContents(); 182 } 183 184 Throwable t = objContext.getException(); 185 if (t instanceof SOAPFaultException) { 186 msg.getSOAPBody().addChildElement(((SOAPFaultException)t).getFault()); 187 } else { 188 StringBuffer str = new StringBuffer (t.toString()); 189 if (!t.getClass().isAnnotationPresent(WebFault.class)) { 190 str.append("\n"); 191 for (StackTraceElement s : t.getStackTrace()) { 192 str.append(s.toString()); 193 str.append("\n"); 194 } 195 } 196 197 SOAPFault fault = msg.getSOAPBody().addFault(faultCode, str.toString()); 198 199 DataWriter<Detail > writer = callback.createWriter(Detail .class); 200 if (writer != null) { 201 writer.write(t, fault.addDetail()); 202 if (!fault.getDetail().hasChildNodes()) { 203 fault.removeChild(fault.getDetail()); 204 } 205 } 206 } 207 } catch (SOAPException se) { 208 LOG.log(Level.SEVERE, "FAULT_MARSHALLING_FAILURE_MSG", se); 209 } 211 ((SOAPMessageContext)mc).setMessage(msg); 212 } 213 214 public void unmarshal(MessageContext mc, ObjectMessageContext objContext, DataBindingCallback callback) { 215 if (null == callback) { 216 LOG.fine("Suppress unmarshalling - no data binding callback."); 217 return; 218 } 219 try { 220 boolean isOutputMsg = (Boolean )mc.get(ObjectMessageContext.MESSAGE_INPUT); 221 if (!SOAPMessageContext.class.isInstance(mc)) { 222 throw new SOAPException ("SOAPMessageContext not available"); 223 } 224 225 SOAPMessageContext soapContext = SOAPMessageContext.class.cast(mc); 226 SOAPMessage soapMessage = soapContext.getMessage(); 227 228 if (callback.getMode() == DataBindingCallback.Mode.PARTS) { 229 Node soapEl = soapMessage.getSOAPBody(); 231 232 if (callback.getSOAPStyle() == Style.RPC) { 233 soapEl = NodeUtils.getChildElementNode(soapEl); 234 } 235 236 if (soapEl.hasChildNodes()) { 237 getParts(soapEl, callback, objContext, isOutputMsg); 238 } else { 239 LOG.fine("Body of SOAP message is empty."); 240 } 241 242 getHeaderParts(soapMessage.getSOAPHeader(), callback, objContext, isOutputMsg); 243 } else if (callback.getMode() == DataBindingCallback.Mode.MESSAGE) { 244 boolean found = false; 245 Object obj = null; 246 for (Class <?> cls : callback.getSupportedFormats()) { 247 if (cls == SOAPMessage .class) { 248 obj = soapMessage; 249 found = true; 250 break; 251 } else if (cls == DOMSource .class 252 || cls == SAXSource .class 253 || cls == StreamSource .class) { 254 DataReader<SOAPMessage > reader = callback.createReader(SOAPMessage .class); 255 obj = reader.read(0, soapMessage); 256 found = true; 257 break; 258 } 259 } 260 if (!found) { 261 throw new SOAPException ("Cannot unmarshal data"); 262 } 263 264 if (isOutputMsg) { 265 objContext.setReturn(obj); 266 } else { 267 objContext.setMessageObjects(obj); 268 } 269 270 } else if (callback.getMode() == DataBindingCallback.Mode.PAYLOAD) { 271 boolean found = false; 272 Object obj = null; 273 for (Class <?> cls : callback.getSupportedFormats()) { 274 if (cls == DOMSource .class 275 || cls == SAXSource .class 276 || cls == StreamSource .class 277 || cls == Object .class) { 278 DataReader<SOAPBody > reader = callback.createReader(SOAPBody .class); 279 obj = reader.read(0, soapMessage.getSOAPBody()); 280 found = true; 281 break; 282 } 283 } 284 285 286 287 if (!found) { 288 throw new SOAPException ("Cannot unmarshal data"); 289 } 290 291 if (isOutputMsg) { 292 objContext.setReturn(obj); 293 } else { 294 objContext.setMessageObjects(obj); 295 } 296 } 297 } catch (SOAPException se) { 298 LOG.log(Level.SEVERE, "SOAP_UNMARSHALLING_FAILURE_MSG", se); 299 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se); 300 } 301 } 302 303 public void unmarshalFault(MessageContext context, ObjectMessageContext objContext, 304 DataBindingCallback callback) { 305 try { 306 if (!SOAPMessageContext.class.isInstance(context)) { 307 throw new SOAPException ("SOAPMessageContext not available"); 308 } 309 310 SOAPMessageContext soapContext = SOAPMessageContext.class.cast(context); 311 SOAPMessage soapMessage = soapContext.getMessage(); 312 313 SOAPFault fault = soapMessage.getSOAPBody().getFault(); 314 DataReader<SOAPFault > reader = callback.createReader(SOAPFault .class); 315 316 Object faultObj = null; 317 if (null != reader) { 318 LOG.log(Level.INFO, "SOAP_FAULT_NO_READER"); 319 faultObj = reader.read(null, 0, fault); 320 } 321 if (null == faultObj) { 322 LOG.log(Level.INFO, "SOAP_FAULT_UNMARSHALLING_MSG", fault.getElementQName().toString()); 323 faultObj = new SOAPFaultException(fault); 324 } 325 326 objContext.setException((Throwable )faultObj); 327 } catch (SOAPException se) { 328 LOG.log(Level.SEVERE, "SOAP_UNMARSHALLING_FAILURE_MSG", se); 329 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se); 330 } 331 } 332 333 public void write(MessageContext msgContext, OutputStreamMessageContext outContext) throws IOException { 334 SOAPMessageContext soapCtx = (SOAPMessageContext)msgContext; 335 try { 336 soapCtx.getMessage().writeTo(outContext.getOutputStream()); 337 if (LOG.isLoggable(Level.FINE)) { 338 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 339 soapCtx.getMessage().writeTo(baos); 340 LOG.log(Level.FINE, baos.toString()); 341 } 342 } catch (SOAPException se) { 343 LOG.log(Level.SEVERE, "SOAP_WRITE_FAILURE_MSG", se); 344 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se); 345 } 346 } 347 348 @SuppressWarnings ("unchecked") 349 public void read(InputStreamMessageContext inCtx, MessageContext context) throws IOException { 350 351 if (!SOAPMessageContext.class.isInstance(context)) { 352 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, 353 "SOAPMessageContext not available"); 354 } 355 SOAPMessageContext soapCtx = SOAPMessageContext.class.cast(context); 356 SOAPMessage soapMessage; 357 QName code = faultCode; 358 try { 359 MimeHeaders headers = new MimeHeaders (); 360 Map <String , List <String >> httpHeaders; 361 362 if (isServer) { 363 httpHeaders = (Map <String , List <String >>)soapCtx.get(MessageContext.HTTP_REQUEST_HEADERS); 364 } else { 365 httpHeaders = (Map <String , List <String >>)soapCtx.get(MessageContext.HTTP_RESPONSE_HEADERS); 366 } 367 if (httpHeaders != null) { 368 for (String key : httpHeaders.keySet()) { 369 if (null != key) { 370 List <String > values = httpHeaders.get(key); 371 for (String value : values) { 372 headers.addHeader(key, value); 373 } 374 } 375 } 376 } 377 378 soapMessage = msgFactory.createMessage(headers, inCtx.getInputStream()); 379 code = FAULTCODE_VERSIONMISMATCH; 381 soapMessage.getSOAPPart().getEnvelope(); 382 } catch (SOAPException se) { 383 LOG.log(Level.SEVERE, "SOAP_PARSING_FAILURE_MSG", se); 384 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, code, se); 385 } 386 387 soapCtx.setMessage(soapMessage); 388 } 389 390 public boolean hasFault(MessageContext msgContext) { 391 boolean hasFault = false; 392 SOAPMessage msg = ((SOAPMessageContext)msgContext).getMessage(); 393 assert msg != null; 394 try { 395 hasFault = msg.getSOAPBody().hasFault(); 396 } catch (SOAPException se) { 397 LOG.log(Level.SEVERE, "SOAP_UNMARSHALLING_FAILURE_MSG", se); 398 throw new ProtocolException(se); 399 } 400 return hasFault; 401 } 402 403 public void updateMessageContext(MessageContext msgContext) { 404 if (msgContext instanceof SOAPMessageContext) { 405 SOAPMessage msg = ((SOAPMessageContext)msgContext).getMessage(); 406 try { 407 updateHeaders(msgContext, msg); 408 } catch (SOAPException se) { 409 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se); 410 } 411 } 412 } 413 414 416 public Set <String > getRoles() { 417 return null; 418 } 419 420 public void setRoles(Set <String > set) { 421 } 423 424 public boolean isMTOMEnabled() { 425 return false; 426 } 427 428 public void setMTOMEnabled(boolean flag) { 429 throw new WebServiceException("MTOM is not supported"); 430 } 431 432 public MessageFactory getMessageFactory() { 433 return msgFactory; 434 } 435 436 @SuppressWarnings ("unchecked") 437 public void updateHeaders(MessageContext ctx, SOAPMessage msg) throws SOAPException { 438 if (msg.saveRequired()) { 439 msg.saveChanges(); 440 } 441 MimeHeaders headers = msg.getMimeHeaders(); 442 Map <String , List <String >> reqHead; 443 String inOutKey = MessageContext.HTTP_REQUEST_HEADERS; 444 if (isServer) { 445 inOutKey = MessageContext.HTTP_RESPONSE_HEADERS; 446 } 447 reqHead = (Map <String , List <String >>)ctx.get(inOutKey); 448 if (reqHead == null) { 449 reqHead = new HashMap <String , List <String >>(); 450 ctx.put(inOutKey, reqHead); 451 } 452 Iterator it = headers.getAllHeaders(); 453 while (it.hasNext()) { 454 MimeHeader header = (MimeHeader )it.next(); 455 if (!"Content-Length".equals(header.getName())) { 456 List <String > vals = reqHead.get(header.getName()); 457 if (null == vals) { 458 vals = new ArrayList <String >(); 459 reqHead.put(header.getName(), vals); 460 } 461 vals.add(header.getValue()); 462 } 463 } 464 } 465 466 private SOAPElement addOperationNode(SOAPElement body, DataBindingCallback callback, boolean isOutBound) 467 throws SOAPException { 468 469 String responseSuffix = isOutBound ? "Response" : ""; 470 471 if (callback.getSOAPStyle() == Style.RPC) { 472 String namespaceURI = callback.getTargetNamespace(); 473 nsStack.add(namespaceURI); 474 String prefix = nsStack.getPrefix(namespaceURI); 475 QName operationName = new QName (namespaceURI, callback.getOperationName() + responseSuffix, 476 prefix); 477 478 SOAPElement el = body.addChildElement(operationName); 479 if (el.lookupPrefix(namespaceURI) == null) { 480 el.addNamespaceDeclaration(prefix, namespaceURI); 481 } 482 return el; 483 } 484 return body; 485 } 486 487 private void getParts(Node xmlNode, DataBindingCallback callback, ObjectMessageContext objCtx, 488 boolean isOutBound) throws SOAPException { 489 490 DataReader<Node > reader = null; 491 for (Class <?> cls : callback.getSupportedFormats()) { 492 if (cls == Node .class) { 493 reader = callback.createReader(Node .class); 494 break; 495 } 496 } 497 498 if (reader == null) { 499 throw new SOAPException ("Could not figure out how to unmarshal data"); 500 } 501 502 if (callback.getSOAPStyle() == Style.DOCUMENT 503 && callback.getSOAPParameterStyle() == ParameterStyle.WRAPPED) { 504 reader.readWrapper(objCtx, isOutBound, xmlNode); 505 return; 506 } 507 508 Node childNode = NodeUtils.getChildElementNode(xmlNode); 509 if (isOutBound && callback.getWebResult() != null && !callback.getWebResult().header()) { 510 511 Object retVal = reader.read(callback.getWebResultQName(), -1, childNode); 512 objCtx.setReturn(retVal); 513 childNode = childNode.getNextSibling(); 514 } 515 516 WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT; 517 int noArgs = callback.getParamsLength(); 518 519 Object [] methodArgs = objCtx.getMessageObjects(); 522 523 for (int idx = 0; idx < noArgs; idx++) { 524 WebParam param = callback.getWebParam(idx); 525 if ((param.mode() != ignoreParamMode) && !param.header()) { 526 527 QName elName = (callback.getSOAPStyle() == Style.DOCUMENT) 528 ? new QName (param.targetNamespace(), param.name()) 529 : new QName ("", param.partName()); 530 531 Object obj = reader.read(elName, idx, childNode); 532 if (param.mode() != WebParam.Mode.IN) { 533 try { 534 methodArgs[idx].getClass().getField("value").set(methodArgs[idx], obj); 537 } catch (Exception ex) { 538 throw new SOAPException ("Can not set the part value into the Holder field."); 539 } 540 } else { 541 methodArgs[idx] = obj; 542 } 543 childNode = childNode.getNextSibling(); 544 } 545 } 546 } 547 548 private void addParts(Node xmlNode, ObjectMessageContext objCtx, boolean isOutBound, 549 DataBindingCallback callback) throws SOAPException { 550 551 DataWriter<Node > writer = null; 552 for (Class <?> cls : callback.getSupportedFormats()) { 553 if (cls == Node .class) { 554 writer = callback.createWriter(Node .class); 555 break; 556 } else { 557 } 560 } 561 if (writer == null) { 562 throw new SOAPException ("Could not figure out how to marshal data"); 563 } 564 565 if (callback.getSOAPStyle() == Style.DOCUMENT 566 && callback.getSOAPParameterStyle() == ParameterStyle.WRAPPED) { 567 writer.writeWrapper(objCtx, isOutBound, xmlNode); 568 return; 569 } 570 571 if (isOutBound && callback.getWebResult() != null && !callback.getWebResult().header()) { 573 writer.write(objCtx.getReturn(), callback.getWebResultQName(), xmlNode); 574 } 575 576 WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT; 578 int noArgs = callback.getParamsLength(); 579 580 Object [] args = objCtx.getMessageObjects(); 583 for (int idx = 0; idx < noArgs; idx++) { 584 WebParam param = callback.getWebParam(idx); 585 if ((param.mode() != ignoreParamMode) && !param.header()) { 586 Object partValue = args[idx]; 587 if (param.mode() != WebParam.Mode.IN) { 588 partValue = ((Holder)args[idx]).value; 589 } 590 591 QName elName = (callback.getSOAPStyle() == Style.DOCUMENT) 592 ? new QName (param.targetNamespace(), param.name()) 593 : new QName ("", param.partName()); 594 writer.write(partValue, elName, xmlNode); 595 } 596 } 597 } 598 599 private void getHeaderParts(Element header, DataBindingCallback callback, ObjectMessageContext objCtx, 600 boolean isOutBound) throws SOAPException { 601 602 if (header == null || !header.hasChildNodes()) { 603 return; 604 } 605 606 DataReader<Node > reader = null; 607 for (Class <?> cls : callback.getSupportedFormats()) { 608 if (cls == Node .class) { 609 reader = callback.createReader(Node .class); 610 break; 611 } else { 612 } 615 } 616 617 if (reader == null) { 618 throw new SOAPException ("Could not figure out how to marshal data"); 619 } 620 621 if (isOutBound && callback.getWebResult() != null && callback.getWebResult().header()) { 622 623 QName elName = callback.getWebResultQName(); 624 NodeList headerElems = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName 625 .getLocalPart()); 626 assert headerElems.getLength() == 1; 627 Node childNode = headerElems.item(0); 628 629 Object retVal = reader.read(elName, -1, childNode); 630 objCtx.setReturn(retVal); 631 } 632 633 WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT; 634 int noArgs = callback.getParamsLength(); 635 636 Object [] methodArgs = (Object [])objCtx.getMessageObjects(); 639 for (int idx = 0; idx < noArgs; idx++) { 640 WebParam param = callback.getWebParam(idx); 641 if ((param.mode() != ignoreParamMode) && param.header()) { 642 QName elName = new QName (param.targetNamespace(), param.name()); 643 NodeList headerElems = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName 644 .getLocalPart()); 645 assert headerElems.getLength() == 1; 646 Node childNode = headerElems.item(0); 647 648 Object obj = reader.read(elName, idx, childNode); 649 if (param.mode() != WebParam.Mode.IN) { 650 try { 651 methodArgs[idx].getClass().getField("value").set(methodArgs[idx], obj); 654 } catch (Exception ex) { 655 throw new SOAPException ("Can not set the part value into the Holder field."); 656 } 657 } else { 658 methodArgs[idx] = obj; 659 } 660 } 661 } 662 } 663 664 private void addHeaderParts(SOAPEnvelope envelope, ObjectMessageContext objCtx, boolean isOutBound, 665 DataBindingCallback callback) throws SOAPException { 666 667 boolean wroteHeader = false; 668 DataWriter<Node > writer = null; 669 for (Class <?> cls : callback.getSupportedFormats()) { 670 if (cls == Node .class) { 671 writer = callback.createWriter(Node .class); 672 break; 673 } else { 674 } 677 } 678 if (writer == null) { 679 throw new SOAPException ("Could not figure out how to marshal data"); 680 } 681 682 if (isOutBound && callback.getWebResult() != null && callback.getWebResult().header()) { 683 SOAPHeader header = envelope.getHeader(); 684 wroteHeader = true; 685 writer.write(objCtx.getReturn(), callback.getWebResultQName(), header); 686 addSOAPHeaderAttributes(header, callback.getWebResultQName(), true); 687 } 688 689 WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT; 691 int noArgs = callback.getParamsLength(); 692 693 Object [] args = (Object [])objCtx.getMessageObjects(); 696 for (int idx = 0; idx < noArgs; idx++) { 697 WebParam param = callback.getWebParam(idx); 698 if ((param.mode() != ignoreParamMode) && param.header()) { 699 SOAPHeader header = envelope.getHeader(); 700 wroteHeader = true; 701 Object partValue = args[idx]; 702 if (param.mode() != WebParam.Mode.IN) { 703 partValue = ((Holder)args[idx]).value; 704 } 705 706 QName elName = new QName (param.targetNamespace(), param.name()); 707 writer.write(partValue, elName, header); 708 709 addSOAPHeaderAttributes(header, elName, true); 710 } 711 } 712 if (!wroteHeader) { 713 envelope.removeChild(envelope.getHeader()); 714 } 715 } 716 717 private void addSOAPHeaderAttributes(SOAPHeader header, QName elName, boolean mustUnderstand) { 718 NodeList children = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName.getLocalPart()); 720 assert children.getLength() == 1; 721 if (children.item(0) instanceof Element ) { 723 Element child = (Element )(children.item(0)); 724 String n = header.lookupPrefix(HEADER_MUSTUNDERSTAND.getNamespaceURI()); 725 n += ":" + HEADER_MUSTUNDERSTAND.getLocalPart(); 726 child.setAttributeNS(HEADER_MUSTUNDERSTAND.getNamespaceURI(), 727 HEADER_MUSTUNDERSTAND.getLocalPart(), 728 mustUnderstand ? "true" : "false"); 729 } 730 731 } 733 734 public SOAPFactory getSOAPFactory() { 735 return soapFactory; 736 } 737 738 private SOAPMessage initSOAPMessage() throws SOAPException { 739 740 SOAPMessage msg = msgFactory.createMessage(); 741 msg.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true"); 742 msg.getSOAPPart().getEnvelope().addNamespaceDeclaration(W3CConstants.NP_SCHEMA_XSD, 743 W3CConstants.NU_SCHEMA_XSD); 744 msg.getSOAPPart().getEnvelope().addNamespaceDeclaration(W3CConstants.NP_SCHEMA_XSI, 745 W3CConstants.NU_SCHEMA_XSI); 746 747 return msg; 748 } 749 } 750 | Popular Tags |