src/share/jaxws_classes/com/sun/xml/internal/ws/handler/HandlerProcessor.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.handler;
ohair@286 27
ohair@286 28 import com.sun.xml.internal.ws.api.WSBinding;
ohair@286 29
ohair@286 30 import javax.xml.ws.ProtocolException;
ohair@286 31 import javax.xml.ws.handler.Handler;
ohair@286 32 import javax.xml.ws.handler.MessageContext;
ohair@286 33 import java.util.ArrayList;
ohair@286 34 import java.util.List;
ohair@286 35 import java.util.logging.Level;
ohair@286 36 import java.util.logging.Logger;
ohair@286 37
ohair@286 38 /**
ohair@286 39 * @author WS Development Team
ohair@286 40 */
ohair@286 41 abstract class HandlerProcessor<C extends MessageUpdatableContext> {
ohair@286 42
ohair@286 43 boolean isClient;
ohair@286 44 static final Logger logger = Logger.getLogger(
ohair@286 45 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".handler");
ohair@286 46
ohair@286 47 // need request or response for Handle interface
ohair@286 48 public enum RequestOrResponse {
ohair@286 49 REQUEST, RESPONSE }
ohair@286 50
ohair@286 51 public enum Direction {
ohair@286 52 OUTBOUND, INBOUND }
ohair@286 53
ohair@286 54 private List<? extends Handler> handlers; // may be logical/soap mixed
ohair@286 55
ohair@286 56 WSBinding binding;
ohair@286 57 private int index = -1;
ohair@286 58 private HandlerTube owner;
ohair@286 59
ohair@286 60 /**
ohair@286 61 * The handlers that are passed in will be sorted into
ohair@286 62 * logical and soap handlers. During this sorting, the
ohair@286 63 * understood headers are also obtained from any soap
ohair@286 64 * handlers.
ohair@286 65 *
ohair@286 66 * @param chain A list of handler objects, which can
ohair@286 67 * be protocol or logical handlers.
ohair@286 68 */
ohair@286 69 protected HandlerProcessor(HandlerTube owner, WSBinding binding, List<? extends Handler> chain) {
ohair@286 70 this.owner = owner;
ohair@286 71 if (chain == null) { // should only happen in testing
ohair@286 72 chain = new ArrayList<Handler>();
ohair@286 73 }
ohair@286 74 handlers = chain;
ohair@286 75 this.binding = binding;
ohair@286 76 }
ohair@286 77
ohair@286 78 /**
ohair@286 79 * Gives index of the handler in the chain to know what handlers in the chain
ohair@286 80 * are invoked
ohair@286 81 */
ohair@286 82 int getIndex() {
ohair@286 83 return index;
ohair@286 84 }
ohair@286 85
ohair@286 86 /**
ohair@286 87 * This is called when a handler returns false or throws a RuntimeException
ohair@286 88 */
ohair@286 89 void setIndex(int i) {
ohair@286 90 index = i;
ohair@286 91 }
ohair@286 92
ohair@286 93 /**
ohair@286 94 * TODO: Just putting thoughts,
ohair@286 95 * Current contract: This is Called during Request Processing.
ohair@286 96 * return true, if all handlers in the chain return true
ohair@286 97 * Current Pipe can call nextPipe.process();
ohair@286 98 * return false, One of the handlers has returned false or thrown a
ohair@286 99 * RuntimeException. Remedy Actions taken:
ohair@286 100 * 1) In this case, The processor will setIndex()to track what
ohair@286 101 * handlers are invoked until that point.
ohair@286 102 * 2) Previously invoked handlers are again invoked (handleMessage()
ohair@286 103 * or handleFault()) to take remedy action.
ohair@286 104 * CurrentPipe should NOT call nextPipe.process()
ohair@286 105 * While closing handlers, check getIndex() to get the invoked
ohair@286 106 * handlers.
ohair@286 107 * @throws RuntimeException this happens when a RuntimeException occurs during
ohair@286 108 * handleMessage during Request processing or
ohair@286 109 * during remedy action 2)
ohair@286 110 * CurrentPipe should NOT call nextPipe.process() and throw the
ohair@286 111 * exception to the previous Pipe
ohair@286 112 * While closing handlers, check getIndex() to get the invoked
ohair@286 113 * handlers.
ohair@286 114 */
ohair@286 115 public boolean callHandlersRequest(Direction direction,
ohair@286 116 C context,
ohair@286 117 boolean responseExpected) {
ohair@286 118 setDirection(direction, context);
ohair@286 119 boolean result;
ohair@286 120 // call handlers
ohair@286 121 try {
ohair@286 122 if (direction == Direction.OUTBOUND) {
ohair@286 123 result = callHandleMessage(context, 0, handlers.size() - 1);
ohair@286 124 } else {
ohair@286 125 result = callHandleMessage(context, handlers.size() - 1, 0);
ohair@286 126 }
ohair@286 127 } catch (ProtocolException pe) {
ohair@286 128 logger.log(Level.FINER, "exception in handler chain", pe);
ohair@286 129 if (responseExpected) {
ohair@286 130 //insert fault message if its not a fault message
ohair@286 131 insertFaultMessage(context, pe);
ohair@286 132 // reverse direction
ohair@286 133 reverseDirection(direction, context);
ohair@286 134 //Set handleFault so that cousinTube is aware of fault
ohair@286 135 setHandleFaultProperty();
ohair@286 136 // call handle fault
ohair@286 137 if (direction == Direction.OUTBOUND) {
ohair@286 138 callHandleFault(context, getIndex() - 1, 0);
ohair@286 139 } else {
ohair@286 140 callHandleFault(context, getIndex() + 1, handlers.size() - 1);
ohair@286 141 }
ohair@286 142 return false;
ohair@286 143 }
ohair@286 144 throw pe;
ohair@286 145 } catch (RuntimeException re) {
ohair@286 146 logger.log(Level.FINER, "exception in handler chain", re);
ohair@286 147 throw re;
ohair@286 148 }
ohair@286 149
ohair@286 150 if (!result) {
ohair@286 151 if (responseExpected) {
ohair@286 152 // reverse direction
ohair@286 153 reverseDirection(direction, context);
ohair@286 154 // call handle message
ohair@286 155 if (direction == Direction.OUTBOUND) {
ohair@286 156 callHandleMessageReverse(context, getIndex() - 1, 0);
ohair@286 157 } else {
ohair@286 158 callHandleMessageReverse(context, getIndex() + 1, handlers.size() - 1);
ohair@286 159 }
ohair@286 160 } else {
ohair@286 161 // Set handleFalse so that cousinTube is aware of false processing
ohair@286 162 // Oneway, dispatch the message
ohair@286 163 // cousinTube should n't call handleMessage() anymore.
ohair@286 164 setHandleFalseProperty();
ohair@286 165 }
ohair@286 166 return false;
ohair@286 167 }
ohair@286 168
ohair@286 169 return result;
ohair@286 170 }
ohair@286 171
ohair@286 172
ohair@286 173 /**
ohair@286 174 * TODO: Just putting thoughts,
ohair@286 175 * Current contract: This is Called during Response Processing.
ohair@286 176 * Runs all handlers until handle returns false or throws a RuntimeException
ohair@286 177 * CurrentPipe should close all the handlers in the chain.
ohair@286 178 * throw RuntimeException, this happens when a RuntimeException occurs during
ohair@286 179 * normal Response processing or remedy action 2) taken
ohair@286 180 * during callHandlersRequest().
ohair@286 181 * CurrentPipe should close all the handlers in the chain. *
ohair@286 182 */
ohair@286 183 public void callHandlersResponse(Direction direction,
ohair@286 184 C context, boolean isFault) {
ohair@286 185 setDirection(direction, context);
ohair@286 186 try {
ohair@286 187 if (isFault) {
ohair@286 188 // call handleFault on handlers
ohair@286 189 if (direction == Direction.OUTBOUND) {
ohair@286 190 callHandleFault(context, 0, handlers.size() - 1);
ohair@286 191 } else {
ohair@286 192 callHandleFault(context, handlers.size() - 1, 0);
ohair@286 193 }
ohair@286 194 } else {
ohair@286 195 // call handleMessage on handlers
ohair@286 196 if (direction == Direction.OUTBOUND) {
ohair@286 197 callHandleMessageReverse(context, 0, handlers.size() - 1);
ohair@286 198 } else {
ohair@286 199 callHandleMessageReverse(context, handlers.size() - 1, 0);
ohair@286 200 }
ohair@286 201 }
ohair@286 202 } catch (RuntimeException re) {
ohair@286 203 logger.log(Level.FINER, "exception in handler chain", re);
ohair@286 204 throw re;
ohair@286 205 }
ohair@286 206 }
ohair@286 207
ohair@286 208
ohair@286 209 /**
ohair@286 210 * Reverses the Message Direction.
ohair@286 211 * MessageContext.MESSAGE_OUTBOUND_PROPERTY is changed.
ohair@286 212 */
ohair@286 213 private void reverseDirection(Direction origDirection, C context) {
ohair@286 214 if (origDirection == Direction.OUTBOUND) {
ohair@286 215 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
ohair@286 216 } else {
ohair@286 217 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, true);
ohair@286 218 }
ohair@286 219 }
ohair@286 220
ohair@286 221 /**
ohair@286 222 * Sets the Message Direction.
ohair@286 223 * MessageContext.MESSAGE_OUTBOUND_PROPERTY is changed.
ohair@286 224 */
ohair@286 225 private void setDirection(Direction direction, C context) {
ohair@286 226 if (direction == Direction.OUTBOUND) {
ohair@286 227 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, true);
ohair@286 228 } else {
ohair@286 229 context.put(MessageContext.MESSAGE_OUTBOUND_PROPERTY, false);
ohair@286 230 }
ohair@286 231 }
ohair@286 232
ohair@286 233 /**
ohair@286 234 * When this property is set HandlerPipes can call handleFault() on the
ohair@286 235 * message
ohair@286 236 */
ohair@286 237 private void setHandleFaultProperty() {
ohair@286 238 owner.setHandleFault();
ohair@286 239 }
ohair@286 240
ohair@286 241 /**
ohair@286 242 * When this property is set HandlerPipes will not call
ohair@286 243 * handleMessage() during Response processing.
ohair@286 244 */
ohair@286 245 private void setHandleFalseProperty() {
ohair@286 246 owner.setHandleFalse();
ohair@286 247 }
ohair@286 248
ohair@286 249 /**
ohair@286 250 * When a ProtocolException is thrown, this is called.
ohair@286 251 * If it's XML/HTTP Binding, clear the the message
ohair@286 252 * If its SOAP/HTTP Binding, put right SOAP Fault version
ohair@286 253 */
ohair@286 254 abstract void insertFaultMessage(C context,
ohair@286 255 ProtocolException exception);
ohair@286 256
ohair@286 257 /*
ohair@286 258 * Calls handleMessage on the handlers. Indices are
ohair@286 259 * inclusive. Exceptions get passed up the chain, and an
ohair@286 260 * exception or return of 'false' ends processing.
ohair@286 261 */
ohair@286 262 private boolean callHandleMessage(C context, int start, int end) {
ohair@286 263 /* Do we need this check?
ohair@286 264 if (handlers.isEmpty() ||
ohair@286 265 start == -1 ||
ohair@286 266 start == handlers.size()) {
ohair@286 267 return false;
ohair@286 268 }
ohair@286 269 */
ohair@286 270 int i = start;
ohair@286 271 try {
ohair@286 272 if (start > end) {
ohair@286 273 while (i >= end) {
ohair@286 274 if (!handlers.get(i).handleMessage(context)) {
ohair@286 275 setIndex(i);
ohair@286 276 return false;
ohair@286 277 }
ohair@286 278 i--;
ohair@286 279 }
ohair@286 280 } else {
ohair@286 281 while (i <= end) {
ohair@286 282 if (!handlers.get(i).handleMessage(context)) {
ohair@286 283 setIndex(i);
ohair@286 284 return false;
ohair@286 285 }
ohair@286 286 i++;
ohair@286 287 }
ohair@286 288 }
ohair@286 289 } catch (RuntimeException e) {
ohair@286 290 setIndex(i);
ohair@286 291 throw e;
ohair@286 292 }
ohair@286 293 return true;
ohair@286 294 }
ohair@286 295
ohair@286 296 /*
ohair@286 297 * Calls handleMessage on the handlers. Indices are
ohair@286 298 * inclusive. Exceptions get passed up the chain, and an
ohair@286 299 * exception (or)
ohair@286 300 * return of 'false' calls addHandleFalseProperty(context) and
ohair@286 301 * ends processing.
ohair@286 302 * setIndex() is not called.
ohair@286 303 *
ohair@286 304 */
ohair@286 305 private boolean callHandleMessageReverse(C context, int start, int end) {
ohair@286 306
ohair@286 307 if (handlers.isEmpty() ||
ohair@286 308 start == -1 ||
ohair@286 309 start == handlers.size()) {
ohair@286 310 return false;
ohair@286 311 }
ohair@286 312
ohair@286 313 int i = start;
ohair@286 314
ohair@286 315 if (start > end) {
ohair@286 316 while (i >= end) {
ohair@286 317 if (!handlers.get(i).handleMessage(context)) {
ohair@286 318 // Set handleFalse so that cousinTube is aware of false processing
ohair@286 319 setHandleFalseProperty();
ohair@286 320 return false;
ohair@286 321 }
ohair@286 322 i--;
ohair@286 323 }
ohair@286 324 } else {
ohair@286 325 while (i <= end) {
ohair@286 326 if (!handlers.get(i).handleMessage(context)) {
ohair@286 327 // Set handleFalse so that cousinTube is aware of false processing
ohair@286 328 setHandleFalseProperty();
ohair@286 329 return false;
ohair@286 330 }
ohair@286 331 i++;
ohair@286 332 }
ohair@286 333 }
ohair@286 334 return true;
ohair@286 335 }
ohair@286 336
ohair@286 337 /*
ohair@286 338 * Calls handleFault on the handlers. Indices are
ohair@286 339 * inclusive. Exceptions get passed up the chain, and an
ohair@286 340 * exception or return of 'false' ends processing.
ohair@286 341 */
ohair@286 342
ohair@286 343 private boolean callHandleFault(C context, int start, int end) {
ohair@286 344
ohair@286 345 if (handlers.isEmpty() ||
ohair@286 346 start == -1 ||
ohair@286 347 start == handlers.size()) {
ohair@286 348 return false;
ohair@286 349 }
ohair@286 350
ohair@286 351 int i = start;
ohair@286 352 if (start > end) {
ohair@286 353 try {
ohair@286 354 while (i >= end) {
ohair@286 355 if (!handlers.get(i).handleFault(context)) {
ohair@286 356 return false;
ohair@286 357 }
ohair@286 358 i--;
ohair@286 359 }
ohair@286 360 } catch (RuntimeException re) {
ohair@286 361 logger.log(Level.FINER,
ohair@286 362 "exception in handler chain", re);
ohair@286 363 throw re;
ohair@286 364 }
ohair@286 365 } else {
ohair@286 366 try {
ohair@286 367 while (i <= end) {
ohair@286 368 if (!handlers.get(i).handleFault(context)) {
ohair@286 369 return false;
ohair@286 370 }
ohair@286 371 i++;
ohair@286 372 }
ohair@286 373 } catch (RuntimeException re) {
ohair@286 374 logger.log(Level.FINER,
ohair@286 375 "exception in handler chain", re);
ohair@286 376 throw re;
ohair@286 377 }
ohair@286 378 }
ohair@286 379 return true;
ohair@286 380 }
ohair@286 381
ohair@286 382 /**
ohair@286 383 * Calls close on the handlers from the starting
ohair@286 384 * index through the ending index (inclusive). Made indices
ohair@286 385 * inclusive to allow both directions more easily.
ohair@286 386 */
ohair@286 387 void closeHandlers(MessageContext context, int start, int end) {
ohair@286 388 if (handlers.isEmpty() ||
ohair@286 389 start == -1) {
ohair@286 390 return;
ohair@286 391 }
ohair@286 392 if (start > end) {
ohair@286 393 for (int i = start; i >= end; i--) {
ohair@286 394 try {
ohair@286 395 handlers.get(i).close(context);
ohair@286 396 } catch (RuntimeException re) {
ohair@286 397 logger.log(Level.INFO,
ohair@286 398 "Exception ignored during close", re);
ohair@286 399 }
ohair@286 400 }
ohair@286 401 } else {
ohair@286 402 for (int i = start; i <= end; i++) {
ohair@286 403 try {
ohair@286 404 handlers.get(i).close(context);
ohair@286 405 } catch (RuntimeException re) {
ohair@286 406 logger.log(Level.INFO,
ohair@286 407 "Exception ignored during close", re);
ohair@286 408 }
ohair@286 409 }
ohair@286 410 }
ohair@286 411 }
ohair@286 412 }

mercurial