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

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

mercurial