KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > providers > java > RPCInvocation


1 /*
2 * The Apache Software License, Version 1.1
3 *
4 *
5 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6 * reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Apache Software Foundation (http://www.apache.org/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Axis" and "Apache Software Foundation" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact apache@apache.org.
31 *
32 * 5. Products derived from this software may not be called "Apache",
33 * nor may "Apache" appear in their name, without prior written
34 * permission of the Apache Software Foundation.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the Apache Software Foundation. For more
52 * information on the Apache Software Foundation, please see
53 * <http://www.apache.org/>.
54 */

55
56 package org.jboss.axis.providers.java;
57
58 import org.jboss.axis.AxisFault;
59 import org.jboss.axis.Constants;
60 import org.jboss.axis.Message;
61 import org.jboss.axis.MessageContext;
62 import org.jboss.axis.MessagePart;
63 import org.jboss.axis.description.OperationDesc;
64 import org.jboss.axis.description.ParameterDesc;
65 import org.jboss.axis.description.ServiceDesc;
66 import org.jboss.axis.enums.Style;
67 import org.jboss.axis.enums.Use;
68 import org.jboss.axis.handlers.soap.SOAPService;
69 import org.jboss.axis.message.RPCElement;
70 import org.jboss.axis.message.RPCHeaderParam;
71 import org.jboss.axis.message.RPCParam;
72 import org.jboss.axis.message.RPCParamElementImpl;
73 import org.jboss.axis.message.SOAPBodyElementAxisImpl;
74 import org.jboss.axis.message.SOAPElementAxisImpl;
75 import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
76 import org.jboss.axis.soap.SOAPConstants;
77 import org.jboss.axis.utils.JavaUtils;
78 import org.jboss.axis.utils.Messages;
79 import org.jboss.logging.Logger;
80 import org.w3c.dom.Element JavaDoc;
81
82 import javax.activation.DataHandler JavaDoc;
83 import javax.xml.namespace.QName JavaDoc;
84 import javax.xml.rpc.JAXRPCException JavaDoc;
85 import javax.xml.rpc.holders.Holder JavaDoc;
86 import javax.xml.soap.AttachmentPart JavaDoc;
87 import javax.xml.soap.SOAPHeaderElement JavaDoc;
88 import java.util.ArrayList JavaDoc;
89 import java.util.Arrays JavaDoc;
90 import java.util.Iterator JavaDoc;
91 import java.util.List JavaDoc;
92 import java.util.Vector JavaDoc;
93
94 /**
95  * Implement message processing by walking over RPCElements of the
96  * envelope body, invoking the appropriate methods on the service object.
97  *
98  * @author Doug Davis (dug@us.ibm.com)
99  */

