KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfox > ejb > BucketSupport


1 /* JFox, the OpenSource J2EE Application Server
2  *
3  * Distributable under GNU LGPL license by gun.org
4  * more details please visit http://www.huihoo.org/jfox
5  */

6
7 package org.jfox.ejb;
8
9 import java.lang.reflect.Method JavaDoc;
10 import java.lang.reflect.Proxy JavaDoc;
11 import java.rmi.RemoteException JavaDoc;
12 import java.util.HashMap JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Map JavaDoc;
15 import javax.ejb.EJBException JavaDoc;
16 import javax.ejb.EJBHome JavaDoc;
17 import javax.ejb.EJBMetaData JavaDoc;
18 import javax.ejb.EnterpriseBean JavaDoc;
19 import javax.ejb.HomeHandle JavaDoc;
20 import javax.ejb.TimedObject JavaDoc;
21 import javax.ejb.TimerService JavaDoc;
22 import javax.naming.LinkRef JavaDoc;
23 import javax.naming.NamingException JavaDoc;
24
25 import org.jfox.ejb.connector.EJBConnectorInvoker;
26 import org.jfox.ejb.connector.EJBInvocation;
27 import org.jfox.ejb.handler.HandlerChain;
28 import org.jfox.ejb.meta.EJBDescriptor;
29 import org.jfox.ejb.meta.EJBReferenceDescriptor;
30 import org.jfox.ejb.meta.EnvEntryDescriptor;
31 import org.jfox.ejb.meta.ResourceEnvRefDescriptor;
32 import org.jfox.ejb.meta.ResourceRefDescriptor;
33 import org.jfox.ejb.timer.EJBTimerService;
34 import org.jfox.ejb.timer.TimedObjectMethod;
35 import org.jfox.ioc.common.AbstractComponent;
36 import org.jfox.ioc.util.Methods;
37 import org.jfox.jndi.InitialContextHelper;
38 import org.jfox.jndi.enc.EnterpriseContext;
39
40 /**
41  * 提供 bucket 的公共方法
42  *
43  * @author <a HREF="mailto:young_yy@hotmail.com">Young Yang</a>
44  */

