KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > providers > StatefulEJBProvider


1 package org.apache.soap.providers;
2
3 import java.io.* ;
4 import java.util.* ;
5 import java.rmi.Remote;
6 import javax.servlet.* ;
7 import javax.servlet.http.* ;
8 import org.apache.soap.* ;
9 import org.apache.soap.rpc.* ;
10 import org.apache.soap.server.* ;
11 import org.apache.soap.util.* ;
12 import org.apache.soap.encoding.soapenc.Base64;
13
14 import java.lang.reflect.*;
15 import javax.rmi.*;
16 import javax.ejb.*;
17 import javax.naming.*;
18 import javax.naming.Context.*;
19
20 public class StatefulEJBProvider implements Provider {
21   public static String CNTXT_PROVIDER_URL = "iiop://localhost:900";
22   public static String CNTXT_FACTORY_NAME =
23                           "com.ibm.ejs.ns.jndi.CNInitialContextFactory";
24   protected boolean isCreate = false;
25   protected String ejbKey = null;
26   public static String DELIM_CHAR = "@";
27
28   private DeploymentDescriptor dd ;
29   private Envelope envelope ;
30   private Call call ;
31   private String targetObjectURI ;
32   private HttpServlet servlet ;
33   private HttpSession session ;
34
35   private Context contxt = null;
36   private Remote remoteObjRef = null;
37   private String methodName = null;
38   private Vector methodParameters = null;
39   private String respEncStyle = null;
40
41   /**
42    * StatefulEJBProvider constructor comment.
43    */

44   public StatefulEJBProvider() {
45     super();
46   }
47
48   public EJBObject deSerialize(String ejbKey) throws SOAPException {
49     try {
50       byte[] ejbKeyBytes = Base64.decode(ejbKey);
51       ByteArrayInputStream byteStream = new ByteArrayInputStream(ejbKeyBytes);
52       ObjectInputStream objStream = new ObjectInputStream(byteStream);
53       Handle ejbHandle = (Handle)objStream.readObject();
54       objStream.close();
55       return ejbHandle.getEJBObject();
56     } catch (Exception e) {
57       throw new SOAPException(Constants.FAULT_CODE_SERVER, e.toString()) ;
58     }
59   }
60
61   public Call getCall() {
62     return call;
63   }
64
65   public Context getContxt() {
66     return contxt;
67   }
68
69   public DeploymentDescriptor getDd() {
70     return dd;
71   }
72
73   public String getMethodName() {
74     return methodName;
75   }
76
77   public Vector getMethodParameters() {
78     return methodParameters;
79   }
80
81   public Remote getRemoteObjRef() {
82     return remoteObjRef;
83   }
84
85   public String getRespEncStyle() {
86     return respEncStyle;
87   }
88
89   public HttpServlet getServlet() {
90     return servlet;
91   }
92
93   public HttpSession getSession() {
94     return session;
95   }
96
97   public String getTargetObjectURI() {
98     return targetObjectURI;
99   }
100
101   public static String getUniqueId(String fullURI) {
102     int occurance = fullURI.indexOf(DELIM_CHAR);
103     if (occurance > 0) return fullURI.substring(occurance + 1);
104     return null;
105   }
106
107   protected void initialize(String url, String factory)
108     throws SOAPException
109   {
110     if (contxt == null)
111     {
112       Properties properties = new Properties();
113
114       if ((url != null) && (!url.trim().equals("")))
115       {
116     properties.put(Context.PROVIDER_URL, url);
117       }
118       if ((factory != null) && (!factory.trim().equals("")))
119       {
120     properties.put(Context.INITIAL_CONTEXT_FACTORY, factory);
121       }
122
123       try
124       {
125         contxt = new InitialContext(properties);
126       }
127       catch (NamingException ne)
128       {
129         // ErrorListener?
130
System.out.println("Naming Exception caught during InitialContext creation @ " + url);
131         throw new SOAPException(Constants.FAULT_CODE_SERVER,
132                                 "Unable to initialize context");
133       }
134     }
135   }
136
137   public void invoke(SOAPContext reqContext, SOAPContext resContext)
138                       throws SOAPException {
139     Parameter ret = null;
140     Object[] args = null;
141     Class[] argTypes = null;
142
143     respEncStyle = call.getEncodingStyleURI();
144
145     if (methodParameters != null) {
146       int parametersCount = methodParameters.size ();
147       args = new Object[parametersCount];
148       argTypes = new Class[parametersCount];
149
150       for (int i = 0; i < parametersCount; i++) {
151         Parameter param = (Parameter) methodParameters.elementAt (i);
152         args[i] = param.getValue ();
153         argTypes[i] = param.getType ();
154
155         if (respEncStyle == null) {
156           respEncStyle = param.getEncodingStyleURI ();
157         }
158       }
159     }
160
161     if (respEncStyle == null) {
162       respEncStyle = Constants.NS_URI_SOAP_ENC;
163     }
164
165     try {
166       Method m = MethodUtils.getMethod (remoteObjRef, methodName, argTypes);
167       Bean result = new Bean (m.getReturnType (),
168                               m.invoke (remoteObjRef, args));
169
170       if (result.type != void.class) {
171         ret = new Parameter (RPCConstants.ELEM_RETURN, result.type,
172                              result.value, null);
173       }
174     } catch (InvocationTargetException e) {
175       Throwable t = e.getTargetException ();
176       throw new SOAPException (Constants.FAULT_CODE_SERVER, t.getMessage(), t);
177     } catch (Throwable t) {
178       throw new SOAPException (Constants.FAULT_CODE_SERVER, t.getMessage(), t);
179     }
180
181     // once the super.invoke() is done, and no error occurs, the handle must be
182
// serialized and stored.
183
if (isCreate) {
184       // The return parameter is an EJBObject (for a create method)
185
// or an Enumeration (for a find method)
186
// IF this is an enumeration, we are only going to return the first
187
// element
188
try{
189         remoteObjRef = (Remote) ret.getValue();
190       } catch (ClassCastException cce) {
191         // Try to cast to an enumeration:
192
Enumeration enum = (Enumeration) ret.getValue();
193         remoteObjRef = (Remote) enum.nextElement();
194       }
195       // Set the return value to null, so that the remote object is not
196
// included in the response destined for the client.
197
ret = null;
198     }
199
200     if (ejbKey == null) {
201       serialize();
202     }
203
204     try {
205       Response res = new Response( targetObjectURI, // URI
206
call.getMethodName(), // Method
207
(Parameter) ret, // ReturnValue
208
null, // Params
209
null, // Header
210
respEncStyle, // encoding
211
resContext ); // response soapcontext - not supported yet
212
res.setFullTargetObjectURI(targetObjectURI +
213                                  StatefulEJBProvider.DELIM_CHAR + ejbKey);
214       Envelope env = res.buildEnvelope();
215       StringWriter sw = new StringWriter();
216       env.marshall( sw, call.getSOAPMappingRegistry(), resContext );
217       resContext.setRootPart( sw.toString(), Constants.HEADERVAL_CONTENT_TYPE_UTF8);
218     }
219     catch( Exception e ) {
220       if ( e instanceof SOAPException ) throw (SOAPException ) e ;
221       throw new SOAPException( Constants.FAULT_CODE_SERVER, e.toString() );
222     }
223   }
224
225   public void locate(DeploymentDescriptor depDesc,
226                      Envelope env,
227                      Call origCall,
228                      String methodName ,
229                      String targURI,
230                      SOAPContext reqContext)
231               throws SOAPException {
232    
233     HttpServlet servletRef = (HttpServlet) reqContext.getProperty( Constants.BAG_HTTPSERVLET );
234     HttpSession sessObj = (HttpSession) reqContext.getProperty( Constants.BAG_HTTPSESSION );
235
236     dd = depDesc ;
237     envelope = env ;
238     call = origCall ;
239     targetObjectURI = origCall.getTargetObjectURI() ;
240     servlet = servletRef ;
241     session = sessObj ;
242
243     this.methodName = origCall.getMethodName();
244     methodParameters = origCall.getParams();
245
246     // Check if there is a key appended to the URI;
247
String fullURI = origCall.getFullTargetObjectURI();
248     ejbKey = StatefulEJBProvider.getUniqueId(fullURI);
249
250     if (ejbKey != null) {
251       remoteObjRef = deSerialize(ejbKey);
252
253       // We have obtained the necessary object.
254
return;
255     }
256
257     Hashtable props = dd.getProps();
258
259     String ContxtProviderURL = (String) props.get("ContextProviderURL");
260     String ContxtFactoryName = (String) props.get("FullContextFactoryName");
261
262     if ((ContxtProviderURL != null) || (ContxtFactoryName != null))
263       initialize(ContxtProviderURL, ContxtFactoryName);
264     else
265       initialize(CNTXT_PROVIDER_URL, CNTXT_FACTORY_NAME);
266
267     String homeInterfaceName = (String) props.get("FullHomeInterfaceName");
268     if (homeInterfaceName == null)
269       throw new SOAPException(Constants.FAULT_CODE_SERVER, "Error in Deployment Descriptor Property Settings");
270
271     // From the Deployment Descriptor get the JNDI lookup name that is inside
272
// the "java" element...
273
String jndiName = (String) props.get("JNDIName");
274     if ( jndiName == null ) jndiName = dd.getProviderClass();
275
276     if ((jndiName != null) && (contxt != null)) {
277       try {
278         // Use service name to locate EJB home object via the contxt
279
EJBHome home = (EJBHome) PortableRemoteObject.narrow(
280                                      contxt.lookup(jndiName),
281                                      Class.forName(homeInterfaceName));
282
283         // Must check to see if the create method has any parameters associated
284
// with it.
285
// There are 2 scenarios:
286
// 1) if the method name in the call is create, then it
287
// will have parameters.
288
// 2) if the method name in the call is not create, and
289
// because no key is associated with this call, then
290
// we assume that we can call create without any
291
// additional parameters, and prepare to invoke the
292
// given method.
293

294         if (methodName.equals("create")) {
295           // The method is create, so let the invoke method deal with it;
296
// just give it the home interface.
297
remoteObjRef = home;
298           isCreate = true;
299           return;
300         }
301
302         // Method name is something other than create - so, the invoke command
303
// has another directive to process; we just perform a basic 'create'
304
// then.
305
Method createMethod = home.getClass().getMethod("create",
306                                                         new Class[0]);
307         remoteObjRef = (EJBObject) createMethod.invoke((Object) home,
308                                                        new Object[0]);
309
310       } catch (Exception e) {
311         throw new SOAPException(Constants.FAULT_CODE_SERVER,
312                                 "Error in connecting to EJB"+ e.toString());
313       }
314     }
315   }
316
317   public void serialize() throws SOAPException {
318     try {
319       ByteArrayOutputStream biteStream = new ByteArrayOutputStream();
320       ObjectOutputStream objector = new ObjectOutputStream(biteStream);
321       objector.writeObject(((EJBObject)remoteObjRef).getHandle());
322       objector.flush();
323       objector.close();
324
325       ejbKey = Base64.encode(biteStream.toByteArray());
326     } catch (Exception e) {
327       throw new SOAPException(Constants.FAULT_CODE_SERVER, e.toString()) ;
328     }
329   }
330
331   public void setCall(Call newCall) {
332     call = newCall;
333   }
334
335   public void setContxt(Context newContxt) {
336     contxt = newContxt;
337   }
338
339   public void setDd(DeploymentDescriptor newDd) {
340     dd = newDd;
341   }
342
343   public void setMethodName(String newMethodName) {
344     methodName = newMethodName;
345   }
346
347   public void setMethodParameters(Vector newMethodParameters) {
348     methodParameters = newMethodParameters;
349   }
350
351   public void setRemoteObjRef(Remote newRemoteObjRef) {
352     remoteObjRef = newRemoteObjRef;
353   }
354
355   public void setRespEncStyle(String newRespEncStyle) {
356     respEncStyle = newRespEncStyle;
357   }
358
359   public void setServlet(HttpServlet newServlet) {
360     servlet = newServlet;
361   }
362
363   public void setSession(HttpSession newSession) {
364     session = newSession;
365   }
366
367   public void setTargetObjectURI(String newTargetObjectURI) {
368     targetObjectURI = newTargetObjectURI;
369   }
370 }
371
Popular Tags