100 public class RPCInvocation
101 {
102
103    private static Logger log = Logger.getLogger(RPCInvocation.class.getName());
104
105    private RPCProvider rpcProvider;
106    private MessageContext messageContext;
107    private SOAPEnvelopeAxisImpl requestEnvelope;
108    private SOAPEnvelopeAxisImpl responseEnvelope;
109    private Object JavaDoc targetObject;
110    private OperationDesc operation;
111    private Object JavaDoc[] argValues;
112    private Object JavaDoc returnValue;
113    private RPCElement body;
114    private List JavaDoc outParams;
115
116    // A flag that indicates thaat the response envelope has already been prepared
117
private boolean responsePrepared;
118
119    public RPCInvocation(RPCProvider rpcProvider, MessageContext messageContext, SOAPEnvelopeAxisImpl reqEnv, SOAPEnvelopeAxisImpl resEnv, Object JavaDoc targetObject)
120    {
121       this.rpcProvider = rpcProvider;
122       this.messageContext = messageContext;
123       this.requestEnvelope = reqEnv;
124       this.responseEnvelope = resEnv;
125       this.targetObject = targetObject;
126    }
127
128    /**
129     * Copy constructor
130     */

131    public RPCInvocation(RPCInvocation invocation)
132    {
133       this.rpcProvider = invocation.rpcProvider;
134       this.messageContext = invocation.messageContext;
135       this.requestEnvelope = invocation.requestEnvelope;
136       this.responseEnvelope = invocation.responseEnvelope;
137       this.targetObject = invocation.targetObject;
138       this.responsePrepared = invocation.responsePrepared;
139    }
140
141    public RPCProvider getProvider()
142    {
143       return rpcProvider;
144    }
145
146    /**
147     * Prepare the invocation object from the given prameters
148     */

149    public void prepareFromRequestEnvelope()
150    {
151
152       log.debug("Enter: prepareFromRequestEnvelope\n" + requestEnvelope);
153
154       SOAPService service = messageContext.getService();
155       ServiceDesc serviceDesc = service.getServiceDescription();
156       operation = messageContext.getOperation();
157
158       try
159       {
160          Vector JavaDoc bodies = requestEnvelope.getBodyElements();
161          if (log.isDebugEnabled())
162          {
163             log.debug(Messages.getMessage("bodyElems00", "" + bodies.size()));
164             log.debug(Messages.getMessage("bodyIs00", "" + bodies.get(0)));
165          }
166
167          // Find the first "root" body element, which is the RPC call.
168
for (int bNum = 0; body == null && bNum < bodies.size(); bNum++)
169          {
170             // If this is a regular old SOAPBodyElement, and it's a root,
171
// we're probably a non-wrapped doc/lit service. In this case,
172
// we deserialize the element, and create an RPCElement "wrapper"
173
// around it which points to the correct method.
174
// FIXME : There should be a cleaner way to do this...
175
if (!(bodies.get(bNum) instanceof RPCElement))
176             {
177                SOAPBodyElementAxisImpl bodyEl = (SOAPBodyElementAxisImpl)bodies.get(bNum);
178                // igors: better check if bodyEl.getID() != null
179
// to make sure this loop does not step on SOAP-ENC objects
180
// that follow the parameters! FIXME?
181
if (bodyEl.isRoot() && operation != null && bodyEl.getID() == null)
182                {
183                   ParameterDesc param = operation.getParameter(bNum);
184                   // at least do not step on non-existent parameters!
185
if (param != null)
186                   {
187                      Object JavaDoc val = bodyEl.getValueAsType(param.getTypeQName());
188                      body = new RPCElement("",
189                              operation.getName(),
190                              new Object JavaDoc[]{val});
191                   }
192                }
193             }
194             else
195             {
196                body = (RPCElement)bodies.get(bNum);
197             }
198          }
199
200          // special case code for a document style operation with no
201
// arguments (which is a strange thing to have, but whatever)
202
if (body == null)
203          {
204             // throw an error if this isn't a document style service
205
if (!(serviceDesc.getStyle().equals(Style.DOCUMENT)))
206             {
207                throw new JAXRPCException JavaDoc(Messages.getMessage("noBody00"));
208             }
209
210             // look for a method in the service that has no arguments,
211
// use the first one we find.
212
ArrayList JavaDoc ops = serviceDesc.getOperations();
213             for (Iterator JavaDoc iterator = ops.iterator(); iterator.hasNext();)
214             {
215                OperationDesc desc = (OperationDesc)iterator.next();
216                if (desc.getNumInParams() == 0)
217                {
218                   // found one with no parameters, use it
219
messageContext.setOperation(desc);
220                   // create an empty element
221
body = new RPCElement(desc.getName());
222                   // stop looking
223
break;
224                }
225             }
226
227             // If we still didn't find anything, report no body error.
228
if (body == null)
229             {
230                throw new JAXRPCException JavaDoc(Messages.getMessage("noBody00"));
231             }
232          }
233
234          String JavaDoc methodName = body.getMethodName();
235          Vector JavaDoc args = body.getParams();
236          int numArgs = args.size();
237
238          // This may have changed, so get it again...
239
// FIXME (there should be a cleaner way to do this)
240
operation = messageContext.getOperation();
241
242          if (operation == null)
243          {
244             QName JavaDoc qname = new QName JavaDoc(body.getNamespaceURI(),
245                     body.getName());
246             operation = getOperation(serviceDesc, qname);
247          }
248
249          if (operation == null)
250          {
251             // BP R2725
252
// As specified by the SOAP processing model, (a) a "VersionMismatch" faultcode must be generated if the
253
// namespace of the "Envelope" element is incorrect, (b) a "MustUnderstand" fault must be generated if the
254
// instance does not understand a SOAP header block with a value of "1" for the soap:mustUnderstand attribute.
255
// In all other cases where a message is inconsistent with its WSDL description, a fault with a "Client"
256
// faultcode should be generated.
257
// [TDI] 17-Aug-2004 com/sun/ts/tests/jaxrpc/wsi/j2w/rpc/literal/R2725
258
Vector JavaDoc headers = requestEnvelope.getHeaders();
259             for (int i = 0; i < headers.size(); i++)
260             {
261                SOAPHeaderElement JavaDoc header = (SOAPHeaderElement JavaDoc)headers.elementAt(i);
262                if (header.getMustUnderstand() == true)
263                {
264                   AxisFault fault = new AxisFault(Messages.getMessage("noSuchOperation", methodName));
265                   fault.setFaultCode(Constants.FAULT_MUSTUNDERSTAND);
266
267                   // This hack wrapps the checked AxisException in a RuntimeException
268
// so we don't loose the fault code, etc
269
// [TDI] 17-Aug-2004
270
throw new JAXRPCException JavaDoc(fault);
271                }
272             }
273
274             throw new JAXRPCException JavaDoc(Messages.getMessage("noSuchOperation", methodName));
275          }
276
277          // Create the array we'll use to hold the actual parameter
278
// values. We know how big to make it from the metadata.
279
argValues = new Object JavaDoc[operation.getNumParams()];
280
281          // A place to keep track of the out params (INOUTs and OUTs)
282
outParams = new ArrayList JavaDoc();
283
284          // Check if we have and endpoint of type doStuff(org.w3c.dom.Element)
285
// In that case we pass the entire SOAPBodyElement to the endpoint
286
boolean isGenericDocumentEndpoint = false;
287          Style style = serviceDesc.getStyle();
288          Use use = serviceDesc.getUse();
289          if (style.equals(Style.DOCUMENT) && use.equals(Use.LITERAL) && operation.getInParams().size() == 1)
290          {
291             ParameterDesc firstInParam = (ParameterDesc)operation.getInParams().get(0);
292             if (Element.class.isAssignableFrom(firstInParam.getJavaType()))
293             {
294                isGenericDocumentEndpoint = true;
295                argValues[0] = body;
296             }
297          }
298
299          // Put the values contained in the RPCParams into an array
300
// suitable for passing to java.lang.reflect.Method.invoke()
301
// Make sure we respect parameter ordering if we know about it
302
// from metadata, and handle whatever conversions are necessary
303
// (values -> Holders, etc)
304
if (isGenericDocumentEndpoint == false)
305          {
306             for (int i = 0; i < numArgs; i++)
307             {
308                RPCParam rpcParam = (RPCParam)args.get(i);
309                Object JavaDoc value = rpcParam.getValue();
310
311                // first check the type on the paramter
312
ParameterDesc paramDesc = rpcParam.getParamDesc();
313
314                // if we found some type info try to make sure the value type is
315
// correct. For instance, if we deserialized a xsd:dateTime in
316
// to a Calendar and the service takes a Date, we need to convert
317
if (paramDesc != null && paramDesc.getJavaType() != null)
318                {
319
320                   // Get the type in the signature (java type or its holder)
321
Class JavaDoc sigType = paramDesc.getJavaType();
322
323                   // Get the content of an attachement part
324
if (value instanceof AttachmentPart JavaDoc)
325                   {
326                      if (sigType.equals(DataHandler JavaDoc.class))
327                         value = ((AttachmentPart JavaDoc)value).getDataHandler();
328                      else
329                         value = ((AttachmentPart JavaDoc)value).getContent();
330                   }
331
332                   // Convert the value into the expected type in the signature
333
value = JavaUtils.convert(value, sigType);
334
335                   rpcParam.setValue(value);
336                   if (paramDesc.getMode() == ParameterDesc.INOUT)
337                   {
338                      outParams.add(rpcParam);
339                   }
340                }
341
342                // Put the value (possibly converted) in the argument array
343
// make sure to use the parameter order if we have it
344
if (paramDesc == null || paramDesc.getOrder() == -1)
345                {
346                   argValues[i] = value;
347                }
348                else
349                {
350                   argValues[paramDesc.getOrder()] = value;
351                }
352
353                if (log.isDebugEnabled())
354                {
355                   log.debug(" " + Messages.getMessage("value00", "" + argValues[i]));
356                }
357             }
358          }
359
360          // See if any subclasses want a crack at faulting on a bad operation
361
// FIXME : Does this make sense here???
362
String JavaDoc allowedMethods = (String JavaDoc)service.getOption("allowedMethods");
363          rpcProvider.checkMethodName(messageContext, allowedMethods, operation.getName());
364
365          // Now create any out holders we need to pass in
366
int count = numArgs;
367          for (int i = 0; i < argValues.length; i++)
368          {
369
370             // We are interested only in OUT/INOUT
371
ParameterDesc param = operation.getParameter(i);
372             if (param.getMode() == ParameterDesc.IN)
373                continue;
374
375             Class JavaDoc holderClass = param.getJavaType();
376             if (holderClass != null &&
377                     Holder JavaDoc.class.isAssignableFrom(holderClass))
378             {
379                int index = count;
380                if (param.getMode() == ParameterDesc.OUT)
381                {
382                   // OUT params don't have param order, just stick them at the end.
383
count++;
384                }
385                else if (param.getMode() == ParameterDesc.INOUT)
386                {
387                   // Use the parameter order if specified or just stick them to the end.
388
if (param.getOrder() != -1)
389                   {
390                      index = param.getOrder();
391                   }
392                   else
393                   {
394                      count++;
395                   }
396                   // If it's already filled, don't muck with it
397
if (argValues[index] != null)
398                   {
399                      continue;
400                   }
401                }
402                argValues[index] = holderClass.newInstance();
403                // Store an RPCParam in the outs collection so we
404
// have an easy and consistent way to write these
405
// back to the client below
406
RPCParam p = new RPCParam(param.getQName(),
407                        argValues[index]);
408                p.setParamDesc(param);
409                outParams.add(p);
410             }
411             else
412             {
413                String JavaDoc message = Messages.getMessage("badOutParameter00", "" + param.getQName(), operation.getName());
414                log.error(message);
415                throw new JAXRPCException JavaDoc(message);
416             }
417          }
418
419          log.debug("Exit: prepareFromRequestEnvelope");
420       }
421       catch (JAXRPCException JavaDoc e)
422       {
423          log.error(e.toString(), e);
424          throw e;
425       }
426       catch (Exception JavaDoc e)
427       {
428          log.error(e.toString(), e);
429          throw new JAXRPCException JavaDoc(e);
430       }
431    }
432
433    public OperationDesc getOperation(ServiceDesc serviceDesc, QName JavaDoc qname)
434    {
435       return serviceDesc.getOperationByElementQName(qname);
436    }
437
438    /**
439     * Prepare the response envelope from the given parameters
440     */

441    public void prepareResponseEnvelope(Object JavaDoc resObject)
442    {
443
444       returnValue = resObject;
445       log.debug("Enter: prepareResponseEnvelope: [resObject=" + resObject + "]");
446
447
448       // There is no way we can get a new resObj from the response SOAPEnvelope.
449
// Sucker is the response handler that modifies the response value.
450
// The RPCInvocation will ignore another call to prepareResponseEnvelope
451
// because this could potentially overwrite what the handlers did.
452
if (responsePrepared)
453       {
454          log.debug("Ignoring request to prepare response envelope");
455          log.debug("Exit: prepareResponseEnvelope\n" + responseEnvelope);
456          return;
457       }
458
459       SOAPService service = messageContext.getService();
460       ServiceDesc serviceDesc = service.getServiceDescription();
461
462       ArrayList JavaDoc immutableElements = new ArrayList JavaDoc();
463
464       try
465       {
466          // Set the encoding style - in contradiction to BP-1.0/R1005
467
// s1as interop tests expect this to be set in the <env:Body>
468
// [TDI 11-Sep-2004]
469
String JavaDoc encodingStyle = messageContext.getEncodingStyle();
470          String JavaDoc bodyEncStyle = responseEnvelope.getBody().getEncodingStyle();
471          if (bodyEncStyle.equals(encodingStyle) == false)
472          {
473             if (bodyEncStyle.equals(""))
474                responseEnvelope.getBody().setEncodingStyle(encodingStyle);
475             else
476                log.warn("Mixed encoding styles are not supported: " + bodyEncStyle + "!=" + encodingStyle);
477          }
478
479          RPCElement resBody = null;
480
481          // Check if we have and endpoint of type org.w3c.dom.Element doStuff(...)
482
// In that case the resObject is the SOAPBodyElement
483
boolean isGenericDocumentReturn = false;
484          Style style = serviceDesc.getStyle();
485          Use use = serviceDesc.getUse();
486          if (style.equals(Style.DOCUMENT) && use.equals(Use.LITERAL) && resObject != null && Element.class.isAssignableFrom(resObject.getClass()))
487          {
488             Element resElement = (Element)resObject;
489             resBody = new RPCElement(resElement.getLocalName());
490             resBody.setPrefix(resElement.getPrefix());
491             resBody.setNamespaceURI(resElement.getNamespaceURI());
492             immutableElements.add(resBody);
493             isGenericDocumentReturn = true;
494          }
495
496          /* Now put the result in the result SOAPEnvelope */
497          /*************************************************/
498          if (isGenericDocumentReturn == false)
499          {
500             String JavaDoc methodName = operation.getMethod().getName();
501             resBody = new RPCElement(methodName + "Response");
502             resBody.setPrefix(body.getPrefix());
503             resBody.setNamespaceURI(body.getNamespaceURI());
504             immutableElements.add(resBody);
505          }
506
507          // Return first
508
if (operation.getMethod().getReturnType() != Void.TYPE)
509          {
510             QName JavaDoc returnQName = operation.getReturnQName();
511             if (returnQName == null)
512             {
513                String JavaDoc methodName = operation.getMethod().getName();
514                returnQName = new QName JavaDoc(body.getNamespaceURI(), methodName + "Response");
515             }
516
517             ParameterDesc retParamDesc = operation.getReturnParamDesc();
518             QName JavaDoc retTypeQName = retParamDesc.getTypeQName();
519             if (resObject != null && retTypeQName != null)
520             {
521                Class JavaDoc retType = messageContext.getTypeMapping().getClassForQName(retTypeQName);
522                if (retType != null && JavaUtils.isConvertable(resObject, retType))
523                   resObject = JavaUtils.convert(resObject, retType);
524             }
525
526             RPCParam param = new RPCParam(returnQName, resObject);
527             param.setParamDesc(retParamDesc);
528             param.setRPCCall(resBody);
529
530             // Added to include the user type in the respone message
531
// Otherwise the client does not use the BeanDeserializer
532
// com/sun/ts/tests/webservices/wsdlImport/file/nested1#invokeNestedImportWsdl
533
if (operation.getUse().equals(Use.LITERAL))
534                param.setXSITypeGeneration(Boolean.TRUE);
535
536             // Added to build the soap tree such that it contains SOAPElements for the parameters
537
// Revisit to do this properly for the different encoding styles, arrays, value types, etc.
538
// TDI 06-June-2006
539
RPCParamElementImpl paramElement = new RPCParamElementImpl(param);
540             resBody.addChildElement(paramElement);
541             immutableElements.add(paramElement);
542
543             if (!operation.isReturnHeader())
544             {
545                // For SOAP 1.2 rpc style, add a result
546
if (messageContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS &&
547                        (serviceDesc.getStyle().equals(Style.RPC)))
548                {
549                   RPCParam resultParam = new RPCParam(Constants.QNAME_RPC_RESULT, returnQName);
550                   resultParam.setXSITypeGeneration(Boolean.FALSE);
551                   resBody.addParam(resultParam);
552                }
553                resBody.addParam(param);
554             }
555             else
556             {
557                responseEnvelope.addHeader(new RPCHeaderParam(param));
558             }
559
560          }
561
562          // Then any other out params
563
if (!outParams.isEmpty())
564          {
565             for (Iterator JavaDoc i = outParams.iterator(); i.hasNext();)
566             {
567                // We know this has a holder, so just unwrap the value
568
RPCParam param = (RPCParam)i.next();
569                Object JavaDoc value = param.getValue();
570                if (value instanceof Holder JavaDoc)
571                {
572                   Holder JavaDoc holder = (Holder JavaDoc)value;
573                   value = JavaUtils.getHolderValue(holder);
574                }
575                ParameterDesc paramDesc = param.getParamDesc();
576
577                param.setValue(value);
578                if (paramDesc != null && paramDesc.isOutHeader())
579                {
580                   responseEnvelope.addHeader(new RPCHeaderParam(param));
581                }
582                else
583                {
584                   resBody.addParam(param);
585                }
586             }
587          }
588
589          responseEnvelope.addBodyElement(resBody);
590          responsePrepared = true;
591
592          // Make the added elements immutable
593
Iterator JavaDoc it = immutableElements.iterator();
594          while (it.hasNext())
595          {
596             SOAPElementAxisImpl soapElement = (SOAPElementAxisImpl)it.next();
597             soapElement.setImmutable(true);
598          }
599
600          // Put the response envelope in the SOAPPart
601
messageContext.setPastPivot(true);
602          Message respMessage = (Message)messageContext.getMessage();
603          ((MessagePart)respMessage.getSOAPPart()).setSOAPEnvelope(responseEnvelope);
604
605          log.debug("Exit: prepareResponseEnvelope\n" + responseEnvelope);
606       }
607       catch (JAXRPCException JavaDoc e)
608       {
609          throw e;
610       }
611       catch (Exception JavaDoc e)
612       {
613          throw new JAXRPCException JavaDoc(e);
614       }
615    }
616
617    public Object JavaDoc[] getArgValues()
618    {
619       return argValues;
620    }
621
622    public RPCElement getBody()
623    {
624       return body;
625    }
626
627    public MessageContext getMessageContext()
628    {
629       return messageContext;
630    }
631
632    public OperationDesc getOperation()
633    {
634       return operation;
635    }
636
637    public List JavaDoc getOutParams()
638    {
639       return outParams;
640    }
641
642    public SOAPEnvelopeAxisImpl getRequestEnvelope()
643    {
644       return requestEnvelope;
645    }
646
647    public SOAPEnvelopeAxisImpl getResponseEnvelope()
648    {
649       return responseEnvelope;
650    }
651
652    public Object JavaDoc getTargetObject()
653    {
654       return targetObject;
655    }
656
657    public String JavaDoc toString()
658    {
659       StringBuffer JavaDoc ret = new StringBuffer JavaDoc("\nRPCInvocation:\n");
660       ret.append("TargetObject=" + targetObject + "\n");
661       ret.append("Operation=" + operation);
662       ret.append("ArgValues=" + (argValues != null ? Arrays.asList(argValues) : null) + "\n");
663       ret.append("ReturnValue=" + returnValue + "\n");
664       return ret.toString();
665    }
666 }
667
Popular Tags