src/share/jaxws_classes/com/sun/xml/internal/ws/handler/HandlerTube.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.istack.internal.Nullable;
    29 import com.sun.xml.internal.ws.api.WSBinding;
    30 import com.sun.xml.internal.ws.api.message.Packet;
    31 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
    32 import com.sun.xml.internal.ws.api.pipe.*;
    33 import com.sun.xml.internal.ws.api.pipe.helper.AbstractFilterTubeImpl;
    34 import com.sun.xml.internal.ws.binding.BindingImpl;
    35 import com.sun.xml.internal.ws.client.HandlerConfiguration;
    37 import javax.xml.ws.handler.MessageContext;
    38 import javax.xml.ws.handler.Handler;
    39 import java.util.List;
    41 /**
    42  * @author WS Development team
    43  */
    45 public abstract class HandlerTube extends AbstractFilterTubeImpl {
    46     /**
    47      * handle hold reference to other Tube for inter-tube communication
    48      */
    49     HandlerTube cousinTube;
    50     protected List<Handler> handlers;
    51     HandlerProcessor processor;
    52     boolean remedyActionTaken = false;
    53     protected final @Nullable WSDLPort port;
    54     // flag used to decide whether to call close on cousinTube
    55     boolean requestProcessingSucessful = false;
    56     private WSBinding binding;
    57     private HandlerConfiguration hc;
    59     public HandlerTube(Tube next, WSDLPort port, WSBinding binding) {
    60         super(next);
    61         this.port = port;
    62         this.binding = binding;
    63     }
    65     public HandlerTube(Tube next, HandlerTube cousinTube, WSBinding binding) {
    66         super(next);
    67         this.cousinTube = cousinTube;
    68         this.binding = binding;
    69         if(cousinTube != null) {
    70             this.port = cousinTube.port;
    71         } else {
    72             this.port = null;
    73         }
    74     }
    76     /**
    77      * Copy constructor for {@link Tube#copy(TubeCloner)}.
    78      */
    79     protected HandlerTube(HandlerTube that, TubeCloner cloner) {
    80         super(that,cloner);
    81         if(that.cousinTube != null) {
    82             this.cousinTube = cloner.copy(that.cousinTube);
    83         }
    84         this.port = that.port;
    85         this.binding = that.binding;
    86     }
    88     protected WSBinding getBinding() {
    89         return binding;
    90     }
    92     @Override
    93     public NextAction processRequest(Packet request) {
    94         setupExchange();
    95         // This check is done to cover handler returning false in Oneway request
    96         if (isHandleFalse()) {
    97             // Cousin HandlerTube returned false during Oneway Request processing.
    98             // Don't call handlers and dispatch the message.
    99             remedyActionTaken = true;
   100             return doInvoke(super.next, request);
   101         }
   103         // This is done here instead of the constructor, since User can change
   104         // the roles and handlerchain after a stub/proxy is created.
   105         setUpProcessorInternal();
   107         MessageUpdatableContext context = getContext(request);
   108         boolean isOneWay = checkOneWay(request);
   109         try {
   110             if (!isHandlerChainEmpty()) {
   111                 // Call handlers on Request
   112                 boolean handlerResult = callHandlersOnRequest(context, isOneWay);
   113                 //Update Packet with user modifications
   114                 context.updatePacket();
   115                 // two-way case where no message is sent
   116                 if (!isOneWay && !handlerResult) {
   117                     return doReturnWith(request);
   118                 }
   119             }
   120             requestProcessingSucessful = true;
   121             // Call next Tube
   122             return doInvoke(super.next, request);
   123         } catch (RuntimeException re) {
   124             if(isOneWay) {
   125                 //Eat the exception, its already logged and close the transportBackChannel
   126                 if(request.transportBackChannel != null ) {
   127                         request.transportBackChannel.close();
   128                 }
   129                 request.setMessage(null);
   130                 return doReturnWith(request);
   131             } else
   132                 throw re;
   133         } finally {
   134             if(!requestProcessingSucessful) {
   135                 initiateClosing(context.getMessageContext());
   136             }
   137         }
   139     }
   141     @Override
   142     public NextAction processResponse(Packet response) {
   143         setupExchange();
   144         MessageUpdatableContext context = getContext(response);
   145         try {
   146             if (isHandleFalse() || (response.getMessage() == null)) {
   147                 // Cousin HandlerTube returned false during Response processing.
   148                 // or it is oneway request
   149                 // or handler chain is empty
   150                 // Don't call handlers.
   151                 return doReturnWith(response);
   152             }
   154             setUpProcessorInternal();
   156             boolean isFault = isHandleFault(response);
   157             if (!isHandlerChainEmpty()) {
   158                 // Call handlers on Response
   159                 callHandlersOnResponse(context, isFault);
   160             }
   161         } finally {
   162             initiateClosing(context.getMessageContext());
   163         }
   164         //Update Packet with user modifications
   165         context.updatePacket();
   167         return doReturnWith(response);
   169     }
   171     @Override
   172     public NextAction processException(Throwable t) {
   173         try {
   174             return doThrow(t);
   175         } finally {
   176                 Packet packet = Fiber.current().getPacket();
   177             MessageUpdatableContext context = getContext(packet);
   178             initiateClosing(context.getMessageContext());
   179             /* TODO revisit: commented this out as the modified packet is no longer used
   180                     In future if the message is propagated even when an exception
   181                     occurs, then uncomment context.updatePacket();
   182             */
   183             //Update Packet with user modifications
   184             //context.updatePacket();
   187         }
   188     }
   190     /**
   191      * Must be overridden by HandlerTube that drives other handler tubes for processing a message.
   192      * On Client-side: ClientLogicalHandlerTube drives the Handler Processing.
   193      * On Server-side: In case SOAP Binding, ServerMessageHandlerTube drives the Handler Processing.
   194      *                 In case XML/HTTP Binding, ServerLogicalHandlerTube drives the Handler Processing.
   195      *
   196      *
   197      * If its a top HandlerTube, should override by calling #close(MessaggeContext);
   198      *
   199      */
   201     protected void initiateClosing(MessageContext mc) {
   202         // Do nothing
   204     }
   206     /**
   207      * Calls close on previously invoked handlers.
   208      * Also, Cleans up any state left over in the Tube instance from the current
   209      * invocation, as Tube instances can be reused after the completion of MEP.
   210      *
   211      * On Client, SOAPHandlers are closed first and then LogicalHandlers
   212      * On Server, LogicalHandlers are closed first and then SOAPHandlers
   213      */
   214     final public void close(MessageContext msgContext) {
   215         //assuming cousinTube is called if requestProcessingSucessful is true
   216         if (requestProcessingSucessful) {
   217             if (cousinTube != null) {
   218                 cousinTube.close(msgContext);
   219             }
   221         }
   222         if (processor != null)
   223             closeHandlers(msgContext);
   225         // Clean up the exchange for next invocation.
   226         exchange = null;
   227         requestProcessingSucessful = false;
   229     }
   231     /**
   232      * On Client, Override by calling #closeClientHandlers(MessageContext mc)
   233      * On Server, Override by calling #closeServerHandlers(MessageContext mc)
   234      *      The difference is the order in which they are closed.
   235      * @param mc
   236      */
   237     abstract void closeHandlers(MessageContext mc);
   239     /**
   240      * Called by close(MessageContext mc) in a Client Handlertube
   241      */
   242     protected void closeClientsideHandlers(MessageContext msgContext) {
   243          if (processor == null)
   244             return;
   245         if (remedyActionTaken) {
   246             //Close only invoked handlers in the chain
   248             //CLIENT-SIDE
   249             processor.closeHandlers(msgContext, processor.getIndex(), 0);
   250             processor.setIndex(-1);
   251             //reset remedyActionTaken
   252             remedyActionTaken = false;
   253         } else {
   254             //Close all handlers in the chain
   256             //CLIENT-SIDE
   257             processor.closeHandlers(msgContext, handlers.size() - 1, 0);
   259         }
   260     }
   262     /**
   263      * Called by close(MessageContext mc) in a Server Handlertube
   264      */
   265     protected void closeServersideHandlers(MessageContext msgContext) {
   266         if (processor == null)
   267             return;
   268         if (remedyActionTaken) {
   269             //Close only invoked handlers in the chain
   271             //SERVER-SIDE
   272             processor.closeHandlers(msgContext, processor.getIndex(), handlers.size() - 1);
   273             processor.setIndex(-1);
   274             //reset remedyActionTaken
   275             remedyActionTaken = false;
   276         } else {
   277             //Close all handlers in the chain
   279             //SERVER-SIDE
   280             processor.closeHandlers(msgContext, 0, handlers.size() - 1);
   282         }
   283     }
   285     abstract void callHandlersOnResponse(MessageUpdatableContext context, boolean handleFault);
   287     abstract boolean callHandlersOnRequest(MessageUpdatableContext context, boolean oneWay);
   289     private boolean checkOneWay(Packet packet) {
   290         if (port != null) {
   291             /* we can determine this value from WSDL */
   292             return packet.getMessage().isOneWay(port);
   293         } else {
   294             /*
   295               otherwise use this value as an approximation, since this carries
   296               the application's intention --- whether it was invokeOneway vs invoke,etc.
   297              */
   298             return !(packet.expectReply != null && packet.expectReply);
   299         }
   300     }
   302     private void setUpProcessorInternal() {
   303         HandlerConfiguration hc = ((BindingImpl) binding).getHandlerConfig();
   304         if (hc != this.hc)
   305                 resetProcessor();
   306         this.hc = hc;
   308         setUpProcessor();
   309     }
   311     abstract void setUpProcessor();
   313     protected void resetProcessor() {
   314         handlers = null;
   315     }
   317     final public boolean isHandlerChainEmpty() {
   318         return handlers.isEmpty();
   319     }
   320     abstract MessageUpdatableContext getContext(Packet p);
   322     private boolean isHandleFault(Packet packet) {
   323         if (cousinTube != null) {
   324             return exchange.isHandleFault();
   325         } else {
   326             boolean isFault = packet.getMessage().isFault();
   327             exchange.setHandleFault(isFault);
   328             return isFault;
   329         }
   330     }
   332     final void setHandleFault() {
   333         exchange.setHandleFault(true);
   334     }
   336     private boolean isHandleFalse() {
   337         return exchange.isHandleFalse();
   338     }
   340     final void setHandleFalse() {
   341         exchange.setHandleFalse();
   342     }
   344     private void setupExchange() {
   345         if(exchange == null) {
   346             exchange = new HandlerTubeExchange();
   347             if(cousinTube != null) {
   348                 cousinTube.exchange = exchange;
   349             }
   350         } else {
   351             if(cousinTube != null) {
   352                 cousinTube.exchange = exchange;
   353             }
   355         }
   356     }
   357     private HandlerTubeExchange exchange;
   359     /**
   360      * This class is used primarily to exchange information or status between
   361      * LogicalHandlerTube and SOAPHandlerTube
   362      */
   363     static final class HandlerTubeExchange {
   364         private boolean handleFalse;
   365         private boolean handleFault;
   367         boolean isHandleFault() {
   368             return handleFault;
   369         }
   371         void setHandleFault(boolean isFault) {
   372             this.handleFault = isFault;
   373         }
   375         public boolean isHandleFalse() {
   376             return handleFalse;
   377         }
   379         void setHandleFalse() {
   380             this.handleFalse = true;
   381         }
   382     }
   384 }

mercurial