001: /*
002: * JFox - The most lightweight Java EE Application Server!
003: * more details please visit http://www.huihoo.org/jfox or http://www.jfox.org.cn.
004: *
005: * JFox is licenced and re-distributable under GNU LGPL.
006: */
007: package org.jfox.ejb3;
008:
009: import java.lang.annotation.Annotation;
010: import java.lang.reflect.Field;
011: import java.lang.reflect.InvocationHandler;
012: import java.lang.reflect.Method;
013: import java.lang.reflect.Modifier;
014: import java.lang.reflect.Proxy;
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.Collection;
018: import java.util.Collections;
019: import java.util.HashMap;
020: import java.util.HashSet;
021: import java.util.List;
022: import java.util.Map;
023: import java.util.Set;
024: import javax.annotation.PostConstruct;
025: import javax.annotation.PreDestroy;
026: import javax.annotation.Resource;
027: import javax.annotation.Resources;
028: import javax.ejb.EJB;
029: import javax.ejb.EJBException;
030: import javax.ejb.EJBLocalObject;
031: import javax.ejb.EJBObject;
032: import javax.ejb.EJBs;
033: import javax.ejb.Local;
034: import javax.ejb.Remote;
035: import javax.interceptor.AroundInvoke;
036: import javax.interceptor.Interceptors;
037: import javax.interceptor.InvocationContext;
038: import javax.naming.Context;
039: import javax.naming.NameAlreadyBoundException;
040: import javax.naming.NameNotFoundException;
041: import javax.naming.NamingException;
042: import javax.persistence.EntityManager;
043: import javax.persistence.EntityManagerFactory;
044: import javax.persistence.PersistenceContext;
045: import javax.persistence.PersistenceUnit;
046: import javax.transaction.Status;
047: import javax.transaction.SystemException;
048:
049: import org.apache.log4j.Logger;
050: import org.jfox.ejb3.dependent.EJBDependence;
051: import org.jfox.ejb3.dependent.FieldEJBDependence;
052: import org.jfox.ejb3.dependent.FieldResourceDependence;
053: import org.jfox.ejb3.dependent.ResourceDependence;
054: import org.jfox.ejb3.interceptor.ExternalInterceptorMethod;
055: import org.jfox.ejb3.interceptor.InterceptorMethod;
056: import org.jfox.ejb3.interceptor.InternalInterceptorMethod;
057: import org.jfox.ejb3.naming.ContextAdapter;
058: import org.jfox.entity.dependent.FieldPersistenceContextDependence;
059: import org.jfox.entity.dependent.FieldPersistenceUnitDependence;
060: import org.jfox.framework.component.Module;
061: import org.jfox.framework.component.ModuleClassLoader;
062: import org.jfox.framework.dependent.InjectionException;
063: import org.jfox.mvc.SessionContext;
064: import org.jfox.util.AnnotationUtils;
065: import org.jfox.util.ClassUtils;
066: import org.jfox.util.MethodUtils;
067:
068: /**
069: * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
070: */
071: public abstract class SessionBucket implements EJBBucket {
072:
073: protected final Logger logger = Logger.getLogger(this .getClass());
074:
075: private Class<?> beanClass;
076: private Class[] ejbInterfaces = null;
077: private String ejbName;
078:
079: private List<String> mappedNames = new ArrayList<String>(2);
080: private String description = "";
081:
082: private EJBContainer container = null;
083:
084: /**
085: * Module of EJB
086: */
087: private Module module;
088:
089: /**
090: * cached methods,speed up to get Method when reflect
091: * cached method is concrete method
092: * hash => Method
093: */
094: private final Map<Long, Method> concreteMethods = new HashMap<Long, Method>();
095:
096: /**
097: * class level @interceptor methods
098: */
099: private List<InterceptorMethod> classInterceptorMethods = new ArrayList<InterceptorMethod>();
100: /**
101: * Method level interceptors
102: * ejb concrete method => interceptor methods
103: */
104: private Map<Method, List<InterceptorMethod>> methodInterceptorMethods = new HashMap<Method, List<InterceptorMethod>>();
105:
106: /**
107: * 在 Bean 实现类ä¸çš„ @AroundInvoke
108: */
109: private List<InterceptorMethod> beanInterceptorMethods = new ArrayList<InterceptorMethod>();
110:
111: /**
112: * stateless session bean �有 PostConstruct & PreDestroy 有效
113: */
114: private List<Method> postConstructMethods = new ArrayList<Method>();
115: private List<Method> preDestroyMethods = new ArrayList<Method>();
116:
117: /**
118: * 类级别的ä¾?赖,æ??述在 Class 上
119: */
120: private List<EJBDependence> classEJBDependents = new ArrayList<EJBDependence>();
121: private List<ResourceDependence> classResourceDependents = new ArrayList<ResourceDependence>();
122:
123: /**
124: * Field级别的ä¾?赖,æ??述在 Field 上
125: */
126: protected List<FieldEJBDependence> fieldEJBdependents = new ArrayList<FieldEJBDependence>();
127: protected List<FieldResourceDependence> fieldResourcedependents = new ArrayList<FieldResourceDependence>();
128:
129: /**
130: * persistenceContext ä¾?èµ–
131: */
132: protected List<FieldPersistenceContextDependence> fieldPersistenceContextDependences = new ArrayList<FieldPersistenceContextDependence>();
133: protected List<FieldPersistenceUnitDependence> fieldPersistenceUnitDependences = new ArrayList<FieldPersistenceUnitDependence>();
134:
135: public SessionBucket(EJBContainer container, Class<?> beanClass,
136: Module module) {
137: this .container = container;
138: this .module = module;
139: this .beanClass = beanClass;
140:
141: //æ ¹æ?® Local/Remote 指定的beanInterface
142: Set<Class> annotatedBeanInterfaces = new HashSet<Class>();
143: if (beanClass.isAnnotationPresent(Remote.class)) {
144: Remote remote = beanClass.getAnnotation(Remote.class);
145: if (remote.value().length != 0) {
146: annotatedBeanInterfaces.addAll(Arrays.asList(remote
147: .value()));
148: }
149: }
150: if (beanClass.isAnnotationPresent(Local.class)) {
151: Local local = beanClass.getAnnotation(Local.class);
152: if (local.value().length != 0) {
153: annotatedBeanInterfaces.addAll(Arrays.asList(local
154: .value()));
155: }
156: }
157: if (annotatedBeanInterfaces.isEmpty()) {
158: this .ejbInterfaces = ClassUtils
159: .getAllInterfaces(getBeanClass());
160: } else {
161: this .ejbInterfaces = annotatedBeanInterfaces
162: .toArray(new Class[annotatedBeanInterfaces.size()]);
163: }
164:
165: introspectMethods();
166: introspectLifecycleAndInterceptors();
167:
168: introspectClassDependents();
169: introspectFieldDependents();
170: }
171:
172: protected void introspectMethods() {
173: // ç¼“å˜ EJB 方法,以便å??射的时候,æ??å?‡æ‰§è¡Œé€Ÿåº¦
174: Set<Long> interfaceMethodHashes = new HashSet<Long>();
175: for (Class<?> interfaceClass : getEJBInterfaces()) {
176: for (Method method : interfaceClass.getMethods()) {
177: long methodHash = MethodUtils.getMethodHash(method);
178: interfaceMethodHashes.add(methodHash);
179: }
180: }
181:
182: Method[] concreteMethods = beanClass.getMethods();
183: for (Method method : concreteMethods) {
184: long methodHash = MethodUtils.getMethodHash(method);
185: if (interfaceMethodHashes.contains(methodHash)) {
186: this .concreteMethods.put(methodHash, method);
187: }
188:
189: }
190: }
191:
192: /**
193: * 找到所有类级别的拦截方法
194: */
195: protected void introspectLifecycleAndInterceptors() {
196: // beanClass is in superClass array
197: Class<?>[] super Classes = ClassUtils
198: .getAllSuperclasses(getBeanClass());
199:
200: List<Long> postConstructMethodHashes = new ArrayList<Long>();
201: List<Long> preDestoryMethodHashes = new ArrayList<Long>();
202: List<Long> aroundInvokeMethodHashes = new ArrayList<Long>();
203: for (Class<?> super Class : super Classes) {
204:
205: // PostConstruct
206: for (Method postConstructMethod : introspectPostContstructMethod(super Class)) {
207: long methodHash = MethodUtils
208: .getMethodHash(postConstructMethod);
209: if (!postConstructMethodHashes.contains(methodHash)) {
210: postConstructMethods.add(0, postConstructMethod);
211: postConstructMethodHashes.add(methodHash);
212: }
213: }
214:
215: // PreDestroy
216: for (Method preDestroyMethod : introspectPreDestroyMethod(super Class)) {
217: long methodHash = MethodUtils
218: .getMethodHash(preDestroyMethod);
219: if (!preDestoryMethodHashes.contains(methodHash)) {
220: preDestroyMethods.add(0, preDestroyMethod);
221: preDestoryMethodHashes.add(methodHash);
222: }
223: }
224:
225: // @AroundInvoke
226: for (Method aroundInvokeMethod : introspectAroundInvokeMethod(super Class)) {
227: // 还没有在classInterceptorMethodsä¸ï¼Œå?类如果覆盖了父类的方法,父类的方法将ä¸?å†?执行
228: long methodHash = MethodUtils
229: .getMethodHash(aroundInvokeMethod);
230: if (!aroundInvokeMethodHashes.contains(methodHash)) {
231: beanInterceptorMethods.add(0,
232: new InternalInterceptorMethod(
233: aroundInvokeMethod));
234: aroundInvokeMethodHashes.add(methodHash);
235: }
236: }
237:
238: //如果是 Bean Class 本身,检查类级 @Interceptors
239: if (super Class.equals(getBeanClass())) {
240: // @Interceptors Method,å?–出所有å?¯è®¿é—®çš„ æ ‡å‡† @Interceptor 的方法
241: Method[] interceptedBeanMethods = AnnotationUtils
242: .getAnnotatedMethods(super Class,
243: Interceptors.class);
244: for (Method interceptedBeanMethod : interceptedBeanMethods) {
245: if (isBusinessMethod(interceptedBeanMethod)) { // 是业务方法
246: Interceptors interceptors = interceptedBeanMethod
247: .getAnnotation(Interceptors.class);
248: Class[] interceptorClasses = interceptors
249: .value();
250: // �出 @AroundInvoke 方法
251: for (Class<?> interceptorClass : interceptorClasses) {
252: Method[] interceptorsAroundInvokeMethods = AnnotationUtils
253: .getAnnotatedMethods(
254: interceptorClass,
255: AroundInvoke.class);
256: List<InterceptorMethod> validAroundInvokeMethods = new ArrayList<InterceptorMethod>();
257: for (Method aroundInvokeMethod : interceptorsAroundInvokeMethods) {
258: if (checkInterceptorMethod(super Class,
259: aroundInvokeMethod)) {
260: validAroundInvokeMethods
261: .add(
262: 0,
263: new ExternalInterceptorMethod(
264: interceptorClass,
265: aroundInvokeMethod));
266: }
267: }
268: methodInterceptorMethods.put(
269: interceptedBeanMethod,
270: validAroundInvokeMethods);
271: }
272: }
273: }
274: // @Interceptors Class, 为了简化, �分� Bean Class 上的Annotation
275: if (super Class.isAnnotationPresent(Interceptors.class)) {
276: Interceptors interceptors = super Class
277: .getAnnotation(Interceptors.class);
278: Class[] interceptorClasses = interceptors.value();
279:
280: // �出 @AroundInvoke 方法
281: for (Class<?> interceptorClass : interceptorClasses) {
282: Method[] interceptorsAroundInvokeMethods = AnnotationUtils
283: .getAnnotatedMethods(interceptorClass,
284: AroundInvoke.class);
285: for (Method aroundInvokeMethod : interceptorsAroundInvokeMethods) {
286: if (checkInterceptorMethod(
287: interceptorClass,
288: aroundInvokeMethod)) {
289: aroundInvokeMethod.setAccessible(true);
290: classInterceptorMethods.add(0,
291: new ExternalInterceptorMethod(
292: interceptorClass,
293: aroundInvokeMethod));
294: }
295: }
296: }
297: //TODO: 检测 Interceptors ä¸çš„ PostConstruct PreDestroy
298: }
299: }
300: }
301: }
302:
303: protected List<Method> introspectPostContstructMethod(
304: Class super Class) {
305: List<Method> postConstructMethods = new ArrayList<Method>();
306: // PostConstruct
307: Method[] _postConstructMethods = AnnotationUtils
308: .getAnnotatedDeclaredMethods(super Class,
309: PostConstruct.class);
310: for (Method postConstructMethod : _postConstructMethods) {
311: postConstructMethod.setAccessible(true);
312: postConstructMethods.add(0, postConstructMethod);
313: }
314: return postConstructMethods;
315: }
316:
317: protected List<Method> introspectPreDestroyMethod(Class super Class) {
318: List<Method> preDestroyMethods = new ArrayList<Method>();
319: Method[] _preDestroyMethods = AnnotationUtils
320: .getAnnotatedDeclaredMethods(super Class,
321: PreDestroy.class);
322: for (Method preDestroyMethod : _preDestroyMethods) {
323: if (checkCallbackMethod(super Class, preDestroyMethod,
324: PreDestroy.class)) {
325: preDestroyMethod.setAccessible(true);
326: preDestroyMethods.add(0, preDestroyMethod);
327: }
328: }
329: return preDestroyMethods;
330: }
331:
332: protected List<Method> introspectAroundInvokeMethod(Class super Class) {
333: List<Method> aroundInvokeMethods = new ArrayList<Method>();
334: Method[] _aroundInvokeMethods = AnnotationUtils
335: .getAnnotatedDeclaredMethods(super Class,
336: AroundInvoke.class);
337: if (_aroundInvokeMethods.length > 0) {
338: for (Method aroundInvokeMethod : _aroundInvokeMethods) {
339: if (checkInterceptorMethod(super Class,
340: aroundInvokeMethod)) {
341: aroundInvokeMethod.setAccessible(true);
342: aroundInvokeMethods.add(0, aroundInvokeMethod);
343: }
344: }
345: }
346: return aroundInvokeMethods;
347: }
348:
349: protected Collection<Method> getPostConstructMethods() {
350: return Collections.unmodifiableCollection(postConstructMethods);
351: }
352:
353: protected Collection<Method> getPreDestroyMethods() {
354: return Collections.unmodifiableCollection(preDestroyMethods);
355: }
356:
357: protected boolean isBusinessMethod(Method method) {
358: return concreteMethods.containsKey(MethodUtils
359: .getMethodHash(method));
360: }
361:
362: protected boolean checkCallbackMethod(Class<?> interceptorClass,
363: Method callbackMethod,
364: Class<? extends Annotation> lifecyleAnnotation) {
365: if (!Modifier.isAbstract(callbackMethod.getModifiers())
366: && !Modifier.isStatic(callbackMethod.getModifiers())
367: && callbackMethod.getParameterTypes().length == 0) {
368: return true;
369: } else {
370: logger
371: .warn("Invalid @"
372: + lifecyleAnnotation.getSimpleName()
373: + " method: " + callbackMethod
374: + " in class: " + interceptorClass);
375: return false;
376: }
377: }
378:
379: protected boolean checkInterceptorMethod(Class<?> interceptorClass,
380: Method aroundInvokeMethod) {
381: // check aroundInvokeMethod �法性
382: if (!Modifier.isAbstract(aroundInvokeMethod.getModifiers()) // � abstract 方法
383: && !Modifier
384: .isStatic(aroundInvokeMethod.getModifiers()) // � static 方法
385: && aroundInvokeMethod.getParameterTypes().length == 1 // �有一个�数
386: && aroundInvokeMethod.getParameterTypes()[0]
387: .equals(InvocationContext.class) // �数类型为 InvocationContext
388: && aroundInvokeMethod.getReturnType().equals(
389: Object.class) // 返回 Object 类型
390: && (!Modifier.isPrivate(aroundInvokeMethod
391: .getModifiers()) // �是 private 方法,或者是Bean自身的方法
392: || interceptorClass.equals(getBeanClass()))) {
393: return true;
394: } else {
395: logger.warn("Invalid @AroundInvoke interceptor method: "
396: + aroundInvokeMethod);
397: return false;
398: }
399: }
400:
401: /**
402: * 查找 Class Level Dependences
403: */
404: protected void introspectClassDependents() {
405: if (this .getBeanClass().isAnnotationPresent(EJBs.class)) {
406: EJB[] ejbs = this .getBeanClass().getAnnotation(EJBs.class)
407: .value();
408: for (EJB ejb : ejbs) {
409: classEJBDependents.add(new EJBDependence(this , ejb));
410: }
411: }
412: if (this .getBeanClass().isAnnotationPresent(EJB.class)) {
413: EJB ejb = this .getBeanClass().getAnnotation(EJB.class);
414: classEJBDependents.add(new EJBDependence(this , ejb));
415: }
416: if (this .getBeanClass().isAnnotationPresent(Resources.class)) {
417: Resource[] resources = this .getBeanClass().getAnnotation(
418: Resources.class).value();
419: for (Resource resource : resources) {
420: classResourceDependents.add(new ResourceDependence(
421: this , resource));
422: }
423: }
424: if (this .getBeanClass().isAnnotationPresent(Resource.class)) {
425: Resource resource = this .getBeanClass().getAnnotation(
426: Resource.class);
427: classResourceDependents.add(new ResourceDependence(this ,
428: resource));
429: }
430: }
431:
432: /**
433: * 查找 Field Level Dependences
434: */
435: protected void introspectFieldDependents() {
436: //需��现 AllSuperClass
437: List<Field> allEJBFields = new ArrayList<Field>();
438: List<Field> allResourceFields = new ArrayList<Field>();
439: List<Field> allPersistenceContextFields = new ArrayList<Field>();
440: List<Field> allPersistenceUnitFields = new ArrayList<Field>();
441:
442: // getAllSuperClass,也包括了自已
443: for (Class<?> clazz : ClassUtils.getAllSuperclasses(this
444: .getBeanClass())) {
445: Field[] ejbFields = AnnotationUtils.getAnnotatedFields(
446: clazz, EJB.class);
447: allEJBFields.addAll(Arrays.asList(ejbFields));
448:
449: Field[] resourceFields = AnnotationUtils
450: .getAnnotatedFields(clazz, Resource.class);
451: allResourceFields.addAll(Arrays.asList(resourceFields));
452:
453: Field[] persistenceContextFields = AnnotationUtils
454: .getAnnotatedFields(clazz, PersistenceContext.class);
455: allPersistenceContextFields.addAll(Arrays
456: .asList(persistenceContextFields));
457:
458: Field[] persistenceUnitFields = AnnotationUtils
459: .getAnnotatedFields(clazz, PersistenceUnit.class);
460: allPersistenceUnitFields.addAll(Arrays
461: .asList(persistenceUnitFields));
462: }
463:
464: for (Field field : allEJBFields) {
465: EJB ejb = field.getAnnotation(EJB.class);
466: fieldEJBdependents.add(new FieldEJBDependence(this , field,
467: ejb));
468: }
469:
470: for (Field field : allResourceFields) {
471: Resource resource = field.getAnnotation(Resource.class);
472: fieldResourcedependents.add(new FieldResourceDependence(
473: this , field, resource));
474: }
475:
476: for (Field field : allPersistenceContextFields) {
477: if (!EntityManager.class.isAssignableFrom(field.getType())) {
478: throw new EJBException(
479: "@PersistenceContext must annotated on field with type "
480: + EntityManager.class.getName() + ", "
481: + field);
482: }
483: PersistenceContext pc = field
484: .getAnnotation(PersistenceContext.class);
485: fieldPersistenceContextDependences
486: .add(new FieldPersistenceContextDependence(this ,
487: field, pc));
488: }
489:
490: for (Field field : allPersistenceUnitFields) {
491: if (!EntityManagerFactory.class.isAssignableFrom(field
492: .getType())) {
493: throw new EJBException(
494: "@PersistenceUnit must annotated on field with type "
495: + EntityManagerFactory.class.getName()
496: + ", " + field);
497: }
498: PersistenceUnit pu = field
499: .getAnnotation(PersistenceUnit.class);
500: fieldPersistenceUnitDependences
501: .add(new FieldPersistenceUnitDependence(this ,
502: field, pu));
503: }
504:
505: }
506:
507: public ModuleClassLoader getBucketClassLoader() {
508: return this .module.getModuleClassLoader();
509: }
510:
511: public Module getModule() {
512: return module;
513: }
514:
515: public Class<?> getBeanClass() {
516: return beanClass;
517: }
518:
519: public Class[] getEJBInterfaces() {
520: return ejbInterfaces;
521: }
522:
523: private String[] getEJBInterfaceNames() {
524: Class[] interfaces = getEJBInterfaces();
525: String[] interfaceNames = new String[interfaces.length];
526: for (int i = 0; i < interfaces.length; i++) {
527: interfaceNames[i] = interfaces[i].getName();
528: }
529: return interfaceNames;
530: }
531:
532: public String getEJBName() {
533: return ejbName;
534: }
535:
536: protected void setEJBName(String ejbName) {
537: this .ejbName = ejbName;
538: }
539:
540: public String getDescription() {
541: return description;
542: }
543:
544: protected void setDescription(String description) {
545: this .description = description;
546: }
547:
548: public String[] getMappedNames() {
549: return mappedNames.toArray(new String[mappedNames.size()]);
550: }
551:
552: protected void addMappedName(String mappedName) {
553: mappedNames.add(mappedName);
554: }
555:
556: public EJBContainer getEJBContainer() {
557: return container;
558: }
559:
560: public Context getENContext(EJBObjectId ejbObjectId) {
561: return getEJBContext(ejbObjectId).getENContext();
562: }
563:
564: protected void injectClassDependents() {
565: //解�类级�赖
566: for (EJBDependence ejbDependence : classEJBDependents) {
567: try {
568: ejbDependence.inject(null);
569: } catch (InjectionException e) {
570: throw new EJBException("@EJB inject failed.", e);
571: }
572: }
573:
574: for (ResourceDependence resourceDependence : classResourceDependents) {
575: try {
576: resourceDependence.inject(null);
577: } catch (InjectionException e) {
578: throw new EJBException("@Resource inject failed.", e);
579: }
580: }
581: }
582:
583: /**
584: * craete new EJBObjectId
585: * <p/>
586: * Stateless: only one EJBObjectId
587: * Stateful: create new EJBObjectId very time to create new EJBContext
588: */
589: protected abstract EJBObjectId createEJBObjectId();
590:
591: /**
592: * create a new EJBContext according ejbObjectId & instance
593: *
594: * @param ejbObjectId ejb object id
595: * @param instance ejb bean instance
596: */
597: protected abstract ExtendEJBContext createEJBContext(
598: EJBObjectId ejbObjectId, Object instance);
599:
600: /**
601: * get EJBContext according ejb object id
602: *
603: * @param ejbObjectId ejb object id
604: * @throws EJBException exception
605: */
606: public abstract ExtendEJBContext getEJBContext(
607: EJBObjectId ejbObjectId);
608:
609: /**
610: * å°†EJBContext返回给 pool, ejb context ä¸åŒ…å?«ejb instance
611: *
612: * @param ejbContext ejb context
613: */
614: public abstract void reuseEJBContext(ExtendEJBContext ejbContext);
615:
616: public Collection<InterceptorMethod> getClassInterceptorMethods() {
617: return Collections
618: .unmodifiableCollection(classInterceptorMethods);
619: }
620:
621: public Collection<InterceptorMethod> getMethodInterceptorMethods(
622: Method method) {
623: if (methodInterceptorMethods.containsKey(method)) {
624: return Collections
625: .unmodifiableList(methodInterceptorMethods
626: .get(method));
627: } else {
628: return Collections.emptyList();
629: }
630: }
631:
632: public Collection<InterceptorMethod> getBeanInterceptorMethods() {
633: return Collections
634: .unmodifiableCollection(beanInterceptorMethods);
635: }
636:
637: public boolean isSession() {
638: return true;
639: }
640:
641: public boolean isRemote() {
642: // no @Local is Remote
643: return getBeanClass().isAnnotationPresent(Remote.class)
644: || !getBeanClass().isAnnotationPresent(Local.class);
645: }
646:
647: public boolean isLocal() {
648: return getBeanClass().isAnnotationPresent(Local.class);
649: }
650:
651: public void start() {
652: // do nothing
653: }
654:
655: /**
656: * destroy bucket, invoke when container unload ejb
657: */
658: public void stop() {
659: // do nothing
660: }
661:
662: public String toString() {
663: return "EJB: " + getEJBName();
664: }
665:
666: /**
667: * 通过动�代�过�的接�方法,�得 Bean 实体方法,以便�以获得 Annotation
668: *
669: * @param interfaceMethod interfaceMethod
670: */
671: public Method getConcreteMethod(Method interfaceMethod) {
672: long methodHash = MethodUtils.getMethodHash(interfaceMethod);
673: return concreteMethods.get(methodHash);
674: }
675:
676: public boolean isBusinessInterface(Class beanInterface) {
677: for (Class bi : this .getEJBInterfaces()) {
678: if (bi.equals(beanInterface)) {
679: return true;
680: }
681: }
682: return false;
683: }
684:
685: /**
686: * 生�基于动�代�的 Stub
687: */
688: public synchronized EJBObject createProxyStub() {
689: List<Class> interfaces = new ArrayList<Class>();
690: interfaces.add(EJBObject.class);
691: interfaces.addAll(Arrays.asList(this .getEJBInterfaces()));
692:
693: // 生� EJB 的动�代�对象
694: return (EJBObject) Proxy.newProxyInstance(this .getModule()
695: .getModuleClassLoader(), interfaces
696: .toArray(new Class[interfaces.size()]),
697: new ProxyStubInvocationHandler());
698: }
699:
700: class ProxyStubInvocationHandler implements InvocationHandler {
701: EJBObjectId ejbObjectId = createEJBObjectId();
702:
703: public Object invoke(Object proxy, Method method, Object[] args)
704: throws Throwable {
705: //EJBObject 方法
706: if (method.getDeclaringClass().equals(EJBObject.class)
707: || method.getDeclaringClass().equals(
708: EJBLocalObject.class)) {
709: return method.invoke(getEJBContext(getEJBObjectId()),
710: args);
711: } else if (MethodUtils.isObjectMethod(method)) {
712: //优化处� Object 方法
713: if (method.getName().equals("toString")) {
714: return "$ejb_proxy_stub{ejbid=" + ejbObjectId
715: + ",interface="
716: + Arrays.toString(getEJBInterfaceNames())
717: + "}";
718: } else if (method.getName().equals("equals")) {
719: return (args[0] instanceof ProxyStubInvocationHandler)
720: && getEJBObjectId()
721: .equals(
722: ((ProxyStubInvocationHandler) args[0])
723: .getEJBObjectId());
724: } else if (method.getName().equals("hashCode")) {
725: return getEJBObjectId().hashCode();
726: } else if (method.getName().equals("clone")) {
727: throw new CloneNotSupportedException(
728: getEJBObjectId().toString());
729: } else {
730: throw new UnsupportedOperationException(
731: "Unsupport Object Method: " + method);
732: }
733: } else {
734: // 其它业务方法
735: return getEJBContainer()
736: .invokeEJB(
737: getEJBObjectId(),
738: method,
739: args,
740: SessionContext
741: .getCurrentThreadSessionContext());
742: }
743: }
744:
745: EJBObjectId getEJBObjectId() {
746: return ejbObjectId;
747: }
748:
749: }
750:
751: public class ENContext extends ContextAdapter {
752: /**
753: * Component env Map, ä¿?å˜ java:comp/env 对象,å?ªä¿?å˜ Class level 的注入
754: * Field Level ä¸?å?š env ä¿?å˜
755: */
756: private Map<String, Object> envMap = new HashMap<String, Object>();
757:
758: //--- java:comp/env naming container
759: public void bind(String name, Object obj)
760: throws NamingException {
761: if (envMap.containsKey(name)) {
762: throw new NameAlreadyBoundException(name);
763: }
764: envMap.put(name, obj);
765: }
766:
767: public void rebind(String name, Object obj)
768: throws NamingException {
769: envMap.put(name, obj);
770: }
771:
772: public void unbind(String name) throws NamingException {
773: if (!envMap.containsKey(name)) {
774: throw new NameNotFoundException(name);
775: }
776: envMap.remove(name);
777: }
778:
779: public Object lookup(String name) throws NamingException {
780: if (!envMap.containsKey(name)) {
781: throw new NameNotFoundException(name);
782: }
783: return envMap.get(name);
784: }
785: }
786:
787: // EJBContext Implementation
788: public class EJBContextImpl extends ExtendEJBContext {
789:
790: public EJBContextImpl(EJBObjectId ejbObjectId,
791: Object ejbInstance) {
792: super (ejbObjectId, ejbInstance);
793: }
794:
795: public boolean getRollbackOnly() throws IllegalStateException {
796: try {
797: return getEJBContainer().getTransactionManager()
798: .getStatus() == Status.STATUS_MARKED_ROLLBACK;
799: } catch (SystemException e) {
800: throw new EJBException(e);
801: }
802: }
803:
804: public Object lookup(final String name) {
805: try {
806: return getENContext().lookup(name);
807: } catch (NamingException e) {
808: logger
809: .warn("EJBContext.lookup " + name + " failed.",
810: e);
811: return null;
812: }
813: }
814:
815: public void setRollbackOnly() throws IllegalStateException {
816: try {
817: getEJBContainer().getTransactionManager()
818: .setRollbackOnly();
819: } catch (SystemException e) {
820: throw new EJBException(e);
821: }
822: }
823:
824: // Object method
825: public String toString() {
826: return "ejb_stub{name=" + getEJBName() + ",interface="
827: + Arrays.toString(getEJBInterfaces()) + "}";
828: }
829:
830: }
831:
832: }
|