src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/EndpointResponseMessageBuilder.java

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 368
0989ad8c0860
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     1 /*
     2  * Copyright (c) 1997, 2010, 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         protected Wrapped(WrapperParameter wp, SOAPVersion soapVersion) {
   147             super(wp.getXMLBridge(), soapVersion);
   149             List<ParameterImpl> children = wp.getWrapperChildren();
   151             indices = new int[children.size()];
   152             getters = new ValueGetter[children.size()];
   153             for( int i=0; i<indices.length; i++ ) {
   154                 ParameterImpl p = children.get(i);
   155                 indices[i] = p.getIndex();
   156                 getters[i] = ValueGetter.get(p);
   157             }
   158         }
   159     }
   161     /**
   162      * Used to create a payload JAXB object by wrapping
   163      * multiple parameters into one "wrapper bean".
   164      */
   165     public final static class DocLit extends Wrapped {
   166         /**
   167          * How does each wrapped parameter binds to XML?
   168          */
   169         private final PropertyAccessor[] accessors;
   171         //private final RawAccessor retAccessor;
   173         /**
   174          * Wrapper bean.
   175          */
   176         private final Class wrapper;
   178         /**
   179          * Needed to get wrapper instantiation method.
   180          */
   181         private BindingContext bindingContext;
   183         /**
   184          * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
   185          */
   186         public DocLit(WrapperParameter wp, SOAPVersion soapVersion) {
   187             super(wp, soapVersion);
   188             bindingContext = wp.getOwner().getBindingContext();
   190             wrapper = (Class)wp.getXMLBridge().getTypeInfo().type;
   192             List<ParameterImpl> children = wp.getWrapperChildren();
   194             accessors = new PropertyAccessor[children.size()];
   195             for( int i=0; i<accessors.length; i++ ) {
   196                 ParameterImpl p = children.get(i);
   197                 QName name = p.getName();
   198                 try {
   199                     accessors[i] = p.getOwner().getBindingContext().getElementPropertyAccessor(
   200                         wrapper, name.getNamespaceURI(), name.getLocalPart() );
   201                 } catch (JAXBException e) {
   202                     throw new WebServiceException(  // TODO: i18n
   203                         wrapper+" do not have a property of the name "+name,e);
   204                 }
   205             }
   207         }
   209         /**
   210          * Packs a bunch of arguments into a {@link WrapperComposite}.
   211          */
   212         Object build(Object[] methodArgs, Object returnValue) {
   213             try {
   214                 //Object bean = wrapper.newInstance();
   215                 Object bean = bindingContext.newWrapperInstace(wrapper);
   217                 // fill in wrapped parameters from methodArgs
   218                 for( int i=indices.length-1; i>=0; i-- ) {
   219                     if (indices[i] == -1) {
   220                         accessors[i].set(bean, returnValue);
   221                     } else {
   222                         accessors[i].set(bean,getters[i].get(methodArgs[indices[i]]));
   223                     }
   224                 }
   226                 return bean;
   227             } catch (InstantiationException e) {
   228                 // this is irrecoverable
   229                 Error x = new InstantiationError(e.getMessage());
   230                 x.initCause(e);
   231                 throw x;
   232             } catch (IllegalAccessException e) {
   233                 // this is irrecoverable
   234                 Error x = new IllegalAccessError(e.getMessage());
   235                 x.initCause(e);
   236                 throw x;
   237             } catch (com.sun.xml.internal.ws.spi.db.DatabindingException e) {
   238                 // this can happen when the set method throw a checked exception or something like that
   239                 throw new WebServiceException(e);    // TODO:i18n
   240             }
   241         }
   242     }
   245     /**
   246      * Used to create a payload JAXB object by wrapping
   247      * multiple parameters into a {@link WrapperComposite}.
   248      *
   249      * <p>
   250      * This is used for rpc/lit, as we don't have a wrapper bean for it.
   251      * (TODO: Why don't we have a wrapper bean for this, when doc/lit does!?)
   252      */
   253     public final static class RpcLit extends Wrapped {
   254         /**
   255          * How does each wrapped parameter binds to XML?
   256          */
   257         private final XMLBridge[] parameterBridges;
   259         /**
   260          * Used for error diagnostics.
   261          */
   262         private final List<ParameterImpl> children;
   264         /**
   265          * Creates a {@link EndpointResponseMessageBuilder} from a {@link WrapperParameter}.
   266          */
   267         public RpcLit(WrapperParameter wp, SOAPVersion soapVersion) {
   268             super(wp, soapVersion);
   269             // we'll use CompositeStructure to pack requests
   270             assert wp.getTypeInfo().type==WrapperComposite.class;
   272             this.children = wp.getWrapperChildren();
   274             parameterBridges = new XMLBridge[children.size()];
   275             for( int i=0; i<parameterBridges.length; i++ )
   276                 parameterBridges[i] = children.get(i).getXMLBridge();
   277         }
   279         /**
   280          * Packs a bunch of arguments intoa {@link WrapperComposite}.
   281          */
   282         WrapperComposite build(Object[] methodArgs, Object returnValue) {
   283             WrapperComposite cs = new WrapperComposite();
   284             cs.bridges = parameterBridges;
   285             cs.values = new Object[parameterBridges.length];
   287             // fill in wrapped parameters from methodArgs
   288             for( int i=indices.length-1; i>=0; i-- ) {
   289                 Object v;
   290                 if (indices[i] == -1) {
   291                     v = getters[i].get(returnValue);
   292                 } else {
   293                     v = getters[i].get(methodArgs[indices[i]]);
   294                 }
   295                 if(v==null) {
   296                     throw new WebServiceException("Method Parameter: "+
   297                         children.get(i).getName() +" cannot be null. This is BP 1.1 R2211 violation.");
   298                 }
   299                 cs.values[i] = v;
   300             }
   302             return cs;
   303         }
   304     }
   305 }

mercurial