KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > bus > bindings > xml > XMLBindingImpl


1 package org.objectweb.celtix.bus.bindings.xml;
2
3 import java.io.*;
4 import java.util.*;
5 import java.util.logging.Level JavaDoc;
6 import java.util.logging.Logger JavaDoc;
7
8 import javax.jws.WebParam;
9 import javax.jws.soap.SOAPBinding.ParameterStyle;
10 import javax.jws.soap.SOAPBinding.Style;
11 import javax.wsdl.BindingInput;
12 import javax.wsdl.BindingOperation;
13 import javax.wsdl.BindingOutput;
14 import javax.wsdl.Port;
15 import javax.wsdl.WSDLException;
16 import javax.xml.namespace.QName JavaDoc;
17 import javax.xml.ws.Holder;
18 import javax.xml.ws.WebFault;
19 import javax.xml.ws.WebServiceException;
20 import javax.xml.ws.handler.MessageContext;
21
22 import org.w3c.dom.*;
23
24 import org.objectweb.celtix.Bus;
25 import org.objectweb.celtix.bindings.AbstractBindingImpl;
26 import org.objectweb.celtix.bindings.DataBindingCallback;
27 import org.objectweb.celtix.bindings.DataReader;
28 import org.objectweb.celtix.bindings.DataWriter;
29 import org.objectweb.celtix.bindings.xmlformat.TBody;
30 import org.objectweb.celtix.bus.handlers.HandlerChainInvoker;
31 import org.objectweb.celtix.common.logging.LogUtils;
32 import org.objectweb.celtix.context.InputStreamMessageContext;
33 import org.objectweb.celtix.context.ObjectMessageContext;
34 import org.objectweb.celtix.context.OutputStreamMessageContext;
35 import org.objectweb.celtix.handlers.HandlerInvoker;
36 import org.objectweb.celtix.helpers.NodeUtils;
37 import org.objectweb.celtix.helpers.WSDLHelper;
38 import org.objectweb.celtix.helpers.XMLUtils;
39 import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
40 import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
41
42 public class XMLBindingImpl extends AbstractBindingImpl {
43     private static final Logger JavaDoc LOG = LogUtils.getL7dLogger(XMLBindingImpl.class);
44     protected final XMLMessageFactory msgFactory;
45     protected final boolean isServer;
46     private final XMLUtils xmlUtils = new XMLUtils();
47
48     private Bus bus;
49     private EndpointReferenceType endpointRef;
50     
51     public XMLBindingImpl(boolean server) {
52         isServer = server;
53         msgFactory = XMLMessageFactory.newInstance();
54     }
55
56     public XMLBindingImpl(Bus b, EndpointReferenceType ert, boolean server) {
57         this(server);
58         this.bus = b;
59         this.endpointRef = ert;
60     }
61
62     public Bus getBus() {
63         return this.bus;
64     }
65
66     public EndpointReferenceType getEndpointReference() {
67         return this.endpointRef;
68     }
69     
70     // --- AbstractBindingImpl interface ---
71

72     public MessageContext createBindingMessageContext(MessageContext srcCtx) {
73         return new XMLMessageContextImpl(srcCtx);
74     }
75
76     public HandlerInvoker createHandlerInvoker() {
77         return new HandlerChainInvoker(getHandlerChain(true));
78     }
79
80     public XMLMessageFactory getMessageFactory() {
81         return this.msgFactory;
82     }
83
84     private XMLMessage initXMLMessage() {
85         return msgFactory.createMessage();
86     }
87
88     public void marshal(ObjectMessageContext objContext, MessageContext mc, DataBindingCallback callback) {
89         try {
90             LOG.entering(getClass().getName(), "marshal");
91             boolean isInputMsg = (Boolean JavaDoc)mc.get(ObjectMessageContext.MESSAGE_INPUT);
92             XMLMessage msg = initXMLMessage();
93             LOG.log(Level.INFO, "XML_MARSHALLING_START", xmlUtils.toString(msg.getRoot()));
94             if (callback.getMode() == DataBindingCallback.Mode.PARTS) {
95                 if (callback.getSOAPStyle() == Style.DOCUMENT
96                     && callback.getSOAPParameterStyle() == ParameterStyle.BARE) {
97                     if (isInputMsg) {
98                         addReturnWrapperRoot(msg, callback);
99                         LOG.log(Level.INFO, "XML_MARSHALLING_BARE_OUT", xmlUtils.toString(msg.getRoot()));
100                     } else {
101                         addWrapperRoot(msg, callback);
102                         LOG.log(Level.INFO, "XML_MARSHALLING_BARE_IN", xmlUtils.toString(msg.getRoot()));
103
104                     }
105                 }
106                 addParts(msg.getRoot(), objContext, isInputMsg, callback);
107             } else if (callback.getMode() == DataBindingCallback.Mode.MESSAGE) {
108                 throw new XMLBindingException("Could not figure out how to marshal data");
109             } else if (callback.getMode() == DataBindingCallback.Mode.PAYLOAD) {
110                 throw new XMLBindingException("Could not figure out how to marshal data");
111             }
112             LOG.log(Level.INFO, "XML_MARSHALLING_END", xmlUtils.toString(msg.getRoot()));
113             ((XMLMessageContext)mc).setMessage(msg);
114             LOG.exiting(getClass().getName(), "marshal", "XML binding Mashal OK");
115         } catch (Exception JavaDoc e) {
116             LOG.log(Level.SEVERE, "XML_MARSHALLING_FAILURE_MSG", e);
117             throw new XMLBindingException("XML binding marshal exception ", e);
118         }
119     }
120     
121     public void marshalFault(ObjectMessageContext objContext,
122                              MessageContext mc,
123                              DataBindingCallback callback) {
124         XMLMessage msg = null;
125         
126         try {
127             msg = XMLMessageContext.class.isInstance(mc) && ((XMLMessageContext)mc).getMessage() != null
128                 ? ((XMLMessageContext)mc).getMessage() : initXMLMessage();
129             if (msg.hasChildNodes()) {
130                 msg.removeContents();
131             }
132             
133             Throwable JavaDoc t = objContext.getException();
134             
135             XMLFault fault = msg.addFault();
136             // REVIST FaultCode to handle other codes.
137
StringBuffer JavaDoc str = new StringBuffer JavaDoc(t.toString());
138             if (!t.getClass().isAnnotationPresent(WebFault.class)) {
139                 str.append("\n");
140                 for (StackTraceElement JavaDoc s : t.getStackTrace()) {
141                     str.append(s.toString());
142                     str.append("\n");
143                 }
144             }
145             fault.addFaultString(str.toString());
146
147             DataWriter<XMLFault> writer = callback.createWriter(XMLFault.class);
148             if (writer != null) {
149                 writer.write(t, fault);
150                 if (fault.getFaultDetail() != null && !fault.getFaultDetail().hasChildNodes()) {
151                     fault.removeChild(fault.getFaultDetail());
152                 }
153             }
154         } catch (XMLBindingException se) {
155             LOG.log(Level.SEVERE, "FAULT_MARSHALLING_FAILURE_MSG", se);
156             // Handle UnChecked Exception, Runtime Exception.
157
}
158         ((XMLMessageContext)mc).setMessage(msg);
159     }
160
161     public void unmarshal(MessageContext mc, ObjectMessageContext objContext, DataBindingCallback callback) {
162         try {
163             LOG.entering(getClass().getName(), "unmarshal");
164
165             boolean isOutputMsg = (Boolean JavaDoc)mc.get(ObjectMessageContext.MESSAGE_INPUT);
166             if (!XMLMessageContext.class.isInstance(mc)) {
167                 throw new XMLBindingException("XMLMessageContext not available");
168             }
169             
170             XMLMessageContext xmlContext = XMLMessageContext.class.cast(mc);
171             XMLMessage xmlMessage = xmlContext.getMessage();
172             
173             if (callback.getMode() == DataBindingCallback.Mode.PARTS) {
174                 Node root = xmlMessage.getRoot();
175                 LOG.log(Level.INFO, "XML_UNMARSHALLING_START", xmlUtils.toString(root));
176                 getParts(root, callback, objContext, isOutputMsg);
177                 LOG.log(Level.INFO, "XML_UNMARSHALLING_END", xmlUtils.toString(root));
178             } else if (callback.getMode() == DataBindingCallback.Mode.MESSAGE) {
179                 throw new XMLBindingException("Could not figure out how to marshal data");
180             } else if (callback.getMode() == DataBindingCallback.Mode.PAYLOAD) {
181                 throw new XMLBindingException("Could not figure out how to marshal data");
182             }
183             LOG.exiting(getClass().getName(), "unmarshal", "XML binding Unmashal OK");
184         } catch (Exception JavaDoc e) {
185             LOG.log(Level.SEVERE, "XML_UNMARSHALLING_FAILURE_MSG", e);
186             throw new XMLBindingException("XML binding unmarshal exception", e);
187         }
188     }
189     
190     public void unmarshalFault(MessageContext context, ObjectMessageContext objContext,
191                                DataBindingCallback callback) {
192         try {
193             if (!XMLMessageContext.class.isInstance(context)) {
194                 throw new XMLBindingException("XMLMessageContext not available");
195             }
196             
197             XMLMessageContext xmlContext = XMLMessageContext.class.cast(context);
198             XMLMessage xmlMessage = xmlContext.getMessage();
199             
200             XMLFault fault = xmlMessage.getFault();
201             if (fault == null) {
202                 fault = xmlMessage.addFault();
203                 fault.addFaultString("Unknow fault raised, the fault is null");
204             }
205             DataReader<XMLFault> reader = callback.createReader(XMLFault.class);
206             
207             if (reader == null) {
208                 throw new WebServiceException("Could not unmarshal fault");
209             }
210             Object JavaDoc faultObj = reader.read(null, 0, fault);
211             
212             objContext.setException((Throwable JavaDoc)faultObj);
213         } catch (Exception JavaDoc se) {
214             LOG.log(Level.SEVERE, "XML_UNMARSHALLING_FAILURE_MSG", se);
215             throw new XMLBindingException("XML binding unmarshal fault exception", se);
216         }
217     }
218
219     public void write(MessageContext msgContext, OutputStreamMessageContext outContext) throws IOException {
220         XMLMessageContext xmlContext = (XMLMessageContext)msgContext;
221         try {
222             xmlContext.getMessage().writeTo(outContext.getOutputStream());
223             
224             if (LOG.isLoggable(Level.FINE)) {
225                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
226                 xmlContext.getMessage().writeTo(baos);
227                 LOG.log(Level.FINE, baos.toString());
228             }
229         } catch (Exception JavaDoc e) {
230             LOG.log(Level.SEVERE, "XML_WRITE_FAILURE_MSG", e);
231             throw new XMLBindingException("XML binding write exception ", e);
232         }
233     }
234     
235     public void read(InputStreamMessageContext inContext, MessageContext context) throws IOException {
236         if (!XMLMessageContext.class.isInstance(context)) {
237             throw new XMLBindingException("XMLMessageContext not available");
238         }
239         try {
240             XMLMessageContext xmlContext = XMLMessageContext.class.cast(context);
241             xmlContext.setMessage(msgFactory.createMessage(inContext.getInputStream()));
242         } catch (Exception JavaDoc e) {
243             LOG.log(Level.SEVERE, "XML_READ_FAILURE_MSG", e);
244             throw new XMLBindingException("XML binding read exception ", e);
245         }
246     }
247
248     public boolean hasFault(MessageContext msgContext) {
249         XMLMessage msg = ((XMLMessageContext)msgContext).getMessage();
250         assert msg != null;
251         return msg.hasFault();
252     }
253
254     public void updateMessageContext(MessageContext msgContext) {
255         // TODO
256
}
257
258     private void getParts(Node xmlNode, DataBindingCallback callback, ObjectMessageContext objCtx,
259                           boolean isOutBound) throws XMLBindingException {
260         DataReader<Node> reader = null;
261         for (Class JavaDoc<?> cls : callback.getSupportedFormats()) {
262             if (cls == Node.class) {
263                 reader = callback.createReader(Node.class);
264                 break;
265             }
266         }
267
268         if (reader == null) {
269             throw new XMLBindingException("Could not figure out how to marshal data");
270         }
271         if (callback.getSOAPStyle() == Style.DOCUMENT
272             && callback.getSOAPParameterStyle() == ParameterStyle.WRAPPED) {
273             reader.readWrapper(objCtx, isOutBound, xmlNode);
274             return;
275         }
276
277         Node childNode = NodeUtils.getChildElementNode(xmlNode);
278
279         if (isOutBound && callback.getWebResult() != null) {
280             Object JavaDoc retVal = reader.read(callback.getWebResultQName(), -1, childNode);
281             objCtx.setReturn(retVal);
282             childNode = childNode.getNextSibling();
283         }
284
285         WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT;
286         int noArgs = callback.getParamsLength();
287         Object JavaDoc[] methodArgs = objCtx.getMessageObjects();
288
289         for (int idx = 0; idx < noArgs; idx++) {
290             WebParam param = callback.getWebParam(idx);
291             if (param.mode() != ignoreParamMode) {
292                 QName JavaDoc elName = (callback.getSOAPStyle() == Style.DOCUMENT)
293                     ? new QName JavaDoc(param.targetNamespace(), param.name())
294                     : new QName JavaDoc("", param.partName());
295
296                 Object JavaDoc obj = reader.read(elName, idx, childNode);
297                 if (param.mode() != WebParam.Mode.IN) {
298                     try {
299                         // TO avoid type safety warning the Holder
300
// needs tobe set as below.
301
methodArgs[idx].getClass().getField("value").set(methodArgs[idx], obj);
302                     } catch (Exception JavaDoc ex) {
303                         throw new XMLBindingException("Can not set the part value into the Holder field.",
304                                                       ex);
305                     }
306                 } else {
307                     methodArgs[idx] = obj;
308                 }
309                 childNode = childNode.getNextSibling();
310             }
311         }
312     }
313
314     private void addWrapperRoot(XMLMessage xmlMessage, DataBindingCallback callback) throws WSDLException {
315         BindingOperation operation = getBindingOperation(callback.getOperationName());
316         
317         BindingInput input = operation.getBindingInput();
318
319         TBody xmlBinding = null;
320         Iterator ite = input.getExtensibilityElements().iterator();
321         while (ite.hasNext()) {
322             Object JavaDoc obj = ite.next();
323             if (obj instanceof TBody) {
324                 xmlBinding = (TBody)obj;
325             }
326         }
327
328         if (needRootNode(operation, false)) {
329             if (xmlBinding == null || xmlBinding.getRootNode() == null) {
330                 throw new XMLBindingException("Bare style must define the rootNode in this case!");
331             }
332             QName JavaDoc rootNode = xmlBinding.getRootNode();
333             Document doc = xmlMessage.getRoot();
334             String JavaDoc targetNamespace = rootNode.getNamespaceURI() == null
335                 ? callback.getTargetNamespace() : rootNode.getNamespaceURI();
336             Element operationNode = doc.createElementNS(targetNamespace, rootNode.getLocalPart());
337             xmlMessage.appendChild(operationNode);
338         }
339     }
340
341     private void addReturnWrapperRoot(XMLMessage xmlMessage,
342                                       DataBindingCallback callback) throws WSDLException {
343         BindingOperation operation = getBindingOperation(callback.getOperationName());
344
345         BindingOutput output = operation.getBindingOutput();
346         TBody xmlBinding = null;
347         Iterator ite = output.getExtensibilityElements().iterator();
348         while (ite.hasNext()) {
349             Object JavaDoc obj = ite.next();
350             if (obj instanceof TBody) {
351                 xmlBinding = (TBody)obj;
352             }
353         }
354         if (needRootNode(operation, true)) {
355             if (xmlBinding == null || xmlBinding.getRootNode() == null) {
356                 throw new XMLBindingException("Bare style must define the rootNode in this case!");
357             }
358             QName JavaDoc rootNode = xmlBinding.getRootNode();
359             Document doc = xmlMessage.getRoot();
360             String JavaDoc targetNamespace = rootNode.getNamespaceURI() == null
361                 ? callback.getTargetNamespace() : rootNode.getNamespaceURI();
362             Element operationNode = doc.createElementNS(targetNamespace, rootNode.getLocalPart());
363             xmlMessage.appendChild(operationNode);
364         }
365     }
366
367     private BindingOperation getBindingOperation(String JavaDoc operationName) throws WSDLException {
368         WSDLHelper helper = new WSDLHelper();
369         Port port = EndpointReferenceUtils.getPort(this.bus.getWSDLManager(), this.endpointRef);
370         return helper.getBindingOperation(port.getBinding(),
371                                           operationName);
372     }
373
374     private boolean needRootNode(BindingOperation operation, boolean out) {
375         WSDLHelper helper = new WSDLHelper();
376         Map parts = helper.getParts(operation.getOperation(), out);
377         return parts.size() != 1;
378     }
379
380     private void addParts(Node xmlNode,
381                           ObjectMessageContext objCtx,
382                           boolean isOutBound,
383                           DataBindingCallback callback) {
384         DataWriter<Node> writer = callback.createWriter(Node.class);
385         if (writer == null) {
386             throw new XMLBindingException("Could not figure out how to marshal data");
387         }
388
389         if (callback.getSOAPStyle() == Style.DOCUMENT
390             && callback.getSOAPParameterStyle() == ParameterStyle.WRAPPED) {
391             writer.writeWrapper(objCtx, isOutBound, xmlNode);
392             return;
393         }
394
395         // Add the Return Type
396
if (isOutBound && callback.getWebResult() != null) {
397             writer.write(objCtx.getReturn(), callback.getWebResultQName(), xmlNode);
398         }
399         // Add the in,inout,out args depend on the inputMode
400
WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT;
401         int noArgs = callback.getParamsLength();
402         Object JavaDoc[] args = objCtx.getMessageObjects();
403         for (int idx = 0; idx < noArgs; idx++) {
404             WebParam param = callback.getWebParam(idx);
405             if (param.mode() != ignoreParamMode) {
406                 Object JavaDoc partValue = args[idx];
407                 if (param.mode() != WebParam.Mode.IN) {
408                     partValue = ((Holder)args[idx]).value;
409                 }
410             
411                 QName JavaDoc elName = (callback.getSOAPStyle() == Style.DOCUMENT)
412                     ? new QName JavaDoc(param.targetNamespace(), param.name())
413                     : new QName JavaDoc("", param.partName());
414                 writer.write(partValue, elName, xmlNode);
415             }
416         }
417     }
418 }
419
Popular Tags