src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/EndpointResponseMessageBuilder.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.sun.xml.internal.ws.api.SOAPVersion;
    29 import com.sun.xml.internal.ws.api.message.Message;
    30 import com.sun.xml.internal.ws.api.message.Messages;
    31 import com.sun.xml.internal.ws.message.jaxb.JAXBMessage;
    32 import com.sun.xml.internal.ws.model.ParameterImpl;
    33 import com.sun.xml.internal.ws.model.WrapperParameter;
    34 import com.sun.xml.internal.ws.spi.db.BindingContext;
    35 import com.sun.xml.internal.ws.spi.db.XMLBridge;
    36 import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
    37 import com.sun.xml.internal.ws.spi.db.WrapperComposite;
    39 import javax.xml.bind.JAXBException;
    40 import javax.xml.namespace.QName;
    41 import javax.xml.ws.Holder;
    42 import javax.xml.ws.WebServiceException;
    43 import java.util.List;
    45 /**
    46  * Builds a JAXB object that represents the payload.
    47  *
    48  * @see MessageFiller
    49  * @author Jitendra Kotamraju
    50  */
    51 public abstract class EndpointResponseMessageBuilder {
    52     public abstract Message createMessage(Object[] methodArgs, Object returnValue);
    54     public static final EndpointResponseMessageBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
    55     public static final EndpointResponseMessageBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
    57     private static final class Empty extends EndpointResponseMessageBuilder {
    58         private final SOAPVersion soapVersion;
    60         public Empty(SOAPVersion soapVersion) {
    61             this.soapVersion = soapVersion;
    62         }
    64         public Message createMessage(Object[] methodArgs, Object returnValue) {
    65             return Messages.createEmpty(soapVersion);
    66         }
    67     }
    69     /**
    70      * Base class for those {@link EndpointResponseMessageBuilder}s that build a {@link Message}
    71      * from JAXB objects.
    72      */
    73     private static abstract class JAXB extends EndpointResponseMessageBuilder {
    74         /**
    75          * This object determines the binding of the object returned
    76          * from {@link #createMessage(Object[], Object)}
    77          */
    78         private final XMLBridge bridge;
    79         private final SOAPVersion soapVersion;
    81         protected JAXB(XMLBridge bridge, SOAPVersion soapVersion) {
    82             assert bridge!=null;
    83             this.bridge = bridge;
    84             this.soapVersion = soapVersion;
    85         }
    87         public final Message createMessage(Object[] methodArgs, Object returnValue) {
    88             return JAXBMessage.create( bridge, build(methodArgs, returnValue), soapVersion );
    89         }
    91         /**
    92          * Builds a JAXB object that becomes the payload.
    93          */
    94         abstract Object build(Object[] methodArgs, Object returnValue);
    95     }
    97     /**
    98      * Used to create a payload JAXB object just by taking
    99      * one of the parameters.
   100      */
   101     public final static class Bare extends JAXB {
   102         /**
   103          * The index of the method invocation parameters that goes into the payload.
   104          */
   105         private final int methodPos;
   107         private final ValueGetter getter;
   109         /**
   110          * Creates a {@link EndpointResponseMessageBuilder} from a bare parameter.
   111          */
   112         public Bare(ParameterImpl p, SOAPVersion soapVersion) {
   113             super(p.getXMLBridge(), soapVersion);
   114             this.methodPos = p.getIndex();
   115             this.getter = ValueGetter.get(p);
   116         }
   118         /**
   119          * Picks up an object from the method arguments and uses it.
   120          */
   121         Object build(Object[] methodArgs, Object returnValue) {
   122             if (methodPos == -1) {
   123                 return returnValue;
   124             }
   125             return getter.get(methodArgs[methodPos]);
   126         }
   127     }
   130     /**
   131      * Used to handle a 'wrapper' style request.
   132      * Common part of rpc/lit and doc/lit.
   133      */
   134     abstract static class Wrapped extends JAXB {
   136         /**
   137          * Where in the method argument list do they come from?
   138          */
   139         protected final int[] indices;
   141         /**
   142          * Abstracts away the {@link Holder} handling when touching method arguments.
   143          */
   144         protected final ValueGetter[] getters;
   146         /**
   147          * How does each wrapped parameter binds to XML?
   148          */
   149         protected XMLBridge[] parameterBridges;
   151         /**
   152          * Used for error diagnostics.
   153          */
   154         protected List<ParameterImpl> children;
   156         protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion) {
   157             super(wp.getXMLBridge(), soapVersion);
   159             children = wp.getWrapperChildren();
   161             indices = new int[children.size()];
   162             getters = new ValueGetter[children.size()];
   163             for( int i=0; i<indices.length; i++ ) {
   164                 ParameterImpl p = children.get(i);
   165                 indices[i] = p.getIndex();
   166                 getters[i] = ValueGetter.get(p);
   167             }
   168         }
   170         /**
   171          * Packs a bunch of arguments intoa {@link WrapperComposite}.
   172          */
   173         WrapperComposite buildWrapperComposite(Object[] methodArgs, Object returnValue) {
   174             WrapperComposite cs = new WrapperComposite();
   175             cs.bridges = parameterBridges;
   176             cs.values = new Object[parameterBridges.length];
   178             // fill in wrapped parameters from methodArgs
   179             for( int i=indices.length-1; i>=0; i-- ) {
   180                 Object v;
   181                 if (indices[i] == -1) {
   182                     v = getters[i].get(returnValue);
   183                 } else {
   184                     v = getters[i].get(methodArgs[indices[i]]);
   185                 }
   186                 if(v==null) {
   187                     throw new WebServiceException("Method Parameter: "+
   188                         children.get(i).getName() +" cannot be null. This is BP 1.1 R2211 violation.");
   189                 }
   190                 cs.values[i] = v;
   191             }
   193             return cs;
   194         }
   195     }
   197     /**
   198      * Used to create a payload JAXB object by wrapping
   199      * multiple parameters into one "wrapper bean".
   200      */
   201     public final static class DocLit extends Wrapped {
   202         /**
   203          * How does each wrapped parameter binds to XML?
   204          */
   205         private final PropertyAccessor[] accessors;
   207         //private final RawAccessor retAccessor;
   209         /**
   210          * Wrapper bean.
   211          */
   212         private final Class wrapper;
   213         private boolean dynamicWrapper;
   215         /**
   216          * Needed to get wrapper instantiation method.
   217          */
   218         private BindingContext bindingContext;
   220         /**
   221          * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
   222          */
   223         public DocLit(WrapperParameter wp, SOAPVersion soapVersion) {
   224             super(wp, soapVersion);
   225             bindingContext = wp.getOwner().getBindingContext();
   226             wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
   227             dynamicWrapper = WrapperComposite.class.equals(wrapper);
   228             children = wp.getWrapperChildren();
   229             parameterBridges = new XMLBridge[children.size()];
   230             accessors = new PropertyAccessor[children.size()];
   231             for( int i=0; i<accessors.length; i++ ) {
   232                 ParameterImpl p = children.get(i);
   233                 QName name = p.getName();
   234                 if (dynamicWrapper) {
   235                     parameterBridges[i] = children.get(i).getInlinedRepeatedElementBridge();
   236                     if (parameterBridges[i] == null) parameterBridges[i] = children.get(i).getXMLBridge();
   237                 } else {
   238                     try {
   239                         accessors[i] = (dynamicWrapper) ? null :
   240                             p.getOwner().getBindingContext().getElementPropertyAccessor(
   241                             wrapper, name.getNamespaceURI(), name.getLocalPart() );
   242                     } catch (JAXBException e) {
   243                         throw new WebServiceException(  // TODO: i18n
   244                             wrapper+" do not have a property of the name "+name,e);
   245                     }
   246                 }
   247             }
   249         }
   251         /**
   252          * Packs a bunch of arguments into a {@link WrapperComposite}.
   253          */
   254         Object build(Object[] methodArgs, Object returnValue) {
   255             if (dynamicWrapper) return buildWrapperComposite(methodArgs, returnValue);
   256             try {
   257                 //Object bean = wrapper.newInstance();
   258                 Object bean = bindingContext.newWrapperInstace(wrapper);
   260                 // fill in wrapped parameters from methodArgs
   261                 for( int i=indices.length-1; i>=0; i-- ) {
   262                     if (indices[i] == -1) {
   263                         accessors[i].set(bean, returnValue);
   264                     } else {
   265                         accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
   266                     }
   267                 }
   269                 return bean;
   270             } catch (InstantiationException e) {
   271                 // this is irrecoverable
   272                 Error x = new InstantiationError(e.getMessage());
   273                 x.initCause(e);
   274                 throw x;
   275             } catch (IllegalAccessException e) {
   276                 // this is irrecoverable
   277                 Error x = new IllegalAccessError(e.getMessage());
   278                 x.initCause(e);
   279                 throw x;
   280             } catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
   281                 // this can happen when the set method throw a checked exception or something like that
   282                 throw new WebServiceException(e);    // TODO:i18n
   283             }
   284         }
   285     }
   288     /**
   289      * Used to create a payload JAXB object by wrapping
   290      * multiple parameters into a {@link WrapperComposite}.
   291      *
   292      * <p>
   293      * This is used for rpc/lit, as we don't have a wrapper bean for it.
   294      * (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
   295      */
   296     public final static class RpcLit extends Wrapped {
   298         /**
   299          * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
   300          */
   301         public RpcLit(WrapperParameter wp, SOAPVersion soapVersion) {
   302             super(wp, soapVersion);
   303             // we'll use CompositeStructure to pack requests
   304             assert wp.getTypeInfo().type==WrapperComposite.class;
   306             parameterBridges = new XMLBridge[children.size()];
   307             for( int i=0; i<parameterBridges.length; i++ )
   308                 parameterBridges[i] = children.get(i).getXMLBridge();
   309         }
   311         /**
   312          * Packs a bunch of arguments intoa {@link WrapperComposite}.
   313          */
   314         Object build(Object[] methodArgs, Object returnValue) {
   315             return buildWrapperComposite(methodArgs, returnValue);
   316         }
   317     }
   318 }

mercurial