KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > rpc > RPCMessage


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2000 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 "SOAP" 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 and was
52  * originally based on software copyright (c) 2000, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.apache.soap.rpc;
59
60 import java.io.*;
61 import java.util.*;
62 import org.w3c.dom.*;
63 import org.apache.soap.util.*;
64 import org.apache.soap.util.xml.*;
65 import org.apache.soap.*;
66 import org.apache.soap.encoding.*;
67 import org.apache.soap.server.*;
68
69 /**
70  * An <code>RPCMessage</code> is the base class that <code>Call</code> and
71  * <code>Response</code> extend from. Any work that is common to both
72  * <code>Call</code> and <code>Response</code> is done here.
73  *
74  * @author Matthew J. Duftler (duftler@us.ibm.com)
75  * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
76  */

77 public class RPCMessage implements Serializer {
78   protected String JavaDoc targetObjectURI;
79   protected String JavaDoc fullTargetObjectURI;
80   protected String JavaDoc methodName;
81   protected Vector params;
82   protected Header header;
83   protected String JavaDoc encodingStyleURI;
84   protected SOAPContext ctx;
85
86   protected RPCMessage(String JavaDoc targetObjectURI, String JavaDoc methodName,
87                        Vector params, Header header,
88                        String JavaDoc encodingStyleURI, SOAPContext ctx) {
89     setTargetObjectURI(targetObjectURI);
90     this.methodName = methodName;
91     this.params = params;
92     this.header = header;
93     this.encodingStyleURI = encodingStyleURI;
94     this.ctx = ctx;
95   }
96
97   public void setTargetObjectURI(String JavaDoc targetObjectURI) {
98     // Any incoming URI must be the full URI
99
this.fullTargetObjectURI = targetObjectURI;
100
101     // Now, we should splice the URI into the actual resource to connect to,
102
// and the key.
103
this.targetObjectURI = StringUtils.parseFullTargetObjectURI(
104                               targetObjectURI);
105   }
106
107   public String JavaDoc getTargetObjectURI() {
108     return targetObjectURI;
109   }
110
111   public void setFullTargetObjectURI(String JavaDoc targetObjectURI) {
112     setTargetObjectURI(targetObjectURI);
113   }
114
115   public String JavaDoc getFullTargetObjectURI() {
116     return fullTargetObjectURI;
117   }
118
119   public void setMethodName(String JavaDoc methodName) {
120     this.methodName = methodName;
121   }
122
123   public String JavaDoc getMethodName() {
124     return methodName;
125   }
126
127   public void setParams(Vector params) {
128     this.params = params;
129   }
130
131   public Vector getParams() {
132     return params;
133   }
134
135   public void setHeader(Header header) {
136     this.header = header;
137   }
138
139   public Header getHeader() {
140     return header;
141   }
142
143   public void setEncodingStyleURI(String JavaDoc encodingStyleURI) {
144     this.encodingStyleURI = encodingStyleURI;
145   }
146
147   public String JavaDoc getEncodingStyleURI() {
148     return encodingStyleURI;
149   }
150
151   protected void setSOAPContext(SOAPContext ctx) {
152     this.ctx = ctx;
153   }
154
155   public SOAPContext getSOAPContext() {
156     return ctx;
157   }
158
159   protected Envelope buildEnvelope(boolean isResponse) {
160     // Construct a new envelope for this message.
161
Envelope env = new Envelope();
162     Body body = new Body();
163     Vector bodyEntries = new Vector();
164
165     bodyEntries.addElement(new Bean(
166         (isResponse ? Response.class : Call.class),
167         this));
168     body.setBodyEntries(bodyEntries);
169     env.setBody(body);
170     env.setHeader(header);
171
172     return env;
173   }
174
175   protected static RPCMessage extractFromEnvelope(Envelope env,
176                                                   ServiceManager svcMgr,
177                                                   boolean isResponse,
178                                                   SOAPMappingRegistry respSMR,
179                                                   SOAPContext ctx)
180     throws IllegalArgumentException JavaDoc {
181     Body body = env.getBody();
182     Vector bodyEntries = body.getBodyEntries();
183     RPCMessage msg = null;
184
185     // Unmarshall the message, which is the first body entry.
186
if (bodyEntries.size() > 0) {
187       Element msgEl = (Element)bodyEntries.elementAt(0);
188       Class JavaDoc toClass = isResponse ? Response.class : Call.class;
189       String JavaDoc declEnvEncStyle = env.getAttribute(new QName(
190         Constants.NS_URI_SOAP_ENV, Constants.ATTR_ENCODING_STYLE));
191       String JavaDoc declBodyEncStyle = body.getAttribute(new QName(
192         Constants.NS_URI_SOAP_ENV, Constants.ATTR_ENCODING_STYLE));
193       String JavaDoc actualEncStyle = declBodyEncStyle != null
194                               ? declBodyEncStyle
195                               : declEnvEncStyle;
196
197       msg = RPCMessage.unmarshall(actualEncStyle, msgEl, toClass, svcMgr,
198                                   respSMR, ctx);
199       msg.setHeader(env.getHeader());
200
201       return msg;
202     } else {
203       throw new IllegalArgumentException JavaDoc("An '" + Constants.Q_ELEM_BODY +
204                                          "' element must contain a " +
205                                          "child element.");
206     }
207   }
208
209   public void marshall(String JavaDoc inScopeEncStyle, Class JavaDoc javaType, Object JavaDoc src,
210                        Object JavaDoc context, Writer sink, NSStack nsStack,
211                        XMLJavaMappingRegistry xjmr, SOAPContext ctx)
212     throws IllegalArgumentException JavaDoc, IOException {
213     nsStack.pushScope();
214
215     RPCMessage msg = (RPCMessage)src;
216     boolean isResponse = (javaType == Response.class);
217     String JavaDoc targetObjectURI = Utils.cleanString(
218                                        msg.getFullTargetObjectURI());
219     String JavaDoc methodName = msg.getMethodName();
220     Vector params = msg.getParams();
221     String JavaDoc suffix = isResponse
222                                    ? RPCConstants.RESPONSE_SUFFIX
223                                    : "";
224     String JavaDoc declMsgEncStyle = msg.getEncodingStyleURI();
225     String JavaDoc actualMsgEncStyle = declMsgEncStyle != null
226                                    ? declMsgEncStyle
227                                    : inScopeEncStyle;
228
229     // If this message is a response, check for a fault.
230
if (isResponse) {
231       Response resp = (Response)msg;
232
233       if (!resp.generatedFault()) {
234         // Get the prefix for the targetObjectURI.
235
StringWriter nsDeclSW = new StringWriter();
236         String JavaDoc targetObjectNSPrefix = nsStack.getPrefixFromURI(
237           targetObjectURI, nsDeclSW);
238
239         sink.write('<' + targetObjectNSPrefix + ':' +
240                    methodName + suffix + nsDeclSW);
241
242         // Determine the prefix associated with the NS_URI_SOAP_ENV
243
// namespace URI.
244
String JavaDoc soapEnvNSPrefix = nsStack.getPrefixFromURI(
245           Constants.NS_URI_SOAP_ENV, sink);
246
247         if (declMsgEncStyle != null
248             && !declMsgEncStyle.equals(inScopeEncStyle)) {
249           sink.write(' ' + soapEnvNSPrefix + ':' +
250                      Constants.ATTR_ENCODING_STYLE + "=\"" +
251                      declMsgEncStyle + '\"');
252         }
253
254         sink.write('>' + StringUtils.lineSeparator);
255
256         // Get the returnValue.
257
Parameter ret = resp.getReturnValue();
258
259         if (ret != null) {
260           String JavaDoc declParamEncStyle = ret.getEncodingStyleURI();
261           String JavaDoc actualParamEncStyle = declParamEncStyle != null
262                                        ? declParamEncStyle
263                                        : actualMsgEncStyle;
264           Serializer ser = xjmr.querySerializer(Parameter.class,
265                                                 actualParamEncStyle);
266
267           ser.marshall(actualMsgEncStyle, Parameter.class, ret, null,
268                        sink, nsStack, xjmr, ctx);
269
270           sink.write(StringUtils.lineSeparator);
271         }
272
273         serializeParams(params, actualMsgEncStyle, sink, nsStack, xjmr, ctx);
274
275         sink.write("</" + targetObjectNSPrefix + ':' +
276                    methodName + suffix + '>' +
277                    StringUtils.lineSeparator);
278       } else {
279         // Get the fault information.
280
Fault fault = resp.getFault();
281
282         fault.marshall(actualMsgEncStyle, sink, nsStack, xjmr, ctx);
283       }
284     } else {
285       // Get the prefix for the targetObjectURI.
286
StringWriter nsDeclSW = new StringWriter();
287       String JavaDoc targetObjectNSPrefix = nsStack.getPrefixFromURI(targetObjectURI,
288                                                              nsDeclSW);
289
290       sink.write('<' + targetObjectNSPrefix + ':' +
291                  methodName + suffix + nsDeclSW);
292
293       // Determine the prefix associated with the NS_URI_SOAP_ENV
294
// namespace URI.
295
String JavaDoc soapEnvNSPrefix = nsStack.getPrefixFromURI(
296         Constants.NS_URI_SOAP_ENV, sink);
297
298       if (declMsgEncStyle != null
299           && !declMsgEncStyle.equals(inScopeEncStyle)) {
300         sink.write(' ' + soapEnvNSPrefix + ':' +
301                    Constants.ATTR_ENCODING_STYLE + "=\"" +
302                    declMsgEncStyle + '\"');
303       }
304
305       sink.write('>' + StringUtils.lineSeparator);
306
307       serializeParams(params, actualMsgEncStyle, sink, nsStack, xjmr, ctx);
308
309       sink.write("</" + targetObjectNSPrefix + ':' +
310                  methodName + suffix + '>');
311     }
312
313     nsStack.popScope();
314   }
315
316   private void serializeParams(Vector params, String JavaDoc inScopeEncStyle,
317                                Writer sink, NSStack nsStack,
318                                XMLJavaMappingRegistry xjmr, SOAPContext ctx)
319     throws IOException {
320     // If parameters exist, serialize them.
321
if (params != null) {
322       int size = params.size();
323
324       for (int i = 0; i < size; i++) {
325         Parameter param = (Parameter)params.elementAt(i);
326         String JavaDoc declParamEncStyle = param.getEncodingStyleURI();
327         String JavaDoc actualParamEncStyle = declParamEncStyle != null
328                                      ? declParamEncStyle
329                                      : inScopeEncStyle;
330         Serializer ser = xjmr.querySerializer(Parameter.class,
331                                               actualParamEncStyle);
332
333         ser.marshall(inScopeEncStyle, Parameter.class, param, null, sink,
334                      nsStack, xjmr, ctx);
335
336         sink.write(StringUtils.lineSeparator);
337       }
338     }
339   }
340
341   public static RPCMessage unmarshall(String JavaDoc inScopeEncStyle, Node src,
342                                       Class JavaDoc toClass, ServiceManager svcMgr,
343                                       SOAPMappingRegistry respSMR,
344                                       SOAPContext ctx)
345     throws IllegalArgumentException JavaDoc {
346     SOAPMappingRegistry smr = null;
347     Element root = (Element)src;
348     boolean isResponse = (toClass == Response.class);
349     String JavaDoc fullTargetObjectURI = null;
350     String JavaDoc targetObjectURI = null;
351     String JavaDoc methodName = null;
352     Parameter returnValue = null;
353     Fault fault = null;
354     Vector params = null;
355     String JavaDoc declMsgEncStyle = DOMUtils.getAttributeNS(root,
356       Constants.NS_URI_SOAP_ENV, Constants.ATTR_ENCODING_STYLE);
357     String JavaDoc actualMsgEncStyle = declMsgEncStyle != null
358                                     ? declMsgEncStyle
359                                     : inScopeEncStyle;
360
361     // Is it a fault?
362
if (isResponse && Constants.Q_ELEM_FAULT.matches(root)) {
363       fault = Fault.unmarshall(actualMsgEncStyle, root, respSMR, ctx);
364     } else {
365       // Must be a method call or a faultless response.
366
String JavaDoc tagName = root.getLocalName();
367
368       // This is the 'full' URI.
369
fullTargetObjectURI = root.getNamespaceURI();
370       targetObjectURI = StringUtils.parseFullTargetObjectURI(
371                             fullTargetObjectURI);
372
373       // Determine the XML serialization registry based on whether
374
// I'm on the server side or on the client side.
375
if (!isResponse) {
376         // I'm on the server side unmarshalling a call.
377
DeploymentDescriptor dd = null;
378         try {
379           dd = svcMgr.query(targetObjectURI);
380           smr = DeploymentDescriptor.buildSOAPMappingRegistry(dd, ctx);
381         } catch (SOAPException e) {
382           throw new IllegalArgumentException JavaDoc("Unable to resolve " +
383                                              "targetObjectURI '" +
384                                              targetObjectURI + "'.");
385         }
386       } else {
387         // I'm on the client unmarshalling a response.
388
smr = respSMR;
389       }
390       
391       // For RPC, default to SOAP section 5 encoding if no
392
// encodingStyle attribute is set.
393
smr.setDefaultEncodingStyle(Constants.NS_URI_SOAP_ENC);
394
395       methodName = tagName;
396
397       /*
398         Sanity check: the name of the method element should be the
399         methodName for a call and should be methodName+"Response"
400         for a response. Note: currently no way to know the methodName
401         other than from the tag name.
402       */

403       if (isResponse && methodName.endsWith(RPCConstants.RESPONSE_SUFFIX)) {
404         // Strip "Response" from end of tagName to derive methodName.
405
methodName = methodName.substring(0, methodName.length() - 8);
406       }
407
408       Element tempEl = DOMUtils.getFirstChildElement(root);
409
410       // Get the return value.
411
if (isResponse && tempEl != null) {
412         String JavaDoc declParamEncStyle = DOMUtils.getAttributeNS(tempEl,
413           Constants.NS_URI_SOAP_ENV, Constants.ATTR_ENCODING_STYLE);
414         String JavaDoc actualParamEncStyle = declParamEncStyle != null
415                                      ? declParamEncStyle
416                                      : actualMsgEncStyle;
417         Bean returnBean = smr.unmarshall(actualParamEncStyle,
418                                          RPCConstants.Q_ELEM_PARAMETER,
419                                          tempEl, ctx);
420
421         returnValue = (Parameter)returnBean.value;
422
423         if (declParamEncStyle != null)
424         {
425           returnValue.setEncodingStyleURI(declParamEncStyle);
426         }
427
428         tempEl = DOMUtils.getNextSiblingElement(tempEl);
429       }
430
431       // Get the parameters.
432
if (tempEl != null) {
433         for (params = new Vector();
434              tempEl != null;
435              tempEl = DOMUtils.getNextSiblingElement(tempEl)) {
436           String JavaDoc declParamEncStyle = DOMUtils.getAttributeNS(tempEl,
437             Constants.NS_URI_SOAP_ENV, Constants.ATTR_ENCODING_STYLE);
438           String JavaDoc actualParamEncStyle = declParamEncStyle != null
439                                        ? declParamEncStyle
440                                        : actualMsgEncStyle;
441           Bean paramBean = smr.unmarshall(actualParamEncStyle,
442                                           RPCConstants.Q_ELEM_PARAMETER,
443                                           tempEl, ctx);
444           Parameter param = (Parameter)paramBean.value;
445
446           if (declParamEncStyle != null) {
447             param.setEncodingStyleURI(declParamEncStyle);
448           }
449
450           params.addElement(param);
451         }
452       }
453     }
454
455     RPCMessage msg = isResponse
456                      ? (fault == null
457                         ? (RPCMessage)new Response(fullTargetObjectURI, methodName,
458                                                    returnValue, params, null,
459                                                    declMsgEncStyle, ctx)
460                         : (RPCMessage)new Response(fullTargetObjectURI, methodName,
461                                                    fault, params, null,
462                                                    declMsgEncStyle, ctx))
463                      : (RPCMessage)new Call(fullTargetObjectURI, methodName,
464                                             params, null, actualMsgEncStyle, ctx);
465
466     if (msg instanceof Call) {
467       ((Call)msg).setSOAPMappingRegistry(smr);
468     }
469
470     return msg;
471   }
472
473   public String JavaDoc toString() {
474     StringWriter sw = new StringWriter();
475     PrintWriter pw = new PrintWriter(sw);
476     boolean isResponse = this instanceof Response;
477
478     pw.print("[Header=" + header + "] " +
479              "[methodName=" + methodName + "] " +
480              "[targetObjectURI=" + targetObjectURI + "] " +
481              "[encodingStyleURI=" + encodingStyleURI + "] " +
482              "[SOAPContext=" + ctx + "] ");
483
484     if (isResponse) {
485       Response res = (Response)this;
486
487       if (res.generatedFault()) {
488         pw.print("[fault=" + res.getFault() + "] ");
489       } else {
490         pw.println("[return=" + res.getReturnValue() + "] ");
491       }
492     }
493
494     pw.print("[Params={");
495
496     if (params != null) {
497       for (int i = 0; i < params.size(); i++) {
498         if (i > 0) {
499           pw.print(", ");
500         }
501
502         pw.print("[" + params.elementAt(i) + "]");
503       }
504     }
505
506     pw.print("}]");
507
508     return sw.toString();
509   }
510 }
511
Popular Tags