src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/BodyBuilder.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.client.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 Kohsuke Kawaguchi
    50  */
    51 abstract class BodyBuilder {
    52     abstract Message createMessage(Object[] methodArgs);
    54     static final BodyBuilder EMPTY_SOAP11 = new Empty(SOAPVersion.SOAP_11);
    55     static final BodyBuilder EMPTY_SOAP12 = new Empty(SOAPVersion.SOAP_12);
    57     private static final class Empty extends BodyBuilder {
    58         private final SOAPVersion soapVersion;
    60         public Empty(SOAPVersion soapVersion) {
    61             this.soapVersion = soapVersion;
    62         }
    64         Message createMessage(Object[] methodArgs) {
    65             return Messages.createEmpty(soapVersion);
    66         }
    67     }
    69     /**
    70      * Base class for those {@link BodyBuilder}s that build a {@link Message}
    71      * from JAXB objects.
    72      */
    73     private static abstract class JAXB extends BodyBuilder {
    74         /**
    75          * This object determines the binding of the object returned
    76          * from {@link #build(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         final Message createMessage(Object[] methodArgs) {
    88             return JAXBMessage.create( bridge, build(methodArgs), soapVersion );
    89         }
    91         /**
    92          * Builds a JAXB object that becomes the payload.
    93          */
    94         abstract Object build(Object[] methodArgs);
    95     }
    97     /**
    98      * Used to create a payload JAXB object just by taking
    99      * one of the parameters.
   100      */
   101     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 BodyBuilder} from a bare parameter.
   111          */
   112         Bare(ParameterImpl p, SOAPVersion soapVersion, ValueGetter getter) {
   113             super(p.getXMLBridge(), soapVersion);
   114             this.methodPos = p.getIndex();
   115             this.getter = getter;
   116         }
   118         /**
   119          * Picks up an object from the method arguments and uses it.
   120          */
   121         Object build(Object[] methodArgs) {
   122             return getter.get(methodArgs[methodPos]);
   123         }
   124     }
   127     /**
   128      * Used to handle a 'wrapper' style request.
   129      * Common part of rpc/lit and doc/lit.
   130      */
   131     abstract static class Wrapped extends JAXB {
   133         /**
   134          * Where in the method argument list do they come from?
   135          */
   136         protected final int[] indices;
   138         /**
   139          * Abstracts away the {@link Holder} handling when touching method arguments.
   140          */
   141         protected final ValueGetter[] getters;
   143         /**
   144          * How does each wrapped parameter binds to XML?
   145          */
   146         protected XMLBridge[] parameterBridges;
   148         /**
   149          * List of Parameters packed in the body.
   150          * Only used for error diagnostics.
   151          */
   152         protected List<ParameterImpl> children;
   154         protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
   155             super(wp.getXMLBridge(), soapVersion);
   156             children = wp.getWrapperChildren();
   157             indices = new int[children.size()];
   158             getters = new ValueGetter[children.size()];
   159             for( int i=0; i<indices.length; i++ ) {
   160                 ParameterImpl p = children.get(i);
   161                 indices[i] = p.getIndex();
   162                 getters[i] = getter.get(p);
   163             }
   164         }
   166         /**
   167          * Packs a bunch of arguments into a {@link WrapperComposite}.
   168          */
   169         protected WrapperComposite buildWrapperComposite(Object[] methodArgs) {
   170             WrapperComposite cs = new WrapperComposite();
   171             cs.bridges = parameterBridges;
   172             cs.values = new Object[parameterBridges.length];
   174             // fill in wrapped parameters from methodArgs
   175             for( int i=indices.length-1; i>=0; i-- ) {
   176                 Object arg = getters[i].get(methodArgs[indices[i]]);
   177                 if(arg==null) {
   178                     throw new WebServiceException("Method Parameter: "+
   179                         children.get(i).getName()+" cannot be null. This is BP 1.1 R2211 violation.");
   180                 }
   181                 cs.values[i] = arg;
   182             }
   184             return cs;
   185         }
   186     }
   188     /**
   189      * Used to create a payload JAXB object by wrapping
   190      * multiple parameters into one "wrapper bean".
   191      */
   192     final static class DocLit extends Wrapped {
   193         /**
   194          * How does each wrapped parameter binds to XML?
   195          */
   196         private final PropertyAccessor[] accessors;
   198         /**
   199          * Wrapper bean.
   200          */
   201         private final Class wrapper;
   203         /**
   204          * Needed to get wrapper instantiation method.
   205          */
   206         private BindingContext bindingContext;
   207         private boolean dynamicWrapper;
   209         /**
   210          * Creates a {@link BodyBuilder} from a {@link WrapperParameter}.
   211          */
   212         DocLit(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
   213             super(wp, soapVersion, getter);
   214             bindingContext = wp.getOwner().getBindingContext();
   215             wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
   216             dynamicWrapper = WrapperComposite.class.equals(wrapper);
   217             parameterBridges = new XMLBridge[children.size()];
   218             accessors = new PropertyAccessor[children.size()];
   219             for( int i=0; i<accessors.length; i++ ) {
   220                 ParameterImpl p = children.get(i);
   221                 QName name = p.getName();
   222                 if (dynamicWrapper) {
   223                     parameterBridges[i] = children.get(i).getInlinedRepeatedElementBridge();
   224                     if (parameterBridges[i] == null) parameterBridges[i] = children.get(i).getXMLBridge();
   225                 } else {
   226                     try {
   227                         accessors[i] = p.getOwner().getBindingContext().getElementPropertyAccessor(
   228                             wrapper, name.getNamespaceURI(), name.getLocalPart() );
   229                     } catch (JAXBException e) {
   230                         throw new WebServiceException(  // TODO: i18n
   231                             wrapper+" do not have a property of the name "+name,e);
   232                     }
   233                 }
   234             }
   236         }
   238         /**
   239          * Packs a bunch of arguments into a {@link WrapperComposite}.
   240          */
   241         Object build(Object[] methodArgs) {
   242             if (dynamicWrapper) return buildWrapperComposite(methodArgs);
   243             try {
   244                 //Object bean = wrapper.newInstance();
   245                 Object bean = bindingContext.newWrapperInstace(wrapper);
   247                 // fill in wrapped parameters from methodArgs
   248                 for( int i=indices.length-1; i>=0; i-- ) {
   249                     accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
   250                 }
   252                 return bean;
   253             } catch (InstantiationException e) {
   254                 // this is irrecoverable
   255                 Error x = new InstantiationError(e.getMessage());
   256                 x.initCause(e);
   257                 throw x;
   258             } catch (IllegalAccessException e) {
   259                 // this is irrecoverable
   260                 Error x = new IllegalAccessError(e.getMessage());
   261                 x.initCause(e);
   262                 throw x;
   263             } catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
   264                 // this can happen when the set method throw a checked exception or something like that
   265                 throw new WebServiceException(e);    // TODO:i18n
   266             }
   267         }
   268     }
   271     /**
   272      * Used to create a payload JAXB object by wrapping
   273      * multiple parameters into a {@link WrapperComposite}.
   274      *
   275      * <p>
   276      * This is used for rpc/lit, as we don't have a wrapper bean for it.
   277      * (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
   278      */
   279     final static class RpcLit extends Wrapped {
   281         /**
   282          * Creates a {@link BodyBuilder} from a {@link WrapperParameter}.
   283          */
   284         RpcLit(WrapperParameter wp, SOAPVersion soapVersion, ValueGetterFactory getter) {
   285             super(wp, soapVersion, getter);
   286             // we'll use CompositeStructure to pack requests
   287             assert wp.getTypeInfo().type==WrapperComposite.class;
   289             parameterBridges = new XMLBridge[children.size()];
   290             for( int i=0; i<parameterBridges.length; i++ )
   291                 parameterBridges[i] = children.get(i).getXMLBridge();
   292         }
   294         Object build(Object[] methodArgs) {
   295             return buildWrapperComposite(methodArgs);
   296         }
   297     }
   298 }

mercurial