45
46 public abstract class BucketSupport extends AbstractComponent implements Bucket {
47 // protected Logger logger = Logger.getLogger(getClass().getName());
48
protected BucketMeta bucketMeta = null;
49 // protected Container container = null;
50

51     // homeClassName 将作为ObjectId 的前缀
52
protected String JavaDoc homeClassName = null;
53     /**
54      * EJBObject 接口中定义的方法
55      * methodHashCode => Method Object
56      */

57     protected Map JavaDoc beanMethods = new HashMap JavaDoc();
58     protected Map JavaDoc homeMethods = new HashMap JavaDoc();
59
60     protected static Map JavaDoc ejbObjectMethods = new HashMap JavaDoc(5);
61     static {
62         ejbObjectMethods.put(String.valueOf(Methods.getMethodHash(EJBObjectMethod.GetEJBHome)),EJBObjectMethod.GetEJBHome);
63         ejbObjectMethods.put(String.valueOf(Methods.getMethodHash(EJBObjectMethod.GetHandle)), EJBObjectMethod.GetHandle);
64         ejbObjectMethods.put(String.valueOf(Methods.getMethodHash(EJBObjectMethod.GetPrimaryKey)), EJBObjectMethod.GetPrimaryKey);
65         ejbObjectMethods.put(String.valueOf(Methods.getMethodHash(EJBObjectMethod.IsIdentical)), EJBObjectMethod.IsIdentical);
66         ejbObjectMethods.put(String.valueOf(Methods.getMethodHash(EJBObjectMethod.Remove)), EJBObjectMethod.Remove);
67     }
68
69     protected EJBObjectIDGenerator idgen = null;
70
71 // protected List interceptors = new ArrayList();
72
protected HandlerChain handlerChain = null;
73
74     // enc
75
protected EnterpriseContext enc = new EnterpriseContext();
76
77     protected TimerService JavaDoc timerService;
78
79     public BucketSupport() {
80
81     }
82
83     public void setBucketMeta(BucketMeta meta) {
84         this.bucketMeta = meta;
85     }
86
87     public void setHandlerChain(HandlerChain handlerChain) {
88         this.handlerChain = handlerChain;
89     }
90
91     public ClassLoader JavaDoc getEJBClassLoader() {
92         return bucketMeta.getBeanClass().getClassLoader();
93     }
94
95     public EJBMetaData JavaDoc getEJBMetaData() throws RemoteException JavaDoc {
96         return bucketMeta.getEJBMetaData();
97     }
98
99     public EJBHome JavaDoc getEJBHome() throws RemoteException JavaDoc {
100         return bucketMeta.getEJBMetaData().getEJBHome();
101     }
102
103     public HomeHandle JavaDoc getHomeHandle() throws RemoteException JavaDoc {
104         return new HomeHandleImpl(bucketMeta.getEJBDescriptor().getJndiName());
105     }
106
107     public EnterpriseContext getEnterpriseContext() {
108         return enc;
109     }
110
111     // call back the ejbCreate method
112
public void ejbCreate(EnterpriseBean JavaDoc bean, String JavaDoc createMethod, Object JavaDoc[] args) throws RemoteException JavaDoc {
113         char c = createMethod.charAt(0);
114         String JavaDoc ejbCreateMethodName = "ejb" + Character.toUpperCase(c) + createMethod.substring(1);
115
116         logger.debug(bean + " " + ejbCreateMethodName);
117         Class JavaDoc[] signatures = null;
118         if(args != null && args.length != 0) {
119             signatures = new Class JavaDoc[args.length];
120             for(int i = 0; i < args.length; i++) {
121                 signatures[i] = args[i].getClass();
122             }
123         }
124
125         try {
126             bean.getClass().getMethod(ejbCreateMethodName, signatures).invoke(bean, args);
127         }
128         catch(Exception JavaDoc e) {
129             throw new RemoteException JavaDoc(e.getMessage(), e);
130         }
131     }
132
133     /**
134      * 生成 EJBHome ,使用 DelegateInvocationHandler, 由客户来决定使用什么协议
135      *
136      * @return
137      */

138     private EJBHome JavaDoc createEJBHome() {
139         EJBHome JavaDoc home = (EJBHome JavaDoc) Proxy.newProxyInstance(bucketMeta.getEJBMetaData().getHomeInterfaceClass().getClassLoader(),
140                 new Class JavaDoc[]{bucketMeta.getEJBMetaData().getHomeInterfaceClass()},
141                 new EJBConnectorInvoker(this.getHomeObjectId(),null));
142         logger.debug("createEJBHome " + homeClassName + " Successful");
143         return home;
144     }
145
146     /**
147      * 缓存在 EJBHome,EJBObject 接口中定义的对象
148      *
149      * @param classObj
150      * @return
151      */

152     protected Map JavaDoc introspectorHomeMethods(Class JavaDoc classObj) {
153         Map JavaDoc homeMethods = new HashMap JavaDoc();
154         Method JavaDoc[] methods = classObj.getMethods();
155         for(int i = 0; i < methods.length; i++) {
156             long hashCode = Methods.getMethodHash(methods[i]);
157             homeMethods.put(String.valueOf(hashCode), methods[i]);
158             logger.debug("Cache Home method: " + hashCode + " => " + classObj.getName() + "." + methods[i].getName());
159         }
160         return homeMethods;
161     }
162
163     /**
164      * 缓存在 EnterpriseBean 类中定义的对象
165      * 这些方法应该都是已经在 EJBObject 接口中已经定义的
166      *
167      * @param beanClass
168      * @return
169      */

170     protected Map JavaDoc introspectorBeanMethods(Class JavaDoc beanClass, Class JavaDoc remoteInterface) {
171         Map JavaDoc methods = new HashMap JavaDoc();
172         Method JavaDoc[] remoteMethods = remoteInterface.getDeclaredMethods();
173         for(int i = 0; i < remoteMethods.length; i++) {
174             Method JavaDoc _method = remoteMethods[i];
175             try {
176                 Method JavaDoc method = beanClass.getMethod(_method.getName(), _method.getParameterTypes());
177                 long hashCode = Methods.getMethodHash(method);
178                 methods.put(String.valueOf(hashCode), method);
179                 logger.debug("Cache Bean method: " + hashCode + " => " + beanClass.getName() + "." + method.getName());
180             }
181             catch(Exception JavaDoc e) {
182                 throw new EJBException JavaDoc(e);
183             }
184         }
185
186         // TimedObject
187
if(TimedObject JavaDoc.class.isAssignableFrom(beanClass)) {
188             long hashCode = Methods.getMethodHash(TimedObjectMethod.TimeOut);
189             methods.put(String.valueOf(hashCode), TimedObjectMethod.TimeOut);
190             logger.debug("Cache business method: " + hashCode + " => " + TimedObjectMethod.TimeOut.getName());
191         }
192
193         return methods;
194     }
195
196
197     public Method JavaDoc getHomeMethod(EJBInvocation invocation) throws NoSuchMethodException JavaDoc {
198         if(!homeMethods.containsKey(invocation.getMethodHash())) {
199             throw new NoSuchMethodException JavaDoc("no such EJBHome method with method hash is " + invocation.getMethodHash());
200         }
201         return (Method JavaDoc) homeMethods.get(invocation.getMethodHash());
202     }
203
204     public Method JavaDoc getBeanMethod(EJBInvocation invocation) throws NoSuchMethodException JavaDoc {
205         String JavaDoc hash = invocation.getMethodHash();
206         if(beanMethods.containsKey(hash)) {
207             return (Method JavaDoc)beanMethods.get(hash);
208         }
209         if(ejbObjectMethods.containsKey(invocation.getMethodHash())){
210            return (Method JavaDoc)ejbObjectMethods.get(hash);
211         }
212         throw new NoSuchMethodException JavaDoc("no such EnterpriseBean method with method hash is " + invocation.getMethodHash());
213     }
214
215     public EJBDescriptor getEJBDescriptor() {
216         return bucketMeta.getEJBDescriptor();
217     }
218
219     public TimerService JavaDoc getTimerService() {
220         return timerService;
221     }
222
223     public EJBObjectId nextObjectId() {
224         return idgen.nextBeanObjectId();
225     }
226
227     public EJBObjectId getHomeObjectId() {
228         return idgen.getHomeObjectId();
229     }
230
231     public Class JavaDoc getBeanClass() {
232         return bucketMeta.getBeanClass();
233     }
234
235     /**
236      * 来自 EJBHome 的方法
237      *
238      * @param invocation
239      * @return
240      * @throws Exception
241      */

242     public Object JavaDoc invokeHome(EJBInvocation invocation) throws Exception JavaDoc {
243         logger.debug("invokeHome " + invocation.getMethod().getName());
244         return handlerChain.invokeHome(this, invocation);
245 // return ((HandlerChain) Registry.getInstance().getComponentInstance(ComponentName.parseString(HandlerChain.class.getName() + "@Stateless"))).invokeHome(this, invocation);
246
}
247
248     /**
249      * 执行 Bean 的方法
250      *
251      * @param invocation
252      * @return
253      * @throws Exception
254      */

255     public Object JavaDoc invokeBean(EJBInvocation invocation) throws Exception JavaDoc {
256         logger.debug("invokeBean " + invocation.getMethod().getName());
257         return handlerChain.invokeBean(this, invocation);
258
259     }
260
261     protected void doInit() throws Exception JavaDoc {
262 // logger = Logger.getLogger(this.getClass().getName() + "[" + bucketMeta.getBeanClass().getName() + "]");
263
idgen = EJBObjectIDGenerator.newInstance(bucketMeta.getEJBDescriptor().getEjbName(),
264                                                  bucketMeta.getEJBMetaData().getHomeInterfaceClass().getName(),
265                                                  bucketMeta.getEJBMetaData().getRemoteInterfaceClass().getName());
266
267         this.homeClassName = bucketMeta.getEJBMetaData().getHomeInterfaceClass().getName();
268         homeMethods = introspectorHomeMethods(bucketMeta.getEJBMetaData().getHomeInterfaceClass());
269         beanMethods = introspectorBeanMethods(bucketMeta.getBeanClass(), bucketMeta.getEJBMetaData().getRemoteInterfaceClass());
270 // beanMethods.putAll(introspectorInterfMethods(EJBObject.class));
271

272         timerService = new EJBTimerService(bucketMeta.getEJBDescriptor().getEjbName());
273
274         // setEJBHome , 以便 doInit 能够将其绑定到 jndi
275
((EJBMetaDataImpl) bucketMeta.getEJBMetaData()).setEJBHome(createEJBHome());
276
277         EJBDescriptor ejbDescriptor = bucketMeta.getEJBDescriptor();
278         InitialContextHelper.getInitialContext().bind(ejbDescriptor.getJndiName(), bucketMeta.getEJBMetaData().getEJBHome());
279
280         // bind refrence to EnterpriseContext
281
bindReference();
282
283     }
284
285     protected void doDestroy() throws Exception JavaDoc {
286         InitialContextHelper.getInitialContext().unbind(bucketMeta.getEJBDescriptor().getJndiName());
287     }
288
289     protected void bindReference() {
290         EJBDescriptor ejbDescriptor = bucketMeta.getEJBDescriptor();
291         try {
292             List JavaDoc entries = ejbDescriptor.getEnvEntries();
293             for(int i = 0; i < entries.size(); i++) {
294                 EnvEntryDescriptor env = (EnvEntryDescriptor) entries.get(i);
295                 String JavaDoc name = env.getName();
296                 Object JavaDoc value = env.getValueObject();
297                 enc.bind(name, value);
298                 logger.debug("bind env-entry, name: " + name);
299             }
300
301             List JavaDoc ejbRefs = ejbDescriptor.getEjbReferences();
302             for(int i = 0; i < ejbRefs.size(); i++) {
303                 EJBReferenceDescriptor ejbRef = (EJBReferenceDescriptor) ejbRefs.get(i);
304 // checkEjbReference(ejbRef);
305
LinkRef JavaDoc linkRef = new LinkRef JavaDoc(ejbRef.getRefName());
306                 enc.bind(ejbRef.getRefName(), linkRef);
307                 logger.debug("bind ejb-ref, name: " + ejbRef.getRefName());
308             }
309
310             List JavaDoc resRefs = ejbDescriptor.getResourceReferences();
311             for(int i = 0; i < resRefs.size(); i++) {
312                 ResourceRefDescriptor resRef = (ResourceRefDescriptor) resRefs.get(i);
313 // checkResourceRef(resRef);
314
LinkRef JavaDoc linkRef = new LinkRef JavaDoc(resRef.getRefName());
315                 enc.bind(resRef.getRefName(), linkRef);
316                 logger.debug("bind resource-ref, name: " + resRef.getRefName());
317             }
318
319             List JavaDoc resourceEnvRefs = ejbDescriptor.getResourceEnvReferences();
320             for(int i = 0; i < resourceEnvRefs.size(); i++) {
321                 ResourceEnvRefDescriptor resourceEnvRef = (ResourceEnvRefDescriptor) resourceEnvRefs.get(i);
322 // checkResourceEnvRef(resourceEnvRef);
323
LinkRef JavaDoc linkRef = new LinkRef JavaDoc(resourceEnvRef.getRefName());
324                 enc.bind(resourceEnvRef.getRefName(), linkRef);
325                 logger.debug("bind resource-env-ref, name: " + resourceEnvRef.getRefName());
326             }
327
328         }
329         catch(NamingException JavaDoc e) {
330             logger.warn("bind EnterpriseContext error", e);
331         }
332     }
333
334
335 }
336
337
Popular Tags