Source Code Cross Referenced for SimpleEJB3Container.java in  » J2EE » jfox » org » jfox » ejb3 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » jfox » org.jfox.ejb3 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.io.Serializable;
010:        import java.lang.reflect.Method;
011:        import java.util.ArrayList;
012:        import java.util.Arrays;
013:        import java.util.Collection;
014:        import java.util.Collections;
015:        import java.util.Date;
016:        import java.util.HashMap;
017:        import java.util.Iterator;
018:        import java.util.List;
019:        import java.util.Map;
020:        import java.util.concurrent.ConcurrentHashMap;
021:        import java.util.concurrent.ScheduledFuture;
022:        import java.util.concurrent.ScheduledThreadPoolExecutor;
023:        import java.util.concurrent.TimeUnit;
024:        import javax.ejb.EJBException;
025:        import javax.ejb.MessageDriven;
026:        import javax.ejb.Stateful;
027:        import javax.ejb.Stateless;
028:        import javax.ejb.Timer;
029:        import javax.ejb.TimerService;
030:        import javax.naming.Binding;
031:        import javax.naming.Context;
032:        import javax.naming.NameAlreadyBoundException;
033:        import javax.naming.NameClassPair;
034:        import javax.naming.NameNotFoundException;
035:        import javax.naming.NamingEnumeration;
036:        import javax.naming.NamingException;
037:        import javax.transaction.SystemException;
038:        import javax.transaction.TransactionManager;
039:
040:        import org.apache.log4j.Logger;
041:        import org.jfox.ejb3.event.EJBLoadedComponentEvent;
042:        import org.jfox.ejb3.event.EJBUnloadedComponentEvent;
043:        import org.jfox.ejb3.invocation.InterceptorsEJBInvocationHandler;
044:        import org.jfox.ejb3.invocation.SecurityEJBInvocationHandler;
045:        import org.jfox.ejb3.invocation.ThreadContextEJBInvocationHandler;
046:        import org.jfox.ejb3.invocation.TransactionEJBInvocationHandler;
047:        import org.jfox.ejb3.naming.ContextAdapter;
048:        import org.jfox.ejb3.naming.InitialContextFactoryImpl;
049:        import org.jfox.ejb3.timer.EJBTimerTask;
050:        import org.jfox.ejb3.transaction.JTATransactionManager;
051:        import org.jfox.framework.annotation.Constant;
052:        import org.jfox.framework.annotation.Service;
053:        import org.jfox.framework.component.ComponentContext;
054:        import org.jfox.framework.component.Module;
055:        import org.jfox.framework.event.ModuleEvent;
056:        import org.jfox.framework.event.ModuleListener;
057:        import org.jfox.framework.event.ModuleLoadingEvent;
058:        import org.jfox.framework.event.ModuleUnloadedEvent;
059:        import org.jfox.jms.JMSConnectionFactory;
060:        import org.jfox.jms.MessageService;
061:        import org.jfox.mvc.SessionContext;
062:
063:        /**
064:         * �支� Local/Stateless Session Bean, Local MDB
065:         * �时,该 Container 也承担了 NamingContainer 的能力
066:         * <p/>
067:         * 必须�� SimpleEJB3Container 第一个加载,�则,无法监�到 ModuleEvent,而无法 load ejb
068:         *
069:         * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
070:         */
071:        @Service(id="EJB3Container",singleton=true,active=true)
072:        public class SimpleEJB3Container implements  EJBContainer,
073:                ModuleListener {
074:
075:            protected Logger logger = Logger
076:                    .getLogger(SimpleEJB3Container.class);
077:
078:            // Transaction Manager
079:            private JTATransactionManager tm = null;
080:
081:            // default Transaction timeout
082:            @Constant(type=Integer.class,value="$jta_transaction_timeout")
083:            private int transactionTimeout = 60; // default transaction timeout 60 seconds
084:
085:            // TimerServer
086:            private ContainerTimerService timerService = null;
087:
088:            // JMS ConnectionFactory
089:            private MessageService messageService = null;
090:
091:            // container naming context, also is initialcontext for IntialContextFactoryImpl
092:            private Context namingContext = null;
093:
094:            /**
095:             * 执行 ejb invocation 的 chain
096:             */
097:            private final List<EJBInvocationHandler> invocationChain = new ArrayList<EJBInvocationHandler>();
098:
099:            /**
100:             * ejb name => EJBBucket
101:             */
102:            private final Map<String, EJBBucket> bucketMap = new ConcurrentHashMap<String, EJBBucket>();
103:
104:            /**
105:             * jndi Resource
106:             */
107:            private final Map<String, Object> jndiMap = new ConcurrentHashMap<String, Object>();
108:
109:            private ComponentContext componentContext;
110:
111:            public SimpleEJB3Container() {
112:                invocationChain.add(new ThreadContextEJBInvocationHandler());
113:                invocationChain.add(new SecurityEJBInvocationHandler());
114:                invocationChain.add(new TransactionEJBInvocationHandler());
115:                invocationChain.add(new InterceptorsEJBInvocationHandler());
116:            }
117:
118:            public void postContruct(ComponentContext componentContext) {
119:                this .componentContext = componentContext;
120:            }
121:
122:            public void postInject() {
123:                // new NamingContext, then set to InitialContextFactoryImpl
124:                namingContext = new ContainerNamingContext();
125:                InitialContextFactoryImpl.setInitialContext(namingContext);
126:
127:                tm = JTATransactionManager.getIntsance();
128:                tm.setDefaultTransactionTimeout(getTransactionTimeout());
129:                timerService = new ContainerTimerService();
130:                messageService = new JMSConnectionFactory();
131:
132:                // 将 TransactionManager 注册 java:/TransactionManager
133:                try {
134:                    tm.setTransactionTimeout(getTransactionTimeout());
135:                    getNamingContext().bind("java:/TransactionManager", tm);
136:                    getNamingContext().bind("java:/UserTransaction", tm);
137:                    getNamingContext().bind("defaultcf", messageService);
138:                } catch (NamingException e) {
139:                    logger.fatal("Bind TransactionManager error.", e);
140:                    System.exit(1);
141:                } catch (SystemException e) {
142:                    logger.fatal("Failed to setTransactionTimeout!", e);
143:                    System.exit(1);
144:                }
145:            }
146:
147:            public boolean preUnregister(ComponentContext context) {
148:                tm.stop();
149:                timerService.stop();
150:                try {
151:                    namingContext.close();
152:                } catch (NamingException e) {
153:                    logger.warn("EJBContainer NamingContext close exception.",
154:                            e);
155:                }
156:                jndiMap.clear();
157:                return true;
158:            }
159:
160:            public void postUnregister() {
161:
162:            }
163:
164:            public int getTransactionTimeout() {
165:                return transactionTimeout;
166:            }
167:
168:            public void setTransactionTimeout(int transactionTimeout) {
169:                this .transactionTimeout = transactionTimeout;
170:                if (tm != null) {
171:                    tm.setDefaultTransactionTimeout(transactionTimeout);
172:                }
173:            }
174:
175:            /**
176:             * 监� Module 事件,根� Module 的 load/unload 事件�加载其中的 EJB
177:             *
178:             * @param moduleEvent module event
179:             */
180:            public void moduleChanged(ModuleEvent moduleEvent) {
181:                Module module = moduleEvent.getModule();
182:                if (moduleEvent instanceof  ModuleLoadingEvent) {
183:                    // 监� ModuleLoadingEvent,以��能够在Action之�完� EJB 装载,从而在 Action 实例化的时候,注入
184:                    // 对于 SYSTEM_MODULE,� SystemModule.start,�了特殊处�
185:                    EJBBucket[] buckets = loadEJB(module);
186:                    for (EJBBucket bucket : buckets) {
187:                        bucketMap.put(bucket.getEJBName(), bucket);
188:                    }
189:                } else if (moduleEvent instanceof  ModuleUnloadedEvent) {
190:                    unloadEJB(module);
191:                }
192:            }
193:
194:            protected EJBBucket[] loadEJB(Module module) {
195:                List<EJBBucket> buckets = new ArrayList<EJBBucket>();
196:
197:                // stateless
198:                Class[] statelessBeans = module.getModuleClassLoader()
199:                        .findClassAnnotatedWith(Stateless.class);
200:                for (Class beanClass : statelessBeans) {
201:                    EJBBucket bucket = new StatelessBucket(
202:                            (EJBContainer) componentContext
203:                                    .getMyselfComponent(), beanClass, module);
204:                    buckets.add(bucket);
205:                    //fireEvent, 以便XFire�以 register Endpoint
206:                    componentContext
207:                            .fireComponentEvent(new EJBLoadedComponentEvent(
208:                                    componentContext.getComponentId(), bucket));
209:                    // bind to jndi
210:                    try {
211:                        for (String mappedName : bucket.getMappedNames()) {
212:                            this .getNamingContext().bind(mappedName,
213:                                    bucket.createProxyStub());
214:                        }
215:                    } catch (NamingException e) {
216:                        throw new EJBException("bind "
217:                                + Arrays.toString(bucket.getMappedNames())
218:                                + " failed!", e);
219:                    }
220:                    bucket.start();
221:                    logger.info("Stateless EJB loaded, bean class: "
222:                            + beanClass.getName());
223:                }
224:                // stateful
225:                Class[] statefulBeans = module.getModuleClassLoader()
226:                        .findClassAnnotatedWith(Stateful.class);
227:                for (Class beanClass : statefulBeans) {
228:                    final EJBBucket bucket = new StatefulBucket(
229:                            (EJBContainer) componentContext
230:                                    .getMyselfComponent(), beanClass, module);
231:                    buckets.add(bucket);
232:                    // bind to jndi
233:                    try {
234:                        for (String mappedName : bucket.getMappedNames()) {
235:                            this .getNamingContext().bind(mappedName,
236:                                    bucket.createProxyStub());
237:                        }
238:                    } catch (NamingException e) {
239:                        throw new EJBException("Failed to bind EJB with name: "
240:                                + Arrays.toString(bucket.getMappedNames())
241:                                + " !", e);
242:                    }
243:                    bucket.start();
244:                    logger.info("Stateful EJB loaded, bean class: "
245:                            + beanClass.getName());
246:                }
247:
248:                // message driven
249:                Class[] mdbBeans = module.getModuleClassLoader()
250:                        .findClassAnnotatedWith(MessageDriven.class);
251:                for (Class beanClass : mdbBeans) {
252:                    EJBBucket bucket = new MDBBucket(
253:                            (EJBContainer) componentContext
254:                                    .getMyselfComponent(), beanClass, module);
255:                    buckets.add(bucket);
256:                    // bind to jndi
257:                    try {
258:                        for (String mappedName : bucket.getMappedNames()) {
259:                            this .getNamingContext().bind(mappedName,
260:                                    bucket.createProxyStub());
261:                        }
262:                    } catch (NamingException e) {
263:                        throw new EJBException("Failed to bind EJB with name: "
264:                                + Arrays.toString(bucket.getMappedNames())
265:                                + " !", e);
266:                    }
267:                    // will register MDBBucket as MessageListener
268:                    bucket.start();
269:                    logger.info("Message Driven EJB loaded, bean class: "
270:                            + beanClass.getName());
271:                }
272:
273:                return buckets.toArray(new EJBBucket[buckets.size()]);
274:            }
275:
276:            protected void unloadEJB(Module module) {
277:                Iterator<Map.Entry<String, EJBBucket>> it = bucketMap
278:                        .entrySet().iterator();
279:                while (it.hasNext()) {
280:                    EJBBucket bucket = it.next().getValue();
281:                    if (bucket.getModule() == module) {
282:                        it.remove();
283:                        //fireEvent, 以便XFire�以 unregister Endpoint
284:                        componentContext
285:                                .fireComponentEvent(new EJBUnloadedComponentEvent(
286:                                        componentContext.getComponentId(),
287:                                        bucket));
288:                        // destroy ejb bucket
289:                        logger.info("Unload EJB: " + bucket.getEJBName()
290:                                + ", Module: " + bucket.getModule().getName());
291:                        bucket.stop();
292:                        try {
293:                            for (String mappedName : bucket.getMappedNames()) {
294:                                this .getNamingContext().unbind(mappedName);
295:                            }
296:
297:                        } catch (NamingException e) {
298:                            throw new EJBException("unbind ejb: "
299:                                    + bucket.getMappedNames() + " failed!", e);
300:                        }
301:                    }
302:                }
303:            }
304:
305:            public Collection<EJBBucket> listBuckets() {
306:                return Collections.unmodifiableCollection(bucketMap.values());
307:            }
308:
309:            public EJBBucket getEJBBucket(String name) {
310:                return bucketMap.get(name);
311:            }
312:
313:            /**
314:             * 通过接�类� EJBBucket
315:             *
316:             * @param interfaceClass bean interface
317:             */
318:            public Collection<EJBBucket> getEJBBucketByBeanInterface(
319:                    Class interfaceClass) {
320:                List<EJBBucket> buckets = new ArrayList<EJBBucket>();
321:                for (EJBBucket bucket : bucketMap.values()) {
322:                    if (bucket.isBusinessInterface(interfaceClass)) {
323:                        buckets.add(bucket);
324:                    }
325:                }
326:                return Collections.unmodifiableCollection(buckets);
327:            }
328:
329:            /**
330:             * 构造 ejb invocation,并且获得 chain,然��起调用
331:             *
332:             * @param ejbObjectId     ejb object id
333:             * @param interfaceMethod ejb interfaceMethod, 已�解��实体方法
334:             * @param params          parameters
335:             * @param securityContext security context
336:             * @throws Exception exception
337:             */
338:            public Object invokeEJB(EJBObjectId ejbObjectId,
339:                    Method interfaceMethod, Object[] params,
340:                    SessionContext securityContext) throws Exception {
341:                logger.debug("invokeEJB: EJBObjectId=" + ejbObjectId
342:                        + ", Method: " + interfaceMethod.getName());
343:                EJBBucket bucket = getEJBBucket(ejbObjectId.getEJBName());
344:                // get instance from bucket's pool
345:                ExtendEJBContext ejbContext = null;
346:                try {
347:                    ejbContext = bucket.getEJBContext(ejbObjectId);
348:                    Method concreteMethod = bucket
349:                            .getConcreteMethod(interfaceMethod);
350:                    if (concreteMethod == null) {
351:                        throw new NoSuchMethodException(
352:                                "Could not found Concrete Business Method for interface method: "
353:                                        + interfaceMethod.getName());
354:                    }
355:                    EJBInvocation invocation = new EJBInvocation(ejbObjectId,
356:                            bucket, ejbContext.getEJBInstance(),
357:                            interfaceMethod, concreteMethod, params,
358:                            securityContext);
359:                    return invokeEJBInvocation(invocation);
360:                } finally {
361:                    // reuse ejb instance
362:                    if (ejbContext != null) {
363:                        bucket.reuseEJBContext(ejbContext);
364:                    }
365:                }
366:
367:            }
368:
369:            /**
370:             * invoke timeout method
371:             *
372:             * @param ejbObjectId     ejb object id
373:             * @param interfaceMethod timeout interfaceMethod,�能是实体方法,也�能是 TimedObject 接�方法
374:             * @param params          parameters
375:             * @throws Exception exception
376:             */
377:            protected Object invokeTimeout(EJBObjectId ejbObjectId,
378:                    Method interfaceMethod, Object[] params,
379:                    SessionContext sessionContext) throws Exception {
380:                EJBBucket bucket = getEJBBucket(ejbObjectId.getEJBName());
381:                // get instance from bucket's pool
382:                ExtendEJBContext ejbContext = null;
383:                try {
384:                    ejbContext = bucket.getEJBContext(ejbObjectId);
385:                    EJBInvocation invocation = new EJBInvocation(ejbObjectId,
386:                            bucket, ejbContext.getEJBInstance(),
387:                            interfaceMethod, interfaceMethod, params,
388:                            sessionContext);
389:                    return invokeEJBInvocation(invocation);
390:                } finally {
391:                    // reuse ejb instance
392:                    if (ejbContext != null) {
393:                        bucket.reuseEJBContext(ejbContext);
394:                    }
395:                }
396:            }
397:
398:            protected Object invokeEJBInvocation(EJBInvocation invocation)
399:                    throws Exception {
400:                invocation.setTransactionManager(getTransactionManager());
401:                Iterator<EJBInvocationHandler> chain = invocationChain
402:                        .iterator();
403:                return chain.next().invoke(invocation, chain);
404:            }
405:
406:            public TransactionManager getTransactionManager() {
407:                return tm;
408:            }
409:
410:            public TimerService getTimerService() {
411:                return timerService;
412:            }
413:
414:            public Context getNamingContext() {
415:                return namingContext;
416:            }
417:
418:            public MessageService getMessageService() {
419:                return messageService;
420:            }
421:
422:            public boolean preInvoke(Method method, Object[] params) {
423:                // just return true
424:                return true;
425:            }
426:
427:            public Object postInvoke(Method method, Object[] params,
428:                    Object result, Throwable exception) {
429:                return result;
430:            }
431:
432:            // ------------ JNDI Context ------
433:
434:            public class ContainerNamingContext extends ContextAdapter {
435:
436:                public void bind(String name, Object obj)
437:                        throws NamingException {
438:                    if (jndiMap.containsKey(name)) {
439:                        throw new NameAlreadyBoundException(name);
440:                    }
441:                    jndiMap.put(name, obj);
442:                }
443:
444:                public void rebind(String name, Object obj)
445:                        throws NamingException {
446:                    jndiMap.put(name, obj);
447:                }
448:
449:                public void unbind(String name) throws NamingException {
450:                    if (!jndiMap.containsKey(name)) {
451:                        throw new NameNotFoundException(name);
452:                    }
453:                }
454:
455:                /**
456:                 * 从 jndiMap lookup resource, ejb proxy stub 已�绑定了
457:                 *
458:                 * @param name resource or ejb name
459:                 * @throws NamingException if name not found
460:                 */
461:                public Object lookup(String name) throws NamingException {
462:
463:                    //解� java:comp/env
464:                    if (name.startsWith(JAVA_COMP_ENV)) {
465:                        EJBInvocation currentEJBInvocation = EJBInvocation
466:                                .current();
467:                        if (currentEJBInvocation == null) {
468:                            // �在 EJB 调用上下文中
469:                            throw new NameNotFoundException(JAVA_COMP_ENV);
470:                        }
471:
472:                        if (name.equals(JAVA_COMP_ENV)) { // lookup java:comp/env
473:                            // EJBBucket extends Context
474:                            return getEJBBucket(
475:                                    currentEJBInvocation.getEJBObjectId()
476:                                            .getEJBName()).getENContext(
477:                                    currentEJBInvocation.getEJBObjectId());
478:                        } else { // lookup java:comp/env/abc
479:                            EJBBucket bucket = getEJBBucket(currentEJBInvocation
480:                                    .getEJBObjectId().getEJBName());
481:                            return bucket.getENContext(
482:                                    currentEJBInvocation.getEJBObjectId())
483:                                    .lookup(
484:                                            name.substring(JAVA_COMP_ENV
485:                                                    .length() + 1));
486:                        }
487:                    }
488:
489:                    if (!jndiMap.containsKey(name)) {
490:                        throw new NameNotFoundException(name);
491:                    }
492:                    return jndiMap.get(name);
493:                }
494:
495:                public NamingEnumeration<NameClassPair> list(String name)
496:                        throws NamingException {
497:                    final NamingEnumeration<Binding> bindings = listBindings(name);
498:                    return new NamingEnumeration<NameClassPair>() {
499:                        public NameClassPair next() throws NamingException {
500:                            return bindings.next();
501:                        }
502:
503:                        public boolean hasMore() throws NamingException {
504:                            return bindings.hasMore();
505:                        }
506:
507:                        public void close() throws NamingException {
508:                            bindings.close();
509:                        }
510:
511:                        public boolean hasMoreElements() {
512:                            return bindings.hasMoreElements();
513:                        }
514:
515:                        public NameClassPair nextElement() {
516:                            return bindings.nextElement();
517:                        }
518:                    };
519:                }
520:
521:                public NamingEnumeration<Binding> listBindings(String name)
522:                        throws NamingException {
523:                    final Map<String, Object> namingMap = new HashMap<String, Object>();
524:                    if (name == null || name.trim().length() == 0
525:                            || name.trim().equals("/")) { // all Bindings
526:                        namingMap.putAll(jndiMap);
527:                    } else {
528:                        namingMap.put(name, jndiMap.get(name));
529:                    }
530:                    final Iterator<Map.Entry<String, Object>> iterator = namingMap
531:                            .entrySet().iterator();
532:                    return new NamingEnumeration<Binding>() {
533:                        public boolean hasMore() throws NamingException {
534:                            return iterator.hasNext();
535:                        }
536:
537:                        public Binding next() throws NamingException {
538:                            Map.Entry<String, Object> entry = iterator.next();
539:                            return new Binding(entry.getKey(), entry.getValue());
540:                        }
541:
542:                        public void close() throws NamingException {
543:                            // do nothing
544:                        }
545:
546:                        public boolean hasMoreElements() {
547:                            return iterator.hasNext();
548:                        }
549:
550:                        public Binding nextElement() {
551:                            try {
552:                                return next();
553:                            } catch (NamingException nException) {
554:                                throw new EJBException(
555:                                        "NamingEnumeration.nextElement exception.",
556:                                        nException);
557:                            }
558:                        }
559:                    };
560:                }
561:            }
562:
563:            // Container Timer Service
564:            public class ContainerTimerService implements  TimerService {
565:
566:                /**
567:                 * EJBTimerTasks, use WeakHashMap, when EJBTimerTask un contained by java.util.Timer,
568:                 * it will be automatic removed by GC
569:                 * EJBTimerTask => timer hashCode
570:                 */
571:                //        private Map<EJBTimerTask, String> timerTasks = new WeakHashMap<EJBTimerTask, String>();
572:                private ScheduledThreadPoolExecutor scheduleService = new ScheduledThreadPoolExecutor(
573:                        2);
574:
575:                public ContainerTimerService() {
576:
577:                }
578:
579:                public Timer createTimer(final long duration,
580:                        final Serializable info)
581:                        throws IllegalArgumentException, IllegalStateException,
582:                        EJBException {
583:                    EJBTimerTask timer = new EJBTimerTask(this , info);
584:                    ScheduledFuture future = scheduleService.schedule(timer,
585:                            duration, TimeUnit.MILLISECONDS);
586:                    timer.setFuture(future);
587:                    //            timerTasks.put(timer, System.currentTimeMillis() + "");
588:                    return timer;
589:                }
590:
591:                public Timer createTimer(Date expiration, Serializable info)
592:                        throws IllegalArgumentException, IllegalStateException,
593:                        EJBException {
594:                    EJBTimerTask timer = new EJBTimerTask(this , info);
595:                    ScheduledFuture future = scheduleService.schedule(timer,
596:                            expiration.getTime() - System.currentTimeMillis(),
597:                            TimeUnit.MILLISECONDS);
598:                    timer.setFuture(future);
599:                    //            timerTasks.put(timer, System.currentTimeMillis() + "");
600:                    return timer;
601:                }
602:
603:                public Timer createTimer(final long initialDuration,
604:                        final long intervalDuration, final Serializable info)
605:                        throws IllegalArgumentException, IllegalStateException,
606:                        EJBException {
607:                    EJBTimerTask timer = new EJBTimerTask(this , info);
608:                    ScheduledFuture future = scheduleService
609:                            .scheduleWithFixedDelay(timer, initialDuration,
610:                                    intervalDuration, TimeUnit.MILLISECONDS);
611:                    timer.setFuture(future);
612:                    //            timerTasks.put(timer, System.currentTimeMillis() + "");
613:                    return timer;
614:                }
615:
616:                public Timer createTimer(Date initialExpiration,
617:                        long intervalDuration, Serializable info)
618:                        throws IllegalArgumentException, IllegalStateException,
619:                        EJBException {
620:                    EJBTimerTask timer = new EJBTimerTask(this , info);
621:                    ScheduledFuture future = scheduleService
622:                            .scheduleWithFixedDelay(timer, initialExpiration
623:                                    .getTime()
624:                                    - System.currentTimeMillis(),
625:                                    intervalDuration, TimeUnit.MILLISECONDS);
626:                    timer.setFuture(future);
627:                    //            timerTasks.put(timer, System.currentTimeMillis() + "");
628:                    return timer;
629:                }
630:
631:                public Collection getTimers() throws IllegalStateException,
632:                        EJBException {
633:                    //            return Collections.unmodifiableCollection(timerTasks.keySet());
634:                    return Arrays.asList(scheduleService.getQueue().toArray(
635:                            new Runnable[scheduleService.getQueue().size()]));
636:                }
637:
638:                /**
639:                 * 执行 Timeout 方法,有 ScheduleService 调用 EJBTimerTask.run,EJBTimerTask回调该方法,
640:                 * 通过容器æ?¥è°ƒç”¨ï¼Œä»¥æ??供事务和执行 lifecycle 回调
641:                 *
642:                 * @param ejbTimerTask ejb TimerTask
643:                 * @throws EJBException ejb exception when error
644:                 */
645:                public void timeout(final EJBTimerTask ejbTimerTask)
646:                        throws EJBException {
647:                    Method timeMethod = null;
648:                    try {
649:                        for (Method _timeoutMethod : ejbTimerTask
650:                                .getTimeoutMethods()) {
651:                            timeMethod = _timeoutMethod;
652:                            logger.info("Call Timeout method: "
653:                                    + _timeoutMethod + " of EJB: "
654:                                    + ejbTimerTask.getEJBObjectId());
655:                            // 这样会�动事务
656:                            invokeTimeout(ejbTimerTask.getEJBObjectId(),
657:                                    _timeoutMethod,
658:                                    new Object[] { ejbTimerTask }, ejbTimerTask
659:                                            .getSessionContext());
660:                        }
661:                    } catch (Exception e) {
662:                        logger.error("Call Timeout method " + timeMethod
663:                                + " throw exception.", e);
664:                        throw new EJBException(
665:                                "TimedObject callback exception.", e);
666:                    }
667:                }
668:
669:                public void stop() {
670:                    scheduleService.shutdown();
671:                }
672:            }
673:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.