src/share/jaxws_classes/com/sun/xml/internal/ws/client/sei/ResponseBuilder.java

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

mercurial