KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > providers > com > RPCProvider


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001 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) 2001, 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 package org.apache.soap.providers.com;
58
59 import java.io.* ;
60 import java.util.* ;
61 import java.text.MessageFormat JavaDoc;
62 import javax.servlet.* ;
63 import javax.servlet.http.* ;
64 import org.apache.soap.* ;
65 import org.apache.soap.rpc.* ;
66 import org.apache.soap.server.* ;
67 import org.apache.soap.util.* ;
68 import java.lang.Math JavaDoc;
69
70 public class RPCProvider implements Provider
71 {
72   private DeploymentDescriptor dd ;
73   private Envelope envelope ;
74   private Call call ;
75   private String JavaDoc methodName ;
76   private String JavaDoc targetObjectURI ;
77   private HttpServlet servlet ;
78   private HttpSession session ;
79   private byte[] vp= null;
80   private String JavaDoc progid= null;
81   private ServletContext sc= null;
82   private String JavaDoc threadingModel= null;
83   private static boolean initLog= false;
84
85   public void locate( DeploymentDescriptor dd,
86                       Envelope env,
87                       Call call,
88                       String JavaDoc methodName,
89                       String JavaDoc targetObjectURI,
90                       SOAPContext reqContext)
91       throws SOAPException
92   {
93     HttpServlet servlet = (HttpServlet) reqContext.getProperty( Constants.BAG_HTTPSERVLET );
94     HttpSession session = (HttpSession) reqContext.getProperty( Constants.BAG_HTTPSESSION );
95     // sc= servlet.getServletConfig().getServletContext();
96
if(!initLog)
97     {
98       Log.init(servlet);
99       initlog(Log.getLevel());
100       initLog=true;
101     }
102
103     Log.msg(Log.SUCCESS, "msg.comprovider.inlocate", getClass().getName(), targetObjectURI, methodName );
104     if( null != dllLoadException)
105     {
106       Log.msg(Log.ERROR, "msg.comprovider.dllfail", dllLoadException );
107       throw dllLoadException;
108      }
109      
110     //This validates that the method name is listed in the deployment descriptor.
111
if (!MessageRouter.validMessage (dd, methodName)) {
112       String JavaDoc msg=
113       Log.msg(Log.ERROR, "msg.comprovider.badMethod", targetObjectURI, methodName);
114         throw new SOAPException (Constants.FAULT_CODE_SERVER, msg);
115       }
116
117     Vector parms= call.getParams();
118     int noParms= 0;
119     if(parms != null)
120     {
121       vp= new byte[sizeOfVariant * parms.size()];
122       noParms= parms.size();
123     }
124
125     for(int i=0; i < noParms; ++i)
126     {
127      Log.msg(Log.INFORMATION, "msg.comprovider.info.parms", new Integer JavaDoc(i), parms.elementAt(i).getClass().getName(), parms.elementAt(i).toString());
128      //Yes. Prameters are reversed here.
129
objectToVariant( ((Parameter)(parms.elementAt(noParms - i -1))).getValue(), vp, i * sizeOfVariant);
130     }
131
132     Hashtable props = dd.getProps();
133
134     progid= (String JavaDoc) props.get("progid");
135     if(null== progid)
136     {
137      if(targetObjectURI.startsWith("urn:"))
138      {
139        progid= targetObjectURI.substring(4);
140      }
141      else
142        progid= targetObjectURI;
143     }
144
145     threadingModel= (String JavaDoc) props.get("threadmodel");
146     if( null == threadingModel) threadingModel= "MULTITHREADED";
147     Log.msg(Log.INFORMATION, "msg.comprovider.info.cominf", progid, threadingModel );
148
149     this.dd = dd ;
150     this.envelope = env ;
151     this.call = call ;
152     this.methodName = methodName ;
153     this.targetObjectURI = targetObjectURI ;
154     this.servlet = servlet ;
155     this.session = session ;
156
157
158     // Add logic to locate/load the service here
159
} //Endof of locate
160

161
162   public void invoke(SOAPContext reqContext, SOAPContext resContext)
163                       throws SOAPException
164   {
165     if( null != dllLoadException)
166     {
167       Log.msg(Log.ERROR, "msg.comprovider.dllfail", dllLoadException );
168       throw dllLoadException;
169      }
170      if( null == progid)
171      {
172        String JavaDoc msg= Log.msg(Log.ERROR, "msg.comprovider.error.nullprog", methodName, targetObjectURI);
173        throw new SOAPException( Constants.FAULT_CODE_SERVER, msg);
174      }
175      if( null == methodName)
176      {
177        String JavaDoc msg= Log.msg(Log.ERROR, "msg.comprovider.error.nullmname", targetObjectURI);
178        throw new SOAPException( Constants.FAULT_CODE_SERVER, msg);
179      }
180
181
182
183     // If you want the client to use a new targetObjectURI for subsequence
184
// calls place it here (targetObjectURI on 'new Response').
185
// i.e. we added an 'instance-id' to the urn
186
Object JavaDoc ret= null;
187          try{
188           ret= invoke( threadingModel, progid, methodName, vp);
189           }catch( Exception JavaDoc e)
190           {
191             String JavaDoc msg= Log.msg(Log.ERROR, "msg.comprovider.error.nativeError", e.toString());
192             throw new SOAPException( Constants.FAULT_CODE_SERVER, msg);
193           }
194           try {
195           Parameter pret= null;
196           if(ret != null) pret= new Parameter(RPCConstants.ELEM_RETURN , ret.getClass(), ret, null);
197               vp=null; //dereference.
198
Response resp = new Response( targetObjectURI, // URI
199
call.getMethodName(), // Method
200
pret, // ReturnValue
201
null, // Params
202
null, // Header
203
call.getEncodingStyleURI (), // encoding
204
resContext ); // response soapcontext - not supported yet
205

206           Envelope env = resp.buildEnvelope();
207           StringWriter sw = new StringWriter();
208           env.marshall( sw, call.getSOAPMappingRegistry(), resContext );
209           resContext.setRootPart( sw.toString(), Constants.HEADERVAL_CONTENT_TYPE_UTF8);
210           }
211           catch( Exception JavaDoc e ) {
212             String JavaDoc msg= Log.msg(Log.ERROR, "msg.comprovider.error.exp", e.toString());
213            if ( e instanceof SOAPException ) throw (SOAPException ) e ;
214             throw new SOAPException( Constants.FAULT_CODE_SERVER, msg );
215           }
216
217    Log.msg(Log.SUCCESS, "msg.comprovider.ok", ret == null ? "*null*" : ret.toString() );
218   } //invoke
219

220   /* JNI Code ---------------------------------------------------------------------------------------------------------------------------------------- */
221   static SOAPException dllLoadException= null; //Can hold an exception on from the loading of the c++ dll.
222
static final String JavaDoc libName= "COMProvider"; //C++ dll name.
223
protected void logit( int level, String JavaDoc msg) //Called by CPP
224
{
225     Log.msg(level, msg);
226   }
227   
228   
229   static final String JavaDoc pname= "org.apache.soap.providers.com";
230   static final String JavaDoc cname= pname + ".RPCProvider";
231   static
232   {
233     try
234     {
235       System.loadLibrary (libName);
236     }
237     catch(java.lang.SecurityException JavaDoc e)
238     {
239       dllLoadException= new SOAPException(Constants.FAULT_CODE_SERVER, "SecurityException from " + cname + " loading library:" + libName + " " + e.getMessage(),e);
240     }
241     catch(java.lang.UnsatisfiedLinkError JavaDoc e)
242     {
243       dllLoadException= new SOAPException(Constants.FAULT_CODE_SERVER, "UnsatisfiedLinkError from " + cname + " loading library:" + libName + " " + e.getMessage(),e);
244     }
245   } //Endof static
246

247   private static SOAPException getSOAPException( String JavaDoc msg)
248   {
249     return new SOAPException(Constants.FAULT_CODE_SERVER, msg);
250   }
251
252   private native Object JavaDoc invoke(String JavaDoc threadingModel, String JavaDoc progId, String JavaDoc methodName, byte[] parms) throws SOAPException;
253   private static native void initlog(short level);
254   private static native byte[] nativeConvertToBString( String JavaDoc o );
255
256   /* Java to CPP Marshalling code. ---------------------------------------------------------------------------------------------------------------------------------------- */
257
258   private static final int sizeOfVariant= 16;
259
260
261   private final byte[] objectToVariant( Object JavaDoc o ) throws SOAPException
262   {
263    return objectToVariant( o, null, 0);
264   }
265   private final byte[] objectsToVariants( Object JavaDoc[] o ) throws SOAPException
266   {
267     byte[] bo= new byte[ o.length * sizeOfVariant];
268     for(int i=0; i < o.length; ++i)
269        objectToVariant( o[i], bo, i * sizeOfVariant);
270     return bo;
271   }
272   private final byte[] objectToVariant( Object JavaDoc o, byte[] bo, int os) throws SOAPException
273   {
274     byte[] v= bo;
275     if( null == v)
276     {
277      v= new byte[sizeOfVariant]; //Size of a variant
278
os=0;
279     }
280       
281      if( null== o)
282      { //to be safe.
283
v[os+0] = 1; //VT_NULL
284
v[os+1] = 0;
285      }
286      else if(o instanceof java.lang.Boolean JavaDoc) //VT_R8
287
{
288       v[os+0] = 11; //VT_BOOL
289
v[os+1] = 0;
290       byte x= (byte)( (((Boolean JavaDoc) o).booleanValue()) ? 0xff: 0);
291       v[os+8]= x;
292       v[os+9]= x;
293       v[os+10]= x;
294       v[os+11]= x;
295      }
296      else if(o instanceof java.lang.Integer JavaDoc) //VT_R8
297
{
298       v[os+0] = 3; //VT_I4
299
v[os+1] = 0;
300       int x= ((Integer JavaDoc)o).intValue();
301       v[os+8]= (byte)x;
302       v[os+9]= (byte)((x>>>8) & 0xff);
303       v[os+10]= (byte)((x>>>16) & 0xff);
304       v[os+11]= (byte)((x>>>24) & 0xff);
305      }
306      else if( o instanceof java.lang.String JavaDoc)
307      {
308       v[os+0] = 8; //VT_BSTR
309
v[os+1] = 0;
310       byte[] pbs= nativeConvertToBString( (String JavaDoc) o );
311       v[os+8]= pbs[0];
312       v[os+9]= pbs[1];
313       v[os+10]= pbs[2];
314       v[os+11]= pbs[3];
315      }
316      else if(o instanceof java.lang.Long JavaDoc) //VT_R8
317
{ //COM has no long type so promote it to double which can contain it.
318
v[os+0] = 5; //VT_R8
319
v[os+1] = 0;
320       long x= Double.doubleToLongBits((double)(((Long JavaDoc)o).longValue()));
321       v[os+8]= (byte)x;
322       v[os+9]= (byte)((x>>>8) & 0xff);
323       v[os+10]= (byte)((x>>>16) & 0xff);
324       v[os+11]= (byte)((x>>>24) & 0xff);
325       v[os+12]= (byte)((x>>>32) & 0xff);
326       v[os+13]= (byte)((x>>>40) & 0xff);
327       v[os+14]= (byte)((x>>>48) & 0xff);
328       v[os+15]= (byte)((x>>>56) & 0xff);
329      }
330      else if(o instanceof java.lang.Short JavaDoc)
331      {
332       v[os+0] = 2; //VT_I2
333
v[os+1] = 0;
334       int x= ((Short JavaDoc)o).intValue();
335       v[os+8]= (byte)x;
336       v[os+9]= (byte)((x>>>8) & 0xff);
337       v[os+10]= (byte)((x>>>16) & 0xff);
338       v[os+11]= (byte)((x>>>24) & 0xff);
339      }
340      else if(o instanceof java.lang.Float JavaDoc)
341      {
342       v[os+0] = 4; //VT_R4
343
v[os+1] = 0;
344        int x= Float.floatToIntBits(((Float JavaDoc)o).floatValue());
345        v[os+8]= (byte)x;
346        v[os+9]= (byte)((x>>>8) & 0xff);
347        v[os+10]= (byte)((x>>>16) & 0xff);
348        v[os+11]= (byte)((x>>>24) & 0xff);
349      }
350      else if(o instanceof java.lang.Double JavaDoc) //VT_R8
351
{
352       v[os+0] = 5; //VT_R8
353
v[os+1] = 0;
354       long x= Double.doubleToLongBits(((Double JavaDoc)o).doubleValue());
355       v[os+8]= (byte)x;
356       v[os+9]= (byte)((x>>>8) & 0xff);
357       v[os+10]= (byte)((x>>>16) & 0xff);
358       v[os+11]= (byte)((x>>>24) & 0xff);
359       v[os+12]= (byte)((x>>>32) & 0xff);
360       v[os+13]= (byte)((x>>>40) & 0xff);
361       v[os+14]= (byte)((x>>>48) & 0xff);
362       v[os+15]= (byte)((x>>>56) & 0xff);
363      }
364      else if(o instanceof java.lang.Byte JavaDoc)
365      {
366       v[os+0] = 17; //VT_UI1
367
v[os+1] = 0;
368       byte x= ((Byte JavaDoc)o).byteValue();
369       v[os+8]= x;
370      }
371      else if(o instanceof java.lang.Character JavaDoc)
372      {
373       v[os+0] = 17; //VT_UI1
374
v[os+1] = 0;
375       byte x= (byte) ((Character JavaDoc)o).charValue();
376       v[os+8]= x;
377      }
378      else if(o instanceof java.lang.Void JavaDoc)
379      {
380       v[os+0] = 1; //VT_NULL
381
v[os+1] = 0;
382      }
383      else if( o.getClass().isArray())
384      {
385       // ArrayInfo ai= new ArrayInfo(o);
386
// v= ai.toVariant();
387
throw new SOAPException(Constants.FAULT_CODE_SERVER, "Currently arrays are unsupported, type received:" + o.getClass().getName());
388      }
389      else
390      {
391       throw new SOAPException(Constants.FAULT_CODE_SERVER, "Currently unsupported data type received:" + o.getClass().getName());
392      /*
393       // v[os+0] = 9; //VT_DISPATCH for object
394       // v[os+1] = 0;
395
396       byte[] cppref= null;
397
398       if(o instanceof )
399       {
400        // System.arraycopy(cppref,0,v,8, cppref.length);
401       }
402       else if(o ) //Specific request to return back empty
403       {
404         v[os+0] = 0; //VT_EMPTY
405         v[os+1] = 0;
406       }
407       else
408       {
409         // cppref= nativeObjectToVariant(o);
410         System.arraycopy(cppref,0,v,8, cppref.length);
411       }
412      */

413       
414      }
415     return v;
416   }
417   
418 } //Endof RPCProvider
419
Popular Tags