KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > bindings > ServerRequest


1 package org.objectweb.celtix.bindings;
2
3 import java.io.IOException JavaDoc;
4 import java.io.OutputStream JavaDoc;
5 import java.lang.reflect.InvocationTargetException JavaDoc;
6 import java.util.logging.Level JavaDoc;
7 import java.util.logging.Logger JavaDoc;
8
9 import javax.xml.namespace.QName JavaDoc;
10 import javax.xml.ws.WebServiceException;
11 import javax.xml.ws.handler.MessageContext;
12
13 import org.objectweb.celtix.common.i18n.Message;
14 import org.objectweb.celtix.common.logging.LogUtils;
15 import org.objectweb.celtix.context.InputStreamMessageContext;
16 import org.objectweb.celtix.context.ObjectMessageContext;
17 import org.objectweb.celtix.context.OutputStreamMessageContext;
18 import org.objectweb.celtix.context.WebServiceContextImpl;
19 import org.objectweb.celtix.handlers.HandlerInvoker;
20 import org.objectweb.celtix.transports.ServerTransport;
21
22 public class ServerRequest {
23     
24     public enum ServerRequestState {
25         STREAM_HANDLERS_INVOKED (1),
26         STREAM_READ (2),
27         PROTOCOL_HANDLERS_INVOKED (3),
28         UNMARSHALLED (4),
29         LOGICAL_HANDLERS_INVOKED (5),
30         DISPATCHED (6);
31         
32         private final int val;
33        
34         ServerRequestState(int v) {
35             this.val = v;
36         }
37         
38         public int value() {
39             return val;
40         }
41     }
42     
43     private static final Logger JavaDoc LOG = LogUtils.getL7dLogger(ServerRequest.class);
44
45     private final AbstractBindingBase binding;
46     private HandlerInvoker handlerInvoker;
47
48     private InputStreamMessageContext istreamCtx;
49     private MessageContext bindingCtx;
50     private ObjectMessageContext objectCtx;
51     private ServerRequestState state;
52     private boolean isOneway;
53     private boolean isOnewayDetermined;
54
55     public ServerRequest(AbstractBindingBase b, InputStreamMessageContext i) {
56         binding = b;
57         istreamCtx = i;
58         istreamCtx.put(ObjectMessageContext.MESSAGE_INPUT, Boolean.FALSE);
59     }
60
61     /**
62      * Used to create a ServerRequest to represent a resent outgoing
63      * message. Hence the state is set up to allow us to proceed directly
64      * to the processOutbound() phase.
65      *
66      * @param b the underlying binding
67      * @param objectContext the object message context
68      */

69     public ServerRequest(AbstractBindingBase b, ObjectMessageContext objectContext) {
70         binding = b;
71         objectCtx = objectContext;
72         handlerInvoker = binding.createHandlerInvoker();
73         state = ServerRequestState.DISPATCHED;
74     }
75
76     public AbstractBindingBase getBinding() {
77         return binding;
78     }
79
80     public HandlerInvoker getHandlerInvoker() {
81         return handlerInvoker;
82     }
83
84     public void setHandlerInvoker(HandlerInvoker h) {
85         handlerInvoker = h;
86     }
87
88     public MessageContext getBindingCtx() {
89         return bindingCtx;
90     }
91
92     public ObjectMessageContext getObjectCtx() {
93         return objectCtx;
94     }
95    
96     public ServerRequestState getState() {
97         return state;
98     }
99
100     public void processInbound() {
101
102         if (null == handlerInvoker) {
103             handlerInvoker = binding.createHandlerInvoker();
104         }
105         handlerInvoker.setInbound();
106
107         handlerInvoker.invokeStreamHandlers(istreamCtx);
108         state = ServerRequestState.STREAM_HANDLERS_INVOKED;
109
110         if (bindingCtx == null) {
111             bindingCtx = binding.getBindingImpl().createBindingMessageContext(istreamCtx);
112         } else {
113             bindingCtx.putAll(istreamCtx);
114         }
115         bindingCtx.put(ObjectMessageContext.MESSAGE_INPUT, Boolean.FALSE);
116
117         try {
118             binding.getBindingImpl().read(istreamCtx, bindingCtx);
119             state = ServerRequestState.STREAM_READ;
120         } catch (IOException JavaDoc ex) {
121             LOG.log(Level.SEVERE, "REQUEST_UNREADABLE_MSG", ex);
122             throw new WebServiceException(ex);
123         }
124
125         boolean continueProcessing = handlerInvoker.invokeProtocolHandlers(isRequestor(), bindingCtx);
126         state = ServerRequestState.PROTOCOL_HANDLERS_INVOKED;
127         if (!continueProcessing) {
128             return;
129         }
130
131         // store method and operation name in binding context if not already there -
132
// using server binding endpoint callback
133

134         storeOperationName();
135
136         if (null == objectCtx) {
137             objectCtx = binding.createObjectContext();
138             initObjectContext(objectCtx);
139             objectCtx.putAll(bindingCtx);
140         }
141
142         binding.getBindingImpl().unmarshal(bindingCtx, objectCtx, getDataBindingCallback());
143         state = ServerRequestState.UNMARSHALLED;
144         objectCtx.put(OutputStreamMessageContext.ONEWAY_MESSAGE_TF, isOneway());
145
146         handlerInvoker.invokeLogicalHandlers(isRequestor(), objectCtx);
147
148         state = ServerRequestState.LOGICAL_HANDLERS_INVOKED;
149     }
150
151     public void doInvocation() {
152         LOG.fine("doInvocation");
153         QName JavaDoc operationName = (QName JavaDoc)objectCtx.get(MessageContext.WSDL_OPERATION);
154         if (null == operationName) {
155             Message msg = new Message("CONTEXT_MISSING_OPERATION_NAME_EXC", LOG);
156             LOG.log(Level.SEVERE, msg.toString());
157             objectCtx.setException(new WebServiceException(msg.toString()));
158             return;
159         }
160         if (LOG.isLoggable(Level.FINE)) {
161             LOG.fine("operation name: " + operationName);
162         }
163
164         
165         
166         ServerDataBindingCallback method = (ServerDataBindingCallback)
167             BindingContextUtils.retrieveDataBindingCallback(objectCtx);
168         if (null == method) {
169             Message msg = new Message("IMPLEMENTOR_MISSING_METHOD_EXC", LOG, operationName);
170             LOG.log(Level.SEVERE, msg.toString());
171             objectCtx.setException(new WebServiceException(msg.toString()));
172             return;
173         }
174         if (LOG.isLoggable(Level.FINE)) {
175             LOG.fine("method: " + method);
176         }
177
178         try {
179             new WebServiceContextImpl(objectCtx);
180             
181             method.invoke(objectCtx);
182         } catch (WebServiceException wex) {
183             Throwable JavaDoc cause = wex.getCause();
184             if (cause != null) {
185                 objectCtx.setException(cause);
186             } else {
187                 objectCtx.setException(wex);
188             }
189         } catch (InvocationTargetException JavaDoc ex) {
190             LogUtils.log(LOG, Level.FINE, "IMPLEMENTOR_INVOCATION_EXCEPTION_MSG",
191                          ex, method.getOperationName());
192             Throwable JavaDoc cause = ex.getCause();
193             if (cause != null) {
194                 objectCtx.setException(cause);
195             } else {
196                 objectCtx.setException(ex);
197             }
198         }
199         
200         state = ServerRequestState.DISPATCHED;
201     }
202
203     public void processOutbound(ServerTransport st, Exception JavaDoc inboundException) {
204         processOutbound(st, inboundException, false);
205     }
206
207     public void processOutbound(ServerTransport st,
208                                 Exception JavaDoc inboundException,
209                                 boolean logicalChainTraversed) {
210         if (LOG.isLoggable(Level.FINE)) {
211             LOG.info("Reverse processing inbound message, exception: " + inboundException);
212         }
213
214         handlerInvoker.setOutbound();
215
216         ObjectMessageContext replyObjectCtx = objectCtx;
217         if (null == replyObjectCtx) {
218             replyObjectCtx = binding.createObjectContext();
219         }
220         replyObjectCtx.put(ObjectMessageContext.MESSAGE_INPUT, Boolean.TRUE);
221         
222         if (null != inboundException) {
223             replyObjectCtx.setException(inboundException);
224         }
225
226         // If protocol handlers were invoked inbound, then also invoke them
227
// outbound - except when message is oneway.
228
// TODO: relax this restriction to allow outbound processing of system
229
// handlers.
230

231         if (!logicalChainTraversed
232             && state.value() >= ServerRequestState.LOGICAL_HANDLERS_INVOKED.value()
233             && !isOneway()) {
234             
235             // Protocol and runtime exceptions have already been caught by
236
// handler invoker and stored in the object context.
237

238             handlerInvoker.invokeLogicalHandlers(isRequestor(), replyObjectCtx);
239         }
240         
241         // If on the inbound path we managed to construct a binding message
242
// context use it - otherwise create a new one.
243

244         MessageContext replyBindingCtx = bindingCtx;
245         if (null == replyBindingCtx) {
246             bindingCtx = binding.getBindingImpl().createBindingMessageContext(replyObjectCtx);
247             replyBindingCtx = bindingCtx;
248         } else if (null != replyObjectCtx) {
249             replyBindingCtx.putAll(replyObjectCtx);
250         }
251                 
252
253         // The following will only succeed if we have a data binding callback.
254

255         if (handlerInvoker.faultRaised(replyObjectCtx)) {
256             LOG.fine("Marshalling fault.");
257             marshalFault(replyObjectCtx, replyBindingCtx);
258         } else if (null != replyObjectCtx.get(ObjectMessageContext.MESSAGE_PAYLOAD)
259             || state.value() >= ServerRequestState.DISPATCHED.value()
260             || null != replyObjectCtx.get(ObjectMessageContext.METHOD_RETURN)) {
261             LOG.fine("Marshalling.");
262             marshal(replyObjectCtx, replyBindingCtx);
263         }
264
265         // If protocol handlers were invoked inbound, then also invoke them
266
// outbound - except when message is oneway.
267
// TODO: relax this restriction to allow outbound processing of system
268
// handlers.
269
// Note we may not be able to find out if the message is oneway (in case where
270
// inbound processing failed while invoking stream handlers).
271

272         if (state.value() >= ServerRequestState.PROTOCOL_HANDLERS_INVOKED.value() && !isOneway()) {
273
274             // Protocol and runtime exceptions have already been caught by
275
// handler invoker and stored in binding context
276
// As marshalling took place prior to invoking the
277
// protocol handlers we need to go back and marshal this fault.
278

279             handlerInvoker.invokeProtocolHandlers(isRequestor(), replyBindingCtx);
280             
281             if (handlerInvoker.faultRaised(replyBindingCtx)
282                 && !binding.getBindingImpl().hasFault(replyBindingCtx)) {
283                 LOG.fine("Marshalling fault raised by protocol handlers.");
284                 replyObjectCtx.setException((Exception JavaDoc)replyBindingCtx.get(
285                     ObjectMessageContext.METHOD_FAULT));
286                 marshalFault(replyObjectCtx, replyBindingCtx);
287             }
288         }
289
290         // create an output stream message context
291

292         binding.getBindingImpl().updateMessageContext(replyBindingCtx);
293
294         try {
295
296             OutputStreamMessageContext ostreamCtx = st.createOutputStreamContext(replyBindingCtx);
297             ostreamCtx.setOneWay(isOneway());
298
299             if (isOneway()) {
300                 st.finalPrepareOutputStreamContext(ostreamCtx);
301             } else {
302                 
303                 if (binding.getBindingImpl().hasFault(replyBindingCtx)) {
304                     ostreamCtx.setFault(true);
305                 }
306
307                 handlerInvoker.invokeStreamHandlers(ostreamCtx);
308                 st.finalPrepareOutputStreamContext(ostreamCtx);
309                 binding.getBindingImpl().write(replyBindingCtx, ostreamCtx);
310                 OutputStream JavaDoc os = ostreamCtx.getOutputStream();
311                 os.flush();
312             }
313
314             LOG.fine("postDispatch from binding on thread : " + Thread.currentThread());
315             st.postDispatch(replyBindingCtx, ostreamCtx);
316             if (ostreamCtx.getOutputStream() != null) {
317                 ostreamCtx.getOutputStream().close();
318             }
319         } catch (IOException JavaDoc ex) {
320             LOG.log(Level.SEVERE, "RESPONSE_UNWRITABLE_MSG", ex);
321             throw new WebServiceException(ex);
322         } finally {
323             complete();
324         }
325     }
326
327     public void complete() {
328         handlerInvoker.mepComplete(istreamCtx);
329     }
330
331     public boolean isRequestor() {
332         return false;
333     }
334
335     public boolean isOneway() {
336         if (!isOnewayDetermined) {
337             isOneway = BindingContextUtils.isOnewayMethod(bindingCtx);
338         }
339         return isOneway;
340     }
341     
342     public void setOneway(boolean oneway) {
343         isOneway = oneway;
344         isOnewayDetermined = true;
345     }
346     
347     public boolean doDispatch() {
348         return state.value() >= ServerRequestState.LOGICAL_HANDLERS_INVOKED.value()
349             && handlerInvoker.isInbound()
350             && objectCtx != null
351             && BindingContextUtils.retrieveDispatch(objectCtx);
352     }
353
354     protected void storeOperationName() {
355         AbstractServerBinding sb = (AbstractServerBinding)binding;
356         if (bindingCtx.containsKey(MessageContext.WSDL_OPERATION)) {
357             if (LOG.isLoggable(Level.FINE)) {
358                 LOG.fine("Determined operation using pre-existing operation name: "
359                          + bindingCtx.get(MessageContext.WSDL_OPERATION));
360             }
361             return;
362         }
363
364         QName JavaDoc operationName = sb.getOperationName(bindingCtx);
365
366         if (null != operationName) {
367             bindingCtx.put(MessageContext.WSDL_OPERATION, operationName);
368         } else {
369             throw new WebServiceException("No operation matching message was found");
370         }
371
372         if (LOG.isLoggable(Level.FINE)) {
373             LOG.fine("Determined operation name using server binding endpoint callback: "
374                      + operationName);
375         }
376     }
377
378     public ServerDataBindingCallback getDataBindingCallback() {
379         ServerDataBindingCallback callback =
380             (ServerDataBindingCallback)BindingContextUtils.retrieveDataBindingCallback(bindingCtx);
381         if (null == callback) {
382             assert null != objectCtx;
383             ServerBindingEndpointCallback sbeCallback = BindingContextUtils
384                 .retrieveServerBindingEndpointCallback(bindingCtx);
385             DataBindingCallback.Mode mode = sbeCallback.getServiceMode();
386             callback = sbeCallback
387                 .getDataBindingCallback((QName JavaDoc)bindingCtx.get(MessageContext.WSDL_OPERATION),
388                                         objectCtx, mode);
389             if (LOG.isLoggable(Level.FINE)) {
390                 LOG.fine("Using data binding callback constructed by server endpoint callback: " + callback);
391             }
392             BindingContextUtils.storeDataBindingCallback(bindingCtx, callback);
393         } else if (LOG.isLoggable(Level.FINE)) {
394             LOG.fine("Using data binding callback stored in context.");
395         }
396         return callback;
397     }
398
399
400     private void initObjectContext(ObjectMessageContext octx) {
401         getDataBindingCallback().initObjectContext(octx);
402     }
403     
404     
405     private void marshalFault(ObjectMessageContext octx, MessageContext bctx) {
406         DataBindingCallback callback =
407             BindingContextUtils.retrieveDataBindingCallback(bindingCtx);
408         if (null == callback) {
409             ServerBindingEndpointCallback sbeCallback = BindingContextUtils
410                 .retrieveServerBindingEndpointCallback(bindingCtx);
411             callback = sbeCallback.getFaultDataBindingCallback(octx);
412         }
413         if (null == callback) {
414             // TODO
415
LOG.log(Level.SEVERE, "NO_DATA_BINDING_CALLBACK");
416         }
417         try {
418             binding.getBindingImpl().marshalFault(octx, bctx, callback);
419         } catch (Exception JavaDoc ex) {
420             LOG.log(Level.SEVERE, "COULD_NOT_MARSHAL_FAULT_MSG", ex);
421         }
422     }
423     
424     private void marshal(ObjectMessageContext octx, MessageContext bctx) {
425         DataBindingCallback callback = getDataBindingCallback();
426         if (null == callback) {
427             // TODO
428
LOG.log(Level.SEVERE, "NO_DATA_BINDING_CALLBACK");
429         } else {
430             try {
431                 binding.getBindingImpl().marshal(octx, bctx, callback);
432             } catch (Exception JavaDoc ex) {
433                 LOG.log(Level.SEVERE, "COULD_NOT_MARSHAL_MSG", ex);
434             }
435         }
436     }
437
438 }
439
Popular Tags