src/share/jaxws_classes/com/sun/xml/internal/ws/server/sei/EndpointArgumentsBuilder.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.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.XMLBridge;
    39 import com.sun.xml.internal.ws.spi.db.DatabindingException;
    40 import com.sun.xml.internal.ws.spi.db.PropertyAccessor;
    41 import com.sun.xml.internal.ws.spi.db.WrapperComposite;
    42 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
    43 import com.sun.xml.internal.ws.encoding.StringDataContentHandler;
    44 import com.sun.xml.internal.ws.encoding.DataHandlerDataSource;
    46 import javax.activation.DataHandler;
    47 import javax.imageio.ImageIO;
    48 import javax.jws.WebParam.Mode;
    49 import javax.xml.bind.JAXBException;
    50 import javax.xml.namespace.QName;
    51 import javax.xml.soap.SOAPException;
    52 import javax.xml.soap.SOAPFault;
    53 import javax.xml.stream.XMLStreamException;
    54 import javax.xml.stream.XMLStreamReader;
    55 import javax.xml.stream.XMLStreamConstants;
    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         public void readRequest(Message msg, Object[] args) {
   100             msg.consume();
   101         }
   102     }
   104     /**
   105      * The singleton instance that produces null return value.
   106      * Used for operations that doesn't have any output.
   107      */
   108     public static EndpointArgumentsBuilder NONE = new None();
   110     /**
   111      * Returns the 'uninitialized' value for the given type.
   112      *
   113      * <p>
   114      * For primitive types, it's '0', and for reference types, it's null.
   115      */
   116     public static Object getVMUninitializedValue(Type type) {
   117         // if this map returns null, that means the 'type' is a reference type,
   118         // in which case 'null' is the correct null value, so this code is correct.
   119         return primitiveUninitializedValues.get(type);
   120     }
   122     private static final Map<Class,Object> primitiveUninitializedValues = new HashMap<Class, Object>();
   124     static {
   125         Map<Class, Object> m = primitiveUninitializedValues;
   126         m.put(int.class,(int)0);
   127         m.put(char.class,(char)0);
   128         m.put(byte.class,(byte)0);
   129         m.put(short.class,(short)0);
   130         m.put(long.class,(long)0);
   131         m.put(float.class,(float)0);
   132         m.put(double.class,(double)0);
   133     }
   135     /**
   136      * {@link EndpointArgumentsBuilder} that sets the VM uninitialized value to the type.
   137      */
   138     public static final class NullSetter extends EndpointArgumentsBuilder {
   139         private final EndpointValueSetter setter;
   140         private final Object nullValue;
   142         public NullSetter(EndpointValueSetter setter, Object nullValue){
   143             assert setter!=null;
   144             this.nullValue = nullValue;
   145             this.setter = setter;
   146         }
   147         public void readRequest(Message msg, Object[] args) {
   148             setter.put(nullValue, args);
   149         }
   150     }
   152     /**
   153      * {@link EndpointArgumentsBuilder} that is a composition of multiple
   154      * {@link EndpointArgumentsBuilder}s.
   155      *
   156      * <p>
   157      * Sometimes we need to look at multiple parts of the reply message
   158      * (say, two header params, one body param, and three attachments, etc.)
   159      * and that's when this object is used to combine multiple {@link EndpointArgumentsBuilder}s
   160      * (that each responsible for handling one part).
   161      *
   162      * <p>
   163      * The model guarantees that only at most one {@link EndpointArgumentsBuilder} will
   164      * return a value as a return value (and everything else has to go to
   165      * {@link Holder}s.)
   166      */
   167     public static final class Composite extends EndpointArgumentsBuilder {
   168         private final EndpointArgumentsBuilder[] builders;
   170         public Composite(EndpointArgumentsBuilder... builders) {
   171             this.builders = builders;
   172         }
   174         public Composite(Collection<? extends EndpointArgumentsBuilder> builders) {
   175             this(builders.toArray(new EndpointArgumentsBuilder[builders.size()]));
   176         }
   178         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   179             for (EndpointArgumentsBuilder builder : builders) {
   180                 builder.readRequest(msg,args);
   181             }
   182         }
   183     }
   186     /**
   187      * Reads an Attachment into a Java parameter.
   188      */
   189     public static abstract class AttachmentBuilder extends EndpointArgumentsBuilder {
   190         protected final EndpointValueSetter setter;
   191         protected final ParameterImpl param;
   192         protected final String pname;
   193         protected final String pname1;
   195         AttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
   196             this.setter = setter;
   197             this.param = param;
   198             this.pname = param.getPartName();
   199             this.pname1 = "<"+pname;
   200         }
   202         /**
   203          * Creates an AttachmentBuilder based on the parameter type
   204          *
   205          * @param param
   206          *      runtime Parameter that abstracts the annotated java parameter
   207          * @param setter
   208          *      specifies how the obtained value is set into the argument. Takes
   209          *      care of Holder arguments.
   210          */
   211         public static EndpointArgumentsBuilder createAttachmentBuilder(ParameterImpl param, EndpointValueSetter setter) {
   212             Class type = (Class)param.getTypeInfo().type;
   213             if (DataHandler.class.isAssignableFrom(type)) {
   214                 return new DataHandlerBuilder(param, setter);
   215             } else if (byte[].class==type) {
   216                 return new ByteArrayBuilder(param, setter);
   217             } else if(Source.class.isAssignableFrom(type)) {
   218                 return new SourceBuilder(param, setter);
   219             } else if(Image.class.isAssignableFrom(type)) {
   220                 return new ImageBuilder(param, setter);
   221             } else if(InputStream.class==type) {
   222                 return new InputStreamBuilder(param, setter);
   223             } else if(isXMLMimeType(param.getBinding().getMimeType())) {
   224                 return new JAXBBuilder(param, setter);
   225             } else if(String.class.isAssignableFrom(type)) {
   226                 return new StringBuilder(param, setter);
   227             } else {
   228                 throw new UnsupportedOperationException("Unknown Type="+type+" Attachment is not mapped.");
   229             }
   230         }
   232         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   233             boolean foundAttachment = false;
   234             // TODO not to loop
   235             for (Attachment att : msg.getAttachments()) {
   236                 String part = getWSDLPartName(att);
   237                 if (part == null) {
   238                     continue;
   239                 }
   240                 if(part.equals(pname) || part.equals(pname1)){
   241                     foundAttachment = true;
   242                     mapAttachment(att, args);
   243                     break;
   244                 }
   245             }
   246             if (!foundAttachment) {
   247                 throw new WebServiceException("Missing Attachment for "+pname);
   248             }
   249         }
   251         abstract void mapAttachment(Attachment att, Object[] args) throws JAXBException;
   252     }
   254     private static final class DataHandlerBuilder extends AttachmentBuilder {
   255         DataHandlerBuilder(ParameterImpl param, EndpointValueSetter setter) {
   256             super(param, setter);
   257         }
   259         void mapAttachment(Attachment att, Object[] args) {
   260             setter.put(att.asDataHandler(), args);
   261         }
   262     }
   264     private static final class ByteArrayBuilder extends AttachmentBuilder {
   265         ByteArrayBuilder(ParameterImpl param, EndpointValueSetter setter) {
   266             super(param, setter);
   267         }
   269         void mapAttachment(Attachment att, Object[] args) {
   270             setter.put(att.asByteArray(), args);
   271         }
   272     }
   274     private static final class SourceBuilder extends AttachmentBuilder {
   275         SourceBuilder(ParameterImpl param, EndpointValueSetter setter) {
   276             super(param, setter);
   277         }
   279         void mapAttachment(Attachment att, Object[] args) {
   280             setter.put(att.asSource(), args);
   281         }
   282     }
   284     private static final class ImageBuilder extends AttachmentBuilder {
   285         ImageBuilder(ParameterImpl param, EndpointValueSetter setter) {
   286             super(param, setter);
   287         }
   289         void mapAttachment(Attachment att, Object[] args) {
   290             Image image;
   291             InputStream is = null;
   292             try {
   293                 is = att.asInputStream();
   294                 image = ImageIO.read(is);
   295             } catch(IOException ioe) {
   296                 throw new WebServiceException(ioe);
   297             } finally {
   298                 if (is != null) {
   299                     try {
   300                         is.close();
   301                     } catch(IOException ioe) {
   302                         throw new WebServiceException(ioe);
   303                     }
   304                 }
   305             }
   306             setter.put(image, args);
   307         }
   308     }
   310     private static final class InputStreamBuilder extends AttachmentBuilder {
   311         InputStreamBuilder(ParameterImpl param, EndpointValueSetter setter) {
   312             super(param, setter);
   313         }
   315         void mapAttachment(Attachment att, Object[] args) {
   316             setter.put(att.asInputStream(), args);
   317         }
   318     }
   320     private static final class JAXBBuilder extends AttachmentBuilder {
   321         JAXBBuilder(ParameterImpl param, EndpointValueSetter setter) {
   322             super(param, setter);
   323         }
   325         void mapAttachment(Attachment att, Object[] args) throws JAXBException {
   326             Object obj = param.getXMLBridge().unmarshal(att.asInputStream());
   327             setter.put(obj, args);
   328         }
   329     }
   331     private static final class StringBuilder extends AttachmentBuilder {
   332         StringBuilder(ParameterImpl param, EndpointValueSetter setter) {
   333             super(param, setter);
   334         }
   336         void mapAttachment(Attachment att, Object[] args) {
   337             att.getContentType();
   338             StringDataContentHandler sdh = new StringDataContentHandler();
   339             try {
   340                 String str = (String)sdh.getContent(new DataHandlerDataSource(att.asDataHandler()));
   341                 setter.put(str, args);
   342             } catch(Exception e) {
   343                 throw new WebServiceException(e);
   344             }
   345         }
   346     }
   348     /**
   349      * Gets the WSDL part name of this attachment.
   350      *
   351      * <p>
   352      * According to WSI AP 1.0
   353      * <PRE>
   354      * 3.8 Value-space of Content-Id Header
   355      *   Definition: content-id part encoding
   356      *   The "content-id part encoding" consists of the concatenation of:
   357      * 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:
   358      *     o Each disallowed character is converted to UTF-8 as one or more bytes.
   359      *     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).
   360      *     o The original character is replaced by the resulting character sequence.
   361      * The character '=' (0x3D).
   362      * A globally unique value such as a UUID.
   363      * The character '@' (0x40).
   364      * A valid domain name under the authority of the entity constructing the message.
   365      * </PRE>
   366      *
   367      * So a wsdl:part fooPart will be encoded as:
   368      *      <fooPart=somereallybignumberlikeauuid@example.com>
   369      *
   370      * @return null
   371      *      if the parsing fails.
   372      */
   373     public static final String getWSDLPartName(com.sun.xml.internal.ws.api.message.Attachment att){
   374         String cId = att.getContentId();
   376         int index = cId.lastIndexOf('@', cId.length());
   377         if(index == -1){
   378             return null;
   379         }
   380         String localPart = cId.substring(0, index);
   381         index = localPart.lastIndexOf('=', localPart.length());
   382         if(index == -1){
   383             return null;
   384         }
   385         try {
   386             return java.net.URLDecoder.decode(localPart.substring(0, index), "UTF-8");
   387         } catch (UnsupportedEncodingException e) {
   388             throw new WebServiceException(e);
   389         }
   390     }
   395     /**
   396      * Reads a header into a JAXB object.
   397      */
   398     public static final class Header extends EndpointArgumentsBuilder {
   399         private final XMLBridge<?> bridge;
   400         private final EndpointValueSetter setter;
   401         private final QName headerName;
   402         private final SOAPVersion soapVersion;
   404         /**
   405          * @param name
   406          *      The name of the header element.
   407          * @param bridge
   408          *      specifies how to unmarshal a header into a JAXB object.
   409          * @param setter
   410          *      specifies how the obtained value is returned to the client.
   411          */
   412         public Header(SOAPVersion soapVersion, QName name, XMLBridge<?> bridge, EndpointValueSetter setter) {
   413             this.soapVersion = soapVersion;
   414             this.headerName = name;
   415             this.bridge = bridge;
   416             this.setter = setter;
   417         }
   419         public Header(SOAPVersion soapVersion, ParameterImpl param, EndpointValueSetter setter) {
   420             this(
   421                 soapVersion,
   422                 param.getTypeInfo().tagName,
   423                 param.getXMLBridge(),
   424                 setter);
   425             assert param.getOutBinding()== ParameterBinding.HEADER;
   426         }
   428         private SOAPFaultException createDuplicateHeaderException() {
   429             try {
   430                 SOAPFault fault = soapVersion.getSOAPFactory().createFault();
   431                 fault.setFaultCode(soapVersion.faultCodeClient);
   432                 fault.setFaultString(ServerMessages.DUPLICATE_PORT_KNOWN_HEADER(headerName));
   433                 return new SOAPFaultException(fault);
   434             } catch(SOAPException e) {
   435                 throw new WebServiceException(e);
   436             }
   437         }
   439         public void readRequest(Message msg, Object[] args) throws JAXBException {
   440             com.sun.xml.internal.ws.api.message.Header header = null;
   441             Iterator<com.sun.xml.internal.ws.api.message.Header> it =
   442                 msg.getHeaders().getHeaders(headerName,true);
   443             if (it.hasNext()) {
   444                 header = it.next();
   445                 if (it.hasNext()) {
   446                     throw createDuplicateHeaderException();
   447                 }
   448             }
   450             if(header!=null) {
   451                 setter.put( header.readAsJAXB(bridge), args );
   452             } else {
   453                 // header not found.
   454             }
   455         }
   456     }
   458     /**
   459      * Reads the whole payload into a single JAXB bean.
   460      */
   461     public static final class Body extends EndpointArgumentsBuilder {
   462         private final XMLBridge<?> bridge;
   463         private final EndpointValueSetter setter;
   465         /**
   466          * @param bridge
   467          *      specifies how to unmarshal the payload into a JAXB object.
   468          * @param setter
   469          *      specifies how the obtained value is returned to the client.
   470          */
   471         public Body(XMLBridge<?> bridge, EndpointValueSetter setter) {
   472             this.bridge = bridge;
   473             this.setter = setter;
   474         }
   476         public void readRequest(Message msg, Object[] args) throws JAXBException {
   477             setter.put( msg.readPayloadAsJAXB(bridge), args );
   478         }
   479     }
   481     /**
   482      * Treats a payload as multiple parts wrapped into one element,
   483      * and processes all such wrapped parts.
   484      */
   485     public static final class DocLit extends EndpointArgumentsBuilder {
   486         /**
   487          * {@link PartBuilder} keyed by the element name (inside the wrapper element.)
   488          */
   489         private final PartBuilder[] parts;
   491         private final XMLBridge wrapper;
   492         private final QName wrapperName;
   494         public DocLit(WrapperParameter wp, Mode skipMode) {
   495             wrapperName = wp.getName();
   496             wrapper = wp.getXMLBridge();
   497             Class wrapperType = (Class) wrapper.getTypeInfo().type;
   499             List<PartBuilder> parts = new ArrayList<PartBuilder>();
   501             List<ParameterImpl> children = wp.getWrapperChildren();
   502             for (ParameterImpl p : children) {
   503                 if (p.getMode() == skipMode) {
   504                     continue;
   505                 }
   506                 /*
   507                 if(p.isIN())
   508                     continue;
   509                  */
   510                 QName name = p.getName();
   511                 try {
   512                     parts.add( new PartBuilder(
   513                         wp.getOwner().getBindingContext().getElementPropertyAccessor(
   514                             wrapperType,
   515                             name.getNamespaceURI(),
   516                             p.getName().getLocalPart()),
   517                         EndpointValueSetter.get(p)
   518                     ));
   519                     // wrapper parameter itself always bind to body, and
   520                     // so do all its children
   521                     assert p.getBinding()== ParameterBinding.BODY;
   522                 } catch (JAXBException e) {
   523                     throw new WebServiceException(  // TODO: i18n
   524                         wrapperType+" do not have a property of the name "+name,e);
   525                 }
   526             }
   528             this.parts = parts.toArray(new PartBuilder[parts.size()]);
   529         }
   531         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   533             if (parts.length>0) {
   534                 if (!msg.hasPayload()) {
   535                     throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
   536                 }
   537                 XMLStreamReader reader = msg.readPayload();
   538                 XMLStreamReaderUtil.verifyTag(reader, wrapperName);
   539                 Object wrapperBean = wrapper.unmarshal(reader, (msg.getAttachments() != null) ?
   540                         new AttachmentUnmarshallerImpl(msg.getAttachments()): null);
   542                 try {
   543                     for (PartBuilder part : parts) {
   544                         part.readRequest(args,wrapperBean);
   545                     }
   546                 } catch (DatabindingException e) {
   547                     // this can happen when the set method throw a checked exception or something like that
   548                     throw new WebServiceException(e);    // TODO:i18n
   549                 }
   551                 // we are done with the body
   552                 reader.close();
   553                 XMLStreamReaderFactory.recycle(reader);
   554             } else {
   555                 msg.consume();
   556             }
   557         }
   559         /**
   560          * Unmarshals each wrapped part into a JAXB object and moves it
   561          * to the expected place.
   562          */
   563         static final class PartBuilder {
   564             private final PropertyAccessor accessor;
   565             private final EndpointValueSetter setter;
   567             /**
   568              * @param accessor
   569              *      specifies which portion of the wrapper bean to obtain the value from.
   570              * @param setter
   571              *      specifies how the obtained value is returned to the client.
   572              */
   573             public PartBuilder(PropertyAccessor accessor, EndpointValueSetter setter) {
   574                 this.accessor = accessor;
   575                 this.setter = setter;
   576                 assert accessor!=null && setter!=null;
   577             }
   579             final void readRequest( Object[] args, Object wrapperBean ) {
   580                 Object obj = accessor.get(wrapperBean);
   581                 setter.put(obj,args);
   582             }
   585         }
   586     }
   588     /**
   589      * Treats a payload as multiple parts wrapped into one element,
   590      * and processes all such wrapped parts.
   591      */
   592     public static final class RpcLit extends EndpointArgumentsBuilder {
   593         /**
   594          * {@link PartBuilder} keyed by the element name (inside the wrapper element.)
   595          */
   596         private final Map<QName,PartBuilder> parts = new HashMap<QName,PartBuilder>();
   598         private QName wrapperName;
   600         public RpcLit(WrapperParameter wp) {
   601             assert wp.getTypeInfo().type== WrapperComposite.class;
   603             wrapperName = wp.getName();
   604             List<ParameterImpl> children = wp.getWrapperChildren();
   605             for (ParameterImpl p : children) {
   606                 parts.put( p.getName(), new PartBuilder(
   607                     p.getXMLBridge(), EndpointValueSetter.get(p)
   608                 ));
   609                 // wrapper parameter itself always bind to body, and
   610                 // so do all its children
   611                 assert p.getBinding()== ParameterBinding.BODY;
   612             }
   613         }
   615         public void readRequest(Message msg, Object[] args) throws JAXBException, XMLStreamException {
   616             if (!msg.hasPayload()) {
   617                 throw new WebServiceException("No payload. Expecting payload with "+wrapperName+" element");
   618             }
   619             XMLStreamReader reader = msg.readPayload();
   620             XMLStreamReaderUtil.verifyTag(reader,wrapperName);
   621             reader.nextTag();
   623             while(reader.getEventType()==XMLStreamReader.START_ELEMENT) {
   624                 // TODO: QName has a performance issue
   625                 QName name = reader.getName();
   626                 PartBuilder part = parts.get(name);
   627                 if(part==null) {
   628                     // no corresponding part found. ignore
   629                     XMLStreamReaderUtil.skipElement(reader);
   630                     reader.nextTag();
   631                 } else {
   632                     part.readRequest(args,reader, msg.getAttachments());
   633                 }
   634                 // skip any whitespace
   635                 if (reader.getEventType() != XMLStreamConstants.START_ELEMENT &&
   636                         reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
   637                     XMLStreamReaderUtil.nextElementContent(reader);
   638                 }
   639                 if(reader.getEventType() == XMLStreamConstants.END_ELEMENT && name.equals(reader.getName())) {
   640                     XMLStreamReaderUtil.nextElementContent(reader);
   641                 }
   642             }
   644             // we are done with the body
   645             reader.close();
   646             XMLStreamReaderFactory.recycle(reader);
   647         }
   649         /**
   650          * Unmarshals each wrapped part into a JAXB object and moves it
   651          * to the expected place.
   652          */
   653         static final class PartBuilder {
   654             private final XMLBridge bridge;
   655             private final EndpointValueSetter setter;
   657             /**
   658              * @param bridge
   659              *      specifies how the part is unmarshalled.
   660              * @param setter
   661              *      specifies how the obtained value is returned to the endpoint.
   662              */
   663             public PartBuilder(XMLBridge bridge, EndpointValueSetter setter) {
   664                 this.bridge = bridge;
   665                 this.setter = setter;
   666             }
   668             final void readRequest( Object[] args, XMLStreamReader r, AttachmentSet att) throws JAXBException {
   669                 Object obj = bridge.unmarshal(r, (att != null)?new AttachmentUnmarshallerImpl(att):null);
   670                 setter.put(obj,args);
   671             }
   672         }
   673     }
   675     private static boolean isXMLMimeType(String mimeType){
   676         return mimeType.equals("text/xml") || mimeType.equals("application/xml");
   677     }
   678 }

mercurial