KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > bus > bindings > soap > SOAPBindingImpl


1 package org.objectweb.celtix.bus.bindings.soap;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.Set JavaDoc;
11 import java.util.logging.Level JavaDoc;
12 import java.util.logging.Logger JavaDoc;
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 JavaDoc;
18 import javax.xml.soap.Detail JavaDoc;
19 import javax.xml.soap.MessageFactory JavaDoc;
20 import javax.xml.soap.MimeHeader JavaDoc;
21 import javax.xml.soap.MimeHeaders JavaDoc;
22 import javax.xml.soap.SOAPBody JavaDoc;
23 import javax.xml.soap.SOAPConstants JavaDoc;
24 import javax.xml.soap.SOAPElement JavaDoc;
25 import javax.xml.soap.SOAPEnvelope JavaDoc;
26 import javax.xml.soap.SOAPException JavaDoc;
27 import javax.xml.soap.SOAPFactory JavaDoc;
28 import javax.xml.soap.SOAPFault JavaDoc;
29 import javax.xml.soap.SOAPHeader JavaDoc;
30 import javax.xml.soap.SOAPMessage JavaDoc;
31 import javax.xml.transform.dom.DOMSource JavaDoc;
32 import javax.xml.transform.sax.SAXSource JavaDoc;
33 import javax.xml.transform.stream.StreamSource JavaDoc;
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 JavaDoc;
44 import org.w3c.dom.Node JavaDoc;
45 import org.w3c.dom.NodeList JavaDoc;
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 JavaDoc LOG = LogUtils.getL7dLogger(SOAPBindingImpl.class);
67     protected final MessageFactory JavaDoc msgFactory;
68     protected final SOAPFactory JavaDoc soapFactory;
69     protected final boolean isServer;
70     private NSStack nsStack;
71     private QName JavaDoc 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 JavaDoc se) {
81             LOG.log(Level.SEVERE, "SAAJ_FACTORY_CREATION_FAILURE_MSG", se);
82             throw new WebServiceException(se.getMessage());
83         }
84     }
85
86     // --- AbstractBindingImpl interface ---
87

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 JavaDoc)mc.get(ObjectMessageContext.MESSAGE_INPUT);
100             SOAPMessage JavaDoc 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                     // add in, out and inout header params
115
addHeaderParts(msg.getSOAPPart().getEnvelope(), objContext, isInputMsg, callback);
116
117                     SOAPElement JavaDoc soapElement = addOperationNode(msg.getSOAPBody(), callback, isInputMsg);
118                     // add in, out and inout non-header params
119
addParts(soapElement, objContext, isInputMsg, callback);
120                 } else if (callback.getMode() == DataBindingCallback.Mode.MESSAGE) {
121
122                     Object JavaDoc src = isInputMsg ? objContext.getReturn() : objContext.getMessageObjects()[0];
123                     // contains the entire SOAP message
124
boolean found = false;
125                     for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
126                         if (cls == SOAPMessage JavaDoc.class) {
127                             msg = (SOAPMessage JavaDoc)src;
128                             found = true;
129                             break;
130                         } else if (cls == DOMSource JavaDoc.class || cls == SAXSource JavaDoc.class
131                                    || cls == StreamSource JavaDoc.class) {
132                             DataWriter<SOAPMessage JavaDoc> writer = callback.createWriter(SOAPMessage JavaDoc.class);
133                             writer.write(src, msg);
134                             found = true;
135                             break;
136                         }
137                     }
138                     if (!found) {
139                         throw new SOAPException JavaDoc("Could not figure out how to marshal data");
140                     }
141                 } else if (callback.getMode() == DataBindingCallback.Mode.PAYLOAD) {
142                     // contains the contents of the SOAP:Body
143
boolean found = false;
144                     Object JavaDoc src = isInputMsg ? objContext.getReturn() : objContext.getMessageObjects()[0];
145
146                     for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
147                         if (cls == DOMSource JavaDoc.class || cls == SAXSource JavaDoc.class || cls == StreamSource JavaDoc.class
148                             || cls == Object JavaDoc.class) {
149                             DataWriter<SOAPBody JavaDoc> writer = callback.createWriter(SOAPBody JavaDoc.class);
150                             writer.write(src, msg.getSOAPBody());
151                             found = true;
152                             break;
153                         }
154                     }
155                     if (!found) {
156                         throw new SOAPException JavaDoc("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 JavaDoc 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 JavaDoc 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 JavaDoc t = objContext.getException();
185             if (t instanceof SOAPFaultException) {
186                 msg.getSOAPBody().addChildElement(((SOAPFaultException)t).getFault());
187             } else {
188                 StringBuffer JavaDoc str = new StringBuffer JavaDoc(t.toString());
189                 if (!t.getClass().isAnnotationPresent(WebFault.class)) {
190                     str.append("\n");
191                     for (StackTraceElement JavaDoc s : t.getStackTrace()) {
192                         str.append(s.toString());
193                         str.append("\n");
194                     }
195                 }
196
197                 SOAPFault JavaDoc fault = msg.getSOAPBody().addFault(faultCode, str.toString());
198
199                 DataWriter<Detail JavaDoc> writer = callback.createWriter(Detail JavaDoc.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 JavaDoc se) {
208             LOG.log(Level.SEVERE, "FAULT_MARSHALLING_FAILURE_MSG", se);
209             // Handle UnChecked Exception, Runtime Exception.
210
}
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 JavaDoc)mc.get(ObjectMessageContext.MESSAGE_INPUT);
221             if (!SOAPMessageContext.class.isInstance(mc)) {
222                 throw new SOAPException JavaDoc("SOAPMessageContext not available");
223             }
224
225             SOAPMessageContext soapContext = SOAPMessageContext.class.cast(mc);
226             SOAPMessage JavaDoc soapMessage = soapContext.getMessage();
227
228             if (callback.getMode() == DataBindingCallback.Mode.PARTS) {
229                 // Assuming No Headers are inserted.
230
Node JavaDoc 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 JavaDoc obj = null;
246                 for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
247                     if (cls == SOAPMessage JavaDoc.class) {
248                         obj = soapMessage;
249                         found = true;
250                         break;
251                     } else if (cls == DOMSource JavaDoc.class
252                         || cls == SAXSource JavaDoc.class
253                         || cls == StreamSource JavaDoc.class) {
254                         DataReader<SOAPMessage JavaDoc> reader = callback.createReader(SOAPMessage JavaDoc.class);
255                         obj = reader.read(0, soapMessage);
256                         found = true;
257                         break;
258                     }
259                 }
260                 if (!found) {
261                     throw new SOAPException JavaDoc("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 JavaDoc obj = null;
273                 for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
274                     if (cls == DOMSource JavaDoc.class
275                         || cls == SAXSource JavaDoc.class
276                         || cls == StreamSource JavaDoc.class
277                         || cls == Object JavaDoc.class) {
278                         DataReader<SOAPBody JavaDoc> reader = callback.createReader(SOAPBody JavaDoc.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 JavaDoc("Cannot unmarshal data");
289                 }
290
291                 if (isOutputMsg) {
292                     objContext.setReturn(obj);
293                 } else {
294                     objContext.setMessageObjects(obj);
295                 }
296             }
297         } catch (SOAPException JavaDoc 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 JavaDoc("SOAPMessageContext not available");
308             }
309
310             SOAPMessageContext soapContext = SOAPMessageContext.class.cast(context);
311             SOAPMessage JavaDoc soapMessage = soapContext.getMessage();
312
313             SOAPFault JavaDoc fault = soapMessage.getSOAPBody().getFault();
314             DataReader<SOAPFault JavaDoc> reader = callback.createReader(SOAPFault JavaDoc.class);
315
316             Object JavaDoc 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 JavaDoc)faultObj);
327         } catch (SOAPException JavaDoc 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 JavaDoc {
334         SOAPMessageContext soapCtx = (SOAPMessageContext)msgContext;
335         try {
336             soapCtx.getMessage().writeTo(outContext.getOutputStream());
337             if (LOG.isLoggable(Level.FINE)) {
338                 ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
339                 soapCtx.getMessage().writeTo(baos);
340                 LOG.log(Level.FINE, baos.toString());
341             }
342         } catch (SOAPException JavaDoc se) {
343             LOG.log(Level.SEVERE, "SOAP_WRITE_FAILURE_MSG", se);
344             throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se);
345         }
346     }
347     
348     @SuppressWarnings JavaDoc("unchecked")
349     public void read(InputStreamMessageContext inCtx, MessageContext context) throws IOException JavaDoc {
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 JavaDoc soapMessage;
357         QName JavaDoc code = faultCode;
358         try {
359             MimeHeaders JavaDoc headers = new MimeHeaders JavaDoc();
360             Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>> httpHeaders;
361             
362             if (isServer) {
363                 httpHeaders = (Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>>)soapCtx.get(MessageContext.HTTP_REQUEST_HEADERS);
364             } else {
365                 httpHeaders = (Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>>)soapCtx.get(MessageContext.HTTP_RESPONSE_HEADERS);
366             }
367             if (httpHeaders != null) {
368                 for (String JavaDoc key : httpHeaders.keySet()) {
369                     if (null != key) {
370                         List JavaDoc<String JavaDoc> values = httpHeaders.get(key);
371                         for (String JavaDoc value : values) {
372                             headers.addHeader(key, value);
373                         }
374                     }
375                 }
376             }
377
378             soapMessage = msgFactory.createMessage(headers, inCtx.getInputStream());
379             //Test if it is a valid SOAP 1.1 Message
380
code = FAULTCODE_VERSIONMISMATCH;
381             soapMessage.getSOAPPart().getEnvelope();
382         } catch (SOAPException JavaDoc 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 JavaDoc msg = ((SOAPMessageContext)msgContext).getMessage();
393         assert msg != null;
394         try {
395             hasFault = msg.getSOAPBody().hasFault();
396         } catch (SOAPException JavaDoc 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 JavaDoc msg = ((SOAPMessageContext)msgContext).getMessage();
406             try {
407                 updateHeaders(msgContext, msg);
408             } catch (SOAPException JavaDoc se) {
409                 throw SOAPFaultExHelper.createSOAPFaultEx(soapFactory, faultCode, se);
410             }
411         }
412     }
413
414     // --- Abstr actBindingImpl interface ---
415

416     public Set JavaDoc<String JavaDoc> getRoles() {
417         return null;
418     }
419
420     public void setRoles(Set JavaDoc<String JavaDoc> set) {
421         // TODO
422
}
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 JavaDoc getMessageFactory() {
433         return msgFactory;
434     }
435
436     @SuppressWarnings JavaDoc("unchecked")
437     public void updateHeaders(MessageContext ctx, SOAPMessage JavaDoc msg) throws SOAPException JavaDoc {
438         if (msg.saveRequired()) {
439             msg.saveChanges();
440         }
441         MimeHeaders JavaDoc headers = msg.getMimeHeaders();
442         Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>> reqHead;
443         String JavaDoc inOutKey = MessageContext.HTTP_REQUEST_HEADERS;
444         if (isServer) {
445             inOutKey = MessageContext.HTTP_RESPONSE_HEADERS;
446         }
447         reqHead = (Map JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>>)ctx.get(inOutKey);
448         if (reqHead == null) {
449             reqHead = new HashMap JavaDoc<String JavaDoc, List JavaDoc<String JavaDoc>>();
450             ctx.put(inOutKey, reqHead);
451         }
452         Iterator JavaDoc it = headers.getAllHeaders();
453         while (it.hasNext()) {
454             MimeHeader JavaDoc header = (MimeHeader JavaDoc)it.next();
455             if (!"Content-Length".equals(header.getName())) {
456                 List JavaDoc<String JavaDoc> vals = reqHead.get(header.getName());
457                 if (null == vals) {
458                     vals = new ArrayList JavaDoc<String JavaDoc>();
459                     reqHead.put(header.getName(), vals);
460                 }
461                 vals.add(header.getValue());
462             }
463         }
464     }
465
466     private SOAPElement JavaDoc addOperationNode(SOAPElement JavaDoc body, DataBindingCallback callback, boolean isOutBound)
467         throws SOAPException JavaDoc {
468
469         String JavaDoc responseSuffix = isOutBound ? "Response" : "";
470
471         if (callback.getSOAPStyle() == Style.RPC) {
472             String JavaDoc namespaceURI = callback.getTargetNamespace();
473             nsStack.add(namespaceURI);
474             String JavaDoc prefix = nsStack.getPrefix(namespaceURI);
475             QName JavaDoc operationName = new QName JavaDoc(namespaceURI, callback.getOperationName() + responseSuffix,
476                                             prefix);
477
478             SOAPElement JavaDoc 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 JavaDoc xmlNode, DataBindingCallback callback, ObjectMessageContext objCtx,
488                           boolean isOutBound) throws SOAPException JavaDoc {
489
490         DataReader<Node JavaDoc> reader = null;
491         for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
492             if (cls == Node JavaDoc.class) {
493                 reader = callback.createReader(Node JavaDoc.class);
494                 break;
495             }
496         }
497
498         if (reader == null) {
499             throw new SOAPException JavaDoc("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 JavaDoc childNode = NodeUtils.getChildElementNode(xmlNode);
509         if (isOutBound && callback.getWebResult() != null && !callback.getWebResult().header()) {
510
511             Object JavaDoc 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         // Unmarshal parts of mode that should notbe ignored and are not part of
520
// the SOAP Headers
521
Object JavaDoc[] 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 JavaDoc elName = (callback.getSOAPStyle() == Style.DOCUMENT)
528                                 ? new QName JavaDoc(param.targetNamespace(), param.name())
529                                 : new QName JavaDoc("", param.partName());
530
531                 Object JavaDoc obj = reader.read(elName, idx, childNode);
532                 if (param.mode() != WebParam.Mode.IN) {
533                     try {
534                         // TO avoid type safety warning the Holder
535
// needs tobe set as below.
536
methodArgs[idx].getClass().getField("value").set(methodArgs[idx], obj);
537                     } catch (Exception JavaDoc ex) {
538                         throw new SOAPException JavaDoc("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 JavaDoc xmlNode, ObjectMessageContext objCtx, boolean isOutBound,
549                           DataBindingCallback callback) throws SOAPException JavaDoc {
550
551         DataWriter<Node JavaDoc> writer = null;
552         for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
553             if (cls == Node JavaDoc.class) {
554                 writer = callback.createWriter(Node JavaDoc.class);
555                 break;
556             } else {
557                 // TODO - other formats to support?
558
// StreamSource/DOMSource/STaX/etc..
559
}
560         }
561         if (writer == null) {
562             throw new SOAPException JavaDoc("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         // Add the Return Type
572
if (isOutBound && callback.getWebResult() != null && !callback.getWebResult().header()) {
573             writer.write(objCtx.getReturn(), callback.getWebResultQName(), xmlNode);
574         }
575
576         // Add the in,inout,out args depend on the inputMode
577
WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT;
578         int noArgs = callback.getParamsLength();
579
580         // Marshal parts of mode that should notbe ignored and are not part of
581
// the SOAP Headers
582
Object JavaDoc[] 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 JavaDoc partValue = args[idx];
587                 if (param.mode() != WebParam.Mode.IN) {
588                     partValue = ((Holder)args[idx]).value;
589                 }
590
591                 QName JavaDoc elName = (callback.getSOAPStyle() == Style.DOCUMENT)
592                                     ? new QName JavaDoc(param.targetNamespace(), param.name())
593                                     : new QName JavaDoc("", param.partName());
594                 writer.write(partValue, elName, xmlNode);
595             }
596         }
597     }
598
599     private void getHeaderParts(Element JavaDoc header, DataBindingCallback callback, ObjectMessageContext objCtx,
600                                 boolean isOutBound) throws SOAPException JavaDoc {
601
602         if (header == null || !header.hasChildNodes()) {
603             return;
604         }
605
606         DataReader<Node JavaDoc> reader = null;
607         for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
608             if (cls == Node JavaDoc.class) {
609                 reader = callback.createReader(Node JavaDoc.class);
610                 break;
611             } else {
612                 // TODO - other formats to support?
613
// StreamSource/DOMSource/STaX/etc..
614
}
615         }
616
617         if (reader == null) {
618             throw new SOAPException JavaDoc("Could not figure out how to marshal data");
619         }
620
621         if (isOutBound && callback.getWebResult() != null && callback.getWebResult().header()) {
622
623             QName JavaDoc elName = callback.getWebResultQName();
624             NodeList JavaDoc headerElems = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName
625                 .getLocalPart());
626             assert headerElems.getLength() == 1;
627             Node JavaDoc childNode = headerElems.item(0);
628
629             Object JavaDoc 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         // Unmarshal parts of mode that should notbe ignored and are not part of
637
// the SOAP Headers
638
Object JavaDoc[] methodArgs = (Object JavaDoc[])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 JavaDoc elName = new QName JavaDoc(param.targetNamespace(), param.name());
643                 NodeList JavaDoc headerElems = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName
644                     .getLocalPart());
645                 assert headerElems.getLength() == 1;
646                 Node JavaDoc childNode = headerElems.item(0);
647
648                 Object JavaDoc obj = reader.read(elName, idx, childNode);
649                 if (param.mode() != WebParam.Mode.IN) {
650                     try {
651                         // TO avoid type safety warning the Holder
652
// needs tobe set as below.
653
methodArgs[idx].getClass().getField("value").set(methodArgs[idx], obj);
654                     } catch (Exception JavaDoc ex) {
655                         throw new SOAPException JavaDoc("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 JavaDoc envelope, ObjectMessageContext objCtx, boolean isOutBound,
665                                 DataBindingCallback callback) throws SOAPException JavaDoc {
666
667         boolean wroteHeader = false;
668         DataWriter<Node JavaDoc> writer = null;
669         for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
670             if (cls == Node JavaDoc.class) {
671                 writer = callback.createWriter(Node JavaDoc.class);
672                 break;
673             } else {
674                 // TODO - other formats to support?
675
// StreamSource/DOMSource/STaX/etc..
676
}
677         }
678         if (writer == null) {
679             throw new SOAPException JavaDoc("Could not figure out how to marshal data");
680         }
681
682         if (isOutBound && callback.getWebResult() != null && callback.getWebResult().header()) {
683             SOAPHeader JavaDoc header = envelope.getHeader();
684             wroteHeader = true;
685             writer.write(objCtx.getReturn(), callback.getWebResultQName(), header);
686             addSOAPHeaderAttributes(header, callback.getWebResultQName(), true);
687         }
688
689         // Add the in,inout,out args depend on the inputMode
690
WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT;
691         int noArgs = callback.getParamsLength();
692
693         // Marshal parts of mode that should notbe ignored and are not part of
694
// the SOAP Headers
695
Object JavaDoc[] args = (Object JavaDoc[])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 JavaDoc header = envelope.getHeader();
700                 wroteHeader = true;
701                 Object JavaDoc partValue = args[idx];
702                 if (param.mode() != WebParam.Mode.IN) {
703                     partValue = ((Holder)args[idx]).value;
704                 }
705
706                 QName JavaDoc elName = new QName JavaDoc(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 JavaDoc header, QName JavaDoc elName, boolean mustUnderstand) {
718         // Set mustUnderstand Attribute on header parts.
719
NodeList JavaDoc children = header.getElementsByTagNameNS(elName.getNamespaceURI(), elName.getLocalPart());
720         assert children.getLength() == 1;
721         // Set the mustUnderstand attribute
722
if (children.item(0) instanceof Element JavaDoc) {
723             Element JavaDoc child = (Element JavaDoc)(children.item(0));
724             String JavaDoc 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         // TODO Actor/Role Attribute.
732
}
733
734     public SOAPFactory JavaDoc getSOAPFactory() {
735         return soapFactory;
736     }
737
738     private SOAPMessage JavaDoc initSOAPMessage() throws SOAPException JavaDoc {
739
740         SOAPMessage JavaDoc 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