KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > burlap > BurlapClientContainer


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.ejb.burlap;
30
31 import com.caucho.burlap.io.BurlapRemoteResolver;
32 import com.caucho.config.ConfigException;
33 import com.caucho.ejb.AbstractServer;
34 import com.caucho.ejb.EJBExceptionWrapper;
35 import com.caucho.ejb.protocol.EjbProtocolManager;
36 import com.caucho.ejb.protocol.HandleEncoder;
37 import com.caucho.loader.EnvironmentLocal;
38 import com.caucho.server.util.CauchoSystem;
39 import com.caucho.util.L10N;
40 import com.caucho.vfs.Path;
41 import com.caucho.vfs.Vfs;
42
43 import javax.ejb.EJBHome JavaDoc;
44 import javax.ejb.EJBObject JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.util.Hashtable JavaDoc;
47
48 /**
49  * Container for Burlap clients in the same JVM, but not the same
50  * class loader.
51  */

52 class BurlapClientContainer implements BurlapRemoteResolver {
53   protected static L10N L = new L10N(BurlapClientContainer.class);
54
55   private static EnvironmentLocal burlapClient =
56   new EnvironmentLocal("caucho.burlap.client");
57   
58   private String JavaDoc serverId;
59   private BurlapHandleEncoder handleEncoder;
60   // the home stub
61
EJBHome JavaDoc ejbHome;
62
63   Class JavaDoc homeClass;
64   Class JavaDoc remoteClass;
65   // the home stub class
66
Class JavaDoc homeStubClass;
67   // the remote stub class
68
Class JavaDoc remoteStubClass;
69   // the primary key class
70
Class JavaDoc primaryKeyClass;
71
72   private String JavaDoc _basicAuth;
73
74   /**
75    * Creates a client container for same-JVM connections.
76    *
77    * @param serverId the server id
78    */

79   BurlapClientContainer(String JavaDoc serverId)
80     throws ConfigException
81   {
82     this.serverId = serverId;
83
84     remoteStubClass = getRemoteStubClass();
85     homeStubClass = getHomeStubClass();
86   }
87
88   static BurlapClientContainer find(String JavaDoc serverId)
89   {
90     try {
91       Hashtable JavaDoc map = (Hashtable JavaDoc) burlapClient.getLevel();
92       BurlapClientContainer client = null;
93
94       if (map != null)
95         client = (BurlapClientContainer) map.get(serverId);
96
97       // sync doesn't matter since it's okay to load a dup
98
if (client == null) {
99         client = new BurlapClientContainer(serverId);
100         if (map == null)
101           map = new Hashtable JavaDoc();
102         map.put(serverId, client);
103         burlapClient.set(map);
104       }
105       
106       return client;
107     } catch (Exception JavaDoc e) {
108       throw EJBExceptionWrapper.createRuntime(e);
109     }
110   }
111
112   /**
113    * Finds the stub corresponding to the given URL.
114    *
115    * @return the bean's home stub
116    */

117   protected EJBHome JavaDoc getHomeStub()
118     throws ConfigException
119   {
120     try {
121       HomeStub homeStub = (HomeStub) homeStubClass.newInstance();
122
123       homeStub._init(serverId, this);
124
125       return homeStub;
126     } catch (IllegalAccessException JavaDoc e) {
127       throw new ConfigException(e);
128     } catch (InstantiationException JavaDoc e) {
129       throw new ConfigException(e);
130     }
131   }
132
133   /**
134    * Finds the stub for the remote object for the given Handle.
135    *
136    * @param handle the handle for the remote object
137    *
138    * @return the bean's remote stub
139    */

140   protected EJBObject JavaDoc createObjectStub(String JavaDoc url)
141     throws ConfigException
142   {
143     try {
144       ObjectStub objStub = (ObjectStub) remoteStubClass.newInstance();
145       objStub._init(url, this);
146       return objStub;
147     } catch (IllegalAccessException JavaDoc e) {
148       throw new ConfigException(e);
149     } catch (InstantiationException JavaDoc e) {
150       throw new ConfigException(e);
151     }
152   }
153
154   BurlapHomeHandle getHomeHandle()
155   {
156     return new BurlapHomeHandle(ejbHome, serverId);
157   }
158
159   BurlapHandle createHandle(String JavaDoc url)
160   {
161     return new BurlapHandle(url);
162   }
163   
164   public HandleEncoder getHandleEncoder()
165   {
166     try {
167       if (handleEncoder == null)
168         handleEncoder = new BurlapHandleEncoder(null, serverId,
169                                                  getPrimaryKeyClass());
170
171       return handleEncoder;
172     } catch (Exception JavaDoc e) {
173       throw EJBExceptionWrapper.createRuntime(e);
174     }
175   }
176
177   /**
178    * Returns the bean's home stub class, creating it if necessary
179    */

180   Class JavaDoc getHomeStubClass()
181     throws ConfigException
182   {
183     if (homeStubClass != null)
184       return homeStubClass;
185
186     synchronized (this) {
187       if (homeStubClass != null)
188         return homeStubClass;
189
190       StubGenerator gen = new StubGenerator();
191       
192       homeStubClass = gen.createHomeStub(getHomeClass());
193     }
194
195     return homeStubClass;
196   }
197
198   /**
199    * Returns the bean's remote stub class, creating it if necessary
200    */

201   Class JavaDoc getRemoteStubClass()
202     throws ConfigException
203   {
204     if (remoteStubClass != null)
205       return remoteStubClass;
206
207     synchronized (this) {
208       if (remoteStubClass != null)
209         return remoteStubClass;
210
211       Class JavaDoc remoteClass = getRemoteClass();
212       if (remoteClass == null)
213         return null;
214
215       StubGenerator gen = new StubGenerator();
216
217       remoteStubClass = gen.createObjectStub(remoteClass);
218     }
219
220     return remoteStubClass;
221   }
222   
223   /**
224    * Returns the bean's home interface class. If unknown, call the server
225    * for the class name.
226    */

227   Class JavaDoc getHomeClass()
228     throws ConfigException
229   {
230     if (homeClass != null)
231       return homeClass;
232
233     try {
234       synchronized (this) {
235         if (homeClass != null)
236           return homeClass;
237
238         String JavaDoc className = getHomeClassName();
239
240         homeClass = CauchoSystem.loadClass(className, false, null);
241       }
242     } catch (ClassNotFoundException JavaDoc e) {
243       throw new ConfigException(e);
244     }
245     
246     return homeClass;
247   }
248
249   /**
250    * Returns the classname of the home interface.
251    */

252   String JavaDoc getHomeClassName()
253     throws ConfigException
254   {
255     AbstractServer server = EjbProtocolManager.getJVMServer(serverId);
256
257     if (server != null) {
258       Class JavaDoc cl = server.getRemoteHomeClass();
259       if (cl != null)
260         return cl.getName();
261       else
262         throw new ConfigException(L.l("`{0}' has no remote interface.",
263                                       serverId));
264     }
265         
266     try {
267       Path path = Vfs.lookup(serverId);
268
269       return (String JavaDoc) MetaStub.call(path, "_burlap_getAttribute", "java.home.class");
270     } catch (Throwable JavaDoc e) {
271       throw new ConfigException(e);
272     }
273   }
274
275   /**
276    * Returns the bean's remote interface class. If unknown, call the server
277    * for the class name.
278    */

279   Class JavaDoc getRemoteClass()
280     throws ConfigException
281   {
282     if (remoteClass != null)
283       return remoteClass;
284
285     try {
286       synchronized (this) {
287         if (remoteClass != null)
288           return remoteClass;
289
290         String JavaDoc className = getRemoteClassName();
291
292         if (className == null || className.equals("null"))
293           return null;
294
295         remoteClass = CauchoSystem.loadClass(className, false, null);
296       }
297     } catch (ClassNotFoundException JavaDoc e) {
298       throw new ConfigException(e);
299     }
300
301     return remoteClass;
302   }
303
304   /**
305    * Returns the classname of the remote interface.
306    */

307   String JavaDoc getRemoteClassName()
308     throws ConfigException
309   {
310     AbstractServer server = EjbProtocolManager.getJVMServer(serverId);
311
312     if (server != null) {
313       Class JavaDoc cl = server.getRemoteObjectClass();
314       if (cl != null)
315         return cl.getName();
316       else
317         throw new ConfigException(L.l("`{0}' has no remote interface.",
318                                       serverId));
319     }
320     
321     try {
322       Path path = Vfs.lookup(serverId);
323
324       return (String JavaDoc) MetaStub.call(path, "_burlap_getAttribute",
325                                     "java.object.class");
326     } catch (Throwable JavaDoc e) {
327       throw new ConfigException(e);
328     }
329   }
330   
331   /**
332    * Returns the bean's primary key class. If unknown, call the server
333    * for the class name.
334    */

335   Class JavaDoc getPrimaryKeyClass()
336     throws ConfigException
337   {
338     if (primaryKeyClass != null)
339       return primaryKeyClass;
340
341     try {
342       synchronized (this) {
343         if (primaryKeyClass != null)
344           return primaryKeyClass;
345
346         String JavaDoc className = getPrimaryKeyClassName();
347
348         primaryKeyClass = CauchoSystem.loadClass(className, false, null);
349       }
350     } catch (ClassNotFoundException JavaDoc e) {
351       throw new ConfigException(e);
352     }
353     
354     return primaryKeyClass;
355   }
356
357   /**
358    * Returns the classname of the home interface.
359    */

360   String JavaDoc getPrimaryKeyClassName()
361     throws ConfigException
362   {
363     AbstractServer server = EjbProtocolManager.getJVMServer(serverId);
364
365     if (server != null) {
366       Class JavaDoc cl = server.getPrimaryKeyClass();
367       if (cl != null)
368         return cl.getName();
369       else
370         throw new ConfigException(L.l("`{0}' has no remote interface.",
371                                       serverId));
372     }
373         
374     try {
375       Path path = Vfs.lookup(serverId);
376
377       return (String JavaDoc) MetaStub.call(path, "_burlap_getAttribute", "primary-key-class");
378     } catch (Throwable JavaDoc e) {
379       throw new ConfigException(e);
380     }
381   }
382   
383   /**
384    * Looks up a proxy object.
385    */

386   public Object JavaDoc lookup(String JavaDoc type, String JavaDoc url)
387     throws IOException JavaDoc
388   {
389     try {
390       Class JavaDoc api = CauchoSystem.loadClass(type);
391
392       return create(api, url);
393     } catch (Exception JavaDoc e) {
394       throw new IOException JavaDoc(String.valueOf(e));
395     }
396   }
397
398   /**
399    * Creates a new proxy with the specified URL. The returned object
400    * is a proxy with the interface specified by api.
401    *
402    * <pre>
403    * String url = "http://localhost:8080/ejb/hello");
404    * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
405    * </pre>
406    *
407    * @param api the interface the proxy class needs to implement
408    * @param url the URL where the client object is located.
409    *
410    * @return a proxy to the object with the specified interface.
411    */

412   public Object JavaDoc create(Class JavaDoc api, String JavaDoc url)
413     throws Exception JavaDoc
414   {
415     StubGenerator gen = new StubGenerator();
416     gen.setClassDir(CauchoSystem.getWorkPath());
417       
418     Class JavaDoc cl = gen.createStub(api);
419
420     BurlapStub stub = (BurlapStub) cl.newInstance();
421
422     stub._init(url, this);
423
424     return stub;
425   }
426
427   /**
428    * Returns the basic auth.
429    */

430   String JavaDoc getBasicAuthentication()
431   {
432     return _basicAuth;
433   }
434
435   /**
436    * Sets the basic auth.
437    */

438   void setBasicAuthentication(String JavaDoc auth)
439   {
440     if (auth != null)
441       _basicAuth = "Basic " + auth;
442     else
443       _basicAuth = auth;
444   }
445
446   /**
447    * Returns a printable version of the client container
448    */

449   public String JavaDoc toString()
450   {
451     return "BurlapClientContainer[" + serverId + "]";
452   }
453 }
454
Popular Tags