KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > hessian > HessianClientContainer


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.hessian;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.ejb.AbstractServer;
33 import com.caucho.ejb.EJBExceptionWrapper;
34 import com.caucho.ejb.protocol.EjbProtocolManager;
35 import com.caucho.ejb.protocol.HandleEncoder;
36 import com.caucho.hessian.io.HessianRemoteResolver;
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 import java.util.Map JavaDoc;
48
49 /**
50  * Container for Hessian clients in the same JVM, but not the same
51  * class loader.
52  */

53 class HessianClientContainer implements HessianRemoteResolver {
54   protected static L10N L = new L10N(HessianClientContainer.class);
55
56   private static EnvironmentLocal<Map JavaDoc<String JavaDoc,HessianClientContainer>> _hessianClient =
57   new EnvironmentLocal<Map JavaDoc<String JavaDoc,HessianClientContainer>>("caucho.hessian.client");
58   
59   private String JavaDoc _serverId;
60   private HessianHandleEncoder _handleEncoder;
61   // the home stub
62
EJBHome JavaDoc _ejbHome;
63
64   Class JavaDoc _homeClass;
65   Class JavaDoc _remoteClass;
66   // the home stub class
67
Class JavaDoc _homeStubClass;
68   // the remote stub class
69
Class JavaDoc _remoteStubClass;
70   // the primary key class
71
Class JavaDoc _primaryKeyClass;
72
73   private String JavaDoc _basicAuth;
74
75   /**
76    * Creates a client container for same-JVM connections.
77    *
78    * @param serverId the server id
79    */

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

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

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

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

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

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

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

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

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

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

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

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

413   public Object JavaDoc create(Class JavaDoc api, String JavaDoc url)
414     throws Exception JavaDoc
415   {
416     StubGenerator gen = new StubGenerator();
417       
418     Class JavaDoc cl = gen.createStub(api);
419
420     HessianStub stub = (HessianStub) 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 "HessianClientContainer[" + _serverId + "]";
452   }
453 }
454
Popular Tags