1 package org.objectweb.celtix.bus.handlers; 2 3 4 import java.util.ArrayList ; 5 import java.util.Collections ; 6 import java.util.List ; 7 import java.util.logging.Level ; 8 import java.util.logging.Logger ; 9 10 import javax.xml.ws.ProtocolException; 11 import javax.xml.ws.handler.Handler; 12 import javax.xml.ws.handler.LogicalHandler; 13 import javax.xml.ws.handler.MessageContext; 14 15 import org.objectweb.celtix.bus.context.LogicalMessageContextImpl; 16 import org.objectweb.celtix.bus.context.StreamMessageContextImpl; 17 import org.objectweb.celtix.common.logging.LogUtils; 18 import org.objectweb.celtix.context.InputStreamMessageContext; 19 import org.objectweb.celtix.context.ObjectMessageContext; 20 import org.objectweb.celtix.context.OutputStreamMessageContext; 21 import org.objectweb.celtix.context.WebServiceContextImpl; 22 import org.objectweb.celtix.handlers.HandlerInvoker; 23 import org.objectweb.celtix.handlers.StreamHandler; 24 25 29 public class HandlerChainInvoker implements HandlerInvoker { 30 31 private static final Logger LOG = LogUtils.getL7dLogger(HandlerChainInvoker.class); 32 33 private final List <Handler> protocolHandlers = new ArrayList <Handler>(); 34 private List <LogicalHandler> logicalHandlers = new ArrayList <LogicalHandler>(); 35 private final List <StreamHandler> streamHandlers = new ArrayList <StreamHandler>(); 36 private final List <Handler> invokedHandlers = new ArrayList <Handler>(); 37 private final List <Handler> closeHandlers = new ArrayList <Handler>(); 38 39 private boolean outbound; 40 private boolean responseExpected = true; 41 private boolean faultExpected; 42 private boolean handlerProcessingAborted; 43 private boolean closed; 44 45 public HandlerChainInvoker(List <Handler> hc) { 46 this(hc, true); 47 } 48 49 50 51 public HandlerChainInvoker(List <Handler> hc, boolean isOutbound) { 52 if (LOG.isLoggable(Level.FINE)) { 53 LOG.log(Level.FINE, "invoker for chain size: " + (hc != null ? hc.size() : 0)); 54 } 55 56 if (hc != null) { 57 for (Handler h : hc) { 58 if (h instanceof LogicalHandler) { 59 logicalHandlers.add((LogicalHandler)h); 60 } else if (h instanceof StreamHandler) { 61 streamHandlers.add((StreamHandler)h); 62 } else { 63 protocolHandlers.add(h); 64 } 65 } 66 } 67 outbound = isOutbound; 68 } 69 70 public boolean invokeLogicalHandlers(boolean requestor, ObjectMessageContext objectCtx) { 71 objectCtx.setRequestorRole(requestor); 72 objectCtx.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, isOutbound()); 73 LogicalMessageContextImpl logicalContext = new LogicalMessageContextImpl(objectCtx); 74 return invokeHandlerChain(logicalHandlers, logicalContext); 75 76 } 77 78 public boolean invokeProtocolHandlers(boolean requestor, MessageContext bindingContext) { 79 bindingContext.put(ObjectMessageContext.REQUESTOR_ROLE_PROPERTY, requestor); 80 bindingContext.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, isOutbound()); 81 82 return invokeHandlerChain(protocolHandlers, bindingContext); 83 } 84 85 public boolean invokeStreamHandlers(InputStreamMessageContext ctx) { 86 StreamMessageContextImpl sctx = new StreamMessageContextImpl(ctx); 87 sctx.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, this.outbound); 88 return invokeHandlerChain(streamHandlers, sctx); 90 } 91 92 public boolean invokeStreamHandlers(OutputStreamMessageContext ctx) { 93 StreamMessageContextImpl sctx = new StreamMessageContextImpl(ctx); 94 sctx.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, this.outbound); 95 return invokeHandlerChain(streamHandlers, sctx); 96 } 97 98 public void closeHandlers() { 99 } 101 102 public void setResponseExpected(boolean expected) { 103 responseExpected = expected; 104 } 105 106 public boolean isResponseExpected() { 107 return responseExpected; 108 } 109 110 public boolean isOutbound() { 111 return outbound; 112 } 113 114 public boolean isInbound() { 115 return !outbound; 116 } 117 118 public void setInbound() { 119 outbound = false; 120 } 121 122 public void setOutbound() { 123 outbound = true; 124 } 125 126 127 public boolean faultRaised(MessageContext context) { 128 return (null != context && null != context.get(ObjectMessageContext.METHOD_FAULT)) 129 || faultExpected; 130 } 131 132 public void setFault(boolean fe) { 133 faultExpected = fe; 134 } 135 136 142 public void mepComplete(MessageContext context) { 143 if (LOG.isLoggable(Level.FINE)) { 144 LOG.log(Level.FINE, "closing protocol handlers - handler count:" + invokedHandlers.size()); 145 } 146 invokeClose(protocolHandlers, context); 147 invokeClose(logicalHandlers, context); 148 invokeClose(streamHandlers, context); 149 } 150 151 152 159 public boolean isClosed() { 160 return closed; 161 } 162 163 170 public void adoptLogicalHandlers(HandlerInvoker invoker) { 171 logicalHandlers = ((HandlerChainInvoker)invoker).getLogicalHandlers(); 172 } 173 174 List getInvokedHandlers() { 175 return Collections.unmodifiableList(invokedHandlers); 176 } 177 178 public List <LogicalHandler> getLogicalHandlers() { 179 return logicalHandlers; 180 } 181 182 List <Handler> getProtocolHandlers() { 183 return protocolHandlers; 184 } 185 186 List <? extends Handler> getStreamHandlers() { 187 return streamHandlers; 188 } 189 190 private <T extends Handler> void invokeClose(List <T> handlers, MessageContext context) { 191 handlers = reverseHandlerChain(handlers); 192 for (Handler h : handlers) { 193 if (closeHandlers.contains(h)) { 194 h.close(context); 195 } 196 } 197 } 198 199 private boolean invokeHandlerChain(List <? extends Handler> handlerChain, MessageContext ctx) { 200 if (handlerChain.isEmpty()) { 201 LOG.log(Level.FINEST, "no handlers registered"); 202 return true; 203 } 204 205 if (isClosed()) { 206 return false; 207 } 208 209 if (LOG.isLoggable(Level.FINE)) { 210 LOG.log(Level.FINE, "invoking handlers, direction: " + (outbound ? "outbound" : "inbound")); 211 } 212 setMessageOutboundProperty(ctx); 213 214 if (!outbound) { 215 handlerChain = reverseHandlerChain(handlerChain); 216 } 217 218 boolean continueProcessing = true; 219 220 WebServiceContextImpl.setMessageContext(ctx); 221 222 if (!faultRaised(ctx)) { 223 continueProcessing = invokeHandleMessage(handlerChain, ctx); 224 } else { 225 continueProcessing = invokeHandleFault(handlerChain, ctx); 226 } 227 228 if (!continueProcessing) { 229 changeMessageDirection(ctx); 235 handlerProcessingAborted = true; 236 } 237 return continueProcessing; 238 } 239 240 @SuppressWarnings ("unchecked") 241 private boolean invokeHandleFault(List <? extends Handler> handlerChain, MessageContext ctx) { 242 243 boolean continueProcessing = true; 244 245 try { 246 for (Handler<MessageContext> h : handlerChain) { 247 if (invokeThisHandler(h)) { 248 closeHandlers.add(h); 249 continueProcessing = h.handleFault(ctx); 250 } 251 if (!continueProcessing) { 252 break; 253 } 254 markHandlerInvoked(h); 255 } 256 } catch (RuntimeException e) { 257 LOG.log(Level.WARNING, "HANDLER_RAISED_RUNTIME_EXCEPTION", e); 258 continueProcessing = false; 259 closed = true; 260 } 261 return continueProcessing; 262 } 263 264 265 @SuppressWarnings ("unchecked") 266 private boolean invokeHandleMessage(List <? extends Handler> handlerChain, MessageContext ctx) { 267 268 boolean continueProcessing = true; 269 try { 270 for (Handler h : handlerChain) { 271 if (invokeThisHandler(h)) { 272 closeHandlers.add(h); 273 continueProcessing = h.handleMessage(ctx); 274 } 275 if (!continueProcessing) { 276 break; 277 } 278 markHandlerInvoked(h); 279 } 280 } catch (ProtocolException e) { 281 LOG.log(Level.FINE, "handleMessage raised exception", e); 282 continueProcessing = false; 283 setFault(ctx, e); 284 } catch (RuntimeException e) { 285 LOG.log(Level.WARNING, "HANDLER_RAISED_RUNTIME_EXCEPTION", e); 286 continueProcessing = false; 287 closed = true; 288 } 289 return continueProcessing; 290 } 291 292 293 private boolean invokeThisHandler(Handler h) { 294 boolean ret = true; 295 if (handlerProcessingAborted) { 299 ret = invokedHandlers.contains(h); 300 } 301 if (ret && LOG.isLoggable(Level.FINE)) { 302 LOG.log(Level.FINE, "invoking handler of type " + h.getClass().getName()); 303 } 304 return ret; 305 } 306 307 308 private void markHandlerInvoked(Handler h) { 309 if (!invokedHandlers.contains(h)) { 310 invokedHandlers.add(h); 311 } 312 } 313 314 private void changeMessageDirection(MessageContext context) { 315 outbound = !outbound; 316 setMessageOutboundProperty(context); 317 context.put(ObjectMessageContext.MESSAGE_INPUT, Boolean.TRUE); 318 } 319 320 private void setMessageOutboundProperty(MessageContext context) { 321 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, this.outbound); 322 } 323 324 private <T extends Handler> List <T> reverseHandlerChain(List <T> handlerChain) { 325 List <T> reversedHandlerChain = new ArrayList <T>(); 326 reversedHandlerChain.addAll(handlerChain); 327 Collections.reverse(reversedHandlerChain); 328 return reversedHandlerChain; 329 } 330 331 protected final void setFault(MessageContext context, Exception ex) { 332 context.put(ObjectMessageContext.METHOD_FAULT, ex); 333 context.setScope(ObjectMessageContext.METHOD_FAULT, MessageContext.Scope.HANDLER); 334 } 335 } 336 337 | Popular Tags |