src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/TieHandler.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.server.sei;
    28 import com.oracle.webservices.internal.api.databinding.JavaCallInfo;
    29 import com.sun.xml.internal.ws.api.SOAPVersion;
    30 import com.sun.xml.internal.ws.api.WSBinding;
    31 import com.sun.xml.internal.ws.api.databinding.EndpointCallBridge;
    32 import com.sun.xml.internal.ws.api.message.Message;
    33 import com.sun.xml.internal.ws.api.message.MessageContextFactory;
    34 import com.sun.xml.internal.ws.api.message.Packet;
    35 import com.sun.xml.internal.ws.api.model.JavaMethod;
    36 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
    37 import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
    38 import com.sun.xml.internal.ws.model.JavaMethodImpl;
    39 import com.sun.xml.internal.ws.model.ParameterImpl;
    40 import com.sun.xml.internal.ws.model.WrapperParameter;
    41 import com.sun.xml.internal.ws.wsdl.DispatchException;
    43 import javax.jws.WebParam.Mode;
    44 import javax.xml.bind.JAXBException;
    45 import javax.xml.stream.XMLStreamException;
    46 import javax.xml.ws.Holder;
    47 import javax.xml.ws.ProtocolException;
    48 import javax.xml.ws.WebServiceException;
    49 import java.lang.reflect.InvocationTargetException;
    50 import java.lang.reflect.Method;
    51 import java.util.ArrayList;
    52 import java.util.List;
    53 import java.util.logging.Level;
    54 import java.util.logging.Logger;
    56 /**
    57  *
    58  * <p>
    59  * This class mainly performs the following two tasks:
    60  * <ol>
    61  *  <li>Takes a {@link Message} that represents a request,
    62  *      and extracts the arguments (and updates {@link Holder}s.)
    63  *  <li>Accepts return value and {@link Holder} arguments for a Java method,
    64  *      and creates {@link JAXBMessage} that represents a response message.
    65  * </ol>
    66  *
    67  * <h2>Creating {@link JAXBMessage}</h2>
    68  * <p>
    69  * At the construction time, we prepare {@link EndpointArgumentsBuilder} that knows how to create endpoint {@link Method}
    70  * invocation arguments.
    71  * we also prepare {@link EndpointResponseMessageBuilder} and {@link MessageFiller}s
    72  * that know how to move arguments into a {@link Message}.
    73  * Some arguments go to the payload, some go to headers, still others go to attachments.
    74  *
    75  * @author Jitendra Kotamraju
    76  * @author shih-chang.chen@oracle.com
    77  *                 Refactored from EndpointMethodHandler
    78  */
    79 final public class TieHandler implements EndpointCallBridge {
    81     private final SOAPVersion soapVersion;
    82     private final Method method;
    83     private final int noOfArgs;
    84     private final JavaMethodImpl javaMethodModel;
    86      private final Boolean isOneWay;
    88     // Converts {@link Message} --> Object[]
    89     private final EndpointArgumentsBuilder argumentsBuilder;
    91     // these objects together create a response message from method parameters
    92     private final EndpointResponseMessageBuilder bodyBuilder;
    93     private final MessageFiller[] outFillers;
    94     protected MessageContextFactory packetFactory;
    96     public TieHandler(JavaMethodImpl method, WSBinding binding, MessageContextFactory mcf) {
    97         this.soapVersion = binding.getSOAPVersion();
    98         this.method = method.getMethod();
    99         this.javaMethodModel = method;
   100         argumentsBuilder = createArgumentsBuilder();
   101         List<MessageFiller> fillers = new ArrayList<MessageFiller>();
   102         bodyBuilder = createResponseMessageBuilder(fillers);
   103         this.outFillers = fillers.toArray(new MessageFiller[fillers.size()]);
   104         this.isOneWay = method.getMEP().isOneWay();
   105         this.noOfArgs = this.method.getParameterTypes().length;
   106         packetFactory = mcf;
   107     }
   109     /**
   110      * It builds EndpointArgumentsBuilder which converts request {@link Message} to endpoint method's invocation
   111      * arguments Object[]
   112      *
   113      * @return EndpointArgumentsBuilder
   114      */
   115     private EndpointArgumentsBuilder createArgumentsBuilder() {
   116         EndpointArgumentsBuilder argsBuilder;
   117         List<ParameterImpl> rp = javaMethodModel.getRequestParameters();
   118         List<EndpointArgumentsBuilder> builders = new ArrayList<EndpointArgumentsBuilder>();
   120         for( ParameterImpl param : rp ) {
   121             EndpointValueSetter setter = EndpointValueSetter.get(param);
   122             switch(param.getInBinding().kind) {
   123             case BODY:
   124                 if(param.isWrapperStyle()) {
   125                     if(param.getParent().getBinding().isRpcLit())
   126                         builders.add(new EndpointArgumentsBuilder.RpcLit((WrapperParameter)param));
   127                     else
   128                         builders.add(new EndpointArgumentsBuilder.DocLit((WrapperParameter)param, Mode.OUT));
   129                 } else {
   130                     builders.add(new EndpointArgumentsBuilder.Body(param.getXMLBridge(),setter));
   131                 }
   132                 break;
   133             case HEADER:
   134                 builders.add(new EndpointArgumentsBuilder.Header(soapVersion, param, setter));
   135                 break;
   136             case ATTACHMENT:
   137                 builders.add(EndpointArgumentsBuilder.AttachmentBuilder.createAttachmentBuilder(param, setter));
   138                 break;
   139             case UNBOUND:
   140                 builders.add(new EndpointArgumentsBuilder.NullSetter(setter,
   141                     EndpointArgumentsBuilder.getVMUninitializedValue(param.getTypeInfo().type)));
   142                 break;
   143             default:
   144                 throw new AssertionError();
   145             }
   146         }
   148         // creates {@link Holder} arguments for OUT parameters
   149         List<ParameterImpl> resp = javaMethodModel.getResponseParameters();
   150         for( ParameterImpl param : resp ) {
   151             if (param.isWrapperStyle()) {
   152                 WrapperParameter wp = (WrapperParameter)param;
   153                 List<ParameterImpl> children = wp.getWrapperChildren();
   154                 for (ParameterImpl p : children) {
   155                     if (p.isOUT() && p.getIndex() != -1) {
   156                         EndpointValueSetter setter = EndpointValueSetter.get(p);
   157                         builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
   158                     }
   159                 }
   160             } else if (param.isOUT() && param.getIndex() != -1) {
   161                 EndpointValueSetter setter = EndpointValueSetter.get(param);
   162                 builders.add(new EndpointArgumentsBuilder.NullSetter(setter, null));
   163             }
   164         }
   166         switch(builders.size()) {
   167         case 0:
   168             argsBuilder = EndpointArgumentsBuilder.NONE;
   169             break;
   170         case 1:
   171             argsBuilder = builders.get(0);
   172             break;
   173         default:
   174             argsBuilder = new EndpointArgumentsBuilder.Composite(builders);
   175         }
   176         return argsBuilder;
   177     }
   179     /**
   180     * prepare objects for creating response {@link Message}
   181     */
   182     private EndpointResponseMessageBuilder createResponseMessageBuilder(List<MessageFiller> fillers) {
   184         EndpointResponseMessageBuilder tmpBodyBuilder = null;
   185         List<ParameterImpl> rp = javaMethodModel.getResponseParameters();
   187         for (ParameterImpl param : rp) {
   188             ValueGetter getter = ValueGetter.get(param);
   190             switch(param.getOutBinding().kind) {
   191             case BODY:
   192                 if(param.isWrapperStyle()) {
   193                     if(param.getParent().getBinding().isRpcLit()) {
   194                         tmpBodyBuilder = new EndpointResponseMessageBuilder.RpcLit((WrapperParameter)param,
   195                             soapVersion);
   196                     } else {
   197                         tmpBodyBuilder = new EndpointResponseMessageBuilder.DocLit((WrapperParameter)param,
   198                             soapVersion);
   199                     }
   200                 } else {
   201                     tmpBodyBuilder = new EndpointResponseMessageBuilder.Bare(param, soapVersion);
   202                 }
   203                 break;
   204             case HEADER:
   205                 fillers.add(new MessageFiller.Header(param.getIndex(), param.getXMLBridge(), getter ));
   206                 break;
   207             case ATTACHMENT:
   208                 fillers.add(MessageFiller.AttachmentFiller.createAttachmentFiller(param, getter));
   209                 break;
   210             case UNBOUND:
   211                 break;
   212             default:
   213                 throw new AssertionError(); // impossible
   214             }
   215         }
   217         if (tmpBodyBuilder == null) {
   218             // no parameter binds to body. we create an empty message
   219             switch(soapVersion) {
   220             case SOAP_11:
   221                 tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP11;
   222                 break;
   223             case SOAP_12:
   224                 tmpBodyBuilder = EndpointResponseMessageBuilder.EMPTY_SOAP12;
   225                 break;
   226             default:
   227                 throw new AssertionError();
   228             }
   229         }
   230         return tmpBodyBuilder;
   231     }
   233     public Object[] readRequest(Message reqMsg) {
   234         Object[] args = new Object[noOfArgs];
   235         try {
   236             argumentsBuilder.readRequest(reqMsg,args);
   237         } catch (JAXBException e) {
   238             throw new WebServiceException(e);
   239         } catch (XMLStreamException e) {
   240             throw new WebServiceException(e);
   241         }
   242         return args;
   243     }
   245     public Message createResponse(JavaCallInfo call) {
   246         Message responseMessage;
   247         if (call.getException() == null) {
   248             responseMessage = isOneWay ? null : createResponseMessage(call.getParameters(), call.getReturnValue());
   249         } else {
   250             Throwable e = call.getException();
   251             Throwable serviceException = getServiceException(e);
   252             if (e instanceof InvocationTargetException || serviceException != null) {
   253 //              Throwable cause = e.getCause();
   254               //if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
   255                 if (serviceException != null) {
   256                     // Service specific exception
   257                     LOGGER.log(Level.FINE, serviceException.getMessage(), serviceException);
   258                     responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion,
   259                             javaMethodModel.getCheckedException(serviceException.getClass()), serviceException);
   260                 } else {
   261                     Throwable cause = e.getCause();
   262                     if (cause instanceof ProtocolException) {
   263                         // Application code may be throwing it intentionally
   264                         LOGGER.log(Level.FINE, cause.getMessage(), cause);
   265                     } else {
   266                         // Probably some bug in application code
   267                         LOGGER.log(Level.SEVERE, cause.getMessage(), cause);
   268                     }
   269                     responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, cause);
   270                 }
   271             } else if (e instanceof DispatchException) {
   272                 responseMessage = ((DispatchException)e).fault;
   273             } else {
   274                 LOGGER.log(Level.SEVERE, e.getMessage(), e);
   275                 responseMessage = SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
   276             }
   277         }
   278 //        return req.createServerResponse(responseMessage, req.endpoint.getPort(), javaMethodModel.getOwner(), req.endpoint.getBinding());
   280         return responseMessage;
   281     }
   283     Throwable getServiceException(Throwable throwable) {
   284         if (javaMethodModel.getCheckedException(throwable.getClass()) != null) return throwable;
   285         if (throwable.getCause() != null) {
   286             Throwable cause = throwable.getCause();
   287 //            if (!(cause instanceof RuntimeException) && cause instanceof Exception) {
   288              if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
   289 //            }
   290 //            if (javaMethodModel.getCheckedException(cause.getClass()) != null) return cause;
   291         }
   292         return null;
   293     }
   295     /**
   296      * Creates a response {@link JAXBMessage} from method arguments, return value
   297      *
   298      * @return response message
   299      */
   300     private Message createResponseMessage(Object[] args, Object returnValue) {
   301         Message msg = bodyBuilder.createMessage(args, returnValue);
   303         for (MessageFiller filler : outFillers)
   304             filler.fillIn(args, returnValue, msg);
   306         return msg;
   307     }
   309     public Method getMethod() {
   310         return method;
   311     }
   313     private static final Logger LOGGER = Logger.getLogger(TieHandler.class.getName());
   315     @Override
   316         public JavaCallInfo deserializeRequest(Packet req) {
   317         com.sun.xml.internal.ws.api.databinding.JavaCallInfo call = new com.sun.xml.internal.ws.api.databinding.JavaCallInfo();
   318                 call.setMethod(this.getMethod());
   319         Object[] args = this.readRequest(req.getMessage());
   320                 call.setParameters(args);
   321                 return call;
   322         }
   324     @Override
   325         public Packet serializeResponse(JavaCallInfo call) {
   326             Message msg = this.createResponse(call);
   327             Packet p = (msg == null) ? (Packet)packetFactory.createContext() : (Packet)packetFactory.createContext(msg);
   328             p.setState(Packet.State.ServerResponse);
   329             return p;
   330         }
   332     @Override
   333     public JavaMethod getOperationModel() {
   334         return javaMethodModel;
   335     }
   336 }

mercurial