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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial