src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/EndpointArgumentsBuilder.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, 2013, 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.Attachment;
    30 import com.sun.xml.internal.ws.api.message.AttachmentSet;
    31 import com.sun.xml.internal.ws.api.message.Message;
    32 import com.sun.xml.internal.ws.api.model.ParameterBinding;
    33 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
    34 import com.sun.xml.internal.ws.message.AttachmentUnmarshallerImpl;
    35 import com.sun.xml.internal.ws.model.ParameterImpl;
    36 import com.sun.xml.internal.ws.model.WrapperParameter;
    37 import com.sun.xml.internal.ws.resources.ServerMessages;
    38 import com.sun.xml.internal.ws.spi.db.RepeatedElementBridge;
    39 import com.sun.xml.internal.ws.spi.db.XMLBridge;
    40 import com.sun.xml.internal.ws.spi.db.DatabindingException;
    41 import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
    42 import com.sun.xml.internal.ws.spi.db.WrapperComposite;
    43 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
    44 import com.sun.xml.internal.ws.encoding.StringDataContentHandler;
    45 import com.sun.xml.internal.ws.encoding.DataHandlerDataSource;
    47 import javax.activation.DataHandler;
    48 import javax.imageio.ImageIO;
    49 import javax.jws.WebParam.Mode;
    50 import javax.xml.bind.JAXBException;
    51 import javax.xml.namespace.QName;
    52 import javax.xml.soap.SOAPException;
    53 import javax.xml.soap.SOAPFault;
    54 import javax.xml.stream.XMLStreamException;
    55 import javax.xml.stream.XMLStreamReader;
    56 import javax.xml.transform.Source;
    57 import javax.xml.ws.Holder;
    58 import javax.xml.ws.WebServiceException;
    59 import javax.xml.ws.soap.SOAPFaultException;
    60 import java.awt.Image;
    61 import java.io.IOException;
    62 import java.io.InputStream;
    63 import java.io.UnsupportedEncodingException;
    64 import java.lang.reflect.Type;
    65 import java.util.ArrayList;
    66 import java.util.Collection;
    67 import java.util.HashMap;
    68 import java.util.Iterator;
    69 import java.util.List;
    70 import java.util.Map;
    72 /**
    73  * Reads a request {@link Message}, disassembles it, and moves obtained Java values
    74  * to the expected places.
    75  *
    76  * @author Jitendra Kotamraju
    77  */
    78 public abstract class EndpointArgumentsBuilder {
    79     /**
    80      * Reads a request {@link Message}, disassembles it, and moves obtained
    81      * Java values to the expected places.
    82      *
    83      * @param request
    84      *      The request {@link Message} to be de-composed.
    85      * @param args
    86      *      The Java arguments given to the SEI method invocation.
    87      *      Some parts of the reply message may be set to {@link Holder}s in the arguments.
    88      * @throws JAXBException
    89      *      if there's an error during unmarshalling the request message.
    90      * @throws XMLStreamException
    91      *      if there's an error during unmarshalling the request message.
    92      */
    93     public abstract void readRequest(Message request, Object[] args)
    94         throws JAXBException, XMLStreamException;
    96     static final class None extends EndpointArgumentsBuilder {
    97         private None(){
    98         }
    99         @Override
   100         public void readRequest(Message msg, Object[] args) {
   101             msg.consume();
   102         }
   103     }
   105     /**
   106      * The singleton instance that produces null return value.
   107      * Used for operations that doesn't have any output.
   108      */
   109     public final static EndpointArgumentsBuilder NONE = new None();
   111     /**
   112      * Returns the 'uninitialized' value for the given type.
   113      *
   114      * <p>
   115      * For primitive types, it's '0', and for reference types, it's null.
   116      */
   117     @SuppressWarnings("element-type-mismatch")
   118     public static Object getVMUninitializedValue(Type type) {
   119         // if this map returns null, that means the 'type' is a reference type,
   120         // in which case 'null' is the correct null value, so this code is correct.
   121         return primitiveUninitializedValues.get(type);
   122     }
   124     private static final Map<Class,Object> primitiveUninitializedValues = new HashMap<Class, Object>();
   126     static {
   127         Map<Class, Object> m = primitiveUninitializedValues;
   128         m.put(int.class,(int)0);
   129         m.put(char.class,(char)0);
   130         m.put(byte.class,(byte)0);
   131         m.put(short.class,(short)0);
   132         m.put(long.class,(long)0);
   133         m.put(float.class,(float)0);
   134         m.put(double.class,(double)0);
   135     }
   137     protected QName wrapperName;
   139     static final class WrappedPartBuilder {
   140         private final XMLBridge bridge;
   141         private final EndpointValueSetter setter;
   143         /**
   144          * @param bridge
   145          *      specifies how the part is unmarshalled.
   146          * @param setter
   147          *      specifies how the obtained value is returned to the endpoint.
   148          */
   149         public WrappedPartBuilder(XMLBridge bridge, EndpointValueSetter setter) {
   150             this.bridge = bridge;
   151             this.setter = setter;
   152         }
   154         void readRequest( Object[] args, XMLStreamReader r, AttachmentSet att) throws JAXBException {
   155             Object obj = null;
   156             AttachmentUnmarshallerImpl au = (att != null)?new AttachmentUnmarshallerImpl(att):null;
   157             if (bridge instanceof RepeatedElementBridge) {
   158                 RepeatedElementBridge rbridge = (RepeatedElementBridge)bridge;
   159                 ArrayList list = new ArrayList();
   160                 QName name = r.getName();
   161                 while (r.getEventType()==XMLStreamReader.START_ELEMENT && name.equals(r.getName())) {
   162                     list.add(rbridge.unmarshal(r, au));
   163                     XMLStreamReaderUtil.toNextTag(r, name);
   164                 }
   165                 obj = rbridge.collectionHandler().convert(list);
   166             } else {
   167                 obj = bridge.unmarshal(r, au);
   168             }
   169             setter.put(obj,args);
   170         }
   171     }
   173     protected Map<QName,WrappedPartBuilder> wrappedParts = null;
   175     protected void readWrappedRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   176         if (!msg.hasPayload()) {
   177             throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
   178         }
   179         XMLStreamReader reader = msg.readPayload();
   180         XMLStreamReaderUtil.verifyTag(reader,wrapperName);
   181         reader.nextTag();
   182         while(reader.getEventType()==XMLStreamReader.START_ELEMENT) {
   183             // TODO: QName has a performance issue
   184             QName name = reader.getName();
   185             WrappedPartBuilder part = wrappedParts.get(name);
   186             if(part==null) {
   187                 // no corresponding part found. ignore
   188                 XMLStreamReaderUtil.skipElement(reader);
   189                 reader.nextTag();
   190             } else {
   191                 part.readRequest(args,reader, msg.getAttachments());
   192             }
   193             XMLStreamReaderUtil.toNextTag(reader, name);
   194         }
   196         // we are done with the body
   197         reader.close();
   198         XMLStreamReaderFactory.recycle(reader);
   199     }
   201     /**
   202      * {@link EndpointArgumentsBuilder} that sets the VM uninitialized value to the type.
   203      */
   204     public static final class NullSetter extends EndpointArgumentsBuilder {
   205         private final EndpointValueSetter setter;
   206         private final Object nullValue;
   208         public NullSetter(EndpointValueSetter setter, Object nullValue){
   209             assert setter!=null;
   210             this.nullValue = nullValue;
   211             this.setter = setter;
   212         }
   213         public void readRequest(Message msg, Object[] args) {
   214             setter.put(nullValue, args);
   215         }
   216     }
   218     /**
   219      * {@link EndpointArgumentsBuilder} that is a composition of multiple
   220      * {@link EndpointArgumentsBuilder}s.
   221      *
   222      * <p>
   223      * Sometimes we need to look at multiple parts of the reply message
   224      * (say, two header params, one body param, and three attachments, etc.)
   225      * and that's when this object is used to combine multiple {@link EndpointArgumentsBuilder}s
   226      * (that each responsible for handling one part).
   227      *
   228      * <p>
   229      * The model guarantees that only at most one {@link EndpointArgumentsBuilder} will
   230      * return a value as a return value (and everything else has to go to
   231      * {@link Holder}s.)
   232      */
   233     public static final class Composite extends EndpointArgumentsBuilder {
   234         private final EndpointArgumentsBuilder[] builders;
   236         public Composite(EndpointArgumentsBuilder... builders) {
   237             this.builders = builders;
   238         }
   240         public Composite(Collection<? extends EndpointArgumentsBuilder> builders) {
   241             this(builders.toArray(new EndpointArgumentsBuilder[builders.size()]));
   242         }
   244         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   245             for (EndpointArgumentsBuilder builder : builders) {
   246                 builder.readRequest(msg,args);
   247             }
   248         }
   249     }
   252     /**
   253      * Reads an Attachment into a Java parameter.
   254      */
   255     public static abstract class AttachmentBuilder extends EndpointArgumentsBuilder {
   256         protected final EndpointValueSetter setter;
   257         protected final ParameterImpl param;
   258         protected final String pname;
   259         protected final String pname1;
   261         AttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
   262             this.setter = setter;
   263             this.param = param;
   264             this.pname = param.getPartName();
   265             this.pname1 = "<"+pname;
   266         }
   268         /**
   269          * Creates an AttachmentBuilder based on the parameter type
   270          *
   271          * @param param
   272          *      runtime Parameter that abstracts the annotated java parameter
   273          * @param setter
   274          *      specifies how the obtained value is set into the argument. Takes
   275          *      care of Holder arguments.
   276          */
   277         public static EndpointArgumentsBuilder createAttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
   278             Class type = (Class)param.getTypeInfo().type;
   279             if (DataHandler.class.isAssignableFrom(type)) {
   280                 return new DataHandlerBuilder(param, setter);
   281             } else if (byte[].class==type) {
   282                 return new ByteArrayBuilder(param, setter);
   283             } else if(Source.class.isAssignableFrom(type)) {
   284                 return new SourceBuilder(param, setter);
   285             } else if(Image.class.isAssignableFrom(type)) {
   286                 return new ImageBuilder(param, setter);
   287             } else if(InputStream.class==type) {
   288                 return new InputStreamBuilder(param, setter);
   289             } else if(isXMLMimeType(param.getBinding().getMimeType())) {
   290                 return new JAXBBuilder(param, setter);
   291             } else if(String.class.isAssignableFrom(type)) {
   292                 return new StringBuilder(param, setter);
   293             } else {
   294                 throw new UnsupportedOperationException("Unknown Type="+type+" Attachment is not mapped.");
   295             }
   296         }
   298         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   299             boolean foundAttachment = false;
   300             // TODO not to loop
   301             for (Attachment att : msg.getAttachments()) {
   302                 String part = getWSDLPartName(att);
   303                 if (part == null) {
   304                     continue;
   305                 }
   306                 if(part.equals(pname) || part.equals(pname1)){
   307                     foundAttachment = true;
   308                     mapAttachment(att, args);
   309                     break;
   310                 }
   311             }
   312             if (!foundAttachment) {
   313                 throw new WebServiceException("Missing Attachment for "+pname);
   314             }
   315         }
   317         abstract void mapAttachment(Attachment att, Object[] args) throws JAXBException;
   318     }
   320     private static final class DataHandlerBuilder extends AttachmentBuilder {
   321         DataHandlerBuilder(ParameterImpl param, EndpointValueSetter setter) {
   322             super(param, setter);
   323         }
   325         void mapAttachment(Attachment att, Object[] args) {
   326             setter.put(att.asDataHandler(), args);
   327         }
   328     }
   330     private static final class ByteArrayBuilder extends AttachmentBuilder {
   331         ByteArrayBuilder(ParameterImpl param, EndpointValueSetter setter) {
   332             super(param, setter);
   333         }
   335         void mapAttachment(Attachment att, Object[] args) {
   336             setter.put(att.asByteArray(), args);
   337         }
   338     }
   340     private static final class SourceBuilder extends AttachmentBuilder {
   341         SourceBuilder(ParameterImpl param, EndpointValueSetter setter) {
   342             super(param, setter);
   343         }
   345         void mapAttachment(Attachment att, Object[] args) {
   346             setter.put(att.asSource(), args);
   347         }
   348     }
   350     private static final class ImageBuilder extends AttachmentBuilder {
   351         ImageBuilder(ParameterImpl param, EndpointValueSetter setter) {
   352             super(param, setter);
   353         }
   355         void mapAttachment(Attachment att, Object[] args) {
   356             Image image;
   357             InputStream is = null;
   358             try {
   359                 is = att.asInputStream();
   360                 image = ImageIO.read(is);
   361             } catch(IOException ioe) {
   362                 throw new WebServiceException(ioe);
   363             } finally {
   364                 if (is != null) {
   365                     try {
   366                         is.close();
   367                     } catch(IOException ioe) {
   368                         throw new WebServiceException(ioe);
   369                     }
   370                 }
   371             }
   372             setter.put(image, args);
   373         }
   374     }
   376     private static final class InputStreamBuilder extends AttachmentBuilder {
   377         InputStreamBuilder(ParameterImpl param, EndpointValueSetter setter) {
   378             super(param, setter);
   379         }
   381         void mapAttachment(Attachment att, Object[] args) {
   382             setter.put(att.asInputStream(), args);
   383         }
   384     }
   386     private static final class JAXBBuilder extends AttachmentBuilder {
   387         JAXBBuilder(ParameterImpl param, EndpointValueSetter setter) {
   388             super(param, setter);
   389         }
   391         void mapAttachment(Attachment att, Object[] args) throws JAXBException {
   392             Object obj = param.getXMLBridge().unmarshal(att.asInputStream());
   393             setter.put(obj, args);
   394         }
   395     }
   397     private static final class StringBuilder extends AttachmentBuilder {
   398         StringBuilder(ParameterImpl param, EndpointValueSetter setter) {
   399             super(param, setter);
   400         }
   402         void mapAttachment(Attachment att, Object[] args) {
   403             att.getContentType();
   404             StringDataContentHandler sdh = new StringDataContentHandler();
   405             try {
   406                 String str = (String)sdh.getContent(new DataHandlerDataSource(att.asDataHandler()));
   407                 setter.put(str, args);
   408             } catch(Exception e) {
   409                 throw new WebServiceException(e);
   410             }
   411         }
   412     }
   414     /**
   415      * Gets the WSDL part name of this attachment.
   416      *
   417      * <p>
   418      * According to WSI AP 1.0
   419      * <PRE>
   420      * 3.8 Value-space of Content-Id Header
   421      *   Definition: content-id part encoding
   422      *   The "content-id part encoding" consists of the concatenation of:
   423      * The value of the name attribute of the wsdl:part element referenced by the mime:content, in which characters disallowed in content-id headers (non-ASCII characters as represented by code points above 0x7F) are escaped as follows:
   424      *     o Each disallowed character is converted to UTF-8 as one or more bytes.
   425      *     o Any bytes corresponding to a disallowed character are escaped with the URI escaping mechanism (that is, converted to %HH, where HH is the hexadecimal notation of the byte value).
   426      *     o The original character is replaced by the resulting character sequence.
   427      * The character '=' (0x3D).
   428      * A globally unique value such as a UUID.
   429      * The character '@' (0x40).
   430      * A valid domain name under the authority of the entity constructing the message.
   431      * </PRE>
   432      *
   433      * So a wsdl:part fooPart will be encoded as:
   434      *      <fooPart=somereallybignumberlikeauuid@example.com>
   435      *
   436      * @return null
   437      *      if the parsing fails.
   438      */
   439     public static final String getWSDLPartName(com.sun.xml.internal.ws.api.message.Attachment att){
   440         String cId = att.getContentId();
   442         int index = cId.lastIndexOf('@', cId.length());
   443         if(index == -1){
   444             return null;
   445         }
   446         String localPart = cId.substring(0, index);
   447         index = localPart.lastIndexOf('=', localPart.length());
   448         if(index == -1){
   449             return null;
   450         }
   451         try {
   452             return java.net.URLDecoder.decode(localPart.substring(0, index), "UTF-8");
   453         } catch (UnsupportedEncodingException e) {
   454             throw new WebServiceException(e);
   455         }
   456     }
   461     /**
   462      * Reads a header into a JAXB object.
   463      */
   464     public static final class Header extends EndpointArgumentsBuilder {
   465         private final XMLBridge<?> bridge;
   466         private final EndpointValueSetter setter;
   467         private final QName headerName;
   468         private final SOAPVersion soapVersion;
   470         /**
   471          * @param name
   472          *      The name of the header element.
   473          * @param bridge
   474          *      specifies how to unmarshal a header into a JAXB object.
   475          * @param setter
   476          *      specifies how the obtained value is returned to the client.
   477          */
   478         public Header(SOAPVersion soapVersion, QName name, XMLBridge<?> bridge, EndpointValueSetter setter) {
   479             this.soapVersion = soapVersion;
   480             this.headerName = name;
   481             this.bridge = bridge;
   482             this.setter = setter;
   483         }
   485         public Header(SOAPVersion soapVersion, ParameterImpl param, EndpointValueSetter setter) {
   486             this(
   487                 soapVersion,
   488                 param.getTypeInfo().tagName,
   489                 param.getXMLBridge(),
   490                 setter);
   491             assert param.getOutBinding()== ParameterBinding.HEADER;
   492         }
   494         private SOAPFaultException createDuplicateHeaderException() {
   495             try {
   496                 SOAPFault fault = soapVersion.getSOAPFactory().createFault();
   497                 fault.setFaultCode(soapVersion.faultCodeClient);
   498                 fault.setFaultString(ServerMessages.DUPLICATE_PORT_KNOWN_HEADER(headerName));
   499                 return new SOAPFaultException(fault);
   500             } catch(SOAPException e) {
   501                 throw new WebServiceException(e);
   502             }
   503         }
   505         public void readRequest(Message msg, Object[] args) throws JAXBException {
   506             com.sun.xml.internal.ws.api.message.Header header = null;
   507             Iterator<com.sun.xml.internal.ws.api.message.Header> it =
   508                 msg.getHeaders().getHeaders(headerName,true);
   509             if (it.hasNext()) {
   510                 header = it.next();
   511                 if (it.hasNext()) {
   512                     throw createDuplicateHeaderException();
   513                 }
   514             }
   516             if(header!=null) {
   517                 setter.put( header.readAsJAXB(bridge), args );
   518             } else {
   519                 // header not found.
   520             }
   521         }
   522     }
   524     /**
   525      * Reads the whole payload into a single JAXB bean.
   526      */
   527     public static final class Body extends EndpointArgumentsBuilder {
   528         private final XMLBridge<?> bridge;
   529         private final EndpointValueSetter setter;
   531         /**
   532          * @param bridge
   533          *      specifies how to unmarshal the payload into a JAXB object.
   534          * @param setter
   535          *      specifies how the obtained value is returned to the client.
   536          */
   537         public Body(XMLBridge<?> bridge, EndpointValueSetter setter) {
   538             this.bridge = bridge;
   539             this.setter = setter;
   540         }
   542         public void readRequest(Message msg, Object[] args) throws JAXBException {
   543             setter.put( msg.readPayloadAsJAXB(bridge), args );
   544         }
   545     }
   547     /**
   548      * Treats a payload as multiple parts wrapped into one element,
   549      * and processes all such wrapped parts.
   550      */
   551     public static final class DocLit extends EndpointArgumentsBuilder {
   552         /**
   553          * {@link PartBuilder} keyed by the element name (inside the wrapper element.)
   554          */
   555         private final PartBuilder[] parts;
   557         private final XMLBridge wrapper;
   558         private boolean dynamicWrapper;
   560         public DocLit(WrapperParameter wp, Mode skipMode) {
   561             wrapperName = wp.getName();
   562             wrapper = wp.getXMLBridge();
   563             Class wrapperType = (Class) wrapper.getTypeInfo().type;
   564             dynamicWrapper = WrapperComposite.class.equals(wrapperType);
   565             List<PartBuilder> parts = new ArrayList<PartBuilder>();
   566             List<ParameterImpl> children = wp.getWrapperChildren();
   567             for (ParameterImpl p : children) {
   568                 if (p.getMode() == skipMode) {
   569                     continue;
   570                 }
   571                 /*
   572                 if(p.isIN())
   573                     continue;
   574                  */
   575                 QName name = p.getName();
   576                 try {
   577                     if (dynamicWrapper) {
   578                         if (wrappedParts == null) wrappedParts = new HashMap<QName,WrappedPartBuilder>();
   579                         XMLBridge xmlBridge = p.getInlinedRepeatedElementBridge();
   580                         if (xmlBridge == null) xmlBridge = p.getXMLBridge();
   581                         wrappedParts.put( p.getName(), new WrappedPartBuilder(xmlBridge, EndpointValueSetter.get(p)));
   582                     } else {
   583                         parts.add( new PartBuilder(
   584                                 wp.getOwner().getBindingContext().getElementPropertyAccessor(
   585                                     wrapperType,
   586                                     name.getNamespaceURI(),
   587                                     p.getName().getLocalPart()),
   588                                 EndpointValueSetter.get(p)
   589                             ) );
   590                     // wrapper parameter itself always bind to body, and
   591                     // so do all its children
   592                         assert p.getBinding()== ParameterBinding.BODY;
   593                     }
   594                 } catch (JAXBException e) {
   595                     throw new WebServiceException(  // TODO: i18n
   596                         wrapperType+" do not have a property of the name "+name,e);
   597                 }
   598             }
   600             this.parts = parts.toArray(new PartBuilder[parts.size()]);
   601         }
   603         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   604             if (dynamicWrapper) {
   605                 readWrappedRequest(msg, args);
   606             } else {
   607                 if (parts.length>0) {
   608                     if (!msg.hasPayload()) {
   609                         throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
   610                     }
   611                     XMLStreamReader reader = msg.readPayload();
   612                     XMLStreamReaderUtil.verifyTag(reader, wrapperName);
   613                     Object wrapperBean = wrapper.unmarshal(reader, (msg.getAttachments() != null) ?
   614                             new AttachmentUnmarshallerImpl(msg.getAttachments()): null);
   616                     try {
   617                         for (PartBuilder part : parts) {
   618                             part.readRequest(args,wrapperBean);
   619                         }
   620                     } catch (DatabindingException e) {
   621                         // this can happen when the set method throw a checked exception or something like that
   622                         throw new WebServiceException(e);    // TODO:i18n
   623                     }
   625                     // we are done with the body
   626                     reader.close();
   627                     XMLStreamReaderFactory.recycle(reader);
   628                 } else {
   629                     msg.consume();
   630                 }
   631             }
   632         }
   634         /**
   635          * Unmarshals each wrapped part into a JAXB object and moves it
   636          * to the expected place.
   637          */
   638         static final class PartBuilder {
   639             private final PropertyAccessor accessor;
   640             private final EndpointValueSetter setter;
   642             /**
   643              * @param accessor
   644              *      specifies which portion of the wrapper bean to obtain the value from.
   645              * @param setter
   646              *      specifies how the obtained value is returned to the client.
   647              */
   648             public PartBuilder(PropertyAccessor accessor, EndpointValueSetter setter) {
   649                 this.accessor = accessor;
   650                 this.setter = setter;
   651                 assert accessor!=null && setter!=null;
   652             }
   654             final void readRequest( Object[] args, Object wrapperBean ) {
   655                 Object obj = accessor.get(wrapperBean);
   656                 setter.put(obj,args);
   657             }
   660         }
   661     }
   663     /**
   664      * Treats a payload as multiple parts wrapped into one element,
   665      * and processes all such wrapped parts.
   666      */
   667     public static final class RpcLit extends EndpointArgumentsBuilder {
   668         public RpcLit(WrapperParameter wp) {
   669             assert wp.getTypeInfo().type== WrapperComposite.class;
   671             wrapperName = wp.getName();
   672             wrappedParts = new HashMap<QName,WrappedPartBuilder>();
   673             List<ParameterImpl> children = wp.getWrapperChildren();
   674             for (ParameterImpl p : children) {
   675                 wrappedParts.put( p.getName(), new WrappedPartBuilder(
   676                     p.getXMLBridge(), EndpointValueSetter.get(p)
   677                 ));
   678                 // wrapper parameter itself always bind to body, and
   679                 // so do all its children
   680                 assert p.getBinding()== ParameterBinding.BODY;
   681             }
   682         }
   684         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   685             readWrappedRequest(msg, args);
   686         }
   687     }
   689     private static boolean isXMLMimeType(String mimeType){
   690         return mimeType.equals("text/xml") || mimeType.equals("application/xml");
   691     }
   692 }

mercurial